Merge tag android-5.1.0_r1 into AOSP_5.1_MERGE

Change-Id: I3a846fb8ce87ec47d8896cb965797157f284e84d
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
new file mode 100644
index 0000000..7c5a563
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,235 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+if (is_win) {
+  # Only needed on Windows.
+  gles_gypi = exec_script(
+      "//build/gypi_to_gn.py",
+      [ rebase_path("src/libGLESv2.gypi") ],
+      "scope",
+      [ "src/libGLESv2.gypi" ])
+
+  egl_gypi = exec_script(
+      "//build/gypi_to_gn.py",
+      [ rebase_path("src/libEGL.gypi") ],
+      "scope",
+      [ "src/libEGL.gypi" ])
+}
+
+compiler_gypi = exec_script(
+    "//build/gypi_to_gn.py",
+    [ rebase_path("src/compiler.gypi") ],
+    "scope",
+    [ "src/compiler.gypi" ])
+
+# This config is exported to dependent targets (and also applied to internal
+# ones).
+config("external_config") {
+  include_dirs = [
+    "include",
+  ]
+}
+
+# This config is applied to internal Angle targets (not pushed to dependents).
+config("internal_config") {
+  include_dirs = [
+    "include",
+    "src",
+  ]
+}
+
+component("translator") {
+  sources = [
+    "src/compiler/translator/ShaderLang.cpp",
+    "src/compiler/translator/ShaderVars.cpp",
+  ]
+
+  defines = [ "ANGLE_TRANSLATOR_IMPLEMENTATION" ]
+
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [
+    ":internal_config",
+    "//build/config/compiler:no_chromium_code",
+  ]
+
+  deps = [
+    ":translator_lib",
+  ]
+  forward_dependent_configs_from = [ ":translator_lib" ]
+}
+
+# Holds the shared includes so we only need to list them once.
+source_set("includes") {
+  sources = [
+    "include/EGL/egl.h",
+    "include/EGL/eglext.h",
+    "include/EGL/eglplatform.h",
+    "include/GLES2/gl2.h",
+    "include/GLES2/gl2ext.h",
+    "include/GLES2/gl2platform.h",
+    "include/GLES3/gl3.h",
+    "include/GLES3/gl3ext.h",
+    "include/GLES3/gl3platform.h",
+    "include/GLSLANG/ShaderLang.h",
+    "include/KHR/khrplatform.h",
+  ]
+}
+
+static_library("preprocessor") {
+  sources = rebase_path(compiler_gypi.angle_preprocessor_sources, ".", "src")
+
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [
+    ":internal_config",
+    "//build/config/compiler:no_chromium_code",
+  ]
+}
+
+config("translator_static_config") {
+  defines = [ "ANGLE_TRANSLATOR_STATIC" ]
+}
+
+static_library("translator_lib") {
+  sources = rebase_path(compiler_gypi.angle_translator_lib_sources, ".", "src")
+
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [
+    ":internal_config",
+    ":translator_static_config",
+    "//build/config/compiler:no_chromium_code",
+  ]
+  direct_dependent_configs = [ ":external_config" ]
+
+  deps = [
+    ":includes",
+    ":preprocessor",
+  ]
+}
+
+static_library("translator_static") {
+  sources = [
+    "src/compiler/translator/ShaderLang.cpp",
+    "src/compiler/translator/ShaderVars.cpp",
+  ]
+
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [
+    ":internal_config",
+    "//build/config/compiler:no_chromium_code",
+  ]
+  direct_dependent_configs = [ ":translator_static_config" ]
+
+  deps = [
+    ":translator_lib",
+  ]
+  forward_dependent_configs_from = [ ":translator_lib" ]
+}
+
+config("commit_id_config") {
+  include_dirs = [ "$root_gen_dir/angle" ]
+}
+
+action("commit_id") {
+  script = "src/commit_id.py"
+
+  output_file = "$root_gen_dir/angle/id/commit.h"
+  outputs = [ output_file ]
+
+  args = [
+    "gen",
+    rebase_path(".", root_build_dir),
+    rebase_path(output_file, root_build_dir),
+  ]
+
+  direct_dependent_configs = [ ":commit_id_config" ]
+}
+
+if (is_win) {
+  angle_enable_d3d9 = true
+  angle_enable_d3d11 = true
+
+  shared_library("libGLESv2") {
+    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={ " +
+        "\"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }",
+      "GL_APICALL=",
+      "GL_GLEXT_PROTOTYPES=",
+      "EGLAPI=",
+    ]
+    libs = []
+
+    # Shared D3dD sources.
+    if (angle_enable_d3d9 || angle_enable_d3d11) {
+      sources += rebase_path(gles_gypi.angle_d3d_shared_sources, ".", "src")
+    }
+
+    if (angle_enable_d3d9) {
+      sources += rebase_path(gles_gypi.angle_d3d9_sources, ".", "src")
+      defines += [ "ANGLE_ENABLE_D3D9" ]
+      libs += [ "d3d9.lib" ]
+    }
+
+    if (angle_enable_d3d11) {
+      sources += rebase_path(gles_gypi.angle_d3d11_sources, ".", "src")
+      defines += [ "ANGLE_ENABLE_D3D11" ]
+      libs += [ "dxguid.lib" ]
+    }
+
+    if (is_debug) {
+      defines += [ "ANGLE_ENABLE_PERF" ]
+      libs += [ "d3d9.lib" ]
+    }
+
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [
+      ":internal_config",
+      "//build/config/compiler:no_chromium_code",
+    ]
+
+    include_dirs = [ "src/libGLESv2" ]
+
+    deps = [
+      ":commit_id",
+      ":includes",
+      ":translator",
+      #":copy_compiler_dll",  TODO(GYP)
+    ]
+  }
+
+  shared_library("libEGL") {
+    sources = rebase_path(egl_gypi.angle_libegl_sources, ".", "src")
+
+    defines = [
+      "GL_APICALL=",
+      "GL_GLEXT_PROTOTYPES=",
+      "EGLAPI=",
+    ]
+
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [
+      ":internal_config",
+      "//build/config/compiler:no_chromium_code",
+    ]
+
+    if (is_debug) {
+      defines += [ "ANGLE_ENABLE_PERF" ]
+    }
+
+    include_dirs = [ "src/libGLESv2" ]
+    libs = [ "d3d9.lib" ]
+
+    deps = [
+      ":commit_id",
+      ":includes",
+      ":libGLESv2",
+    ]
+  }
+}  # is_win
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index fcb6315..0cae10a 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -52,10 +52,14 @@
 Cloud Party, Inc.
  Conor Dickinson
 
+Digia Plc
+ Andrew Knight
+
 Intel Corporation
  Jin Yang
  Andy Chen
  Josh Triplett
+ Sudarsana Nagineni
 
 Klarälvdalens Datakonsult AB
  Milian Wolff
@@ -75,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 8a87e16..b35a79e 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -71,8 +71,7 @@
                         'AdditionalOptions': ['/MP'],
                         'BufferSecurityCheck': 'true',
                         'DebugInformationFormat': '3',
-                        # TODO(alokp): Disable exceptions before integrating with chromium.
-                        #'ExceptionHandling': '0',
+                        'ExceptionHandling': '0',
                         'EnableFunctionLevelLinking': 'true',
                         'MinimalRebuild': 'false',
                         'RuntimeTypeInfo': 'true',
@@ -152,6 +151,7 @@
                     },
                     'VCLibrarianTool':
                     {
+                        'TargetMachine': '1',
                         'AdditionalLibraryDirectories':
                         [
                             '<(windows_sdk_path)/Lib/win8/um/x86',
@@ -195,7 +195,7 @@
             },
             'conditions':
             [
-                [ 'OS == "win" and MSVS_VERSION != "2010e" and MSVS_VERSION != "2012e"',
+                [ 'OS == "win" and MSVS_VERSION != "2010e"',
                 {
                     'Debug_x64':
                     {
diff --git a/build/common_defines.gypi b/build/common_defines.gypi
index 4b6f347..5f53a7e 100644
--- a/build/common_defines.gypi
+++ b/build/common_defines.gypi
@@ -9,11 +9,7 @@
         'angle_path%': '..',
         'windows_sdk_path%': 'C:/Program Files (x86)/Windows Kits/8.0',
     },
-    'defines':
-    [
-        'NOMINMAX',
-    ],
-    'msvs_disabled_warnings': [ 4100, 4127, 4239, 4244, 4245, 4512, 4702, 4530, 4718, 4267 ],
+    'msvs_disabled_warnings': [ 4100, 4127, 4239, 4244, 4245, 4251, 4512, 4702, 4530, 4718, 4267 ],
     'msvs_system_include_dirs':
     [
         '<(windows_sdk_path)/Include/shared',
@@ -27,10 +23,7 @@
             [
                 '_CRT_SECURE_NO_DEPRECATE',
                 '_SCL_SECURE_NO_WARNINGS',
-                '_HAS_EXCEPTIONS=0',
-                '_WINDOWS',
-                'WIN32',
-                'WIN32_LEAN_AND_MEAN',
+                'NOMINMAX',
             ],
         },
         'VCLinkerTool':
diff --git a/extensions/ANGLE_platform_angle.txt b/extensions/ANGLE_platform_angle.txt
new file mode 100644
index 0000000..81846f4
--- /dev/null
+++ b/extensions/ANGLE_platform_angle.txt
@@ -0,0 +1,141 @@
+Name
+
+    ANGLE_platform_angle
+
+Name Strings
+
+    EGL_ANGLE_platform_angle
+
+Contributors
+
+    Scott Graham, Google
+    Shannon Woods, Google
+    Geoff Lang, Google
+
+Contacts
+
+    Scott Graham, Google (scottmg 'at' google 'dot' com)
+
+Status
+
+    Draft
+
+Version
+
+    Version 2, 2014-06-05
+
+Number
+
+    EGL Extension XXX
+
+Extension Type
+
+    EGL client extension
+
+Dependencies
+
+    Requires EGL_EXT_client_extensions to query its existence without
+    a display.
+
+    Requires EGL_EXT_platform_base.
+
+    This extension is written against the wording of version 9 of the
+    EGL_EXT_platform_base specification.
+
+    ANGLE_platform_angle_d3d affects the definition of this extension.
+    ANGLE_platform_angle_opengl affects the definition of this extension.
+
+Overview
+
+    This extension defines how to create EGL resources from resources using
+    the functions defined by EGL_EXT_platform_base.
+
+New Types
+
+    None
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    Accepted as the <platform> argument of eglGetPlatformDisplayEXT:
+
+        EGL_PLATFORM_ANGLE_ANGLE                           0x3201
+
+    Accepted as an attribute name in the <attrib_list> argument of
+    eglGetPlatformDisplayEXT:
+
+        EGL_PLATFORM_ANGLE_TYPE_ANGLE                      0x3202
+
+    Accepted as values for the EGL_PLATFORM_ANGLE_TYPE_ANGLE attribute:
+
+        EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE              0x3203
+
+Additions to the EGL Specification
+
+    None.
+
+New Behavior
+
+    To determine if the EGL implementation supports this extension, clients
+    should query the EGL_EXTENSIONS string of EGL_NO_DISPLAY.
+
+    To obtain an EGLDisplay backed by a ANGLE display, call
+    eglGetPlatformDisplayEXT with <platform> set to EGL_PLATFORM_ANGLE_ANGLE.
+
+    The <native_display> parameter is of type EGLNativeDisplayType. If
+    <native_display> is EGL_DEFAULT_DISPLAY a default display is returned.
+    Multiple calls with the same <native_display> will return the same
+    EGLDisplay handle. The value of EGL_PLATFORM_ANGLE_TYPE_ANGLE, if any,
+    is ignored if there was previously a EGLDisplay successfully created for a
+    given value of EGLNativeDisplayType.
+
+    If no <attrib_list> is specified, the value of
+    EGL_PLATFORM_ANGLE_TYPE_ANGLE is implicitly set to
+    EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE. Otherwise, the value of
+    EGL_PLATFORM_ANGLE_TYPE_ANGLE should be:
+      - EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE for an implementation dependent
+        display, equivalent to using a <native_display> of EGL_DEFAULT_DISPLAY,
+      - EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE for a D3D9 display which translates
+        to OpenGL ES,
+      - EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE for a D3D11 display which
+        translates to OpenGL ES,
+      - EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE a D3D11 WARP display which
+        translates to OpenGL ES,
+      - EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE for an OpenGL display which
+        translates to OpenGL ES,
+      - EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE for a native OpenGL ES display
+
+    If no display matching the requested <native_display> or of the type
+    requested by the value of EGL_PLATFORM_ANGLE_TYPE_ANGLE is available,
+    EGL_NO_DISPLAY is returned. No error condition is raised in this case.
+
+Dependencies on ANGLE_platform_angle_d3d
+
+    The EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
+    EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE and
+    EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE <native_display> parameters to
+    eglGetPlatformDisplayEXT are only valid if ANGLE_platform_angle_d3d is
+    supported.
+
+Dependencies on ANGLE_platform_angle_opengl
+
+    The EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE and
+    EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE <native_display> parameters to
+    eglGetPlatformDisplayEXT are only valid if ANGLE_platform_angle_opengl is
+    supported.
+
+Issues
+
+    None
+
+Revision History
+
+    Version 1, 2014-02-04 (Scott Graham)
+        - Initial draft
+    Version 2, 2014-06-05 (Geoff Lang)
+        - Rename extension from ANGLE_platform_angle_d3d to
+          ANGLE_platform_angle.
+        - Add sub-extensions for specific platforms.
diff --git a/extensions/ANGLE_platform_angle_d3d.txt b/extensions/ANGLE_platform_angle_d3d.txt
index 019150f..05da04f 100644
--- a/extensions/ANGLE_platform_angle_d3d.txt
+++ b/extensions/ANGLE_platform_angle_d3d.txt
@@ -1,4 +1,3 @@
-
 Name
 
     ANGLE_platform_angle_d3d
@@ -9,12 +8,12 @@
 
 Contributors
 
-    Scott Graham, Google
     Shannon Woods, Google
+    Geoff Lang, Google
 
 Contacts
 
-    Scott Graham, Google (scottmg 'at' google 'dot' com)
+    Geoff Lang, Google (geofflang 'at' chromium 'dot' org)
 
 Status
 
@@ -22,7 +21,7 @@
 
 Version
 
-    Version 1, 2014-02-04
+    Version 1, 2014-06-05
 
 Number
 
@@ -34,18 +33,11 @@
 
 Dependencies
 
-    Requires EGL_EXT_client_extensions to query its existence without
-    a display.
-
-    Requires EGL_EXT_platform_base.
-
-    This extension is written against the wording of version 9 of the
-    EGL_EXT_platform_base specification.
+    Requires ANGLE_platform_angle.
 
 Overview
 
-    This extension defines how to create EGL resources from resources using
-    the functions defined by EGL_EXT_platform_base.
+    This extension enables selection of D3D display types.
 
 New Types
 
@@ -57,56 +49,21 @@
 
 New Tokens
 
-    Accepted as the <platform> argument of eglGetPlatformDisplayEXT:
+    Accepted as values for the EGL_PLATFORM_ANGLE_TYPE_ANGLE attribute:
 
-        EGL_PLATFORM_ANGLE_D3D_ANGLE                       0x3201
-
-    Accepted as an attribute name in the <attrib_list> argument of
-    eglGetPlatformDisplayEXT:
-
-        EGL_PLATFORM_ANGLE_D3D_TYPE_ANGLE                  0x3202
-
-    Accepted as values for the EGL_PLATFORM_ANGLE_D3D_TYPE_ANGLE attribute:
-
-        EGL_PLATFORM_ANGLE_D3D_TYPE_D3D9_ANGLE             0x3203
-        EGL_PLATFORM_ANGLE_D3D_TYPE_D3D11_ANGLE            0x3204
-        EGL_PLATFORM_ANGLE_D3D_TYPE_D3D11_WARP_ANGLE       0x3205
+        EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE                 0x3204
+        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE                0x3205
+        EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE           0x3206
 
 Additions to the EGL Specification
 
     None.
 
-New Behavior
-
-    To determine if the EGL implementation supports this extension, clients
-    should query the EGL_EXTENSIONS string of EGL_NO_DISPLAY.
-
-    To obtain an EGLDisplay backed by a ANGLE D3D display, call
-    eglGetPlatformDisplayEXT with <platform> set to
-    EGL_PLATFORM_ANGLE_D3D_ANGLE.
-    
-    The <native_display> parameter is of type EGLNativeDisplayType. If
-    <native_display> is EGL_DEFAULT_DISPLAY a default display is returned.
-    Multiple calls with the same <native_display> will return the same
-    EGLDisplay handle. The value of EGL_PLATFORM_ANGLE_D3D_TYPE_ANGLE, if any,
-    is ignored if there was previously a EGLDisplay successfully created for a
-    given value of EGLNativeDisplayType.
-    
-    If no <attrib_list> is specified, a D3D9 device is created. Otherwise, the
-    value of EGL_PLATFORM_ANGLE_D3D_TYPE_ANGLE should be:
-      - EGL_PLATFORM_ANGLE_D3D_TYPE_D3D9_ANGLE for D3D9 hardware,
-      - EGL_PLATFORM_ANGLE_D3D_TYPE_D3D11_ANGLE for D3D11 hardware,
-      - EGL_PLATFORM_ANGLE_D3D_TYPE_D3D11_WARP_ANGLE for D3D11 WARP.
-        
-    If no display matching the requested <native_display> or of the type
-    requested by the value of EGL_PLATFORM_ANGLE_D3D_TYPE_ANGLE is available,
-    EGL_NO_DISPLAY is returned. No error condition is raised in this case.
-
 Issues
 
     None
 
 Revision History
 
-    Version 1, 2014-02-04 (Scott Graham)
+    Version 1, 2014-06-05 (Geoff Lang)
         - Initial draft
diff --git a/extensions/ANGLE_platform_angle_opengl.txt b/extensions/ANGLE_platform_angle_opengl.txt
new file mode 100644
index 0000000..4492a84
--- /dev/null
+++ b/extensions/ANGLE_platform_angle_opengl.txt
@@ -0,0 +1,68 @@
+Name
+
+    ANGLE_platform_angle_opengl
+
+Name Strings
+
+    EGL_ANGLE_platform_angle_opengl
+
+Contributors
+
+    Shannon Woods, Google
+    Geoff Lang, Google
+
+Contacts
+
+    Geoff Lang, Google (geofflang 'at' chromium 'dot' org)
+
+Status
+
+    Draft
+
+Version
+
+    Version 1, 2014-06-05
+
+Number
+
+    EGL Extension XXX
+
+Extension Type
+
+    EGL client extension
+
+Dependencies
+
+    Requires ANGLE_platform_angle.
+
+Overview
+
+    This extension enables selection of OpenGL display types.
+
+New Types
+
+    None
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    Accepted as values for the EGL_PLATFORM_ANGLE_TYPE_ANGLE attribute:
+
+        EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE               0x3207
+        EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE             0x3208
+
+Additions to the EGL Specification
+
+    None.
+
+Issues
+
+    None
+
+Revision History
+
+    Version 1, 2014-06-05 (Geoff Lang)
+        - Initial draft
\ No newline at end of file
diff --git a/generate_projects b/generate_projects
index 8175277..ffcaafb 100644
--- a/generate_projects
+++ b/generate_projects
@@ -18,7 +18,7 @@
 
 generation_dir = "projects"
 gyp_generators = "msvs"
-msvs_version = "2010e"
+msvs_version = "2013e"
 build_samples = True
 build_tests = False
 release_symbols = False
diff --git a/include/EGL/egl.h b/include/EGL/egl.h
index b55e6c6..12590a0 100644
--- a/include/EGL/egl.h
+++ b/include/EGL/egl.h
@@ -1,11 +1,12 @@
-/* -*- mode: c; tab-width: 8; -*- */
-/* vi: set sw=4 ts=8: */
-/* Reference version of egl.h for EGL 1.4.
- * $Revision: 9356 $ on $Date: 2009-10-21 05:52:25 -0400 (Wed, 21 Oct 2009) $
- */
+#ifndef __egl_h_
+#define __egl_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /*
-** Copyright (c) 2007-2009 The Khronos Group Inc.
+** Copyright (c) 2013-2014 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
@@ -26,304 +27,272 @@
 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 */
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+**   http://www.opengl.org/registry/
+**
+** Khronos $Revision: 27018 $ on $Date: 2014-06-10 08:06:12 -0700 (Tue, 10 Jun 2014) $
+*/
 
-#ifndef __egl_h_
-#define __egl_h_
-
-/* All platform-dependent types and macro boilerplate (such as EGLAPI
- * and EGLAPIENTRY) should go in eglplatform.h.
- */
 #include <EGL/eglplatform.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/* Generated on date 20140610 */
 
-/* EGL Types */
-/* EGLint is defined in eglplatform.h */
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_VERSION_1_0
+#define EGL_VERSION_1_0 1
 typedef unsigned int EGLBoolean;
-typedef unsigned int EGLenum;
-typedef void *EGLConfig;
-typedef void *EGLContext;
 typedef void *EGLDisplay;
+#include <KHR/khrplatform.h>
+#include <EGL/eglplatform.h>
+typedef void *EGLConfig;
 typedef void *EGLSurface;
-typedef void *EGLClientBuffer;
-
-/* EGL Versioning */
-#define EGL_VERSION_1_0			1
-#define EGL_VERSION_1_1			1
-#define EGL_VERSION_1_2			1
-#define EGL_VERSION_1_3			1
-#define EGL_VERSION_1_4			1
-
-/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
- * enums are assigned unique values starting at 0x3000.
- */
-
-/* EGL aliases */
-#define EGL_FALSE			0
-#define EGL_TRUE			1
-
-/* Out-of-band handle values */
-#define EGL_DEFAULT_DISPLAY		((EGLNativeDisplayType)0)
-#define EGL_NO_CONTEXT			((EGLContext)0)
-#define EGL_NO_DISPLAY			((EGLDisplay)0)
-#define EGL_NO_SURFACE			((EGLSurface)0)
-
-/* Out-of-band attribute value */
-#define EGL_DONT_CARE			((EGLint)-1)
-
-/* Errors / GetError return values */
-#define EGL_SUCCESS			0x3000
-#define EGL_NOT_INITIALIZED		0x3001
-#define EGL_BAD_ACCESS			0x3002
-#define EGL_BAD_ALLOC			0x3003
-#define EGL_BAD_ATTRIBUTE		0x3004
-#define EGL_BAD_CONFIG			0x3005
-#define EGL_BAD_CONTEXT			0x3006
-#define EGL_BAD_CURRENT_SURFACE		0x3007
-#define EGL_BAD_DISPLAY			0x3008
-#define EGL_BAD_MATCH			0x3009
-#define EGL_BAD_NATIVE_PIXMAP		0x300A
-#define EGL_BAD_NATIVE_WINDOW		0x300B
-#define EGL_BAD_PARAMETER		0x300C
-#define EGL_BAD_SURFACE			0x300D
-#define EGL_CONTEXT_LOST		0x300E	/* EGL 1.1 - IMG_power_management */
-
-/* Reserved 0x300F-0x301F for additional errors */
-
-/* Config attributes */
-#define EGL_BUFFER_SIZE			0x3020
-#define EGL_ALPHA_SIZE			0x3021
-#define EGL_BLUE_SIZE			0x3022
-#define EGL_GREEN_SIZE			0x3023
-#define EGL_RED_SIZE			0x3024
-#define EGL_DEPTH_SIZE			0x3025
-#define EGL_STENCIL_SIZE		0x3026
-#define EGL_CONFIG_CAVEAT		0x3027
-#define EGL_CONFIG_ID			0x3028
-#define EGL_LEVEL			0x3029
-#define EGL_MAX_PBUFFER_HEIGHT		0x302A
-#define EGL_MAX_PBUFFER_PIXELS		0x302B
-#define EGL_MAX_PBUFFER_WIDTH		0x302C
-#define EGL_NATIVE_RENDERABLE		0x302D
-#define EGL_NATIVE_VISUAL_ID		0x302E
-#define EGL_NATIVE_VISUAL_TYPE		0x302F
-#define EGL_SAMPLES			0x3031
-#define EGL_SAMPLE_BUFFERS		0x3032
-#define EGL_SURFACE_TYPE		0x3033
-#define EGL_TRANSPARENT_TYPE		0x3034
-#define EGL_TRANSPARENT_BLUE_VALUE	0x3035
-#define EGL_TRANSPARENT_GREEN_VALUE	0x3036
-#define EGL_TRANSPARENT_RED_VALUE	0x3037
-#define EGL_NONE			0x3038	/* Attrib list terminator */
-#define EGL_BIND_TO_TEXTURE_RGB		0x3039
-#define EGL_BIND_TO_TEXTURE_RGBA	0x303A
-#define EGL_MIN_SWAP_INTERVAL		0x303B
-#define EGL_MAX_SWAP_INTERVAL		0x303C
-#define EGL_LUMINANCE_SIZE		0x303D
-#define EGL_ALPHA_MASK_SIZE		0x303E
-#define EGL_COLOR_BUFFER_TYPE		0x303F
-#define EGL_RENDERABLE_TYPE		0x3040
-#define EGL_MATCH_NATIVE_PIXMAP		0x3041	/* Pseudo-attribute (not queryable) */
-#define EGL_CONFORMANT			0x3042
-
-/* Reserved 0x3041-0x304F for additional config attributes */
-
-/* Config attribute values */
-#define EGL_SLOW_CONFIG			0x3050	/* EGL_CONFIG_CAVEAT value */
-#define EGL_NON_CONFORMANT_CONFIG	0x3051	/* EGL_CONFIG_CAVEAT value */
-#define EGL_TRANSPARENT_RGB		0x3052	/* EGL_TRANSPARENT_TYPE value */
-#define EGL_RGB_BUFFER			0x308E	/* EGL_COLOR_BUFFER_TYPE value */
-#define EGL_LUMINANCE_BUFFER		0x308F	/* EGL_COLOR_BUFFER_TYPE value */
-
-/* More config attribute values, for EGL_TEXTURE_FORMAT */
-#define EGL_NO_TEXTURE			0x305C
-#define EGL_TEXTURE_RGB			0x305D
-#define EGL_TEXTURE_RGBA		0x305E
-#define EGL_TEXTURE_2D			0x305F
-
-/* Config attribute mask bits */
-#define EGL_PBUFFER_BIT			0x0001	/* EGL_SURFACE_TYPE mask bits */
-#define EGL_PIXMAP_BIT			0x0002	/* EGL_SURFACE_TYPE mask bits */
-#define EGL_WINDOW_BIT			0x0004	/* EGL_SURFACE_TYPE mask bits */
-#define EGL_VG_COLORSPACE_LINEAR_BIT	0x0020	/* EGL_SURFACE_TYPE mask bits */
-#define EGL_VG_ALPHA_FORMAT_PRE_BIT	0x0040	/* EGL_SURFACE_TYPE mask bits */
-#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200	/* EGL_SURFACE_TYPE mask bits */
-#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400	/* EGL_SURFACE_TYPE mask bits */
-
-#define EGL_OPENGL_ES_BIT		0x0001	/* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENVG_BIT			0x0002	/* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENGL_ES2_BIT		0x0004	/* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENGL_BIT			0x0008	/* EGL_RENDERABLE_TYPE mask bits */
-
-/* QueryString targets */
-#define EGL_VENDOR			0x3053
-#define EGL_VERSION			0x3054
-#define EGL_EXTENSIONS			0x3055
-#define EGL_CLIENT_APIS			0x308D
-
-/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
-#define EGL_HEIGHT			0x3056
-#define EGL_WIDTH			0x3057
-#define EGL_LARGEST_PBUFFER		0x3058
-#define EGL_TEXTURE_FORMAT		0x3080
-#define EGL_TEXTURE_TARGET		0x3081
-#define EGL_MIPMAP_TEXTURE		0x3082
-#define EGL_MIPMAP_LEVEL		0x3083
-#define EGL_RENDER_BUFFER		0x3086
-#define EGL_VG_COLORSPACE		0x3087
-#define EGL_VG_ALPHA_FORMAT		0x3088
-#define EGL_HORIZONTAL_RESOLUTION	0x3090
-#define EGL_VERTICAL_RESOLUTION		0x3091
-#define EGL_PIXEL_ASPECT_RATIO		0x3092
-#define EGL_SWAP_BEHAVIOR		0x3093
-#define EGL_MULTISAMPLE_RESOLVE		0x3099
-
-/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
-#define EGL_BACK_BUFFER			0x3084
-#define EGL_SINGLE_BUFFER		0x3085
-
-/* OpenVG color spaces */
-#define EGL_VG_COLORSPACE_sRGB		0x3089	/* EGL_VG_COLORSPACE value */
-#define EGL_VG_COLORSPACE_LINEAR	0x308A	/* EGL_VG_COLORSPACE value */
-
-/* OpenVG alpha formats */
-#define EGL_VG_ALPHA_FORMAT_NONPRE	0x308B	/* EGL_ALPHA_FORMAT value */
-#define EGL_VG_ALPHA_FORMAT_PRE		0x308C	/* EGL_ALPHA_FORMAT value */
-
-/* Constant scale factor by which fractional display resolutions &
- * aspect ratio are scaled when queried as integer values.
- */
-#define EGL_DISPLAY_SCALING		10000
-
-/* Unknown display resolution/aspect ratio */
-#define EGL_UNKNOWN			((EGLint)-1)
-
-/* Back buffer swap behaviors */
-#define EGL_BUFFER_PRESERVED		0x3094	/* EGL_SWAP_BEHAVIOR value */
-#define EGL_BUFFER_DESTROYED		0x3095	/* EGL_SWAP_BEHAVIOR value */
-
-/* CreatePbufferFromClientBuffer buffer types */
-#define EGL_OPENVG_IMAGE		0x3096
-
-/* QueryContext targets */
-#define EGL_CONTEXT_CLIENT_TYPE		0x3097
-
-/* CreateContext attributes */
-#define EGL_CONTEXT_CLIENT_VERSION	0x3098
-
-/* Multisample resolution behaviors */
-#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A	/* EGL_MULTISAMPLE_RESOLVE value */
-#define EGL_MULTISAMPLE_RESOLVE_BOX	0x309B	/* EGL_MULTISAMPLE_RESOLVE value */
-
-/* BindAPI/QueryAPI targets */
-#define EGL_OPENGL_ES_API		0x30A0
-#define EGL_OPENVG_API			0x30A1
-#define EGL_OPENGL_API			0x30A2
-
-/* GetCurrentSurface targets */
-#define EGL_DRAW			0x3059
-#define EGL_READ			0x305A
-
-/* WaitNative engines */
-#define EGL_CORE_NATIVE_ENGINE		0x305B
-
-/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
-#define EGL_COLORSPACE			EGL_VG_COLORSPACE
-#define EGL_ALPHA_FORMAT		EGL_VG_ALPHA_FORMAT
-#define EGL_COLORSPACE_sRGB		EGL_VG_COLORSPACE_sRGB
-#define EGL_COLORSPACE_LINEAR		EGL_VG_COLORSPACE_LINEAR
-#define EGL_ALPHA_FORMAT_NONPRE		EGL_VG_ALPHA_FORMAT_NONPRE
-#define EGL_ALPHA_FORMAT_PRE		EGL_VG_ALPHA_FORMAT_PRE
-
-/* EGL extensions must request enum blocks from the Khronos
- * API Registrar, who maintains the enumerant registry. Submit
- * a bug in Khronos Bugzilla against task "Registry".
- */
-
-
-
-/* EGL Functions */
-
-EGLAPI EGLint EGLAPIENTRY eglGetError(void);
-
-EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
-EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
-EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
-
-EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
-			 EGLint config_size, EGLint *num_config);
-EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
-			   EGLConfig *configs, EGLint config_size,
-			   EGLint *num_config);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
-			      EGLint attribute, EGLint *value);
-
-EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
-				  EGLNativeWindowType win,
-				  const EGLint *attrib_list);
-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
-				   const EGLint *attrib_list);
-EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
-				  EGLNativePixmapType pixmap,
-				  const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
-EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
-			   EGLint attribute, EGLint *value);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
-EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
-
-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
-	      EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
-	      EGLConfig config, const EGLint *attrib_list);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
-			    EGLint attribute, EGLint value);
-EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-
-
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
-
-
-EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
-			    EGLContext share_context,
-			    const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
-EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
-			  EGLSurface read, EGLContext ctx);
-
-EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
-EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
-EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
-			   EGLint attribute, EGLint *value);
-
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
-EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
-			  EGLNativePixmapType target);
-
-/* This is a generic function pointer type, whose name indicates it must
- * be cast to the proper type *and calling convention* before use.
- */
+typedef void *EGLContext;
 typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+#define EGL_ALPHA_SIZE                    0x3021
+#define EGL_BAD_ACCESS                    0x3002
+#define EGL_BAD_ALLOC                     0x3003
+#define EGL_BAD_ATTRIBUTE                 0x3004
+#define EGL_BAD_CONFIG                    0x3005
+#define EGL_BAD_CONTEXT                   0x3006
+#define EGL_BAD_CURRENT_SURFACE           0x3007
+#define EGL_BAD_DISPLAY                   0x3008
+#define EGL_BAD_MATCH                     0x3009
+#define EGL_BAD_NATIVE_PIXMAP             0x300A
+#define EGL_BAD_NATIVE_WINDOW             0x300B
+#define EGL_BAD_PARAMETER                 0x300C
+#define EGL_BAD_SURFACE                   0x300D
+#define EGL_BLUE_SIZE                     0x3022
+#define EGL_BUFFER_SIZE                   0x3020
+#define EGL_CONFIG_CAVEAT                 0x3027
+#define EGL_CONFIG_ID                     0x3028
+#define EGL_CORE_NATIVE_ENGINE            0x305B
+#define EGL_DEPTH_SIZE                    0x3025
+#define EGL_DONT_CARE                     ((EGLint)-1)
+#define EGL_DRAW                          0x3059
+#define EGL_EXTENSIONS                    0x3055
+#define EGL_FALSE                         0
+#define EGL_GREEN_SIZE                    0x3023
+#define EGL_HEIGHT                        0x3056
+#define EGL_LARGEST_PBUFFER               0x3058
+#define EGL_LEVEL                         0x3029
+#define EGL_MAX_PBUFFER_HEIGHT            0x302A
+#define EGL_MAX_PBUFFER_PIXELS            0x302B
+#define EGL_MAX_PBUFFER_WIDTH             0x302C
+#define EGL_NATIVE_RENDERABLE             0x302D
+#define EGL_NATIVE_VISUAL_ID              0x302E
+#define EGL_NATIVE_VISUAL_TYPE            0x302F
+#define EGL_NONE                          0x3038
+#define EGL_NON_CONFORMANT_CONFIG         0x3051
+#define EGL_NOT_INITIALIZED               0x3001
+#define EGL_NO_CONTEXT                    ((EGLContext)0)
+#define EGL_NO_DISPLAY                    ((EGLDisplay)0)
+#define EGL_NO_SURFACE                    ((EGLSurface)0)
+#define EGL_PBUFFER_BIT                   0x0001
+#define EGL_PIXMAP_BIT                    0x0002
+#define EGL_READ                          0x305A
+#define EGL_RED_SIZE                      0x3024
+#define EGL_SAMPLES                       0x3031
+#define EGL_SAMPLE_BUFFERS                0x3032
+#define EGL_SLOW_CONFIG                   0x3050
+#define EGL_STENCIL_SIZE                  0x3026
+#define EGL_SUCCESS                       0x3000
+#define EGL_SURFACE_TYPE                  0x3033
+#define EGL_TRANSPARENT_BLUE_VALUE        0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE       0x3036
+#define EGL_TRANSPARENT_RED_VALUE         0x3037
+#define EGL_TRANSPARENT_RGB               0x3052
+#define EGL_TRANSPARENT_TYPE              0x3034
+#define EGL_TRUE                          1
+#define EGL_VENDOR                        0x3053
+#define EGL_VERSION                       0x3054
+#define EGL_WIDTH                         0x3057
+#define EGL_WINDOW_BIT                    0x0004
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
+EGLAPI EGLint EGLAPIENTRY eglGetError (void);
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
+#endif /* EGL_VERSION_1_0 */
 
-/* Now, define eglGetProcAddress using the generic function ptr. type */
-EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
-       eglGetProcAddress(const char *procname);
+#ifndef EGL_VERSION_1_1
+#define EGL_VERSION_1_1 1
+#define EGL_BACK_BUFFER                   0x3084
+#define EGL_BIND_TO_TEXTURE_RGB           0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA          0x303A
+#define EGL_CONTEXT_LOST                  0x300E
+#define EGL_MIN_SWAP_INTERVAL             0x303B
+#define EGL_MAX_SWAP_INTERVAL             0x303C
+#define EGL_MIPMAP_TEXTURE                0x3082
+#define EGL_MIPMAP_LEVEL                  0x3083
+#define EGL_NO_TEXTURE                    0x305C
+#define EGL_TEXTURE_2D                    0x305F
+#define EGL_TEXTURE_FORMAT                0x3080
+#define EGL_TEXTURE_RGB                   0x305D
+#define EGL_TEXTURE_RGBA                  0x305E
+#define EGL_TEXTURE_TARGET                0x3081
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
+#endif /* EGL_VERSION_1_1 */
+
+#ifndef EGL_VERSION_1_2
+#define EGL_VERSION_1_2 1
+typedef unsigned int EGLenum;
+typedef void *EGLClientBuffer;
+#define EGL_ALPHA_FORMAT                  0x3088
+#define EGL_ALPHA_FORMAT_NONPRE           0x308B
+#define EGL_ALPHA_FORMAT_PRE              0x308C
+#define EGL_ALPHA_MASK_SIZE               0x303E
+#define EGL_BUFFER_PRESERVED              0x3094
+#define EGL_BUFFER_DESTROYED              0x3095
+#define EGL_CLIENT_APIS                   0x308D
+#define EGL_COLORSPACE                    0x3087
+#define EGL_COLORSPACE_sRGB               0x3089
+#define EGL_COLORSPACE_LINEAR             0x308A
+#define EGL_COLOR_BUFFER_TYPE             0x303F
+#define EGL_CONTEXT_CLIENT_TYPE           0x3097
+#define EGL_DISPLAY_SCALING               10000
+#define EGL_HORIZONTAL_RESOLUTION         0x3090
+#define EGL_LUMINANCE_BUFFER              0x308F
+#define EGL_LUMINANCE_SIZE                0x303D
+#define EGL_OPENGL_ES_BIT                 0x0001
+#define EGL_OPENVG_BIT                    0x0002
+#define EGL_OPENGL_ES_API                 0x30A0
+#define EGL_OPENVG_API                    0x30A1
+#define EGL_OPENVG_IMAGE                  0x3096
+#define EGL_PIXEL_ASPECT_RATIO            0x3092
+#define EGL_RENDERABLE_TYPE               0x3040
+#define EGL_RENDER_BUFFER                 0x3086
+#define EGL_RGB_BUFFER                    0x308E
+#define EGL_SINGLE_BUFFER                 0x3085
+#define EGL_SWAP_BEHAVIOR                 0x3093
+#define EGL_UNKNOWN                       ((EGLint)-1)
+#define EGL_VERTICAL_RESOLUTION           0x3091
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
+#endif /* EGL_VERSION_1_2 */
+
+#ifndef EGL_VERSION_1_3
+#define EGL_VERSION_1_3 1
+#define EGL_CONFORMANT                    0x3042
+#define EGL_CONTEXT_CLIENT_VERSION        0x3098
+#define EGL_MATCH_NATIVE_PIXMAP           0x3041
+#define EGL_OPENGL_ES2_BIT                0x0004
+#define EGL_VG_ALPHA_FORMAT               0x3088
+#define EGL_VG_ALPHA_FORMAT_NONPRE        0x308B
+#define EGL_VG_ALPHA_FORMAT_PRE           0x308C
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT       0x0040
+#define EGL_VG_COLORSPACE                 0x3087
+#define EGL_VG_COLORSPACE_sRGB            0x3089
+#define EGL_VG_COLORSPACE_LINEAR          0x308A
+#define EGL_VG_COLORSPACE_LINEAR_BIT      0x0020
+#endif /* EGL_VERSION_1_3 */
+
+#ifndef EGL_VERSION_1_4
+#define EGL_VERSION_1_4 1
+#define EGL_DEFAULT_DISPLAY               ((EGLNativeDisplayType)0)
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT   0x0200
+#define EGL_MULTISAMPLE_RESOLVE           0x3099
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT   0x309A
+#define EGL_MULTISAMPLE_RESOLVE_BOX       0x309B
+#define EGL_OPENGL_API                    0x30A2
+#define EGL_OPENGL_BIT                    0x0008
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT   0x0400
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
+#endif /* EGL_VERSION_1_4 */
+
+#ifndef EGL_VERSION_1_5
+#define EGL_VERSION_1_5 1
+typedef void *EGLSync;
+typedef intptr_t EGLAttrib;
+typedef khronos_utime_nanoseconds_t EGLTime;
+#define EGL_CONTEXT_MAJOR_VERSION         0x3098
+#define EGL_CONTEXT_MINOR_VERSION         0x30FB
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK   0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
+#define EGL_NO_RESET_NOTIFICATION         0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET         0x31BF
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define EGL_CONTEXT_OPENGL_DEBUG          0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS  0x31B2
+#define EGL_OPENGL_ES3_BIT                0x00000040
+#define EGL_CL_EVENT_HANDLE               0x309C
+#define EGL_SYNC_CL_EVENT                 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE        0x30FF
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE  0x30F0
+#define EGL_SYNC_TYPE                     0x30F7
+#define EGL_SYNC_STATUS                   0x30F1
+#define EGL_SYNC_CONDITION                0x30F8
+#define EGL_SIGNALED                      0x30F2
+#define EGL_UNSIGNALED                    0x30F3
+#define EGL_SYNC_FLUSH_COMMANDS_BIT       0x0001
+#define EGL_FOREVER                       0xFFFFFFFFFFFFFFFFull
+#define EGL_TIMEOUT_EXPIRED               0x30F5
+#define EGL_CONDITION_SATISFIED           0x30F6
+#define EGL_NO_SYNC                       ((EGLSync)0)
+#define EGL_SYNC_FENCE                    0x30F9
+#define EGL_GL_COLORSPACE                 0x309D
+#define EGL_GL_COLORSPACE_SRGB            0x3089
+#define EGL_GL_COLORSPACE_LINEAR          0x308A
+#define EGL_GL_RENDERBUFFER               0x30B9
+#define EGL_GL_TEXTURE_2D                 0x30B1
+#define EGL_GL_TEXTURE_LEVEL              0x30BC
+#define EGL_GL_TEXTURE_3D                 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET            0x30BD
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
+EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
+#endif /* EGL_VERSION_1_5 */
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __egl_h_ */
+#endif
diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index 937af41..9e29605 100644
--- a/include/EGL/eglext.h
+++ b/include/EGL/eglext.h
@@ -1,12 +1,12 @@
 #ifndef __eglext_h_
-#define __eglext_h_
+#define __eglext_h_ 1
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /*
-** Copyright (c) 2007-2013 The Khronos Group Inc.
+** Copyright (c) 2013-2014 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
@@ -27,186 +27,706 @@
 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 */
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+**   http://www.opengl.org/registry/
+**
+** Khronos $Revision: 27018 $ on $Date: 2014-06-10 08:06:12 -0700 (Tue, 10 Jun 2014) $
+*/
 
 #include <EGL/eglplatform.h>
 
-/*************************************************************/
+#define EGL_EGLEXT_VERSION 20140610
 
-/* Header file version number */
-/* Current version at http://www.khronos.org/registry/egl/ */
-/* $Revision: 20690 $ on $Date: 2013-02-22 20:15:05 -0500 (Fri, 22 Feb 2013) $ */
-#define EGL_EGLEXT_VERSION 15
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: _nomatch_^
+ * Default extensions included: egl
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_KHR_cl_event
+#define EGL_KHR_cl_event 1
+#define EGL_CL_EVENT_HANDLE_KHR           0x309C
+#define EGL_SYNC_CL_EVENT_KHR             0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE_KHR    0x30FF
+#endif /* EGL_KHR_cl_event */
+
+#ifndef EGL_KHR_cl_event2
+#define EGL_KHR_cl_event2 1
+typedef void *EGLSyncKHR;
+typedef intptr_t EGLAttribKHR;
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#endif
+#endif /* EGL_KHR_cl_event2 */
+
+#ifndef EGL_KHR_client_get_all_proc_addresses
+#define EGL_KHR_client_get_all_proc_addresses 1
+#endif /* EGL_KHR_client_get_all_proc_addresses */
 
 #ifndef EGL_KHR_config_attribs
 #define EGL_KHR_config_attribs 1
-#define EGL_CONFORMANT_KHR			0x3042	/* EGLConfig attribute */
-#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR	0x0020	/* EGL_SURFACE_TYPE bitfield */
-#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR		0x0040	/* EGL_SURFACE_TYPE bitfield */
-#endif
+#define EGL_CONFORMANT_KHR                0x3042
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR  0x0020
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR   0x0040
+#endif /* EGL_KHR_config_attribs */
 
-#ifndef EGL_KHR_lock_surface
-#define EGL_KHR_lock_surface 1
-#define EGL_READ_SURFACE_BIT_KHR		0x0001	/* EGL_LOCK_USAGE_HINT_KHR bitfield */
-#define EGL_WRITE_SURFACE_BIT_KHR		0x0002	/* EGL_LOCK_USAGE_HINT_KHR bitfield */
-#define EGL_LOCK_SURFACE_BIT_KHR		0x0080	/* EGL_SURFACE_TYPE bitfield */
-#define EGL_OPTIMAL_FORMAT_BIT_KHR		0x0100	/* EGL_SURFACE_TYPE bitfield */
-#define EGL_MATCH_FORMAT_KHR			0x3043	/* EGLConfig attribute */
-#define EGL_FORMAT_RGB_565_EXACT_KHR		0x30C0	/* EGL_MATCH_FORMAT_KHR value */
-#define EGL_FORMAT_RGB_565_KHR			0x30C1	/* EGL_MATCH_FORMAT_KHR value */
-#define EGL_FORMAT_RGBA_8888_EXACT_KHR		0x30C2	/* EGL_MATCH_FORMAT_KHR value */
-#define EGL_FORMAT_RGBA_8888_KHR		0x30C3	/* EGL_MATCH_FORMAT_KHR value */
-#define EGL_MAP_PRESERVE_PIXELS_KHR		0x30C4	/* eglLockSurfaceKHR attribute */
-#define EGL_LOCK_USAGE_HINT_KHR			0x30C5	/* eglLockSurfaceKHR attribute */
-#define EGL_BITMAP_POINTER_KHR			0x30C6	/* eglQuerySurface attribute */
-#define EGL_BITMAP_PITCH_KHR			0x30C7	/* eglQuerySurface attribute */
-#define EGL_BITMAP_ORIGIN_KHR			0x30C8	/* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR		0x30C9	/* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR	0x30CA	/* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR	0x30CB	/* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR	0x30CC	/* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR	0x30CD	/* eglQuerySurface attribute */
-#define EGL_LOWER_LEFT_KHR			0x30CE	/* EGL_BITMAP_ORIGIN_KHR value */
-#define EGL_UPPER_LEFT_KHR			0x30CF	/* EGL_BITMAP_ORIGIN_KHR value */
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface);
-#endif
+#ifndef EGL_KHR_create_context
+#define EGL_KHR_create_context 1
+#define EGL_CONTEXT_MAJOR_VERSION_KHR     0x3098
+#define EGL_CONTEXT_MINOR_VERSION_KHR     0x30FB
+#define EGL_CONTEXT_FLAGS_KHR             0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define EGL_NO_RESET_NOTIFICATION_KHR     0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR     0x31BF
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR  0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#define EGL_OPENGL_ES3_BIT_KHR            0x00000040
+#endif /* EGL_KHR_create_context */
 
-#ifndef EGL_KHR_image
-#define EGL_KHR_image 1
-#define EGL_NATIVE_PIXMAP_KHR			0x30B0	/* eglCreateImageKHR target */
-typedef void *EGLImageKHR;
-#define EGL_NO_IMAGE_KHR			((EGLImageKHR)0)
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
-#endif
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define EGL_SYNC_CONDITION_KHR            0x30F8
+#define EGL_SYNC_FENCE_KHR                0x30F9
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_fence_sync */
 
-#ifndef EGL_KHR_vg_parent_image
-#define EGL_KHR_vg_parent_image 1
-#define EGL_VG_PARENT_IMAGE_KHR			0x30BA	/* eglCreateImageKHR target */
-#endif
+#ifndef EGL_KHR_get_all_proc_addresses
+#define EGL_KHR_get_all_proc_addresses 1
+#endif /* EGL_KHR_get_all_proc_addresses */
 
-#ifndef EGL_KHR_gl_texture_2D_image
-#define EGL_KHR_gl_texture_2D_image 1
-#define EGL_GL_TEXTURE_2D_KHR			0x30B1	/* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_LEVEL_KHR		0x30BC	/* eglCreateImageKHR attribute */
-#endif
-
-#ifndef EGL_KHR_gl_texture_cubemap_image
-#define EGL_KHR_gl_texture_cubemap_image 1
-#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR	0x30B3	/* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR	0x30B4	/* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR	0x30B5	/* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR	0x30B6	/* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR	0x30B7	/* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR	0x30B8	/* eglCreateImageKHR target */
-#endif
-
-#ifndef EGL_KHR_gl_texture_3D_image
-#define EGL_KHR_gl_texture_3D_image 1
-#define EGL_GL_TEXTURE_3D_KHR			0x30B2	/* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_ZOFFSET_KHR		0x30BD	/* eglCreateImageKHR attribute */
-#endif
+#ifndef EGL_KHR_gl_colorspace
+#define EGL_KHR_gl_colorspace 1
+#define EGL_GL_COLORSPACE_KHR             0x309D
+#define EGL_GL_COLORSPACE_SRGB_KHR        0x3089
+#define EGL_GL_COLORSPACE_LINEAR_KHR      0x308A
+#endif /* EGL_KHR_gl_colorspace */
 
 #ifndef EGL_KHR_gl_renderbuffer_image
 #define EGL_KHR_gl_renderbuffer_image 1
-#define EGL_GL_RENDERBUFFER_KHR			0x30B9	/* eglCreateImageKHR target */
-#endif
+#define EGL_GL_RENDERBUFFER_KHR           0x30B9
+#endif /* EGL_KHR_gl_renderbuffer_image */
 
-#if KHRONOS_SUPPORT_INT64   /* EGLTimeKHR requires 64-bit uint support */
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+#define EGL_GL_TEXTURE_2D_KHR             0x30B1
+#define EGL_GL_TEXTURE_LEVEL_KHR          0x30BC
+#endif /* EGL_KHR_gl_texture_2D_image */
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+#define EGL_GL_TEXTURE_3D_KHR             0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET_KHR        0x30BD
+#endif /* EGL_KHR_gl_texture_3D_image */
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
+#endif /* EGL_KHR_gl_texture_cubemap_image */
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+typedef void *EGLImageKHR;
+#define EGL_NATIVE_PIXMAP_KHR             0x30B0
+#define EGL_NO_IMAGE_KHR                  ((EGLImageKHR)0)
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
+#endif
+#endif /* EGL_KHR_image */
+
+#ifndef EGL_KHR_image_base
+#define EGL_KHR_image_base 1
+#define EGL_IMAGE_PRESERVED_KHR           0x30D2
+#endif /* EGL_KHR_image_base */
+
+#ifndef EGL_KHR_image_pixmap
+#define EGL_KHR_image_pixmap 1
+#endif /* EGL_KHR_image_pixmap */
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+#define EGL_READ_SURFACE_BIT_KHR          0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR         0x0002
+#define EGL_LOCK_SURFACE_BIT_KHR          0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR        0x0100
+#define EGL_MATCH_FORMAT_KHR              0x3043
+#define EGL_FORMAT_RGB_565_EXACT_KHR      0x30C0
+#define EGL_FORMAT_RGB_565_KHR            0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR    0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR          0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR       0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR           0x30C5
+#define EGL_BITMAP_POINTER_KHR            0x30C6
+#define EGL_BITMAP_PITCH_KHR              0x30C7
+#define EGL_BITMAP_ORIGIN_KHR             0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR   0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR  0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define EGL_LOWER_LEFT_KHR                0x30CE
+#define EGL_UPPER_LEFT_KHR                0x30CF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface);
+#endif
+#endif /* EGL_KHR_lock_surface */
+
+#ifndef EGL_KHR_lock_surface2
+#define EGL_KHR_lock_surface2 1
+#define EGL_BITMAP_PIXEL_SIZE_KHR         0x3110
+#endif /* EGL_KHR_lock_surface2 */
+
+#ifndef EGL_KHR_lock_surface3
+#define EGL_KHR_lock_surface3 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#endif
+#endif /* EGL_KHR_lock_surface3 */
+
+#ifndef EGL_KHR_platform_android
+#define EGL_KHR_platform_android 1
+#define EGL_PLATFORM_ANDROID_KHR          0x3141
+#endif /* EGL_KHR_platform_android */
+
+#ifndef EGL_KHR_platform_gbm
+#define EGL_KHR_platform_gbm 1
+#define EGL_PLATFORM_GBM_KHR              0x31D7
+#endif /* EGL_KHR_platform_gbm */
+
+#ifndef EGL_KHR_platform_wayland
+#define EGL_KHR_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_KHR          0x31D8
+#endif /* EGL_KHR_platform_wayland */
+
+#ifndef EGL_KHR_platform_x11
+#define EGL_KHR_platform_x11 1
+#define EGL_PLATFORM_X11_KHR              0x31D5
+#define EGL_PLATFORM_X11_SCREEN_KHR       0x31D6
+#endif /* EGL_KHR_platform_x11 */
+
 #ifndef EGL_KHR_reusable_sync
 #define EGL_KHR_reusable_sync 1
-
-typedef void* EGLSyncKHR;
 typedef khronos_utime_nanoseconds_t EGLTimeKHR;
-
-#define EGL_SYNC_STATUS_KHR			0x30F1
-#define EGL_SIGNALED_KHR			0x30F2
-#define EGL_UNSIGNALED_KHR			0x30F3
-#define EGL_TIMEOUT_EXPIRED_KHR			0x30F5
-#define EGL_CONDITION_SATISFIED_KHR		0x30F6
-#define EGL_SYNC_TYPE_KHR			0x30F7
-#define EGL_SYNC_REUSABLE_KHR			0x30FA
-#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR		0x0001	/* eglClientWaitSyncKHR <flags> bitfield */
-#define EGL_FOREVER_KHR				0xFFFFFFFFFFFFFFFFull
-#define EGL_NO_SYNC_KHR				((EGLSyncKHR)0)
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
-EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
-EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
-#endif /* EGL_EGLEXT_PROTOTYPES */
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_STATUS_KHR               0x30F1
+#define EGL_SIGNALED_KHR                  0x30F2
+#define EGL_UNSIGNALED_KHR                0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR           0x30F5
+#define EGL_CONDITION_SATISFIED_KHR       0x30F6
+#define EGL_SYNC_TYPE_KHR                 0x30F7
+#define EGL_SYNC_REUSABLE_KHR             0x30FA
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR   0x0001
+#define EGL_FOREVER_KHR                   0xFFFFFFFFFFFFFFFFull
+#define EGL_NO_SYNC_KHR                   ((EGLSyncKHR)0)
 typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
 typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
 #endif
-#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_reusable_sync */
 
-#ifndef EGL_KHR_image_base
-#define EGL_KHR_image_base 1
-/* Most interfaces defined by EGL_KHR_image_pixmap above */
-#define EGL_IMAGE_PRESERVED_KHR			0x30D2	/* eglCreateImageKHR attribute */
+#ifndef EGL_KHR_stream
+#define EGL_KHR_stream 1
+typedef void *EGLStreamKHR;
+typedef khronos_uint64_t EGLuint64KHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_NO_STREAM_KHR                 ((EGLStreamKHR)0)
+#define EGL_CONSUMER_LATENCY_USEC_KHR     0x3210
+#define EGL_PRODUCER_FRAME_KHR            0x3212
+#define EGL_CONSUMER_FRAME_KHR            0x3213
+#define EGL_STREAM_STATE_KHR              0x3214
+#define EGL_STREAM_STATE_CREATED_KHR      0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR   0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR        0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR                0x321B
+#define EGL_BAD_STATE_KHR                 0x321C
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
 #endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_stream */
 
-#ifndef EGL_KHR_image_pixmap
-#define EGL_KHR_image_pixmap 1
-/* Interfaces defined by EGL_KHR_image above */
+#ifndef EGL_KHR_stream_consumer_gltexture
+#define EGL_KHR_stream_consumer_gltexture 1
+#ifdef EGL_KHR_stream
+#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream);
 #endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_consumer_gltexture */
+
+#ifndef EGL_KHR_stream_cross_process_fd
+#define EGL_KHR_stream_cross_process_fd 1
+typedef int EGLNativeFileDescriptorKHR;
+#ifdef EGL_KHR_stream
+#define EGL_NO_FILE_DESCRIPTOR_KHR        ((EGLNativeFileDescriptorKHR)(-1))
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_cross_process_fd */
+
+#ifndef EGL_KHR_stream_fifo
+#define EGL_KHR_stream_fifo 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_FIFO_LENGTH_KHR        0x31FC
+#define EGL_STREAM_TIME_NOW_KHR           0x31FD
+#define EGL_STREAM_TIME_CONSUMER_KHR      0x31FE
+#define EGL_STREAM_TIME_PRODUCER_KHR      0x31FF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_fifo */
+
+#ifndef EGL_KHR_stream_producer_aldatalocator
+#define EGL_KHR_stream_producer_aldatalocator 1
+#ifdef EGL_KHR_stream
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_aldatalocator */
+
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_KHR_stream_producer_eglsurface 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_BIT_KHR                0x0800
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_eglsurface */
+
+#ifndef EGL_KHR_surfaceless_context
+#define EGL_KHR_surfaceless_context 1
+#endif /* EGL_KHR_surfaceless_context */
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+#define EGL_VG_PARENT_IMAGE_KHR           0x30BA
+#endif /* EGL_KHR_vg_parent_image */
+
+#ifndef EGL_KHR_wait_sync
+#define EGL_KHR_wait_sync 1
+typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#endif
+#endif /* EGL_KHR_wait_sync */
+
+#ifndef EGL_ANDROID_blob_cache
+#define EGL_ANDROID_blob_cache 1
+typedef khronos_ssize_t EGLsizeiANDROID;
+typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
+typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#endif
+#endif /* EGL_ANDROID_blob_cache */
+
+#ifndef EGL_ANDROID_framebuffer_target
+#define EGL_ANDROID_framebuffer_target 1
+#define EGL_FRAMEBUFFER_TARGET_ANDROID    0x3147
+#endif /* EGL_ANDROID_framebuffer_target */
+
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_ANDROID         0x3140
+#endif /* EGL_ANDROID_image_native_buffer */
+
+#ifndef EGL_ANDROID_native_fence_sync
+#define EGL_ANDROID_native_fence_sync 1
+#define EGL_SYNC_NATIVE_FENCE_ANDROID     0x3144
+#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID  0x3145
+#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+#define EGL_NO_NATIVE_FENCE_FD_ANDROID    -1
+typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync);
+#endif
+#endif /* EGL_ANDROID_native_fence_sync */
+
+#ifndef EGL_ANDROID_recordable
+#define EGL_ANDROID_recordable 1
+#define EGL_RECORDABLE_ANDROID            0x3142
+#endif /* EGL_ANDROID_recordable */
+
+#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
+#define EGL_ANGLE_d3d_share_handle_client_buffer 1
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
+
+#ifndef EGL_ANGLE_window_fixed_size
+#define EGL_ANGLE_window_fixed_size 1
+#define EGL_FIXED_SIZE_ANGLE        0x3201
+#endif /* EGL_ANGLE_window_fixed_size */
+
+#ifndef EGL_ANGLE_query_surface_pointer
+#define EGL_ANGLE_query_surface_pointer 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#endif
+#endif /* EGL_ANGLE_query_surface_pointer */
+
+#ifndef EGL_ANGLE_software_display
+#define EGL_ANGLE_software_display 1
+#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
+#endif /* EGL_ANGLE_software_display */
+
+#ifndef EGL_ANGLE_direct3d_display
+#define EGL_ANGLE_direct3d_display 1
+#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
+#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
+#endif /* EGL_ANGLE_direct3d_display */
+
+#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
+#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
+
+#ifndef EGL_ANGLE_platform_angle
+#define EGL_ANGLE_platform_angle 1
+#define EGL_PLATFORM_ANGLE_ANGLE          0x3201
+#define EGL_PLATFORM_ANGLE_TYPE_ANGLE     0x3202
+#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203
+#endif /* EGL_ANGLE_platform_angle */
+
+#ifndef EGL_ANGLE_platform_angle_d3d
+#define EGL_ANGLE_platform_angle_d3d 1
+#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3204
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206
+#endif /* EGL_ANGLE_platform_angle_d3d */
+
+#ifndef EGL_ANGLE_platform_angle_opengl
+#define EGL_ANGLE_platform_angle_opengl 1
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3207
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x3208
+#endif /* EGL_ANGLE_platform_angle_opengl */
+
+#ifndef EGL_ARM_pixmap_multisample_discard
+#define EGL_ARM_pixmap_multisample_discard 1
+#define EGL_DISCARD_SAMPLES_ARM           0x3286
+#endif /* EGL_ARM_pixmap_multisample_discard */
+
+#ifndef EGL_EXT_buffer_age
+#define EGL_EXT_buffer_age 1
+#define EGL_BUFFER_AGE_EXT                0x313D
+#endif /* EGL_EXT_buffer_age */
+
+#ifndef EGL_EXT_client_extensions
+#define EGL_EXT_client_extensions 1
+#endif /* EGL_EXT_client_extensions */
+
+#ifndef EGL_EXT_create_context_robustness
+#define EGL_EXT_create_context_robustness 1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define EGL_NO_RESET_NOTIFICATION_EXT     0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_EXT     0x31BF
+#endif /* EGL_EXT_create_context_robustness */
+
+#ifndef EGL_EXT_device_base
+#define EGL_EXT_device_base 1
+typedef void *EGLDeviceEXT;
+#define EGL_NO_DEVICE_EXT                 ((EGLDeviceEXT)(0))
+#define EGL_BAD_DEVICE_EXT                0x322B
+#define EGL_DEVICE_EXT                    0x322C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#endif
+#endif /* EGL_EXT_device_base */
+
+#ifndef EGL_EXT_image_dma_buf_import
+#define EGL_EXT_image_dma_buf_import 1
+#define EGL_LINUX_DMA_BUF_EXT             0x3270
+#define EGL_LINUX_DRM_FOURCC_EXT          0x3271
+#define EGL_DMA_BUF_PLANE0_FD_EXT         0x3272
+#define EGL_DMA_BUF_PLANE0_OFFSET_EXT     0x3273
+#define EGL_DMA_BUF_PLANE0_PITCH_EXT      0x3274
+#define EGL_DMA_BUF_PLANE1_FD_EXT         0x3275
+#define EGL_DMA_BUF_PLANE1_OFFSET_EXT     0x3276
+#define EGL_DMA_BUF_PLANE1_PITCH_EXT      0x3277
+#define EGL_DMA_BUF_PLANE2_FD_EXT         0x3278
+#define EGL_DMA_BUF_PLANE2_OFFSET_EXT     0x3279
+#define EGL_DMA_BUF_PLANE2_PITCH_EXT      0x327A
+#define EGL_YUV_COLOR_SPACE_HINT_EXT      0x327B
+#define EGL_SAMPLE_RANGE_HINT_EXT         0x327C
+#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
+#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
+#define EGL_ITU_REC601_EXT                0x327F
+#define EGL_ITU_REC709_EXT                0x3280
+#define EGL_ITU_REC2020_EXT               0x3281
+#define EGL_YUV_FULL_RANGE_EXT            0x3282
+#define EGL_YUV_NARROW_RANGE_EXT          0x3283
+#define EGL_YUV_CHROMA_SITING_0_EXT       0x3284
+#define EGL_YUV_CHROMA_SITING_0_5_EXT     0x3285
+#endif /* EGL_EXT_image_dma_buf_import */
+
+#ifndef EGL_EXT_multiview_window
+#define EGL_EXT_multiview_window 1
+#define EGL_MULTIVIEW_VIEW_COUNT_EXT      0x3134
+#endif /* EGL_EXT_multiview_window */
+
+#ifndef EGL_EXT_platform_base
+#define EGL_EXT_platform_base 1
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#endif
+#endif /* EGL_EXT_platform_base */
+
+#ifndef EGL_EXT_platform_device
+#define EGL_EXT_platform_device 1
+#define EGL_PLATFORM_DEVICE_EXT           0x313F
+#endif /* EGL_EXT_platform_device */
+
+#ifndef EGL_EXT_platform_wayland
+#define EGL_EXT_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_EXT          0x31D8
+#endif /* EGL_EXT_platform_wayland */
+
+#ifndef EGL_EXT_platform_x11
+#define EGL_EXT_platform_x11 1
+#define EGL_PLATFORM_X11_EXT              0x31D5
+#define EGL_PLATFORM_X11_SCREEN_EXT       0x31D6
+#endif /* EGL_EXT_platform_x11 */
+
+#ifndef EGL_EXT_protected_surface
+#define EGL_EXT_protected_surface 1
+#define EGL_PROTECTED_CONTENT_EXT         0x32C0
+#endif /* EGL_EXT_protected_surface */
+
+#ifndef EGL_EXT_swap_buffers_with_damage
+#define EGL_EXT_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_EXT_swap_buffers_with_damage */
+
+#ifndef EGL_HI_clientpixmap
+#define EGL_HI_clientpixmap 1
+struct EGLClientPixmapHI {
+    void  *pData;
+    EGLint iWidth;
+    EGLint iHeight;
+    EGLint iStride;
+};
+#define EGL_CLIENT_PIXMAP_POINTER_HI      0x8F74
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#endif
+#endif /* EGL_HI_clientpixmap */
+
+#ifndef EGL_HI_colorformats
+#define EGL_HI_colorformats 1
+#define EGL_COLOR_FORMAT_HI               0x8F70
+#define EGL_COLOR_RGB_HI                  0x8F71
+#define EGL_COLOR_RGBA_HI                 0x8F72
+#define EGL_COLOR_ARGB_HI                 0x8F73
+#endif /* EGL_HI_colorformats */
 
 #ifndef EGL_IMG_context_priority
 #define EGL_IMG_context_priority 1
-#define EGL_CONTEXT_PRIORITY_LEVEL_IMG		0x3100
-#define EGL_CONTEXT_PRIORITY_HIGH_IMG		0x3101
-#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG		0x3102
-#define EGL_CONTEXT_PRIORITY_LOW_IMG		0x3103
-#endif
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG    0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG     0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG   0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG      0x3103
+#endif /* EGL_IMG_context_priority */
 
-#ifndef EGL_KHR_lock_surface2
-#define EGL_KHR_lock_surface2 1
-#define EGL_BITMAP_PIXEL_SIZE_KHR		0x3110
+#ifndef EGL_MESA_drm_image
+#define EGL_MESA_drm_image 1
+#define EGL_DRM_BUFFER_FORMAT_MESA        0x31D0
+#define EGL_DRM_BUFFER_USE_MESA           0x31D1
+#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
+#define EGL_DRM_BUFFER_MESA               0x31D3
+#define EGL_DRM_BUFFER_STRIDE_MESA        0x31D4
+#define EGL_DRM_BUFFER_USE_SCANOUT_MESA   0x00000001
+#define EGL_DRM_BUFFER_USE_SHARE_MESA     0x00000002
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
 #endif
+#endif /* EGL_MESA_drm_image */
+
+#ifndef EGL_MESA_platform_gbm
+#define EGL_MESA_platform_gbm 1
+#define EGL_PLATFORM_GBM_MESA             0x31D7
+#endif /* EGL_MESA_platform_gbm */
+
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region */
+
+#ifndef EGL_NOK_swap_region2
+#define EGL_NOK_swap_region2 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region2 */
+
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+#define EGL_Y_INVERTED_NOK                0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
+#ifndef EGL_NV_3dvision_surface
+#define EGL_NV_3dvision_surface 1
+#define EGL_AUTO_STEREO_NV                0x3136
+#endif /* EGL_NV_3dvision_surface */
 
 #ifndef EGL_NV_coverage_sample
 #define EGL_NV_coverage_sample 1
-#define EGL_COVERAGE_BUFFERS_NV			0x30E0
-#define EGL_COVERAGE_SAMPLES_NV			0x30E1
-#endif
+#define EGL_COVERAGE_BUFFERS_NV           0x30E0
+#define EGL_COVERAGE_SAMPLES_NV           0x30E1
+#endif /* EGL_NV_coverage_sample */
+
+#ifndef EGL_NV_coverage_sample_resolve
+#define EGL_NV_coverage_sample_resolve 1
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NV    0x3131
+#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
+#endif /* EGL_NV_coverage_sample_resolve */
 
 #ifndef EGL_NV_depth_nonlinear
 #define EGL_NV_depth_nonlinear 1
-#define EGL_DEPTH_ENCODING_NV			0x30E2
-#define EGL_DEPTH_ENCODING_NONE_NV 0
-#define EGL_DEPTH_ENCODING_NONLINEAR_NV		0x30E3
-#endif
+#define EGL_DEPTH_ENCODING_NV             0x30E2
+#define EGL_DEPTH_ENCODING_NONE_NV        0
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV   0x30E3
+#endif /* EGL_NV_depth_nonlinear */
 
-#if KHRONOS_SUPPORT_INT64   /* EGLTimeNV requires 64-bit uint support */
+#ifndef EGL_NV_native_query
+#define EGL_NV_native_query 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#endif
+#endif /* EGL_NV_native_query */
+
+#ifndef EGL_NV_post_convert_rounding
+#define EGL_NV_post_convert_rounding 1
+#endif /* EGL_NV_post_convert_rounding */
+
+#ifndef EGL_NV_post_sub_buffer
+#define EGL_NV_post_sub_buffer 1
+#define EGL_POST_SUB_BUFFER_SUPPORTED_NV  0x30BE
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#endif
+#endif /* EGL_NV_post_sub_buffer */
+
+#ifndef EGL_NV_stream_sync
+#define EGL_NV_stream_sync 1
+#define EGL_SYNC_NEW_FRAME_NV             0x321F
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#endif
+#endif /* EGL_NV_stream_sync */
+
 #ifndef EGL_NV_sync
 #define EGL_NV_sync 1
-#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV	0x30E6
-#define EGL_SYNC_STATUS_NV			0x30E7
-#define EGL_SIGNALED_NV				0x30E8
-#define EGL_UNSIGNALED_NV			0x30E9
-#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV		0x0001
-#define EGL_FOREVER_NV				0xFFFFFFFFFFFFFFFFull
-#define EGL_ALREADY_SIGNALED_NV			0x30EA
-#define EGL_TIMEOUT_EXPIRED_NV			0x30EB
-#define EGL_CONDITION_SATISFIED_NV		0x30EC
-#define EGL_SYNC_TYPE_NV			0x30ED
-#define EGL_SYNC_CONDITION_NV			0x30EE
-#define EGL_SYNC_FENCE_NV			0x30EF
-#define EGL_NO_SYNC_NV				((EGLSyncNV)0)
-typedef void* EGLSyncNV;
+typedef void *EGLSyncNV;
 typedef khronos_utime_nanoseconds_t EGLTimeNV;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
+#define EGL_SYNC_STATUS_NV                0x30E7
+#define EGL_SIGNALED_NV                   0x30E8
+#define EGL_UNSIGNALED_NV                 0x30E9
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV    0x0001
+#define EGL_FOREVER_NV                    0xFFFFFFFFFFFFFFFFull
+#define EGL_ALREADY_SIGNALED_NV           0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV            0x30EB
+#define EGL_CONDITION_SATISFIED_NV        0x30EC
+#define EGL_SYNC_TYPE_NV                  0x30ED
+#define EGL_SYNC_CONDITION_NV             0x30EE
+#define EGL_SYNC_FENCE_NV                 0x30EF
+#define EGL_NO_SYNC_NV                    ((EGLSyncNV)0)
+typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
 EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
@@ -214,368 +734,25 @@
 EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
 EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
 EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
-typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
 #endif
-#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_sync */
 
-#if KHRONOS_SUPPORT_INT64   /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */
-#ifndef EGL_KHR_fence_sync
-#define EGL_KHR_fence_sync 1
-/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
-#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR	0x30F0
-#define EGL_SYNC_CONDITION_KHR			0x30F8
-#define EGL_SYNC_FENCE_KHR			0x30F9
-#endif
-#endif
-
-#ifndef EGL_HI_clientpixmap
-#define EGL_HI_clientpixmap 1
-
-/* Surface Attribute */
-#define EGL_CLIENT_PIXMAP_POINTER_HI		0x8F74
-/*
- * Structure representing a client pixmap
- * (pixmap's data is in client-space memory).
- */
-struct EGLClientPixmapHI
-{
-	void*		pData;
-	EGLint		iWidth;
-	EGLint		iHeight;
-	EGLint		iStride;
-};
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
-#endif	/* EGL_HI_clientpixmap */
-
-#ifndef EGL_HI_colorformats
-#define EGL_HI_colorformats 1
-/* Config Attribute */
-#define EGL_COLOR_FORMAT_HI			0x8F70
-/* Color Formats */
-#define EGL_COLOR_RGB_HI			0x8F71
-#define EGL_COLOR_RGBA_HI			0x8F72
-#define EGL_COLOR_ARGB_HI			0x8F73
-#endif /* EGL_HI_colorformats */
-
-#ifndef EGL_MESA_drm_image
-#define EGL_MESA_drm_image 1
-#define EGL_DRM_BUFFER_FORMAT_MESA		0x31D0	    /* CreateDRMImageMESA attribute */
-#define EGL_DRM_BUFFER_USE_MESA			0x31D1	    /* CreateDRMImageMESA attribute */
-#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA	0x31D2	    /* EGL_IMAGE_FORMAT_MESA attribute value */
-#define EGL_DRM_BUFFER_MESA			0x31D3	    /* eglCreateImageKHR target */
-#define EGL_DRM_BUFFER_STRIDE_MESA		0x31D4
-#define EGL_DRM_BUFFER_USE_SCANOUT_MESA		0x00000001  /* EGL_DRM_BUFFER_USE_MESA bits */
-#define EGL_DRM_BUFFER_USE_SHARE_MESA		0x00000002  /* EGL_DRM_BUFFER_USE_MESA bits */
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
-#endif
-
-#ifndef EGL_NV_post_sub_buffer
-#define EGL_NV_post_sub_buffer 1
-#define EGL_POST_SUB_BUFFER_SUPPORTED_NV	0x30BE
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
-#endif
-
-#ifndef EGL_ANGLE_query_surface_pointer
-#define EGL_ANGLE_query_surface_pointer 1
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
-#endif
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
-#endif
-
-#ifndef EGL_ANGLE_software_display
-#define EGL_ANGLE_software_display 1
-#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
-#endif
-
-#ifndef EGL_ANGLE_direct3d_display
-#define EGL_ANGLE_direct3d_display 1
-#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
-#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
-#endif
-
-#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
-#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
-#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE	0x3200
-#endif
-
-#ifndef EGL_NV_coverage_sample_resolve
-#define EGL_NV_coverage_sample_resolve 1
-#define EGL_COVERAGE_SAMPLE_RESOLVE_NV		0x3131
-#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV	0x3132
-#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV	0x3133
-#endif
-
-#if KHRONOS_SUPPORT_INT64   /* EGLuint64NV requires 64-bit uint support */
 #ifndef EGL_NV_system_time
 #define EGL_NV_system_time 1
 typedef khronos_utime_nanoseconds_t EGLuint64NV;
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void);
-EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void);
-#endif /* EGL_EGLEXT_PROTOTYPES */
+#ifdef KHRONOS_SUPPORT_INT64
 typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
 typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
-#endif
-#endif
-
-#if KHRONOS_SUPPORT_INT64 /* EGLuint64KHR requires 64-bit uint support */
-#ifndef EGL_KHR_stream
-#define EGL_KHR_stream 1
-typedef void* EGLStreamKHR;
-typedef khronos_uint64_t EGLuint64KHR;
-#define EGL_NO_STREAM_KHR			((EGLStreamKHR)0)
-#define EGL_CONSUMER_LATENCY_USEC_KHR		0x3210
-#define EGL_PRODUCER_FRAME_KHR			0x3212
-#define EGL_CONSUMER_FRAME_KHR			0x3213
-#define EGL_STREAM_STATE_KHR			0x3214
-#define EGL_STREAM_STATE_CREATED_KHR		0x3215
-#define EGL_STREAM_STATE_CONNECTING_KHR		0x3216
-#define EGL_STREAM_STATE_EMPTY_KHR		0x3217
-#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR    0x3218
-#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR    0x3219
-#define EGL_STREAM_STATE_DISCONNECTED_KHR	0x321A
-#define EGL_BAD_STREAM_KHR			0x321B
-#define EGL_BAD_STATE_KHR			0x321C
 #ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream);
-EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC)(EGLDisplay dpy, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void);
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
 #endif
-#endif
-
-#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
-#ifndef EGL_KHR_stream_consumer_gltexture
-#define EGL_KHR_stream_consumer_gltexture 1
-#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR	0x321E
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream);
-EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream);
-EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
-#endif
-#endif
-
-#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
-#ifndef EGL_KHR_stream_producer_eglsurface
-#define EGL_KHR_stream_producer_eglsurface 1
-#define EGL_STREAM_BIT_KHR			0x0800
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
-#endif
-#endif
-
-#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
-#ifndef EGL_KHR_stream_producer_aldatalocator
-#define EGL_KHR_stream_producer_aldatalocator 1
-#endif
-#endif
-
-#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
-#ifndef EGL_KHR_stream_fifo
-#define EGL_KHR_stream_fifo 1
-/* reuse EGLTimeKHR */
-#define EGL_STREAM_FIFO_LENGTH_KHR		0x31FC
-#define EGL_STREAM_TIME_NOW_KHR			0x31FD
-#define EGL_STREAM_TIME_CONSUMER_KHR		0x31FE
-#define EGL_STREAM_TIME_PRODUCER_KHR		0x31FF
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
-#endif
-#endif
-
-#ifndef EGL_EXT_create_context_robustness
-#define EGL_EXT_create_context_robustness 1
-#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT	0x30BF
-#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
-#define EGL_NO_RESET_NOTIFICATION_EXT		0x31BE
-#define EGL_LOSE_CONTEXT_ON_RESET_EXT		0x31BF
-#endif
-
-#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
-#define EGL_ANGLE_d3d_share_handle_client_buffer 1
-/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */
-#endif
-
-#ifndef EGL_ANGLE_window_fixed_size
-#define EGL_ANGLE_window_fixed_size 1
-#define EGL_FIXED_SIZE_ANGLE        0x3201
-#endif
-
-#ifndef EGL_KHR_create_context
-#define EGL_KHR_create_context 1
-#define EGL_CONTEXT_MAJOR_VERSION_KHR			    EGL_CONTEXT_CLIENT_VERSION
-#define EGL_CONTEXT_MINOR_VERSION_KHR			    0x30FB
-#define EGL_CONTEXT_FLAGS_KHR				    0x30FC
-#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR		    0x30FD
-#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR  0x31BD
-#define EGL_NO_RESET_NOTIFICATION_KHR			    0x31BE
-#define EGL_LOSE_CONTEXT_ON_RESET_KHR			    0x31BF
-#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR		    0x00000001
-#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR	    0x00000002
-#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR	    0x00000004
-#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR		    0x00000001
-#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR    0x00000002
-#define EGL_OPENGL_ES3_BIT_KHR				    0x00000040
-#endif
-
-#ifndef EGL_KHR_surfaceless_context
-#define EGL_KHR_surfaceless_context 1
-/* No tokens/entry points, just relaxes an error condition */
-#endif
-
-#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
-#ifndef EGL_KHR_stream_cross_process_fd
-#define EGL_KHR_stream_cross_process_fd 1
-typedef int EGLNativeFileDescriptorKHR;
-#define EGL_NO_FILE_DESCRIPTOR_KHR		((EGLNativeFileDescriptorKHR)(-1))
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR(EGLDisplay dpy, EGLStreamKHR stream);
-EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
-typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
-#endif
-#endif
-
-#ifndef EGL_EXT_multiview_window
-#define EGL_EXT_multiview_window 1
-#define EGL_MULTIVIEW_VIEW_COUNT_EXT		0x3134
-#endif
-
-#ifndef EGL_KHR_wait_sync
-#define EGL_KHR_wait_sync 1
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
-#endif
-
-#ifndef EGL_NV_post_convert_rounding
-#define EGL_NV_post_convert_rounding 1
-/* No tokens or entry points, just relaxes behavior of SwapBuffers */
-#endif
-
-#ifndef EGL_NV_native_query
-#define EGL_NV_native_query 1
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV( EGLDisplay dpy, EGLNativeDisplayType* display_id);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV( EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType* window);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV( EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType* pixmap);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC)(EGLDisplay dpy, EGLNativeDisplayType *display_id);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC)(EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC)(EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
-#endif
-
-#ifndef EGL_NV_3dvision_surface
-#define EGL_NV_3dvision_surface 1
-#define EGL_AUTO_STEREO_NV			0x3136
-#endif
-
-#ifndef EGL_ANDROID_framebuffer_target
-#define EGL_ANDROID_framebuffer_target 1
-#define EGL_FRAMEBUFFER_TARGET_ANDROID		0x3147
-#endif
-
-#ifndef EGL_ANDROID_blob_cache
-#define EGL_ANDROID_blob_cache 1
-typedef khronos_ssize_t EGLsizeiANDROID;
-typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
-typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC)(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
-#endif
-
-#ifndef EGL_ANDROID_image_native_buffer
-#define EGL_ANDROID_image_native_buffer 1
-#define EGL_NATIVE_BUFFER_ANDROID		0x3140
-#endif
-
-#ifndef EGL_ANDROID_native_fence_sync
-#define EGL_ANDROID_native_fence_sync 1
-#define EGL_SYNC_NATIVE_FENCE_ANDROID		0x3144
-#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID	0x3145
-#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID	0x3146
-#define EGL_NO_NATIVE_FENCE_FD_ANDROID		-1
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID( EGLDisplay dpy, EGLSyncKHR);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC)(EGLDisplay dpy, EGLSyncKHR);
-#endif
-
-#ifndef EGL_ANDROID_recordable
-#define EGL_ANDROID_recordable 1
-#define EGL_RECORDABLE_ANDROID			0x3142
-#endif
-
-#ifndef EGL_EXT_buffer_age
-#define EGL_EXT_buffer_age 1
-#define EGL_BUFFER_AGE_EXT			0x313D
-#endif
-
-#ifndef EGL_EXT_image_dma_buf_import
-#define EGL_EXT_image_dma_buf_import 1
-#define EGL_LINUX_DMA_BUF_EXT			0x3270
-#define EGL_LINUX_DRM_FOURCC_EXT		0x3271
-#define EGL_DMA_BUF_PLANE0_FD_EXT		0x3272
-#define EGL_DMA_BUF_PLANE0_OFFSET_EXT		0x3273
-#define EGL_DMA_BUF_PLANE0_PITCH_EXT		0x3274
-#define EGL_DMA_BUF_PLANE1_FD_EXT		0x3275
-#define EGL_DMA_BUF_PLANE1_OFFSET_EXT		0x3276
-#define EGL_DMA_BUF_PLANE1_PITCH_EXT		0x3277
-#define EGL_DMA_BUF_PLANE2_FD_EXT		0x3278
-#define EGL_DMA_BUF_PLANE2_OFFSET_EXT		0x3279
-#define EGL_DMA_BUF_PLANE2_PITCH_EXT		0x327A
-#define EGL_YUV_COLOR_SPACE_HINT_EXT		0x327B
-#define EGL_SAMPLE_RANGE_HINT_EXT		0x327C
-#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
-#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
-#define EGL_ITU_REC601_EXT			0x327F
-#define EGL_ITU_REC709_EXT			0x3280
-#define EGL_ITU_REC2020_EXT			0x3281
-#define EGL_YUV_FULL_RANGE_EXT			0x3282
-#define EGL_YUV_NARROW_RANGE_EXT		0x3283
-#define EGL_YUV_CHROMA_SITING_0_EXT		0x3284
-#define EGL_YUV_CHROMA_SITING_0_5_EXT		0x3285
-#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_system_time */
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __eglext_h_ */
+#endif
diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h
index 9a89420..3ab8844 100644
--- a/include/EGL/eglplatform.h
+++ b/include/EGL/eglplatform.h
@@ -2,7 +2,7 @@
 #define __eglplatform_h_
 
 /*
-** Copyright (c) 2007-2009 The Khronos Group Inc.
+** Copyright (c) 2007-2013 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
@@ -25,7 +25,7 @@
 */
 
 /* Platform-specific types and definitions for egl.h
- * $Revision: 12306 $ on $Date: 2010-08-25 12:51:28 -0400 (Wed, 25 Aug 2010) $
+ * $Revision: 23432 $ on $Date: 2013-10-09 00:57:24 -0700 (Wed, 09 Oct 2013) $
  *
  * Adopters may modify khrplatform.h and this file to suit their platform.
  * You are encouraged to submit all modifications to the Khronos group so that
@@ -83,6 +83,16 @@
 typedef void *EGLNativeWindowType;
 typedef void *EGLNativePixmapType;
 
+#elif defined(__ANDROID__) || defined(ANDROID)
+
+#include <android/native_window.h>
+
+struct egl_native_pixmap_t;
+
+typedef struct ANativeWindow*           EGLNativeWindowType;
+typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
+typedef void*                           EGLNativeDisplayType;
+
 #elif defined(__unix__)
 
 /* X11 (tentative)  */
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index c38fdae..b7989f5 100644
--- a/include/GLSLANG/ShaderLang.h
+++ b/include/GLSLANG/ShaderLang.h
@@ -23,32 +23,32 @@
 #define COMPILER_EXPORT
 #endif
 
-#include "KHR/khrplatform.h"
 #include <stddef.h>
 
+#include "KHR/khrplatform.h"
+
 //
 // This is the platform independent interface between an OGL driver
 // and the shading language compiler.
 //
 
+namespace sh
+{
+// GLenum alias
+typedef unsigned int GLenum;
+}
+
+// Must be included after GLenum proxy typedef
+// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
+#include "ShaderVars.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 // Version number for shader translation API.
 // It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 125
-
-//
-// The names of the following enums have been derived by replacing GL prefix
-// with SH. For example, SH_INFO_LOG_LENGTH is equivalent to GL_INFO_LOG_LENGTH.
-// The enum values are also equal to the values of their GL counterpart. This
-// is done to make it easier for applications to use the shader library.
-//
-typedef enum {
-  SH_FRAGMENT_SHADER = 0x8B30,
-  SH_VERTEX_SHADER   = 0x8B31
-} ShShaderType;
+#define ANGLE_SH_VERSION 130
 
 typedef enum {
   SH_GLES2_SPEC = 0x8B40,
@@ -86,52 +86,6 @@
 } ShShaderOutput;
 
 typedef enum {
-  SH_NONE           = 0,
-  SH_INT            = 0x1404,
-  SH_UNSIGNED_INT   = 0x1405,
-  SH_FLOAT          = 0x1406,
-  SH_FLOAT_VEC2     = 0x8B50,
-  SH_FLOAT_VEC3     = 0x8B51,
-  SH_FLOAT_VEC4     = 0x8B52,
-  SH_INT_VEC2       = 0x8B53,
-  SH_INT_VEC3       = 0x8B54,
-  SH_INT_VEC4       = 0x8B55,
-  SH_UNSIGNED_INT_VEC2 = 0x8DC6,
-  SH_UNSIGNED_INT_VEC3 = 0x8DC7,
-  SH_UNSIGNED_INT_VEC4 = 0x8DC8,
-  SH_BOOL           = 0x8B56,
-  SH_BOOL_VEC2      = 0x8B57,
-  SH_BOOL_VEC3      = 0x8B58,
-  SH_BOOL_VEC4      = 0x8B59,
-  SH_FLOAT_MAT2     = 0x8B5A,
-  SH_FLOAT_MAT3     = 0x8B5B,
-  SH_FLOAT_MAT4     = 0x8B5C,
-  SH_FLOAT_MAT2x3   = 0x8B65,
-  SH_FLOAT_MAT2x4   = 0x8B66,
-  SH_FLOAT_MAT3x2   = 0x8B67,
-  SH_FLOAT_MAT3x4   = 0x8B68,
-  SH_FLOAT_MAT4x2   = 0x8B69,
-  SH_FLOAT_MAT4x3   = 0x8B6A,
-  SH_SAMPLER_2D     = 0x8B5E,
-  SH_SAMPLER_3D     = 0x8B5F,
-  SH_SAMPLER_CUBE   = 0x8B60,
-  SH_SAMPLER_2D_RECT_ARB = 0x8B63,
-  SH_SAMPLER_EXTERNAL_OES = 0x8D66,
-  SH_SAMPLER_2D_ARRAY   = 0x8DC1,
-  SH_INT_SAMPLER_2D     = 0x8DCA,
-  SH_INT_SAMPLER_3D     = 0x8DCB,
-  SH_INT_SAMPLER_CUBE   = 0x8DCC,
-  SH_INT_SAMPLER_2D_ARRAY = 0x8DCF,
-  SH_UNSIGNED_INT_SAMPLER_2D     = 0x8DD2,
-  SH_UNSIGNED_INT_SAMPLER_3D     = 0x8DD3,
-  SH_UNSIGNED_INT_SAMPLER_CUBE   = 0x8DD4,
-  SH_UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7,
-  SH_SAMPLER_2D_SHADOW       = 0x8B62,
-  SH_SAMPLER_CUBE_SHADOW     = 0x8DC5,
-  SH_SAMPLER_2D_ARRAY_SHADOW = 0x8DC4
-} ShDataType;
-
-typedef enum {
   SH_PRECISION_HIGHP     = 0x5001,
   SH_PRECISION_MEDIUMP   = 0x5002,
   SH_PRECISION_LOWP      = 0x5003,
@@ -151,14 +105,9 @@
   SH_NAME_MAX_LENGTH                = 0x6001,
   SH_HASHED_NAME_MAX_LENGTH         = 0x6002,
   SH_HASHED_NAMES_COUNT             = 0x6003,
-  SH_ACTIVE_UNIFORMS_ARRAY          = 0x6004,
-  SH_SHADER_VERSION                 = 0x6005,
-  SH_ACTIVE_INTERFACE_BLOCKS_ARRAY  = 0x6006,
-  SH_ACTIVE_OUTPUT_VARIABLES_ARRAY  = 0x6007,
-  SH_ACTIVE_ATTRIBUTES_ARRAY        = 0x6008,
-  SH_ACTIVE_VARYINGS_ARRAY          = 0x6009,
-  SH_RESOURCES_STRING_LENGTH        = 0x600A,
-  SH_OUTPUT_TYPE                    = 0x600B
+  SH_SHADER_VERSION                 = 0x6004,
+  SH_RESOURCES_STRING_LENGTH        = 0x6005,
+  SH_OUTPUT_TYPE                    = 0x6006
 } ShShaderInfo;
 
 // Compile options.
@@ -193,7 +142,7 @@
   // This flag only has an effect if all of the following are true:
   // - The shader spec is SH_WEBGL_SPEC.
   // - The compile options contain the SH_TIMING_RESTRICTIONS flag.
-  // - The shader type is SH_FRAGMENT_SHADER.
+  // - The shader type is GL_FRAGMENT_SHADER.
   SH_DEPENDENCY_GRAPH = 0x0400,
 
   // Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
@@ -236,6 +185,15 @@
   // It is intended as a workaround for drivers which incorrectly optimize
   // out such varyings and cause a link failure.
   SH_INIT_VARYINGS_WITHOUT_STATIC_USE = 0x20000,
+
+  // This flag scalarizes vec/ivec/bvec/mat constructor args.
+  // It is intended as a workaround for Linux/Mac driver bugs.
+  SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = 0x40000,
+
+  // This flag overwrites a struct name with a unique prefix.
+  // It is intended as a workaround for drivers that do not handle
+  // struct scopes correctly, including all Mac drivers and Linux AMD.
+  SH_REGENERATE_STRUCT_NAMES = 0x80000,
 } ShCompileOptions;
 
 // Defines alternate strategies for implementing array index clamping.
@@ -345,14 +303,14 @@
 // Returns the handle of constructed compiler, null if the requested compiler is
 // not supported.
 // Parameters:
-// type: Specifies the type of shader - SH_FRAGMENT_SHADER or SH_VERTEX_SHADER.
+// type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER.
 // spec: Specifies the language spec the compiler must conform to -
 //       SH_GLES2_SPEC or SH_WEBGL_SPEC.
 // output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
 //         SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT.
 // resources: Specifies the built-in resources.
 COMPILER_EXPORT ShHandle ShConstructCompiler(
-    ShShaderType type,
+    sh::GLenum type,
     ShShaderSpec spec,
     ShShaderOutput output,
     const ShBuiltInResources* resources);
@@ -476,7 +434,7 @@
                                        int index,
                                        size_t* length,
                                        int* size,
-                                       ShDataType* type,
+                                       sh::GLenum* type,
                                        ShPrecisionType* precision,
                                        int* staticUse,
                                        char* name,
@@ -500,21 +458,21 @@
                                            char* name,
                                            char* hashedName);
 
-// Returns a parameter from a compiled shader.
+// Shader variable inspection.
+// Returns a pointer to a list of variables of the designated type.
+// (See ShaderVars.h for type definitions, included above)
+// Returns NULL on failure.
 // Parameters:
 // handle: Specifies the compiler
-// pname: Specifies the parameter to query.
-// The following parameters are defined:
-// SH_ACTIVE_UNIFORMS_ARRAY: an STL vector of active uniforms. Valid only for
-//                           HLSL output.
-// params: Requested parameter
-COMPILER_EXPORT void ShGetInfoPointer(const ShHandle handle,
-                                      ShShaderInfo pname,
-                                      void** params);
+COMPILER_EXPORT const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
+COMPILER_EXPORT const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle);
+COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle);
+COMPILER_EXPORT const std::vector<sh::Attribute> *ShGetOutputVariables(const ShHandle handle);
+COMPILER_EXPORT const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
 
 typedef struct
 {
-    ShDataType type;
+    sh::GLenum type;
     int size;
 } ShVariableInfo;
 
@@ -531,6 +489,29 @@
     ShVariableInfo* varInfoArray,
     size_t varInfoArraySize);
 
+// Gives the compiler-assigned register for an interface block.
+// The method writes the value to the output variable "indexOut".
+// Returns true if it found a valid interface block, false otherwise.
+// Parameters:
+// handle: Specifies the compiler
+// interfaceBlockName: Specifies the interface block
+// indexOut: output variable that stores the assigned register
+COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
+                                                 const char *interfaceBlockName,
+                                                 unsigned int *indexOut);
+
+// Gives the compiler-assigned register for uniforms in the default
+// interface block.
+// The method writes the value to the output variable "indexOut".
+// Returns true if it found a valid default uniform, false otherwise.
+// Parameters:
+// handle: Specifies the compiler
+// interfaceBlockName: Specifies the uniform
+// indexOut: output variable that stores the assigned register
+COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
+                                          const char *uniformName,
+                                          unsigned int *indexOut);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/GLSLANG/ShaderVars.h b/include/GLSLANG/ShaderVars.h
new file mode 100644
index 0000000..9c38647
--- /dev/null
+++ b/include/GLSLANG/ShaderVars.h
@@ -0,0 +1,123 @@
+//
+// 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.
+//
+// ShaderVars.h:
+//  Types to represent GL variables (varyings, uniforms, etc)
+//
+
+#ifndef _COMPILER_INTERFACE_VARIABLES_
+#define _COMPILER_INTERFACE_VARIABLES_
+
+#include <string>
+#include <vector>
+#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
+{
+
+// Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
+enum InterpolationType
+{
+    INTERPOLATION_SMOOTH,
+    INTERPOLATION_CENTROID,
+    INTERPOLATION_FLAT
+};
+
+// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
+enum BlockLayoutType
+{
+    BLOCKLAYOUT_STANDARD,
+    BLOCKLAYOUT_PACKED,
+    BLOCKLAYOUT_SHARED
+};
+
+// Base class for all variables defined in shaders, including Varyings, Uniforms, etc
+// Note: we must override the copy constructor and assignment operator so we can
+// work around excessive GCC binary bloating:
+// See https://code.google.com/p/angleproject/issues/detail?id=697
+struct COMPILER_EXPORT ShaderVariable
+{
+    ShaderVariable();
+    ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
+    ~ShaderVariable();
+    ShaderVariable(const ShaderVariable &other);
+    ShaderVariable &operator=(const ShaderVariable &other);
+
+    bool isArray() const { return arraySize > 0; }
+    unsigned int elementCount() const { return std::max(1u, arraySize); }
+    bool isStruct() const { return !fields.empty(); }
+
+    GLenum type;
+    GLenum precision;
+    std::string name;
+    std::string mappedName;
+    unsigned int arraySize;
+    bool staticUse;
+    std::vector<ShaderVariable> fields;
+    std::string structName;
+};
+
+struct COMPILER_EXPORT Uniform : public ShaderVariable
+{
+    Uniform();
+    ~Uniform();
+    Uniform(const Uniform &other);
+    Uniform &operator=(const Uniform &other);
+};
+
+struct COMPILER_EXPORT Attribute : public ShaderVariable
+{
+    Attribute();
+    ~Attribute();
+    Attribute(const Attribute &other);
+    Attribute &operator=(const Attribute &other);
+
+    int location;
+};
+
+struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
+{
+    InterfaceBlockField();
+    ~InterfaceBlockField();
+    InterfaceBlockField(const InterfaceBlockField &other);
+    InterfaceBlockField &operator=(const InterfaceBlockField &other);
+
+    bool isRowMajorLayout;
+};
+
+struct COMPILER_EXPORT Varying : public ShaderVariable
+{
+    Varying();
+    ~Varying();
+    Varying(const Varying &other);
+    Varying &operator=(const Varying &other);
+
+    InterpolationType interpolation;
+    bool isInvariant;
+};
+
+struct COMPILER_EXPORT InterfaceBlock
+{
+    InterfaceBlock();
+    ~InterfaceBlock();
+    InterfaceBlock(const InterfaceBlock &other);
+    InterfaceBlock &operator=(const InterfaceBlock &other);
+
+    std::string name;
+    std::string mappedName;
+    std::string instanceName;
+    unsigned int arraySize;
+    BlockLayoutType layout;
+    bool isRowMajorLayout;
+    bool staticUse;
+    std::vector<InterfaceBlockField> fields;
+};
+
+}
+
+#endif // _COMPILER_INTERFACE_VARIABLES_
diff --git a/include/angle_gl.h b/include/angle_gl.h
new file mode 100644
index 0000000..d093f75
--- /dev/null
+++ b/include/angle_gl.h
@@ -0,0 +1,23 @@
+//
+// 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.
+//
+// angle_gl.h:
+//   Includes all necessary GL headers and definitions for ANGLE.
+//
+
+#ifndef ANGLE_GL_H_
+#define ANGLE_GL_H_
+
+#include "GLES2/gl2.h"
+#include "GLES2/gl2ext.h"
+#include "GLES3/gl3.h"
+#include "GLES3/gl3ext.h"
+
+// The following enum is used in ANGLE, but is from desktop GL
+#ifndef GL_SAMPLER_2D_RECT_ARB
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#endif
+
+#endif // ANGLE_GL_H_
diff --git a/projects/build/All.vcxproj b/projects/build/All.vcxproj
index e4d508a..057f1b7 100644
--- a/projects/build/All.vcxproj
+++ b/projects/build/All.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Utility</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,21 +42,24 @@
     <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>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <DisableSpecificWarnings>4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <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>
@@ -53,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>
@@ -65,22 +80,60 @@
       <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;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <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>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Lib>
+    <Link>
+      <AdditionalDependencies></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;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <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>
       <DisableSpecificWarnings>4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <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>
@@ -88,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>
@@ -100,9 +154,45 @@
       <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;..\..\src;..\..\include;..\..\src\libGLESv2;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <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>
+      <WarningLevel>Level4</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories>C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Lib>
+    <Link>
+      <AdditionalDependencies></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;..\..\samples\angle\sample_util;..\..\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <Culture>0x0409</Culture>
+      <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>
@@ -137,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>
@@ -209,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 5862edd..ba79f14 100644
--- a/projects/build/all.sln
+++ b/projects/build/all.sln
@@ -1,5 +1,5 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual C++ Express 2010
+Microsoft Visual Studio Solution File, Format Version 13.00
+# Visual Studio 2013
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "All", "All.vcxproj", "{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}"
 	ProjectSection(ProjectDependencies) = postProject
 		{63FB0B97-D1D9-5158-8E85-7F5B1E403817} = {63FB0B97-D1D9-5158-8E85-7F5B1E403817}
@@ -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}"
@@ -170,112 +203,242 @@
 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
+		{0BD6333E-E82C-7665-C386-CDA40096413D}.Debug|x64.ActiveCfg = Debug|x64
+		{0BD6333E-E82C-7665-C386-CDA40096413D}.Debug|x64.Build.0 = Debug|x64
 		{0BD6333E-E82C-7665-C386-CDA40096413D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0BD6333E-E82C-7665-C386-CDA40096413D}.Debug|Win32.Build.0 = Debug|Win32
+		{0BD6333E-E82C-7665-C386-CDA40096413D}.Release|x64.ActiveCfg = Release|x64
+		{0BD6333E-E82C-7665-C386-CDA40096413D}.Release|x64.Build.0 = Release|x64
 		{0BD6333E-E82C-7665-C386-CDA40096413D}.Release|Win32.ActiveCfg = Release|Win32
 		{0BD6333E-E82C-7665-C386-CDA40096413D}.Release|Win32.Build.0 = Release|Win32
+		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Debug|x64.ActiveCfg = Debug|x64
+		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Debug|x64.Build.0 = Debug|x64
 		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Debug|Win32.ActiveCfg = Debug|Win32
 		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Debug|Win32.Build.0 = Debug|Win32
+		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Release|x64.ActiveCfg = Release|x64
+		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Release|x64.Build.0 = Release|x64
 		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Release|Win32.ActiveCfg = Release|Win32
 		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Release|Win32.Build.0 = Release|Win32
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|x64.ActiveCfg = Debug|x64
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|x64.Build.0 = Debug|x64
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|Win32.ActiveCfg = Debug|Win32
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|Win32.Build.0 = Debug|Win32
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|x64.ActiveCfg = Release|x64
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|x64.Build.0 = Release|x64
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|Win32.ActiveCfg = Release|Win32
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|Win32.Build.0 = Release|Win32
+		{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
+		{293E74D1-544C-D368-02A0-52F61A4D0679}.Debug|x64.ActiveCfg = Debug|x64
+		{293E74D1-544C-D368-02A0-52F61A4D0679}.Debug|x64.Build.0 = Debug|x64
 		{293E74D1-544C-D368-02A0-52F61A4D0679}.Debug|Win32.ActiveCfg = Debug|Win32
 		{293E74D1-544C-D368-02A0-52F61A4D0679}.Debug|Win32.Build.0 = Debug|Win32
+		{293E74D1-544C-D368-02A0-52F61A4D0679}.Release|x64.ActiveCfg = Release|x64
+		{293E74D1-544C-D368-02A0-52F61A4D0679}.Release|x64.Build.0 = Release|x64
 		{293E74D1-544C-D368-02A0-52F61A4D0679}.Release|Win32.ActiveCfg = Release|Win32
 		{293E74D1-544C-D368-02A0-52F61A4D0679}.Release|Win32.Build.0 = Release|Win32
+		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Debug|x64.ActiveCfg = Debug|x64
+		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Debug|x64.Build.0 = Debug|x64
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Debug|Win32.Build.0 = Debug|Win32
+		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Release|x64.ActiveCfg = Release|x64
+		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Release|x64.Build.0 = Release|x64
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Release|Win32.ActiveCfg = Release|Win32
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Release|Win32.Build.0 = Release|Win32
+		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Debug|x64.ActiveCfg = Debug|x64
+		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Debug|x64.Build.0 = Debug|x64
 		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Debug|Win32.ActiveCfg = Debug|Win32
 		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Debug|Win32.Build.0 = Debug|Win32
+		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Release|x64.ActiveCfg = Release|x64
+		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Release|x64.Build.0 = Release|x64
 		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Release|Win32.ActiveCfg = Release|Win32
 		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.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
+		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Debug|x64.ActiveCfg = Debug|x64
+		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Debug|x64.Build.0 = Debug|x64
 		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Debug|Win32.ActiveCfg = Debug|Win32
 		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Debug|Win32.Build.0 = Debug|Win32
+		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Release|x64.ActiveCfg = Release|x64
+		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Release|x64.Build.0 = Release|x64
 		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Release|Win32.ActiveCfg = Release|Win32
 		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Release|Win32.Build.0 = Release|Win32
+		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Debug|x64.ActiveCfg = Debug|x64
+		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Debug|x64.Build.0 = Debug|x64
 		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Debug|Win32.Build.0 = Debug|Win32
+		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Release|x64.ActiveCfg = Release|x64
+		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Release|x64.Build.0 = Release|x64
 		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Release|Win32.ActiveCfg = Release|Win32
 		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Release|Win32.Build.0 = Release|Win32
+		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Debug|x64.ActiveCfg = Debug|x64
+		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Debug|x64.Build.0 = Debug|x64
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Debug|Win32.Build.0 = Debug|Win32
+		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Release|x64.ActiveCfg = Release|x64
+		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Release|x64.Build.0 = Release|x64
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Release|Win32.ActiveCfg = Release|Win32
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Release|Win32.Build.0 = Release|Win32
+		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Debug|x64.ActiveCfg = Debug|x64
+		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Debug|x64.Build.0 = Debug|x64
 		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Debug|Win32.ActiveCfg = Debug|Win32
 		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Debug|Win32.Build.0 = Debug|Win32
+		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Release|x64.ActiveCfg = Release|x64
+		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Release|x64.Build.0 = Release|x64
 		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Release|Win32.ActiveCfg = Release|Win32
 		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.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
+		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Debug|x64.ActiveCfg = Debug|x64
+		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Debug|x64.Build.0 = Debug|x64
 		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Debug|Win32.ActiveCfg = Debug|Win32
 		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Debug|Win32.Build.0 = Debug|Win32
+		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Release|x64.ActiveCfg = Release|x64
+		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Release|x64.Build.0 = Release|x64
 		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Release|Win32.ActiveCfg = Release|Win32
 		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.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
+		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Debug|x64.ActiveCfg = Debug|x64
+		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Debug|x64.Build.0 = Debug|x64
 		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Debug|Win32.ActiveCfg = Debug|Win32
 		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Debug|Win32.Build.0 = Debug|Win32
+		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Release|x64.ActiveCfg = Release|x64
+		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Release|x64.Build.0 = Release|x64
 		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Release|Win32.ActiveCfg = Release|Win32
 		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Release|Win32.Build.0 = Release|Win32
+		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Debug|x64.ActiveCfg = Debug|x64
+		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Debug|x64.Build.0 = Debug|x64
 		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Debug|Win32.ActiveCfg = Debug|Win32
 		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Debug|Win32.Build.0 = Debug|Win32
+		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Release|x64.ActiveCfg = Release|x64
+		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Release|x64.Build.0 = Release|x64
 		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Release|Win32.ActiveCfg = Release|Win32
 		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Release|Win32.Build.0 = Release|Win32
+		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Debug|x64.ActiveCfg = Debug|x64
+		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Debug|x64.Build.0 = Debug|x64
 		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Debug|Win32.Build.0 = Debug|Win32
+		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Release|x64.ActiveCfg = Release|x64
+		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Release|x64.Build.0 = Release|x64
 		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Release|Win32.ActiveCfg = Release|Win32
 		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Release|Win32.Build.0 = Release|Win32
+		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Debug|x64.ActiveCfg = Debug|x64
+		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Debug|x64.Build.0 = Debug|x64
 		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Debug|Win32.ActiveCfg = Debug|Win32
 		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Debug|Win32.Build.0 = Debug|Win32
+		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Release|x64.ActiveCfg = Release|x64
+		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Release|x64.Build.0 = Release|x64
 		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Release|Win32.ActiveCfg = Release|Win32
 		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Release|Win32.Build.0 = Release|Win32
+		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Debug|x64.ActiveCfg = Debug|x64
+		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Debug|x64.Build.0 = Debug|x64
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Debug|Win32.Build.0 = Debug|Win32
+		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Release|x64.ActiveCfg = Release|x64
+		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Release|x64.Build.0 = Release|x64
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Release|Win32.ActiveCfg = Release|Win32
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.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
+		{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
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Debug|Win32.Build.0 = Debug|Win32
+		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Release|x64.ActiveCfg = Release|x64
+		{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
+		{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}.Debug|x64.ActiveCfg = Debug|x64
+		{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}.Debug|x64.Build.0 = Debug|x64
 		{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}.Debug|Win32.Build.0 = Debug|Win32
+		{D048EF6F-5312-AF41-8D8A-DB22CD8634E6}.Release|x64.ActiveCfg = Release|x64
+		{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
 		{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
diff --git a/projects/samples/dds_to_header.vcxproj b/projects/samples/dds_to_header.vcxproj
index fc3e227..48cd7d7 100644
--- a/projects/samples/dds_to_header.vcxproj
+++ b/projects/samples/dds_to_header.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,7 +42,9 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </PropertyGroup>
@@ -42,11 +55,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -69,7 +84,44 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>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;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>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'">
@@ -78,11 +130,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -105,7 +159,43 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>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;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>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>
diff --git a/projects/samples/essl_to_glsl.vcxproj b/projects/samples/essl_to_glsl.vcxproj
index 8b7b377..ec07d28 100644
--- a/projects/samples/essl_to_glsl.vcxproj
+++ b/projects/samples/essl_to_glsl.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{293E74D1-544C-D368-02A0-52F61A4D0679}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,7 +42,9 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </PropertyGroup>
@@ -42,11 +55,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -69,7 +84,45 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\include;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>NOMINMAX;ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\include;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;ANGLE_TRANSLATOR_STATIC;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;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>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -78,11 +131,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -105,7 +160,44 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\include;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>NOMINMAX;ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\include;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;ANGLE_TRANSLATOR_STATIC;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;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>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
diff --git a/projects/samples/essl_to_hlsl.vcxproj b/projects/samples/essl_to_hlsl.vcxproj
index 827e6d0..da4aa21 100644
--- a/projects/samples/essl_to_hlsl.vcxproj
+++ b/projects/samples/essl_to_hlsl.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{B4D06330-EED1-6F99-BCA4-2F913908C38A}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,7 +42,9 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </PropertyGroup>
@@ -42,11 +55,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -69,7 +84,45 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\include;..\..\src;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>NOMINMAX;ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\src;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;ANGLE_TRANSLATOR_STATIC;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\src;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>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -78,11 +131,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -105,7 +160,44 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\include;..\..\src;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>NOMINMAX;ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\src;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;ANGLE_TRANSLATOR_STATIC;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;..\..\src;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>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
diff --git a/projects/samples/hello_triangle.vcxproj b/projects/samples/hello_triangle.vcxproj
index c45a35b..95349e8 100644
--- a/projects/samples/hello_triangle.vcxproj
+++ b/projects/samples/hello_triangle.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 f8c9543..787b1c7 100644
--- a/projects/samples/mip_map_2d.vcxproj
+++ b/projects/samples/mip_map_2d.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{A6E86EB3-561F-9FAB-670F-EF23556344BE}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 2c34b2f..774df3d 100644
--- a/projects/samples/multi_texture.vcxproj
+++ b/projects/samples/multi_texture.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{37E1BB43-65DC-A25A-042E-30B88E6C75A2}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -141,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 ac8f4f0..c145002 100644
--- a/projects/samples/multiple_draw_buffers.vcxproj
+++ b/projects/samples/multiple_draw_buffers.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{58BE89D7-25D5-CC84-EDBF-412C12C59709}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -147,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 fb6a6c3..751bc23 100644
--- a/projects/samples/particle_system.vcxproj
+++ b/projects/samples/particle_system.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -135,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 a676887..44a985c 100644
--- a/projects/samples/post_sub_buffer.vcxproj
+++ b/projects/samples/post_sub_buffer.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{CBE3D362-43EA-60FC-D5AC-490039CA449A}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 ebba90f..5944555 100644
--- a/projects/samples/sample_util.vcxproj
+++ b/projects/samples/sample_util.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}</ProjectGuid>
@@ -20,6 +28,9 @@
     <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">
@@ -31,22 +42,25 @@
     <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;..\..\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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4201;4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -55,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <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;..\..\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>
-      <DisableSpecificWarnings>4201;4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -91,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>
@@ -103,45 +157,67 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <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;..\..\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>
   <ItemGroup>
     <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 b927860..a0d4f12 100644
--- a/projects/samples/samples.sln
+++ b/projects/samples/samples.sln
@@ -1,5 +1,11 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual C++ Express 2010
+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}"
@@ -141,108 +166,226 @@
 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
+		{0BD6333E-E82C-7665-C386-CDA40096413D}.Debug|x64.ActiveCfg = Debug|x64
+		{0BD6333E-E82C-7665-C386-CDA40096413D}.Debug|x64.Build.0 = Debug|x64
 		{0BD6333E-E82C-7665-C386-CDA40096413D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0BD6333E-E82C-7665-C386-CDA40096413D}.Debug|Win32.Build.0 = Debug|Win32
+		{0BD6333E-E82C-7665-C386-CDA40096413D}.Release|x64.ActiveCfg = Release|x64
+		{0BD6333E-E82C-7665-C386-CDA40096413D}.Release|x64.Build.0 = Release|x64
 		{0BD6333E-E82C-7665-C386-CDA40096413D}.Release|Win32.ActiveCfg = Release|Win32
 		{0BD6333E-E82C-7665-C386-CDA40096413D}.Release|Win32.Build.0 = Release|Win32
+		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Debug|x64.ActiveCfg = Debug|x64
+		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Debug|x64.Build.0 = Debug|x64
 		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Debug|Win32.ActiveCfg = Debug|Win32
 		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Debug|Win32.Build.0 = Debug|Win32
+		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Release|x64.ActiveCfg = Release|x64
+		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Release|x64.Build.0 = Release|x64
 		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Release|Win32.ActiveCfg = Release|Win32
 		{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}.Release|Win32.Build.0 = Release|Win32
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|x64.ActiveCfg = Debug|x64
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|x64.Build.0 = Debug|x64
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|Win32.ActiveCfg = Debug|Win32
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|Win32.Build.0 = Debug|Win32
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|x64.ActiveCfg = Release|x64
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|x64.Build.0 = Release|x64
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|Win32.ActiveCfg = Release|Win32
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|Win32.Build.0 = Release|Win32
+		{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
+		{293E74D1-544C-D368-02A0-52F61A4D0679}.Debug|x64.ActiveCfg = Debug|x64
+		{293E74D1-544C-D368-02A0-52F61A4D0679}.Debug|x64.Build.0 = Debug|x64
 		{293E74D1-544C-D368-02A0-52F61A4D0679}.Debug|Win32.ActiveCfg = Debug|Win32
 		{293E74D1-544C-D368-02A0-52F61A4D0679}.Debug|Win32.Build.0 = Debug|Win32
+		{293E74D1-544C-D368-02A0-52F61A4D0679}.Release|x64.ActiveCfg = Release|x64
+		{293E74D1-544C-D368-02A0-52F61A4D0679}.Release|x64.Build.0 = Release|x64
 		{293E74D1-544C-D368-02A0-52F61A4D0679}.Release|Win32.ActiveCfg = Release|Win32
 		{293E74D1-544C-D368-02A0-52F61A4D0679}.Release|Win32.Build.0 = Release|Win32
+		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Debug|x64.ActiveCfg = Debug|x64
+		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Debug|x64.Build.0 = Debug|x64
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Debug|Win32.Build.0 = Debug|Win32
+		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Release|x64.ActiveCfg = Release|x64
+		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Release|x64.Build.0 = Release|x64
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Release|Win32.ActiveCfg = Release|Win32
 		{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}.Release|Win32.Build.0 = Release|Win32
+		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Debug|x64.ActiveCfg = Debug|x64
+		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Debug|x64.Build.0 = Debug|x64
 		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Debug|Win32.ActiveCfg = Debug|Win32
 		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Debug|Win32.Build.0 = Debug|Win32
+		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Release|x64.ActiveCfg = Release|x64
+		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Release|x64.Build.0 = Release|x64
 		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.Release|Win32.ActiveCfg = Release|Win32
 		{37E1BB43-65DC-A25A-042E-30B88E6C75A2}.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
+		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Debug|x64.ActiveCfg = Debug|x64
+		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Debug|x64.Build.0 = Debug|x64
 		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Debug|Win32.ActiveCfg = Debug|Win32
 		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Debug|Win32.Build.0 = Debug|Win32
+		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Release|x64.ActiveCfg = Release|x64
+		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Release|x64.Build.0 = Release|x64
 		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Release|Win32.ActiveCfg = Release|Win32
 		{3F4D97A9-0809-E0E4-5A3F-B6ACB6EABB46}.Release|Win32.Build.0 = Release|Win32
+		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Debug|x64.ActiveCfg = Debug|x64
+		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Debug|x64.Build.0 = Debug|x64
 		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Debug|Win32.Build.0 = Debug|Win32
+		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Release|x64.ActiveCfg = Release|x64
+		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Release|x64.Build.0 = Release|x64
 		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Release|Win32.ActiveCfg = Release|Win32
 		{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}.Release|Win32.Build.0 = Release|Win32
+		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Debug|x64.ActiveCfg = Debug|x64
+		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Debug|x64.Build.0 = Debug|x64
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Debug|Win32.Build.0 = Debug|Win32
+		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Release|x64.ActiveCfg = Release|x64
+		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Release|x64.Build.0 = Release|x64
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Release|Win32.ActiveCfg = Release|Win32
 		{46160987-0221-9E14-3B88-80F9FCFCFFBF}.Release|Win32.Build.0 = Release|Win32
+		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Debug|x64.ActiveCfg = Debug|x64
+		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Debug|x64.Build.0 = Debug|x64
 		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Debug|Win32.ActiveCfg = Debug|Win32
 		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Debug|Win32.Build.0 = Debug|Win32
+		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Release|x64.ActiveCfg = Release|x64
+		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Release|x64.Build.0 = Release|x64
 		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.Release|Win32.ActiveCfg = Release|Win32
 		{58BE89D7-25D5-CC84-EDBF-412C12C59709}.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
+		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Debug|x64.ActiveCfg = Debug|x64
+		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Debug|x64.Build.0 = Debug|x64
 		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Debug|Win32.ActiveCfg = Debug|Win32
 		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Debug|Win32.Build.0 = Debug|Win32
+		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Release|x64.ActiveCfg = Release|x64
+		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Release|x64.Build.0 = Release|x64
 		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.Release|Win32.ActiveCfg = Release|Win32
 		{6BC75FF2-C11A-C393-F9BB-BF29FF29D736}.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
+		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Debug|x64.ActiveCfg = Debug|x64
+		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Debug|x64.Build.0 = Debug|x64
 		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Debug|Win32.ActiveCfg = Debug|Win32
 		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Debug|Win32.Build.0 = Debug|Win32
+		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Release|x64.ActiveCfg = Release|x64
+		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Release|x64.Build.0 = Release|x64
 		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Release|Win32.ActiveCfg = Release|Win32
 		{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}.Release|Win32.Build.0 = Release|Win32
+		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Debug|x64.ActiveCfg = Debug|x64
+		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Debug|x64.Build.0 = Debug|x64
 		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Debug|Win32.ActiveCfg = Debug|Win32
 		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Debug|Win32.Build.0 = Debug|Win32
+		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Release|x64.ActiveCfg = Release|x64
+		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Release|x64.Build.0 = Release|x64
 		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Release|Win32.ActiveCfg = Release|Win32
 		{92582B26-5131-8C32-39D9-5768C7FA12B4}.Release|Win32.Build.0 = Release|Win32
+		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Debug|x64.ActiveCfg = Debug|x64
+		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Debug|x64.Build.0 = Debug|x64
 		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Debug|Win32.Build.0 = Debug|Win32
+		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Release|x64.ActiveCfg = Release|x64
+		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Release|x64.Build.0 = Release|x64
 		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Release|Win32.ActiveCfg = Release|Win32
 		{93B7F18A-947E-69A1-9CD8-D1E5144E792A}.Release|Win32.Build.0 = Release|Win32
+		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Debug|x64.ActiveCfg = Debug|x64
+		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Debug|x64.Build.0 = Debug|x64
 		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Debug|Win32.ActiveCfg = Debug|Win32
 		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Debug|Win32.Build.0 = Debug|Win32
+		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Release|x64.ActiveCfg = Release|x64
+		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Release|x64.Build.0 = Release|x64
 		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Release|Win32.ActiveCfg = Release|Win32
 		{A6E86EB3-561F-9FAB-670F-EF23556344BE}.Release|Win32.Build.0 = Release|Win32
+		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Debug|x64.ActiveCfg = Debug|x64
+		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Debug|x64.Build.0 = Debug|x64
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Debug|Win32.Build.0 = Debug|Win32
+		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Release|x64.ActiveCfg = Release|x64
+		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Release|x64.Build.0 = Release|x64
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.Release|Win32.ActiveCfg = Release|Win32
 		{B4D06330-EED1-6F99-BCA4-2F913908C38A}.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
+		{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
 		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Debug|Win32.Build.0 = Debug|Win32
+		{CBE3D362-43EA-60FC-D5AC-490039CA449A}.Release|x64.ActiveCfg = Release|x64
+		{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
 		{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
diff --git a/projects/samples/simple_instancing.vcxproj b/projects/samples/simple_instancing.vcxproj
index d75c874..577f0d3 100644
--- a/projects/samples/simple_instancing.vcxproj
+++ b/projects/samples/simple_instancing.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{130A534E-6BA3-DB9C-B0D2-5ACE5CCB2632}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 1f883e3..afd56a0 100644
--- a/projects/samples/simple_texture_2d.vcxproj
+++ b/projects/samples/simple_texture_2d.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{0BD6333E-E82C-7665-C386-CDA40096413D}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 344a0c1..037e1ba 100644
--- a/projects/samples/simple_texture_cubemap.vcxproj
+++ b/projects/samples/simple_texture_cubemap.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{93B7F18A-947E-69A1-9CD8-D1E5144E792A}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 89fd705..146b578 100644
--- a/projects/samples/simple_vertex_shader.vcxproj
+++ b/projects/samples/simple_vertex_shader.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{459E5678-892C-4EF9-6ED8-0D9E5272B4FF}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 3797c24..4cc706a 100644
--- a/projects/samples/stencil_operations.vcxproj
+++ b/projects/samples/stencil_operations.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{92582B26-5131-8C32-39D9-5768C7FA12B4}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 33d23b6..3218dfd 100644
--- a/projects/samples/texture_wrap.vcxproj
+++ b/projects/samples/texture_wrap.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{46160987-0221-9E14-3B88-80F9FCFCFFBF}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </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>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -67,22 +82,60 @@
       <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>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <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>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -90,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>
@@ -103,9 +157,45 @@
       <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>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <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>
+      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4251;4512;4702;4530;4718;4267;4201;%(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>
+    </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>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <ResourceCompile>
+      <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>
   <ItemGroup>
@@ -127,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 cdf9f53..9726e34 100644
--- a/projects/src/angle.sln
+++ b/projects/src/angle.sln
@@ -1,5 +1,5 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual C++ Express 2010
+Microsoft Visual Studio Solution File, Format Version 13.00
+# Visual Studio 2013
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "commit_id", "commit_id.vcxproj", "{3B7F5656-177F-52EE-26B3-D6A75368D0A9}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_compiler_dll", "copy_compiler_dll.vcxproj", "{22DC02D5-1598-943C-13E1-82185B469F81}"
@@ -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}"
@@ -35,44 +47,98 @@
 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
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|x64.ActiveCfg = Debug|x64
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|x64.Build.0 = Debug|x64
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|Win32.ActiveCfg = Debug|Win32
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Debug|Win32.Build.0 = Debug|Win32
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|x64.ActiveCfg = Release|x64
+		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|x64.Build.0 = Release|x64
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|Win32.ActiveCfg = Release|Win32
 		{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}.Release|Win32.Build.0 = Release|Win32
+		{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
+		{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
 		{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
diff --git a/projects/src/commit_id.vcxproj b/projects/src/commit_id.vcxproj
index 6acbadc..da98f64 100644
--- a/projects/src/commit_id.vcxproj
+++ b/projects/src/commit_id.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{3B7F5656-177F-52EE-26B3-D6A75368D0A9}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Utility</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,7 +42,9 @@
     <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>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -40,10 +53,10 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -51,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>
@@ -64,7 +78,38 @@
     </Link>
     <ResourceCompile>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <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>
+    </Lib>
+    <Link>
+      <AdditionalDependencies></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>
+      <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -72,10 +117,10 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -83,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>
@@ -96,7 +142,37 @@
     </Link>
     <ResourceCompile>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <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>
+    </Lib>
+    <Link>
+      <AdditionalDependencies></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>
+      <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
diff --git a/projects/src/copy_compiler_dll.vcxproj b/projects/src/copy_compiler_dll.vcxproj
index 6b8587c..b01ab2b 100644
--- a/projects/src/copy_compiler_dll.vcxproj
+++ b/projects/src/copy_compiler_dll.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{22DC02D5-1598-943C-13E1-82185B469F81}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Utility</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,7 +42,9 @@
     <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>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -41,11 +54,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -53,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>
@@ -67,7 +82,43 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>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;%(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>
+    </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>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'">
@@ -76,11 +127,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -88,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>
@@ -102,7 +155,42 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>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;%(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>
+    </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>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>
@@ -113,7 +201,7 @@
       <FileType>Document</FileType>
       <Command>call call $(OutDir)obj\global_intermediate\angle\copy_compiler_dll.bat &quot;$(Platform)&quot; &quot;C:\Program Files (x86)\Windows Kits\8.0&quot; &quot;$(OutDir)&quot;</Command>
       <Message>Copying D3D Compiler DLL...</Message>
-      <Outputs>$(OutDir)\D3DCompiler_46.dll</Outputs>
+      <Outputs>$(OutDir)\d3dcompiler_46.dll</Outputs>
     </CustomBuild>
   </ItemGroup>
   <ItemGroup>
diff --git a/projects/src/copy_scripts.vcxproj b/projects/src/copy_scripts.vcxproj
index 748d69a..e7c2613 100644
--- a/projects/src/copy_scripts.vcxproj
+++ b/projects/src/copy_scripts.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{63FB0B97-D1D9-5158-8E85-7F5B1E403817}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>Utility</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,7 +42,9 @@
     <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>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -40,10 +53,10 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -51,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>
@@ -64,7 +78,38 @@
     </Link>
     <ResourceCompile>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>Disabled</Optimization>
+      <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>
+    </Lib>
+    <Link>
+      <AdditionalDependencies></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>
+      <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -72,10 +117,10 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <ExceptionHandling>false</ExceptionHandling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MinimalRebuild>false</MinimalRebuild>
       <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -83,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>
@@ -96,7 +142,37 @@
     </Link>
     <ResourceCompile>
       <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <MinimalRebuild>false</MinimalRebuild>
+      <Optimization>MaxSpeed</Optimization>
+      <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>
+    </Lib>
+    <Link>
+      <AdditionalDependencies></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>
+      <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
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 4daf31d..8e25de4 100644
--- a/projects/src/libEGL.vcxproj
+++ b/projects/src/libEGL.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{FBAEE4F6-562A-588F-01F9-72DCABB3B061}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>DynamicLibrary</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,7 +42,9 @@
     <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)\$(ProjectName)$(TargetExt)</TargetPath>
   </PropertyGroup>
@@ -42,11 +55,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;NOMINMAX;ANGLE_ENABLE_PERF;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;ANGLE_ENABLE_PERF;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -54,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>
@@ -70,7 +85,46 @@
     <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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;NOMINMAX;ANGLE_ENABLE_PERF;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;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_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>
+    </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>
+      <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>
+      <ModuleDefinitionFile>..\..\src\libEGL\libEGL.def</ModuleDefinitionFile>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <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_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -79,11 +133,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;ANGLE_ENABLE_D3D9;ANGLE_ENABLE_D3D11;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -91,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>
@@ -107,7 +163,45 @@
     <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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;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_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>
+    </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>
+      <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>
+      <ModuleDefinitionFile>..\..\src\libEGL\libEGL.def</ModuleDefinitionFile>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <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_ENABLE_D3D9;ANGLE_ENABLE_D3D11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
@@ -124,13 +218,15 @@
     <ClInclude Include="..\..\src\common\debug.h"/>
     <ClInclude Include="..\..\src\common\mathutil.h"/>
     <ClInclude Include="..\..\src\common\event_tracer.h"/>
+    <ClInclude Include="..\..\src\common\platform.h"/>
     <ClInclude Include="..\..\src\common\version.h"/>
     <ClInclude Include="..\..\src\common\utilities.h"/>
+    <ClInclude Include="..\..\src\common\tls.h"/>
     <ClInclude Include="..\..\src\common\angleutils.h"/>
-    <ClInclude Include="..\..\src\common\shadervars.h"/>
-    <ClInclude Include="..\..\src\common\blocklayout.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\gl2.h"/>
     <ClInclude Include="..\..\include\GLES2\gl2platform.h"/>
     <ClInclude Include="..\..\include\GLES2\gl2ext.h"/>
@@ -149,10 +245,11 @@
     <ClCompile Include="..\..\src\libEGL\libEGL.cpp"/>
     <ClCompile Include="..\..\src\common\mathutil.cpp"/>
     <ClCompile Include="..\..\src\common\RefCountObject.cpp"/>
+    <ClCompile Include="..\..\src\common\tls.cpp"/>
     <ClCompile Include="..\..\src\common\debug.cpp"/>
     <ClCompile Include="..\..\src\common\event_tracer.cpp"/>
     <ClCompile Include="..\..\src\common\utilities.cpp"/>
-    <ClCompile Include="..\..\src\common\blocklayout.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 5994e46..feb9c0c 100644
--- a/projects/src/libEGL.vcxproj.filters
+++ b/projects/src/libEGL.vcxproj.filters
@@ -78,6 +78,9 @@
     <ClInclude Include="..\..\src\common\RefCountObject.h">
       <Filter>src\common</Filter>
     </ClInclude>
+    <ClCompile Include="..\..\src\common\tls.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
     <ClInclude Include="..\..\src\common\debug.h">
       <Filter>src\common</Filter>
     </ClInclude>
@@ -90,6 +93,9 @@
     <ClInclude Include="..\..\src\common\event_tracer.h">
       <Filter>src\common</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\common\platform.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\common\version.h">
       <Filter>src\common</Filter>
     </ClInclude>
@@ -99,27 +105,30 @@
     <ClCompile Include="..\..\src\common\event_tracer.cpp">
       <Filter>src\common</Filter>
     </ClCompile>
+    <ClInclude Include="..\..\src\common\tls.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>
-    <ClInclude Include="..\..\src\common\shadervars.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\blocklayout.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\common\blocklayout.cpp">
+    <ClCompile Include="..\..\src\common\angleutils.cpp">
       <Filter>src\common</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\gl2.h">
       <Filter>include\GLES2</Filter>
     </ClInclude>
diff --git a/projects/src/libGLESv2.vcxproj b/projects/src/libGLESv2.vcxproj
index 28a7793..2be234a 100644
--- a/projects/src/libGLESv2.vcxproj
+++ b/projects/src/libGLESv2.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}</ProjectGuid>
@@ -20,6 +28,9 @@
     <CharacterSet>MultiByte</CharacterSet>
     <ConfigurationType>DynamicLibrary</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Label="Locals">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
   <ImportGroup Label="ExtensionSettings"/>
   <ImportGroup Label="PropertySheets">
@@ -31,22 +42,25 @@
     <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)\$(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>
+      <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;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;NOMINMAX;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>
@@ -54,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>
@@ -68,22 +83,62 @@
       <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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;NOMINMAX;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>$(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>
+    </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>
+      <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>
+      <ModuleDefinitionFile>..\..\src\libGLESv2\libGLESv2.def</ModuleDefinitionFile>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <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>..\..\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>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;NOMINMAX;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>
@@ -91,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>
@@ -105,292 +161,68 @@
       <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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };GL_APICALL=;GL_GLEXT_PROTOTYPES=;EGLAPI=;NOMINMAX;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>$(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>
+    </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>
+      <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>
+      <ModuleDefinitionFile>..\..\src\libGLESv2\libGLESv2.def</ModuleDefinitionFile>
+      <OutputFile>$(OutDir)$(ProjectName)$(TargetExt)</OutputFile>
+      <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"/>
     <None Include="..\..\src\libGLESv2\libGLESv2.def"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\Clear11.hlsl"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\generate_shaders.bat"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\Swizzle11.hlsl"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\Passthrough2D11.hlsl"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\Passthrough3D11.hlsl"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\BufferToTexture11.hlsl"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d9\shaders\Blit.ps"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d9\shaders\Blit.vs"/>
-    <None Include="..\..\src\libGLESv2\renderer\d3d9\shaders\generate_shaders.bat"/>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\libGLESv2\Shader.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\BinaryStream.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\resource.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Renderbuffer.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\VertexArray.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Uniform.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\ProgramBinary.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\constants.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Buffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\RenderbufferProxySet.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\validationES.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\queryconversions.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\validationES3.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Program.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Sampler.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\FramebufferAttachment.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\Framebuffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\formatutils.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\IndexDataManager.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\Renderer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\TextureStorage.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\imageformats.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\ShaderExecutable.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\IndexBuffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\loadimage.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\copyimage.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\copyvertex.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\BufferStorage.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\SwapChain.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\VertexDataManager.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\VertexBuffer.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\PixelTransfer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\SwapChain11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\VertexBuffer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\RenderStateCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\IndexBuffer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Clear11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\BufferStorage11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\RenderTarget11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Image11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Renderer11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\InputLayoutCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\renderer11_utils.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\TextureStorage11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\ShaderExecutable11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Fence11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Query11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\formatutils11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Blit11.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr2di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_gs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr2dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthrough2d11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr3di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg2di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlei3dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearsint11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearuint11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba3dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzleui2darrayps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb2dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughlumalpha3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg3di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg2dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzleui2dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlef2dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlef3dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_ps_4f.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb2di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba3di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearsint11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzleui3dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearfloat11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb3di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlei2dps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthrough3d11gs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlei2darrayps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearfloat11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughlum3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba2di11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughlum2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr3dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughdepth2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_ps_4ui.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlef2darrayps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb3d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba2dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_ps_4i.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughlumalpha2d11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearuint11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg3dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthrough3d11vs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb3dui11ps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\IndexBuffer9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\VertexDeclarationCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\ShaderCache.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\ShaderExecutable9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\VertexBuffer9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Image9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\SwapChain9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\formatutils9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Renderer9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\renderer9_utils.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Blit9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Query9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Fence9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\TextureStorage9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\RenderTarget9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\BufferStorage9.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\luminanceps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\passthroughps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\flipyvs.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\componentmaskps.h"/>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\standardvs.h"/>
-    <ClInclude Include="..\..\src\common\mathutil.h"/>
-    <ClInclude Include="..\..\src\common\blocklayout.h"/>
-    <ClInclude Include="..\..\src\common\debug.h"/>
-    <ClInclude Include="..\..\src\common\shadervars.h"/>
-    <ClInclude Include="..\..\src\common\utilities.h"/>
-    <ClInclude Include="..\..\src\common\angleutils.h"/>
-    <ClInclude Include="..\..\src\common\RefCountObject.h"/>
-    <ClInclude Include="..\..\src\common\event_tracer.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\KHR\khrplatform.h"/>
-    <ClInclude Include="..\..\include\GLSLANG\ShaderLang.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\RenderbufferProxySet.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\angletypes.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Float16ToFloat32.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\ResourceManager.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\validationES3.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\FramebufferAttachment.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Query.cpp"/>
     <ClCompile Include="..\..\src\libGLESv2\libGLESv2.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\formatutils.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\Context.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\TransformFeedback.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\ProgramBinary.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\IndexDataManager.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexBuffer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimage.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\VertexDataManager.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\loadimageSSE2.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\VertexBuffer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\Image.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\BufferStorage.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexRangeCache.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\Renderer.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\TextureStorage.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Clear11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Query11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\TextureStorage11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\ShaderExecutable11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\VertexBuffer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Renderer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Blit11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\RenderStateCache.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\RenderTarget11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\InputLayoutCache.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\renderer11_utils.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\SwapChain11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\IndexBuffer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\formatutils11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\PixelTransfer11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Image11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Fence11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\BufferStorage11.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\renderer9_utils.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Image9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\ShaderExecutable9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\RenderTarget9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Renderer9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Fence9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\SwapChain9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\VertexBuffer9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Query9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\VertexDeclarationCache.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Blit9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\BufferStorage9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\TextureStorage9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\IndexBuffer9.cpp"/>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\formatutils9.cpp"/>
-    <ClCompile Include="..\..\src\common\event_tracer.cpp"/>
-    <ClCompile Include="..\..\src\common\blocklayout.cpp"/>
-    <ClCompile Include="..\..\src\common\RefCountObject.cpp"/>
-    <ClCompile Include="..\..\src\common\utilities.cpp"/>
-    <ClCompile Include="..\..\src\common\mathutil.cpp"/>
-    <ClCompile Include="..\..\src\common\debug.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>
@@ -399,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 bee9491..6707221 100644
--- a/projects/src/libGLESv2.vcxproj.filters
+++ b/projects/src/libGLESv2.vcxproj.filters
@@ -1,847 +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\d3d11">
-      <UniqueIdentifier>{10FB1414-88D2-B512-6D76-522749905268}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d11\shaders">
-      <UniqueIdentifier>{467D5622-06CC-2CF1-19E5-3CDD46A4008C}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d11\shaders\compiled">
-      <UniqueIdentifier>{F444E9E6-7D51-0546-F1E4-B6C8FCDA5FC6}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d">
-      <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d9">
-      <UniqueIdentifier>{8BB193D2-4A8B-A094-A81E-D5E262AB1F92}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\d3d9\shaders">
-      <UniqueIdentifier>{467D5622-06CC-2CF1-19E5-3CDD46A4008C}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\libGLESv2\renderer\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\Renderbuffer.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\RenderbufferProxySet.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\VertexArray.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <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\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\ResourceManager.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\validationES3.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\constants.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\Buffer.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\FramebufferAttachment.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\RenderbufferProxySet.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\Query.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\validationES.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\libGLESv2.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>
-    <ClInclude Include="..\..\src\libGLESv2\Sampler.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\HandleAllocator.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\formatutils.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <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>
-    <ClCompile Include="..\..\src\libGLESv2\TransformFeedback.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>
-    <ClInclude Include="..\..\src\libGLESv2\main.h">
-      <Filter>src\libGLESv2</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\ProgramBinary.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\FramebufferAttachment.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>
-    <ClCompile Include="..\..\src\libGLESv2\Framebuffer.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\Texture.cpp">
-      <Filter>src\libGLESv2</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\IndexDataManager.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\copyimage.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\Renderer.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexDataManager.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\TextureStorage.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\imageformats.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexBuffer.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\ShaderExecutable.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\IndexBuffer.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>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\VertexDataManager.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <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\BufferStorage.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\VertexBuffer.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <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>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\BufferStorage.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <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\VertexDataManager.h">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\IndexRangeCache.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\VertexBuffer.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\TextureStorage.cpp">
-      <Filter>src\libGLESv2\renderer</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Clear11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Query11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\PixelTransfer11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\TextureStorage11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\ShaderExecutable11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\SwapChain11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\VertexBuffer11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\RenderStateCache.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\VertexBuffer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Renderer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\IndexBuffer11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Clear11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\BufferStorage11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\RenderTarget11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Blit11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Image11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Renderer11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\RenderStateCache.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\InputLayoutCache.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\RenderTarget11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\InputLayoutCache.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\renderer11_utils.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\renderer11_utils.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\SwapChain11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\TextureStorage11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\ShaderExecutable11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Fence11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\IndexBuffer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\formatutils11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\PixelTransfer11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Query11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\formatutils11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\Blit11.h">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Image11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\Fence11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d11\BufferStorage11.cpp">
-      <Filter>src\libGLESv2\renderer\d3d11</Filter>
-    </ClCompile>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\Clear11.hlsl">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders</Filter>
-    </None>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\generate_shaders.bat">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders</Filter>
-    </None>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\Swizzle11.hlsl">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders</Filter>
-    </None>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\Passthrough2D11.hlsl">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders</Filter>
-    </None>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\Passthrough3D11.hlsl">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders</Filter>
-    </None>
-    <None Include="..\..\src\libGLESv2\renderer\d3d11\shaders\BufferToTexture11.hlsl">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders</Filter>
-    </None>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr2di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_gs.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr2dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthrough2d11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr3di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg2di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlei3dps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearsint11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearuint11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba3dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzleui2darrayps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb2dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughlumalpha3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg3di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg2dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzleui2dps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_vs.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlef2dps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlef3dps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_ps_4f.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb2di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba3di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearsint11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzleui3dps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearfloat11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb3di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlei2dps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthrough3d11gs.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlei2darrayps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearfloat11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughlum3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba2di11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughlum2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr3dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughdepth2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_ps_4ui.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughr2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\swizzlef2darrayps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb3d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgba2dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\buffertotexture11_ps_4i.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughlumalpha2d11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\clearuint11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrg3dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthrough3d11vs.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d11\shaders\compiled\passthroughrgb3dui11ps.h">
-      <Filter>src\libGLESv2\renderer\d3d11\shaders\compiled</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h">
-      <Filter>src\libGLESv2\renderer\d3d</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\renderer9_utils.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\IndexBuffer9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Image9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\ShaderExecutable9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\VertexDeclarationCache.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\ShaderCache.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\RenderTarget9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\ShaderExecutable9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\VertexBuffer9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Renderer9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Image9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\SwapChain9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\formatutils9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Fence9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\SwapChain9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\VertexBuffer9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Renderer9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Query9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\VertexDeclarationCache.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\renderer9_utils.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Blit9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\Blit9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\BufferStorage9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\TextureStorage9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Query9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\Fence9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\TextureStorage9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\IndexBuffer9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\RenderTarget9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d9\formatutils9.cpp">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\BufferStorage9.h">
-      <Filter>src\libGLESv2\renderer\d3d9</Filter>
-    </ClInclude>
-    <None Include="..\..\src\libGLESv2\renderer\d3d9\shaders\Blit.ps">
-      <Filter>src\libGLESv2\renderer\d3d9\shaders</Filter>
-    </None>
-    <None Include="..\..\src\libGLESv2\renderer\d3d9\shaders\Blit.vs">
-      <Filter>src\libGLESv2\renderer\d3d9\shaders</Filter>
-    </None>
-    <None Include="..\..\src\libGLESv2\renderer\d3d9\shaders\generate_shaders.bat">
-      <Filter>src\libGLESv2\renderer\d3d9\shaders</Filter>
-    </None>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\luminanceps.h">
-      <Filter>src\libGLESv2\renderer\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\passthroughps.h">
-      <Filter>src\libGLESv2\renderer\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\flipyvs.h">
-      <Filter>src\libGLESv2\renderer\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\componentmaskps.h">
-      <Filter>src\libGLESv2\renderer\d3d9\shaders\compiled</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d9\shaders\compiled\standardvs.h">
-      <Filter>src\libGLESv2\renderer\d3d9\shaders\compiled</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>
-    <ClInclude Include="..\..\src\common\debug.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\shadervars.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\common\utilities.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <ClCompile Include="..\..\src\common\blocklayout.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClInclude Include="..\..\src\common\angleutils.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\RefCountObject.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\common\utilities.cpp">
-      <Filter>src\common</Filter>
-    </ClCompile>
-    <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\version.h">
-      <Filter>src\common</Filter>
-    </ClInclude>
-    <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\KHR\khrplatform.h">
-      <Filter>include\KHR</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\GLSLANG\ShaderLang.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 0b702e2..fc818cf 100644
--- a/projects/src/preprocessor.vcxproj
+++ b/projects/src/preprocessor.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{C7BAF548-697D-2DCB-9DF3-9D1506A7B444}</ProjectGuid>
@@ -20,6 +28,9 @@
     <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">
@@ -31,7 +42,9 @@
     <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>
@@ -42,11 +55,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -55,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>
@@ -69,7 +84,44 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>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;%(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>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'">
@@ -78,11 +130,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -91,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>
@@ -105,7 +159,43 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>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;%(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>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>
diff --git a/projects/src/translator.vcxproj b/projects/src/translator.vcxproj
index a5e97fd..3258264 100644
--- a/projects/src/translator.vcxproj
+++ b/projects/src/translator.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{C15697F6-5057-016E-BD29-422971875679}</ProjectGuid>
@@ -20,6 +28,9 @@
     <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">
@@ -31,7 +42,9 @@
     <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>
@@ -42,11 +55,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };ANGLE_TRANSLATOR_IMPLEMENTATION;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_IMPLEMENTATION;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -55,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>
@@ -69,7 +84,45 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\src;..\..\include;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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };ANGLE_TRANSLATOR_IMPLEMENTATION;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_IMPLEMENTATION;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;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;ANGLE_TRANSLATOR_IMPLEMENTATION;%(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;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>ANGLE_TRANSLATOR_IMPLEMENTATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -78,11 +131,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };ANGLE_TRANSLATOR_IMPLEMENTATION;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_IMPLEMENTATION;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -91,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>
@@ -105,7 +160,44 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\src;..\..\include;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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };ANGLE_TRANSLATOR_IMPLEMENTATION;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_IMPLEMENTATION;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;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;ANGLE_TRANSLATOR_IMPLEMENTATION;%(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;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>ANGLE_TRANSLATOR_IMPLEMENTATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
@@ -113,6 +205,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\compiler\translator\ShaderLang.cpp"/>
+    <ClCompile Include="..\..\src\compiler\translator\ShaderVars.cpp"/>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/src/translator.vcxproj.filters b/projects/src/translator.vcxproj.filters
index 8b76279..acac9ba 100644
--- a/projects/src/translator.vcxproj.filters
+++ b/projects/src/translator.vcxproj.filters
@@ -13,5 +13,8 @@
     <ClCompile Include="..\..\src\compiler\translator\ShaderLang.cpp">
       <Filter>compiler\translator</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\compiler\translator\ShaderVars.cpp">
+      <Filter>compiler\translator</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
diff --git a/projects/src/translator_lib.vcxproj b/projects/src/translator_lib.vcxproj
index 2688685..259d91a 100644
--- a/projects/src/translator_lib.vcxproj
+++ b/projects/src/translator_lib.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{276D20F5-2943-414C-0FF6-21F4723A5CF6}</ProjectGuid>
@@ -20,6 +28,9 @@
     <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">
@@ -31,7 +42,9 @@
     <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>
@@ -42,11 +55,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -56,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>
@@ -70,7 +85,46 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\src;..\..\include;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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;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;ANGLE_TRANSLATOR_STATIC;%(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>
+      <AdditionalOptions>/ignore:4221 %(AdditionalOptions)</AdditionalOptions>
+      <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;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>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -79,11 +133,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -93,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>
@@ -107,7 +163,45 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\src;..\..\include;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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;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;ANGLE_TRANSLATOR_STATIC;%(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>
+      <AdditionalOptions>/ignore:4221 %(AdditionalOptions)</AdditionalOptions>
+      <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;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>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
@@ -117,13 +211,14 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\third_party\compiler\ArrayBoundsClamper.h"/>
-    <ClInclude Include="..\..\src\common\shadervars.h"/>
     <ClInclude Include="..\..\src\common\RefCountObject.h"/>
+    <ClInclude Include="..\..\src\common\tls.h"/>
     <ClInclude Include="..\..\src\common\mathutil.h"/>
     <ClInclude Include="..\..\src\common\event_tracer.h"/>
     <ClInclude Include="..\..\src\common\debug.h"/>
     <ClInclude Include="..\..\src\common\version.h"/>
     <ClInclude Include="..\..\src\common\blocklayout.h"/>
+    <ClInclude Include="..\..\src\common\platform.h"/>
     <ClInclude Include="..\..\src\common\utilities.h"/>
     <ClInclude Include="..\..\src\common\angleutils.h"/>
     <ClInclude Include="..\..\src\compiler\translator\BaseTypes.h"/>
@@ -135,13 +230,14 @@
     <ClInclude Include="..\..\src\compiler\translator\FlagStd140Structs.h"/>
     <ClInclude Include="..\..\src\compiler\translator\length_limits.h"/>
     <ClInclude Include="..\..\src\compiler\translator\PoolAlloc.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\OutputHLSL.h"/>
     <ClInclude Include="..\..\src\compiler\translator\BuiltInFunctionEmulator.h"/>
     <ClInclude Include="..\..\src\compiler\translator\DetectDiscontinuity.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\RenameFunction.h"/>
     <ClInclude Include="..\..\src\compiler\translator\UnfoldShortCircuit.h"/>
     <ClInclude Include="..\..\src\compiler\translator\TranslatorGLSL.h"/>
     <ClInclude Include="..\..\src\compiler\translator\SymbolTable.h"/>
     <ClInclude Include="..\..\src\compiler\translator\InitializeGlobals.h"/>
-    <ClInclude Include="..\..\src\compiler\translator\osinclude.h"/>
     <ClInclude Include="..\..\src\compiler\translator\Initialize.h"/>
     <ClInclude Include="..\..\src\compiler\translator\QualifierAlive.h"/>
     <ClInclude Include="..\..\src\compiler\translator\ConstantUnion.h"/>
@@ -153,30 +249,34 @@
     <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\ShHandle.h"/>
     <ClInclude Include="..\..\src\compiler\translator\OutputGLSLBase.h"/>
     <ClInclude Include="..\..\src\compiler\translator\ForLoopUnroll.h"/>
     <ClInclude Include="..\..\src\compiler\translator\Pragma.h"/>
-    <ClInclude Include="..\..\src\compiler\translator\intermediate.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\Compiler.h"/>
     <ClInclude Include="..\..\src\compiler\translator\TranslatorHLSL.h"/>
     <ClInclude Include="..\..\src\compiler\translator\OutputESSL.h"/>
-    <ClInclude Include="..\..\src\compiler\translator\RenameFunction.h"/>
+    <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"/>
-    <ClInclude Include="..\..\src\compiler\translator\OutputHLSL.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\UtilsHLSL.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\ScalarizeVecAndMatConstructorArgs.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\intermediate.h"/>
     <ClInclude Include="..\..\src\compiler\translator\InitializeParseContext.h"/>
     <ClInclude Include="..\..\src\compiler\translator\VariableInfo.h"/>
     <ClInclude Include="..\..\src\compiler\translator\LoopInfo.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\UniformHLSL.h"/>
+    <ClInclude Include="..\..\src\compiler\translator\RegenerateStructNames.h"/>
     <ClInclude Include="..\..\src\compiler\translator\glslang_tab.h"/>
     <ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h"/>
     <ClInclude Include="..\..\src\compiler\translator\ExtensionBehavior.h"/>
@@ -185,8 +285,10 @@
     <ClInclude Include="..\..\src\compiler\translator\depgraph\DependencyGraph.h"/>
     <ClInclude Include="..\..\src\compiler\translator\depgraph\DependencyGraphOutput.h"/>
     <ClInclude Include="..\..\src\compiler\translator\depgraph\DependencyGraphBuilder.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\gl2platform.h"/>
     <ClInclude Include="..\..\include\GLES2\gl2ext.h"/>
     <ClInclude Include="..\..\include\GLES2\gl2.h"/>
@@ -200,6 +302,7 @@
   <ItemGroup>
     <ClCompile Include="..\..\src\third_party\compiler\ArrayBoundsClamper.cpp"/>
     <ClCompile Include="..\..\src\common\event_tracer.cpp"/>
+    <ClCompile Include="..\..\src\common\tls.cpp"/>
     <ClCompile Include="..\..\src\common\utilities.cpp"/>
     <ClCompile Include="..\..\src\common\RefCountObject.cpp"/>
     <ClCompile Include="..\..\src\common\mathutil.cpp"/>
@@ -219,14 +322,15 @@
     <ClCompile Include="..\..\src\compiler\translator\InitializeVariables.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\InitializeDll.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\PoolAlloc.cpp"/>
-    <ClCompile Include="..\..\src\compiler\translator\ossource_win.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\RewriteElseBlocks.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\Diagnostics.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\QualifierAlive.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\util.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\ValidateOutputs.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\TranslatorESSL.cpp"/>
+    <ClCompile Include="..\..\src\compiler\translator\RegenerateStructNames.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\VariablePacker.cpp"/>
+    <ClCompile Include="..\..\src\compiler\translator\ScalarizeVecAndMatConstructorArgs.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\DirectiveHandler.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\parseConst.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\VersionGLSL.cpp"/>
@@ -235,25 +339,26 @@
     <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"/>
     <ClCompile Include="..\..\src\compiler\translator\SearchSymbol.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\UnfoldShortCircuitAST.cpp"/>
+    <ClCompile Include="..\..\src\compiler\translator\UtilsHLSL.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\TranslatorGLSL.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\SymbolTable.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\FlagStd140Structs.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\LoopInfo.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\OutputHLSL.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\DetectDiscontinuity.cpp"/>
+    <ClCompile Include="..\..\src\compiler\translator\StructureHLSL.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\UnfoldShortCircuit.cpp"/>
+    <ClCompile Include="..\..\src\compiler\translator\UniformHLSL.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\compilerdebug.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\VariableInfo.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\Compiler.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\Initialize.cpp"/>
-    <ClCompile Include="..\..\src\compiler\translator\ossource_posix.cpp">
-      <ExcludedFromBuild>true</ExcludedFromBuild>
-    </ClCompile>
     <ClCompile Include="..\..\src\compiler\translator\timing\RestrictVertexShaderTiming.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\timing\RestrictFragmentShaderTiming.cpp"/>
     <ClCompile Include="..\..\src\compiler\translator\depgraph\DependencyGraphTraverse.cpp"/>
diff --git a/projects/src/translator_lib.vcxproj.filters b/projects/src/translator_lib.vcxproj.filters
index cbaa024..0a85957 100644
--- a/projects/src/translator_lib.vcxproj.filters
+++ b/projects/src/translator_lib.vcxproj.filters
@@ -19,9 +19,6 @@
     <Filter Include="src\compiler\translator">
       <UniqueIdentifier>{502101C2-1680-5126-1D2E-39419A1AE009}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\compiler\translator\_excluded_files">
-      <UniqueIdentifier>{158E591E-B6EA-0C85-8F5A-18EAFA09B4CE}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\compiler\translator\timing">
       <UniqueIdentifier>{E1BE6BE7-5019-57F8-5C7D-26FC8CE74904}</UniqueIdentifier>
     </Filter>
@@ -57,10 +54,10 @@
     <ClInclude Include="..\..\src\third_party\compiler\ArrayBoundsClamper.h">
       <Filter>src\third_party\compiler</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\common\shadervars.h">
+    <ClInclude Include="..\..\src\common\RefCountObject.h">
       <Filter>src\common</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\common\RefCountObject.h">
+    <ClInclude Include="..\..\src\common\tls.h">
       <Filter>src\common</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\common\mathutil.h">
@@ -72,6 +69,9 @@
     <ClCompile Include="..\..\src\common\event_tracer.cpp">
       <Filter>src\common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\common\tls.cpp">
+      <Filter>src\common</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\common\utilities.cpp">
       <Filter>src\common</Filter>
     </ClCompile>
@@ -93,6 +93,9 @@
     <ClInclude Include="..\..\src\common\blocklayout.h">
       <Filter>src\common</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\common\platform.h">
+      <Filter>src\common</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\common\utilities.h">
       <Filter>src\common</Filter>
     </ClInclude>
@@ -153,6 +156,9 @@
     <ClInclude Include="..\..\src\compiler\translator\PoolAlloc.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\compiler\translator\OutputHLSL.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\compiler\translator\BuiltInFunctionEmulator.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
@@ -162,6 +168,9 @@
     <ClCompile Include="..\..\src\compiler\translator\ParseContext.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
+    <ClInclude Include="..\..\src\compiler\translator\RenameFunction.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
     <ClCompile Include="..\..\src\compiler\translator\Types.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
@@ -189,15 +198,9 @@
     <ClInclude Include="..\..\src\compiler\translator\InitializeGlobals.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\compiler\translator\osinclude.h">
-      <Filter>src\compiler\translator</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\compiler\translator\Initialize.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
-    <ClCompile Include="..\..\src\compiler\translator\ossource_win.cpp">
-      <Filter>src\compiler\translator</Filter>
-    </ClCompile>
     <ClInclude Include="..\..\src\compiler\translator\QualifierAlive.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
@@ -246,18 +249,21 @@
     <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\Intermediate.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\compiler\translator\InitializeVariables.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\compiler\translator\localintermediate.h">
+    <ClCompile Include="..\..\src\compiler\translator\RegenerateStructNames.cpp">
       <Filter>src\compiler\translator</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\compiler\translator\ShHandle.h">
-      <Filter>src\compiler\translator</Filter>
-    </ClInclude>
+    </ClCompile>
     <ClInclude Include="..\..\src\compiler\translator\OutputGLSLBase.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
@@ -267,12 +273,15 @@
     <ClInclude Include="..\..\src\compiler\translator\Pragma.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\compiler\translator\intermediate.h">
+    <ClInclude Include="..\..\src\compiler\translator\Compiler.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
     <ClCompile Include="..\..\src\compiler\translator\VariablePacker.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\compiler\translator\ScalarizeVecAndMatConstructorArgs.cpp">
+      <Filter>src\compiler\translator</Filter>
+    </ClCompile>
     <ClInclude Include="..\..\src\compiler\translator\TranslatorHLSL.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
@@ -285,7 +294,7 @@
     <ClCompile Include="..\..\src\compiler\translator\parseConst.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
-    <ClInclude Include="..\..\src\compiler\translator\RenameFunction.h">
+    <ClInclude Include="..\..\src\compiler\translator\StructureHLSL.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\compiler\translator\ValidateLimitations.h">
@@ -294,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">
@@ -309,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">
@@ -336,9 +345,15 @@
     <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>
+    <ClInclude Include="..\..\src\compiler\translator\UtilsHLSL.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
     <ClCompile Include="..\..\src\compiler\translator\intermOut.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
@@ -354,15 +369,21 @@
     <ClCompile Include="..\..\src\compiler\translator\UnfoldShortCircuitAST.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
-    <ClInclude Include="..\..\src\compiler\translator\OutputHLSL.h">
+    <ClCompile Include="..\..\src\compiler\translator\UtilsHLSL.cpp">
       <Filter>src\compiler\translator</Filter>
-    </ClInclude>
+    </ClCompile>
     <ClCompile Include="..\..\src\compiler\translator\TranslatorGLSL.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\compiler\translator\SymbolTable.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
+    <ClInclude Include="..\..\src\compiler\translator\ScalarizeVecAndMatConstructorArgs.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\compiler\translator\intermediate.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\compiler\translator\InitializeParseContext.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
@@ -381,9 +402,18 @@
     <ClInclude Include="..\..\src\compiler\translator\LoopInfo.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\compiler\translator\UniformHLSL.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\compiler\translator\RegenerateStructNames.h">
+      <Filter>src\compiler\translator</Filter>
+    </ClInclude>
     <ClCompile Include="..\..\src\compiler\translator\DetectDiscontinuity.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\compiler\translator\StructureHLSL.cpp">
+      <Filter>src\compiler\translator</Filter>
+    </ClCompile>
     <ClInclude Include="..\..\src\compiler\translator\glslang_tab.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
@@ -393,6 +423,9 @@
     <ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h">
       <Filter>src\compiler\translator</Filter>
     </ClInclude>
+    <ClCompile Include="..\..\src\compiler\translator\UniformHLSL.cpp">
+      <Filter>src\compiler\translator</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\compiler\translator\compilerdebug.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
@@ -408,9 +441,6 @@
     <ClCompile Include="..\..\src\compiler\translator\Initialize.cpp">
       <Filter>src\compiler\translator</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\compiler\translator\ossource_posix.cpp">
-      <Filter>src\compiler\translator\_excluded_files</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\compiler\translator\timing\RestrictVertexShaderTiming.cpp">
       <Filter>src\compiler\translator\timing</Filter>
     </ClCompile>
@@ -444,12 +474,18 @@
     <ClCompile Include="..\..\src\compiler\translator\depgraph\DependencyGraphBuilder.cpp">
       <Filter>src\compiler\translator\depgraph</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\gl2platform.h">
       <Filter>include\GLES2</Filter>
     </ClInclude>
diff --git a/projects/src/translator_static.vcxproj b/projects/src/translator_static.vcxproj
index 6c943aa..c723225 100644
--- a/projects/src/translator_static.vcxproj
+++ b/projects/src/translator_static.vcxproj
@@ -1,14 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<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>{19386E01-D811-FA3B-9F1E-122BB0C0E9F5}</ProjectGuid>
@@ -20,6 +28,9 @@
     <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">
@@ -31,7 +42,9 @@
     <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>
@@ -42,11 +55,12 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };ANGLE_TRANSLATOR_STATIC;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -55,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>
@@ -69,7 +84,45 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\src;..\..\include;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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };ANGLE_TRANSLATOR_STATIC;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;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;ANGLE_TRANSLATOR_STATIC;%(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;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>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -78,11 +131,12 @@
       <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
       <BufferSecurityCheck>true</BufferSecurityCheck>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4239;4244;4245;4512;4702;4530;4718;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <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;_HAS_EXCEPTIONS=0;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };ANGLE_TRANSLATOR_STATIC;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;NOMINMAX;ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <TreatWarningAsError>true</TreatWarningAsError>
@@ -91,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>
@@ -105,7 +160,44 @@
     <ResourceCompile>
       <AdditionalIncludeDirectories>..\..\src;..\..\include;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>ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT(&quot;d3dcompiler_46.dll&quot;), TEXT(&quot;d3dcompiler_43.dll&quot;) };ANGLE_TRANSLATOR_STATIC;NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>ANGLE_TRANSLATOR_STATIC;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\src;..\..\include;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;ANGLE_TRANSLATOR_STATIC;%(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;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>ANGLE_TRANSLATOR_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
@@ -113,6 +205,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\compiler\translator\ShaderLang.cpp"/>
+    <ClCompile Include="..\..\src\compiler\translator\ShaderVars.cpp"/>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
   <ImportGroup Label="ExtensionTargets"/>
diff --git a/projects/src/translator_static.vcxproj.filters b/projects/src/translator_static.vcxproj.filters
index 8b76279..acac9ba 100644
--- a/projects/src/translator_static.vcxproj.filters
+++ b/projects/src/translator_static.vcxproj.filters
@@ -13,5 +13,8 @@
     <ClCompile Include="..\..\src\compiler\translator\ShaderLang.cpp">
       <Filter>compiler\translator</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\compiler\translator\ShaderVars.cpp">
+      <Filter>compiler\translator</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
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/post_sub_buffer/PostSubBuffer.cpp b/samples/angle/post_sub_buffer/PostSubBuffer.cpp
index 044437a..e5cd10f 100644
--- a/samples/angle/post_sub_buffer/PostSubBuffer.cpp
+++ b/samples/angle/post_sub_buffer/PostSubBuffer.cpp
@@ -143,7 +143,7 @@
         // Instead of letting the application call eglSwapBuffers, call eglPostSubBufferNV here instead
         size_t windowWidth = getWindow()->getWidth();
         size_t windowHeight = getWindow()->getHeight();
-        EGLDisplay display = getWindow()->getDisplay();
+        EGLDisplay display = getDisplay();
         EGLSurface surface = getSurface();
         mPostSubBufferNV(display, surface, 60, 60, windowWidth - 120, windowHeight - 120);
     }
diff --git a/samples/angle/sample_util/SampleApplication.cpp b/samples/angle/sample_util/SampleApplication.cpp
index 518ffdb..e0228fb 100644
--- a/samples/angle/sample_util/SampleApplication.cpp
+++ b/samples/angle/sample_util/SampleApplication.cpp
@@ -5,29 +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, RendererType requestedRenderer)
-    : mSurface(EGL_NO_SURFACE),
-      mContext(EGL_NO_CONTEXT),
-      mClientVersion(glesMajorVersion),
-      mRequestedRenderer(requestedRenderer),
-      mWidth(width),
-      mHeight(height),
-      mName(name),
-      mRunning(false),
-#ifdef _WIN32
-      mTimer(new Win32Timer()),
-      mWindow(new Win32Window())
-#endif
+                                     EGLint glesMajorVersion, EGLint requestedRenderer)
+    : 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()
@@ -53,37 +50,42 @@
 
 void SampleApplication::swap()
 {
-    eglSwapBuffers(mWindow->getDisplay(), 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 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, mRequestedRenderer))
+    if (!mOSWindow->initialize(mName, mEGLWindow->getWidth(), mEGLWindow->getHeight()))
     {
         return -1;
     }
 
-    if (!initializeGL())
+    if (!mEGLWindow->initializeGL(mOSWindow.get()))
     {
         return -1;
     }
@@ -126,14 +128,14 @@
         draw();
         swap();
 
-        mWindow->messageLoop();
+        mOSWindow->messageLoop();
 
         prevTime = elapsedTime;
     }
 
     destroy();
-    destroyGL();
-    mWindow->destroy();
+    mEGLWindow->destroyGL();
+    mOSWindow->destroy();
 
     return result;
 }
@@ -145,79 +147,5 @@
 
 bool SampleApplication::popEvent(Event *event)
 {
-    return mWindow->popEvent(event);
-}
-
-bool SampleApplication::initializeGL()
-{
-    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(mWindow->getDisplay(), 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(mWindow->getDisplay(), mConfig, mWindow->getNativeWindow(), surfaceAttributes);
-    if (mSurface == EGL_NO_SURFACE)
-    {
-        eglGetError(); // Clear error and try again
-        mSurface = eglCreateWindowSurface(mWindow->getDisplay(), mConfig, NULL, NULL);
-    }
-
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyGL();
-        return false;
-    }
-
-    EGLint contextAttibutes[] =
-    {
-        EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
-        EGL_NONE
-    };
-    mContext = eglCreateContext(mWindow->getDisplay(), mConfig, NULL, contextAttibutes);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyGL();
-        return false;
-    }
-
-    eglMakeCurrent(mWindow->getDisplay(), mSurface, mSurface, mContext);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroyGL();
-        return false;
-    }
-
-    // Turn off vsync
-    eglSwapInterval(mWindow->getDisplay(), 0);
-
-    return true;
-}
-
-void SampleApplication::destroyGL()
-{
-    eglDestroySurface(mWindow->getDisplay(), mSurface);
-    mSurface = 0;
-
-    eglDestroyContext(mWindow->getDisplay(), mContext);
-    mContext = 0;
+    return mOSWindow->popEvent(event);
 }
diff --git a/samples/angle/sample_util/SampleApplication.h b/samples/angle/sample_util/SampleApplication.h
index b344540..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,11 +18,13 @@
 #include <cstdint>
 #include <memory>
 
+class EGLWindow;
+
 class SampleApplication
 {
   public:
     SampleApplication(const std::string& name, size_t width, size_t height,
-                      EGLint glesMajorVersion = 2, RendererType requestedRenderer = RENDERER_D3D11);
+                      EGLint glesMajorVersion = 2, EGLint requestedRenderer = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
     virtual ~SampleApplication();
 
     virtual bool initialize();
@@ -39,8 +35,9 @@
 
     virtual void swap();
 
-    Window *getWindow() const;
+    OSWindow *getWindow() const;
     EGLConfig getConfig() const;
+    EGLDisplay getDisplay() const;
     EGLSurface getSurface() const;
     EGLContext getContext() const;
 
@@ -50,23 +47,12 @@
     void exit();
 
   private:
-    bool initializeGL();
-    void destroyGL();
-
-    EGLConfig mConfig;
-    EGLSurface mSurface;
-    EGLContext mContext;
-
-    GLuint mClientVersion;
-    RendererType 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/samples/translator/translator.cpp b/samples/translator/translator.cpp
index 8d0696c..79d311e 100644
--- a/samples/translator/translator.cpp
+++ b/samples/translator/translator.cpp
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <vector>
+#include "angle_gl.h"
 
 //
 // Return codes from main.
@@ -24,7 +25,7 @@
 };
 
 static void usage();
-static ShShaderType FindShaderType(const char* fileName);
+static sh::GLenum FindShaderType(const char* fileName);
 static bool CompileFile(char* fileName, ShHandle compiler, int compileOptions);
 static void LogMsg(const char* msg, const char* name, const int num, const char* logName);
 static void PrintActiveVariables(ShHandle compiler, ShShaderInfo varType);
@@ -137,16 +138,16 @@
         } else {
             ShHandle compiler = 0;
             switch (FindShaderType(argv[0])) {
-            case SH_VERTEX_SHADER:
+            case GL_VERTEX_SHADER:
                 if (vertexCompiler == 0)
                     vertexCompiler = ShConstructCompiler(
-                        SH_VERTEX_SHADER, spec, output, &resources);
+                        GL_VERTEX_SHADER, spec, output, &resources);
                 compiler = vertexCompiler;
                 break;
-            case SH_FRAGMENT_SHADER:
+            case GL_FRAGMENT_SHADER:
                 if (fragmentCompiler == 0)
                     fragmentCompiler = ShConstructCompiler(
-                        SH_FRAGMENT_SHADER, spec, output, &resources);
+                        GL_FRAGMENT_SHADER, spec, output, &resources);
                 compiler = fragmentCompiler;
                 break;
             default: break;
@@ -242,7 +243,7 @@
 //   .frag*    = fragment shader
 //   .vert*    = vertex shader
 //
-ShShaderType FindShaderType(const char* fileName)
+sh::GLenum FindShaderType(const char* fileName)
 {
     assert(fileName);
 
@@ -253,11 +254,11 @@
 
     ext = strrchr(fileName, '.');
     if (ext) {
-        if (strncmp(ext, ".frag", 4) == 0) return SH_FRAGMENT_SHADER;
-        if (strncmp(ext, ".vert", 4) == 0) return SH_VERTEX_SHADER;
+        if (strncmp(ext, ".frag", 4) == 0) return GL_FRAGMENT_SHADER;
+        if (strncmp(ext, ".vert", 4) == 0) return GL_VERTEX_SHADER;
     }
 
-    return SH_FRAGMENT_SHADER;
+    return GL_FRAGMENT_SHADER;
 }
 
 //
@@ -297,7 +298,7 @@
 
     size_t activeVars = 0;
     int size = 0;
-    ShDataType type = SH_NONE;
+    sh::GLenum type = GL_NONE;
     ShPrecisionType precision = SH_PRECISION_UNDEFINED;
     int staticUse = 0;
     const char* typeName = NULL;
@@ -313,34 +314,34 @@
             default: assert(0);
         }
         switch (type) {
-            case SH_FLOAT: typeName = "GL_FLOAT"; break;
-            case SH_FLOAT_VEC2: typeName = "GL_FLOAT_VEC2"; break;
-            case SH_FLOAT_VEC3: typeName = "GL_FLOAT_VEC3"; break;
-            case SH_FLOAT_VEC4: typeName = "GL_FLOAT_VEC4"; break;
-            case SH_INT: typeName = "GL_INT"; break;
-            case SH_INT_VEC2: typeName = "GL_INT_VEC2"; break;
-            case SH_INT_VEC3: typeName = "GL_INT_VEC3"; break;
-            case SH_INT_VEC4: typeName = "GL_INT_VEC4"; break;
-            case SH_UNSIGNED_INT: typeName = "GL_UNSIGNED_INT"; break;
-            case SH_UNSIGNED_INT_VEC2: typeName = "GL_UNSIGNED_INT_VEC2"; break;
-            case SH_UNSIGNED_INT_VEC3: typeName = "GL_UNSIGNED_INT_VEC3"; break;
-            case SH_UNSIGNED_INT_VEC4: typeName = "GL_UNSIGNED_INT_VEC4"; break;
-            case SH_BOOL: typeName = "GL_BOOL"; break;
-            case SH_BOOL_VEC2: typeName = "GL_BOOL_VEC2"; break;
-            case SH_BOOL_VEC3: typeName = "GL_BOOL_VEC3"; break;
-            case SH_BOOL_VEC4: typeName = "GL_BOOL_VEC4"; break;
-            case SH_FLOAT_MAT2: typeName = "GL_FLOAT_MAT2"; break;
-            case SH_FLOAT_MAT3: typeName = "GL_FLOAT_MAT3"; break;
-            case SH_FLOAT_MAT4: typeName = "GL_FLOAT_MAT4"; break;
-            case SH_FLOAT_MAT2x3: typeName = "GL_FLOAT_MAT2x3"; break;
-            case SH_FLOAT_MAT3x2: typeName = "GL_FLOAT_MAT3x2"; break;
-            case SH_FLOAT_MAT4x2: typeName = "GL_FLOAT_MAT4x2"; break;
-            case SH_FLOAT_MAT2x4: typeName = "GL_FLOAT_MAT2x4"; break;
-            case SH_FLOAT_MAT3x4: typeName = "GL_FLOAT_MAT3x4"; break;
-            case SH_FLOAT_MAT4x3: typeName = "GL_FLOAT_MAT4x3"; break;
-            case SH_SAMPLER_2D: typeName = "GL_SAMPLER_2D"; break;
-            case SH_SAMPLER_CUBE: typeName = "GL_SAMPLER_CUBE"; break;
-            case SH_SAMPLER_EXTERNAL_OES: typeName = "GL_SAMPLER_EXTERNAL_OES"; break;
+            case GL_FLOAT: typeName = "GL_FLOAT"; break;
+            case GL_FLOAT_VEC2: typeName = "GL_FLOAT_VEC2"; break;
+            case GL_FLOAT_VEC3: typeName = "GL_FLOAT_VEC3"; break;
+            case GL_FLOAT_VEC4: typeName = "GL_FLOAT_VEC4"; break;
+            case GL_INT: typeName = "GL_INT"; break;
+            case GL_INT_VEC2: typeName = "GL_INT_VEC2"; break;
+            case GL_INT_VEC3: typeName = "GL_INT_VEC3"; break;
+            case GL_INT_VEC4: typeName = "GL_INT_VEC4"; break;
+            case GL_UNSIGNED_INT: typeName = "GL_UNSIGNED_INT"; break;
+            case GL_UNSIGNED_INT_VEC2: typeName = "GL_UNSIGNED_INT_VEC2"; break;
+            case GL_UNSIGNED_INT_VEC3: typeName = "GL_UNSIGNED_INT_VEC3"; break;
+            case GL_UNSIGNED_INT_VEC4: typeName = "GL_UNSIGNED_INT_VEC4"; break;
+            case GL_BOOL: typeName = "GL_BOOL"; break;
+            case GL_BOOL_VEC2: typeName = "GL_BOOL_VEC2"; break;
+            case GL_BOOL_VEC3: typeName = "GL_BOOL_VEC3"; break;
+            case GL_BOOL_VEC4: typeName = "GL_BOOL_VEC4"; break;
+            case GL_FLOAT_MAT2: typeName = "GL_FLOAT_MAT2"; break;
+            case GL_FLOAT_MAT3: typeName = "GL_FLOAT_MAT3"; break;
+            case GL_FLOAT_MAT4: typeName = "GL_FLOAT_MAT4"; break;
+            case GL_FLOAT_MAT2x3: typeName = "GL_FLOAT_MAT2x3"; break;
+            case GL_FLOAT_MAT3x2: typeName = "GL_FLOAT_MAT3x2"; break;
+            case GL_FLOAT_MAT4x2: typeName = "GL_FLOAT_MAT4x2"; break;
+            case GL_FLOAT_MAT2x4: typeName = "GL_FLOAT_MAT2x4"; break;
+            case GL_FLOAT_MAT3x4: typeName = "GL_FLOAT_MAT3x4"; break;
+            case GL_FLOAT_MAT4x3: typeName = "GL_FLOAT_MAT4x3"; break;
+            case GL_SAMPLER_2D: typeName = "GL_SAMPLER_2D"; break;
+            case GL_SAMPLER_CUBE: typeName = "GL_SAMPLER_CUBE"; break;
+            case GL_SAMPLER_EXTERNAL_OES: typeName = "GL_SAMPLER_EXTERNAL_OES"; break;
             default: assert(0);
         }
         printf("%lu: name:%s type:%s size:%d\n", i, name, typeName, size);
diff --git a/src/angle.gypi b/src/angle.gypi
index ef16749..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':
                         [
@@ -110,7 +113,7 @@
                             'message': 'Copying D3D Compiler DLL...',
                             'msvs_cygwin_shell': 0,
                             'inputs': [ 'copy_compiler_dll.bat' ],
-                            'outputs': [ '<(PRODUCT_DIR)/D3DCompiler_46.dll' ],
+                            'outputs': [ '<(PRODUCT_DIR)/d3dcompiler_46.dll' ],
                             'action':
                             [
                                 "<(angle_gen_path)/copy_compiler_dll.bat",
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-mips64.mk b/src/commit_id.target.darwin-mips64.mk
new file mode 100644
index 0000000..20a9059
--- /dev/null
+++ b/src/commit_id.target.darwin-mips64.mk
@@ -0,0 +1,55 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := third_party_angle_src_commit_id_gyp
+LOCAL_MODULE_STEM := commit_id
+LOCAL_MODULE_SUFFIX := .stamp
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp
+
+### Rules for action "Generate ANGLE Commit ID Header":
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: $(gyp_shared_intermediate_dir)/angle/commit_id.py $(LOCAL_PATH)/third_party/angle/.git/index $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: Generating ANGLE Commit ID ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/angle/src; mkdir -p $(gyp_shared_intermediate_dir)/angle/id; python "$(gyp_shared_intermediate_dir)/angle/commit_id.py" gen ../../../third_party/angle "$(gyp_shared_intermediate_dir)/angle/id/commit.h"
+
+
+
+GYP_GENERATED_OUTPUTS := \
+	$(gyp_shared_intermediate_dir)/angle/id/commit.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_commit_id_gyp
+
+# Alias gyp target name.
+.PHONY: commit_id
+commit_id: third_party_angle_src_commit_id_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+	$(hide) echo "Gyp timestamp: $@"
+	$(hide) mkdir -p $(dir $@)
+	$(hide) touch $@
+
+LOCAL_2ND_ARCH_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-mips64.mk b/src/commit_id.target.linux-mips64.mk
new file mode 100644
index 0000000..20a9059
--- /dev/null
+++ b/src/commit_id.target.linux-mips64.mk
@@ -0,0 +1,55 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := third_party_angle_src_commit_id_gyp
+LOCAL_MODULE_STEM := commit_id
+LOCAL_MODULE_SUFFIX := .stamp
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp
+
+### Rules for action "Generate ANGLE Commit ID Header":
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/angle/id/commit.h: $(gyp_shared_intermediate_dir)/angle/commit_id.py $(LOCAL_PATH)/third_party/angle/.git/index $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: Generating ANGLE Commit ID ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/angle/src; mkdir -p $(gyp_shared_intermediate_dir)/angle/id; python "$(gyp_shared_intermediate_dir)/angle/commit_id.py" gen ../../../third_party/angle "$(gyp_shared_intermediate_dir)/angle/id/commit.h"
+
+
+
+GYP_GENERATED_OUTPUTS := \
+	$(gyp_shared_intermediate_dir)/angle/id/commit.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_commit_id_gyp
+
+# Alias gyp target name.
+.PHONY: commit_id
+commit_id: third_party_angle_src_commit_id_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+	$(hide) echo "Gyp timestamp: $@"
+	$(hide) mkdir -p $(dir $@)
+	$(hide) touch $@
+
+LOCAL_2ND_ARCH_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 88b6393..6eeaee1 100644
--- a/src/common/RefCountObject.h
+++ b/src/common/RefCountObject.h
@@ -12,13 +12,12 @@
 #ifndef COMMON_REFCOUNTOBJECT_H_
 #define COMMON_REFCOUNTOBJECT_H_
 
-#include <cstddef>
-
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-
 #include "common/debug.h"
 
+#include "angle_gl.h"
+
+#include <cstddef>
+
 class RefCountObject
 {
   public:
@@ -63,33 +62,6 @@
 };
 
 template <class ObjectType>
-class FramebufferTextureBindingPointer : public RefCountObjectBindingPointer
-{
-public:
-    FramebufferTextureBindingPointer() : mType(GL_NONE), mMipLevel(0), mLayer(0) { }
-
-    void set(ObjectType *newObject, GLenum type, GLint mipLevel, GLint layer)
-    {
-        RefCountObjectBindingPointer::set(newObject);
-        mType = type;
-        mMipLevel = mipLevel;
-        mLayer = layer;
-    }
-
-    ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
-    ObjectType *operator->() const { return get(); }
-
-    GLenum type() const { return mType; }
-    GLint mipLevel() const { return mMipLevel; }
-    GLint layer() const { return mLayer; }
-
-private:
-    GLenum mType;
-    GLint mMipLevel;
-    GLint mLayer;
-};
-
-template <class ObjectType>
 class OffsetBindingPointer : public RefCountObjectBindingPointer
 {
   public:
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 9c182a8..50a4132 100644
--- a/src/common/angleutils.h
+++ b/src/common/angleutils.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -9,7 +9,14 @@
 #ifndef COMMON_ANGLEUTILS_H_
 #define COMMON_ANGLEUTILS_H_
 
+#include "common/platform.h"
+
 #include <stddef.h>
+#include <limits.h>
+#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
@@ -17,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;
 }
@@ -50,6 +57,16 @@
 }
 
 template <typename T>
+void SafeDeleteContainer(T& resource)
+{
+    for (typename T::iterator i = resource.begin(); i != resource.end(); i++)
+    {
+        SafeDelete(*i);
+    }
+    resource.clear();
+}
+
+template <typename T>
 void SafeDeleteArray(T*& resource)
 {
     delete[] resource;
@@ -78,6 +95,46 @@
     memset(obj, 0, sizeof(T));
 }
 
+inline const char* MakeStaticString(const std::string &str)
+{
+    static std::set<std::string> strings;
+    std::set<std::string>::iterator it = strings.find(str);
+    if (it != strings.end())
+    {
+        return it->c_str();
+    }
+
+    return strings.insert(str).first->c_str();
+}
+
+inline std::string ArrayString(unsigned int i)
+{
+    // We assume UINT_MAX and GL_INVALID_INDEX are equal
+    // See DynamicHLSL.cpp
+    if (i == UINT_MAX)
+    {
+        return "";
+    }
+
+    std::stringstream strstr;
+
+    strstr << "[";
+    strstr << i;
+    strstr << "]";
+
+    return strstr.str();
+}
+
+inline std::string Str(int i)
+{
+    std::stringstream strstr;
+    strstr << i;
+    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 a0c9289..e3b2d43 100644
--- a/src/common/blocklayout.cpp
+++ b/src/common/blocklayout.cpp
@@ -8,62 +8,18 @@
 //
 
 #include "common/blocklayout.h"
-#include "common/shadervars.h"
 #include "common/mathutil.h"
 #include "common/utilities.h"
 
-namespace gl
+namespace sh
 {
 
-BlockLayoutEncoder::BlockLayoutEncoder(std::vector<BlockMemberInfo> *blockInfoOut)
-    : mCurrentOffset(0),
-      mBlockInfoOut(blockInfoOut)
+BlockLayoutEncoder::BlockLayoutEncoder()
+    : mCurrentOffset(0)
 {
 }
 
-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);
-        }
-    }
-}
-
-void 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);
-
-    if (mBlockInfoOut)
-    {
-        mBlockInfoOut->push_back(memberInfo);
-    }
-
-    advanceOffset(field.type, field.arraySize, field.isRowMajorMatrix, arrayStride, matrixStride);
-}
-
-void BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
+BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
 {
     int arrayStride;
     int matrixStride;
@@ -72,12 +28,9 @@
 
     const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix);
 
-    if (mBlockInfoOut)
-    {
-        mBlockInfoOut->push_back(memberInfo);
-    }
-
     advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
+
+    return memberInfo;
 }
 
 void BlockLayoutEncoder::nextRegister()
@@ -85,8 +38,7 @@
     mCurrentOffset = rx::roundUp<size_t>(mCurrentOffset, ComponentsPerRegister);
 }
 
-Std140BlockEncoder::Std140BlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut)
-    : BlockLayoutEncoder(blockInfoOut)
+Std140BlockEncoder::Std140BlockEncoder()
 {
 }
 
@@ -103,7 +55,7 @@
 void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
 {
     // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
-    ASSERT(gl::UniformComponentSize(gl::UniformComponentType(type)) == BytesPerComponent);
+    ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
 
     size_t baseAlignment = 0;
     int matrixStride = 0;
@@ -127,7 +79,7 @@
     }
     else
     {
-        const int numComponents = gl::UniformComponentCount(type);
+        const int numComponents = gl::VariableComponentCount(type);
         baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
     }
 
@@ -151,13 +103,12 @@
     }
     else
     {
-        mCurrentOffset += gl::UniformComponentCount(type);
+        mCurrentOffset += gl::VariableComponentCount(type);
     }
 }
 
-HLSLBlockEncoder::HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut, HLSLBlockEncoderStrategy strategy)
-    : BlockLayoutEncoder(blockInfoOut),
-      mEncoderStrategy(strategy)
+HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy)
+    : mEncoderStrategy(strategy)
 {
 }
 
@@ -173,7 +124,7 @@
 void HLSLBlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
 {
     // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
-    ASSERT(gl::UniformComponentSize(gl::UniformComponentType(type)) == BytesPerComponent);
+    ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
 
     int matrixStride = 0;
     int arrayStride = 0;
@@ -204,7 +155,7 @@
     }
     else if (isPacked())
     {
-        int numComponents = gl::UniformComponentCount(type);
+        int numComponents = gl::VariableComponentCount(type);
         if ((numComponents + (mCurrentOffset % ComponentsPerRegister)) > ComponentsPerRegister)
         {
             nextRegister();
@@ -232,7 +183,7 @@
     }
     else if (isPacked())
     {
-        mCurrentOffset += gl::UniformComponentCount(type);
+        mCurrentOffset += gl::VariableComponentCount(type);
     }
     else
     {
@@ -245,50 +196,14 @@
     mCurrentOffset += (numRegisters * ComponentsPerRegister);
 }
 
-void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, gl::Uniform *variable, HLSLBlockEncoder *encoder,
-                                 const std::vector<gl::BlockMemberInfo> &blockInfo, ShShaderOutput outputType)
+HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(ShShaderOutput outputType)
 {
-    // because this method computes offsets (element indexes) instead of any total sizes,
-    // we can ignore the array size of the variable
-
-    if (variable->isStruct())
+    switch (outputType)
     {
-        encoder->enterAggregateType();
-
-        variable->registerIndex = baseRegisterIndex;
-
-        for (size_t fieldIndex = 0; fieldIndex < variable->fields.size(); fieldIndex++)
-        {
-            HLSLVariableGetRegisterInfo(baseRegisterIndex, &variable->fields[fieldIndex], encoder, blockInfo, outputType);
-        }
-
-        // Since the above loop only encodes one element of an array, ensure we don't lose track of the
-        // current register offset
-        if (variable->isArray())
-        {
-            unsigned int structRegisterCount = (HLSLVariableRegisterCount(*variable, outputType) / variable->arraySize);
-            encoder->skipRegisters(structRegisterCount * (variable->arraySize - 1));
-        }
-
-        encoder->exitAggregateType();
+      case SH_HLSL9_OUTPUT: return ENCODE_LOOSE;
+      case SH_HLSL11_OUTPUT: return ENCODE_PACKED;
+      default: UNREACHABLE(); return ENCODE_PACKED;
     }
-    else
-    {
-        encoder->encodeType(variable->type, variable->arraySize, false);
-
-        const size_t registerBytes = (encoder->BytesPerComponent * encoder->ComponentsPerRegister);
-        variable->registerIndex = baseRegisterIndex + (blockInfo.back().offset / registerBytes);
-        variable->elementIndex = (blockInfo.back().offset % registerBytes) / sizeof(float);
-    }
-}
-
-void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, gl::Uniform *variable, ShShaderOutput outputType)
-{
-    std::vector<BlockMemberInfo> blockInfo;
-    HLSLBlockEncoder encoder(&blockInfo,
-                             outputType == SH_HLSL9_OUTPUT ? HLSLBlockEncoder::ENCODE_LOOSE
-                                                           : HLSLBlockEncoder::ENCODE_PACKED);
-    HLSLVariableGetRegisterInfo(baseRegisterIndex, variable, &encoder, blockInfo, outputType);
 }
 
 template <class ShaderVarType>
@@ -317,7 +232,7 @@
 
 unsigned int HLSLVariableRegisterCount(const Varying &variable)
 {
-    HLSLBlockEncoder encoder(NULL, HLSLBlockEncoder::ENCODE_PACKED);
+    HLSLBlockEncoder encoder(HLSLBlockEncoder::ENCODE_PACKED);
     HLSLVariableRegisterCount(variable, &encoder);
 
     const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
@@ -326,10 +241,7 @@
 
 unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType)
 {
-    HLSLBlockEncoder encoder(NULL,
-                             outputType == SH_HLSL9_OUTPUT ? HLSLBlockEncoder::ENCODE_LOOSE
-                                                           : HLSLBlockEncoder::ENCODE_PACKED);
-
+    HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType));
     HLSLVariableRegisterCount(variable, &encoder);
 
     const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
diff --git a/src/common/blocklayout.h b/src/common/blocklayout.h
index e6ffff1..d46ac6e 100644
--- a/src/common/blocklayout.h
+++ b/src/common/blocklayout.h
@@ -10,30 +10,53 @@
 #ifndef COMMON_BLOCKLAYOUT_H_
 #define COMMON_BLOCKLAYOUT_H_
 
-#include <vector>
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-#include <GLSLANG/ShaderLang.h>
 #include <cstddef>
+#include <vector>
 
-namespace gl
+#include "angle_gl.h"
+#include <GLSLANG/ShaderLang.h>
+
+namespace sh
 {
-
 struct ShaderVariable;
 struct InterfaceBlockField;
-struct BlockMemberInfo;
 struct Uniform;
 struct Varying;
+struct InterfaceBlock;
+
+struct BlockMemberInfo
+{
+    BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
+        : offset(offset),
+          arrayStride(arrayStride),
+          matrixStride(matrixStride),
+          isRowMajorMatrix(isRowMajorMatrix)
+    {}
+
+    static BlockMemberInfo getDefaultBlockInfo()
+    {
+        return BlockMemberInfo(-1, -1, -1, false);
+    }
+
+    int offset;
+    int arrayStride;
+    int matrixStride;
+    bool isRowMajorMatrix;
+};
 
 class BlockLayoutEncoder
 {
   public:
-    BlockLayoutEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
+    BlockLayoutEncoder();
 
-    void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
-    void 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; }
+    size_t getCurrentElement() const { return mCurrentOffset % ComponentsPerRegister; }
+
+    virtual void enterAggregateType() = 0;
+    virtual void exitAggregateType() = 0;
 
     static const size_t BytesPerComponent = 4u;
     static const unsigned int ComponentsPerRegister = 4u;
@@ -43,13 +66,8 @@
 
     void nextRegister();
 
-    virtual void enterAggregateType() = 0;
-    virtual void exitAggregateType() = 0;
     virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;
     virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;
-
-  private:
-    std::vector<BlockMemberInfo> *mBlockInfoOut;
 };
 
 // Block layout according to the std140 block layout
@@ -58,18 +76,19 @@
 class Std140BlockEncoder : public BlockLayoutEncoder
 {
   public:
-    Std140BlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
+    Std140BlockEncoder();
 
-  protected:
     virtual void enterAggregateType();
     virtual void exitAggregateType();
+
+  protected:
     virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
     virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
 };
 
 // Block layout packed according to the D3D9 or default D3D10+ register packing rules
 // See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
-// The strategy should be ENCODE_LOOSE for D3D9 constnat blocks, and ENCODE_PACKED
+// The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
 // for everything else (D3D10+ constant blocks and all attributes/varyings).
 
 class HLSLBlockEncoder : public BlockLayoutEncoder
@@ -81,8 +100,7 @@
         ENCODE_LOOSE
     };
 
-    HLSLBlockEncoder(std::vector<BlockMemberInfo> *blockInfoOut,
-                     HLSLBlockEncoderStrategy strategy);
+    HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy);
 
     virtual void enterAggregateType();
     virtual void exitAggregateType();
@@ -90,6 +108,8 @@
 
     bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
 
+    static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
+
   protected:
     virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
     virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
@@ -97,10 +117,6 @@
     HLSLBlockEncoderStrategy mEncoderStrategy;
 };
 
-// This method assigns values to the variable's "registerIndex" and "elementIndex" fields.
-// "elementIndex" is only used for structures.
-void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, Uniform *variable, ShShaderOutput outputType);
-
 // This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder
 // class to count the number of used registers in a struct (which are individually packed according to the same rules).
 unsigned int HLSLVariableRegisterCount(const Varying &variable);
diff --git a/src/common/debug.cpp b/src/common/debug.cpp
index ac0a86a..dcad327 100644
--- a/src/common/debug.cpp
+++ b/src/common/debug.cpp
@@ -7,15 +7,14 @@
 // debug.cpp: Debugging utilities.
 
 #include "common/debug.h"
+#include "common/platform.h"
+#include "common/angleutils.h"
+
 #include <stdarg.h>
 #include <vector>
 #include <fstream>
 #include <cstdio>
 
-#if defined(ANGLE_ENABLE_PERF)
-#include <d3d9.h>
-#endif
-
 namespace gl
 {
 #if defined(ANGLE_ENABLE_PERF)
@@ -27,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)
@@ -50,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());
     }
@@ -72,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/debug.h b/src/common/debug.h
index 8c07971..997ebca 100644
--- a/src/common/debug.h
+++ b/src/common/debug.h
@@ -62,7 +62,7 @@
 // A macro to log a performance event around a scope.
 #if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
 #if defined(_MSC_VER)
-#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__(__FUNCTION__ message "\n", __VA_ARGS__);
+#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
 #else
 #define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper(message "\n", ##__VA_ARGS__);
 #endif // _MSC_VER
@@ -83,6 +83,12 @@
 #define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
 #endif
 
+#ifndef ANGLE_ENABLE_TRACE
+#define UNUSED_TRACE_VARIABLE(variable) ((void)variable)
+#else
+#define UNUSED_TRACE_VARIABLE(variable)
+#endif
+
 // A macro to indicate unimplemented functionality
 
 // Define NOASSERT_UNIMPLEMENTED to non zero to skip the assert fail in the unimplemented checks
diff --git a/src/common/event_tracer.h b/src/common/event_tracer.h
index 14b7b29..fa97435 100644
--- a/src/common/event_tracer.h
+++ b/src/common/event_tracer.h
@@ -5,12 +5,14 @@
 #ifndef COMMON_EVENT_TRACER_H_
 #define COMMON_EVENT_TRACER_H_
 
+#include "common/platform.h"
+
 #if !defined(TRACE_ENTRY)
-#if defined(_WIN32)
-#define TRACE_ENTRY __stdcall
-#else
-#define TRACE_ENTRY
-#endif // // _WIN32
+#   ifdef ANGLE_PLATFORM_WINDOWS
+#       define TRACE_ENTRY __stdcall
+#   else
+#       define TRACE_ENTRY
+#   endif // ANGLE_PLATFORM_WINDOWS
 #endif //TRACE_ENTRY
 
 extern "C" {
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 2d36631..ffcb908 100644
--- a/src/common/mathutil.h
+++ b/src/common/mathutil.h
@@ -10,10 +10,7 @@
 #define LIBGLESV2_MATHUTIL_H_
 
 #include "common/debug.h"
-
-#if defined(_WIN32)
-#include <intrin.h>
-#endif
+#include "common/platform.h"
 
 #include <limits>
 #include <algorithm>
@@ -112,7 +109,7 @@
 
 inline bool supportsSSE2()
 {
-#if defined(_WIN32)
+#ifdef ANGLE_PLATFORM_WINDOWS
     static bool checked = false;
     static bool supports = false;
 
@@ -506,21 +503,33 @@
 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)
 {
     return value + alignment - 1 - (value - 1) % alignment;
 }
 
+inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
+{
+    unsigned int divided = value / divisor;
+    return (divided + ((value % divisor == 0) ? 0 : 1));
+}
+
 template <class T>
 inline bool IsUnsignedAdditionSafe(T lhs, T rhs)
 {
diff --git a/src/common/platform.h b/src/common/platform.h
new file mode 100644
index 0000000..d07297d
--- /dev/null
+++ b/src/common/platform.h
@@ -0,0 +1,67 @@
+//
+// 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.
+//
+
+// platform.h: Operating system specific includes and defines.
+
+#ifndef COMMON_PLATFORM_H_
+#define COMMON_PLATFORM_H_
+
+#if defined(_WIN32) || defined(_WIN64)
+#   define ANGLE_PLATFORM_WINDOWS 1
+#elif defined(__APPLE__)
+#   define ANGLE_PLATFORM_APPLE 1
+#   define ANGLE_PLATFORM_POSIX 1
+#elif defined(__linux__)
+#   define ANGLE_PLATFORM_LINUX 1
+#   define ANGLE_PLATFORM_POSIX 1
+#elif defined(ANDROID)
+#   define ANGLE_PLATFORM_ANDROID 1
+#   define ANGLE_PLATFORM_POSIX 1
+#elif defined(__FreeBSD__) || \
+      defined(__OpenBSD__) || \
+      defined(__NetBSD__) || \
+      defined(__DragonFly__) || \
+      defined(__sun) || \
+      defined(__GLIBC__) || \
+      defined(__GNU__) || \
+      defined(__QNX__)
+#   define ANGLE_PLATFORM_POSIX 1
+#else
+#   error Unsupported platform.
+#endif
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+#   ifndef STRICT
+#       define STRICT 1
+#   endif
+#   ifndef WIN32_LEAN_AND_MEAN
+#       define WIN32_LEAN_AND_MEAN 1
+#   endif
+#   ifndef NOMINMAX
+#       define NOMINMAX 1
+#   endif
+
+#   include <windows.h>
+#   include <intrin.h>
+
+#   if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
+#       include <d3d9.h>
+#       include <d3dcompiler.h>
+#   endif
+
+#   if defined(ANGLE_ENABLE_D3D11)
+#       include <d3d10_1.h>
+#       include <d3d11.h>
+#       include <dxgi.h>
+#       include <dxgi1_2.h>
+#       include <d3dcompiler.h>
+#   endif
+
+#   undef near
+#   undef far
+#endif
+
+#endif // COMMON_PLATFORM_H_
diff --git a/src/common/shadervars.h b/src/common/shadervars.h
deleted file mode 100644
index 99187a0..0000000
--- a/src/common/shadervars.h
+++ /dev/null
@@ -1,162 +0,0 @@
-//
-// 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.
-//
-// shadervars.h:
-//  Types to represent GL variables (varyings, uniforms, etc)
-//
-
-#ifndef COMMON_SHADERVARIABLE_H_
-#define COMMON_SHADERVARIABLE_H_
-
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-
-namespace gl
-{
-
-// Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
-enum InterpolationType
-{
-    INTERPOLATION_SMOOTH,
-    INTERPOLATION_CENTROID,
-    INTERPOLATION_FLAT
-};
-
-// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
-enum BlockLayoutType
-{
-    BLOCKLAYOUT_STANDARD,
-    BLOCKLAYOUT_PACKED,
-    BLOCKLAYOUT_SHARED
-};
-
-// Base class for all variables defined in shaders, including Varyings, Uniforms, etc
-struct ShaderVariable
-{
-    GLenum type;
-    GLenum precision;
-    std::string name;
-    unsigned int arraySize;
-
-    ShaderVariable(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn)
-      : type(typeIn),
-        precision(precisionIn),
-        name(nameIn),
-        arraySize(arraySizeIn)
-    {}
-
-    bool isArray() const { return arraySize > 0; }
-    unsigned int elementCount() const { return std::max(1u, arraySize); }
-};
-
-// Uniform registers (and element indices) are assigned when outputting shader code
-struct Uniform : public ShaderVariable
-{
-    unsigned int registerIndex;
-    unsigned int elementIndex; // Offset within a register, for struct members
-    std::vector<Uniform> fields;
-
-    Uniform(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn,
-            unsigned int registerIndexIn, unsigned int elementIndexIn)
-      : ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
-        registerIndex(registerIndexIn),
-        elementIndex(elementIndexIn)
-    {}
-
-    bool isStruct() const { return !fields.empty(); }
-};
-
-struct Attribute : public ShaderVariable
-{
-    int location;
-
-    Attribute()
-      : ShaderVariable(GL_NONE, GL_NONE, "", 0),
-        location(-1)
-    {}
-
-    Attribute(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, int locationIn)
-      : ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
-        location(locationIn)
-    {}
-};
-
-struct InterfaceBlockField : public ShaderVariable
-{
-    bool isRowMajorMatrix;
-    std::vector<InterfaceBlockField> fields;
-
-    InterfaceBlockField(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, bool isRowMajorMatrix)
-      : ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
-        isRowMajorMatrix(isRowMajorMatrix)
-    {}
-
-    bool isStruct() const { return !fields.empty(); }
-};
-
-struct Varying : public ShaderVariable
-{
-    InterpolationType interpolation;
-    std::vector<Varying> fields;
-    std::string structName;
-
-    Varying(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, InterpolationType interpolationIn)
-      : ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
-        interpolation(interpolationIn)
-    {}
-
-    bool isStruct() const { return !fields.empty(); }
-};
-
-struct BlockMemberInfo
-{
-    int offset;
-    int arrayStride;
-    int matrixStride;
-    bool isRowMajorMatrix;
-
-    static BlockMemberInfo getDefaultBlockInfo()
-    {
-        return BlockMemberInfo(-1, -1, -1, false);
-    }
-
-    BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
-      : offset(offset),
-        arrayStride(arrayStride),
-        matrixStride(matrixStride),
-        isRowMajorMatrix(isRowMajorMatrix)
-    {}
-};
-
-typedef std::vector<BlockMemberInfo> BlockMemberInfoArray;
-
-struct InterfaceBlock
-{
-    std::string name;
-    unsigned int arraySize;
-    size_t dataSize;
-    BlockLayoutType layout;
-    bool isRowMajorLayout;
-    std::vector<InterfaceBlockField> fields;
-    std::vector<BlockMemberInfo> blockInfo;
-
-    unsigned int registerIndex;
-
-    InterfaceBlock(const char *name, unsigned int arraySize, unsigned int registerIndex)
-      : name(name),
-        arraySize(arraySize),
-        layout(BLOCKLAYOUT_SHARED),
-        registerIndex(registerIndex),
-        isRowMajorLayout(false)
-    {}
-};
-
-}
-
-#endif // COMMON_SHADERVARIABLE_H_
diff --git a/src/common/tls.cpp b/src/common/tls.cpp
new file mode 100644
index 0000000..6b78219
--- /dev/null
+++ b/src/common/tls.cpp
@@ -0,0 +1,74 @@
+//
+// 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.
+//
+
+// tls.cpp: Simple cross-platform interface for thread local storage.
+
+#include "common/tls.h"
+
+#include <assert.h>
+
+TLSIndex CreateTLSIndex()
+{
+    TLSIndex index;
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+    index = TlsAlloc();
+#elif defined(ANGLE_PLATFORM_POSIX)
+    // Create global pool key
+    if ((pthread_key_create(&index, NULL)) != 0)
+    {
+        index = TLS_INVALID_INDEX;
+    }
+#endif
+
+    assert(index != TLS_INVALID_INDEX && "CreateTLSIndex(): Unable to allocate Thread Local Storage");
+    return index;
+}
+
+bool DestroyTLSIndex(TLSIndex index)
+{
+    assert(index != TLS_INVALID_INDEX && "DestroyTLSIndex(): Invalid TLS Index");
+    if (index == TLS_INVALID_INDEX)
+    {
+        return false;
+    }
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+    return (TlsFree(index) == TRUE);
+#elif defined(ANGLE_PLATFORM_POSIX)
+    return (pthread_key_delete(index) == 0);
+#endif
+}
+
+bool SetTLSValue(TLSIndex index, void *value)
+{
+    assert(index != TLS_INVALID_INDEX && "SetTLSValue(): Invalid TLS Index");
+    if (index == TLS_INVALID_INDEX)
+    {
+        return false;
+    }
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+    return (TlsSetValue(index, value) == TRUE);
+#elif defined(ANGLE_PLATFORM_POSIX)
+    return (pthread_setspecific(index, value) == 0);
+#endif
+}
+
+void *GetTLSValue(TLSIndex index)
+{
+    assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
+    if (index == TLS_INVALID_INDEX)
+    {
+        return NULL;
+    }
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+    return TlsGetValue(index);
+#elif defined(ANGLE_PLATFORM_POSIX)
+    return pthread_getspecific(index);
+#endif
+}
diff --git a/src/common/tls.h b/src/common/tls.h
new file mode 100644
index 0000000..4b25fbc
--- /dev/null
+++ b/src/common/tls.h
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+// tls.h: Simple cross-platform interface for thread local storage.
+
+#ifndef COMMON_TLS_H_
+#define COMMON_TLS_H_
+
+#include "common/platform.h"
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+    typedef DWORD TLSIndex;
+#   define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
+#elif defined(ANGLE_PLATFORM_POSIX)
+#   include <pthread.h>
+#   include <semaphore.h>
+#   include <errno.h>
+    typedef pthread_key_t TLSIndex;
+#   define TLS_INVALID_INDEX (static_cast<TLSIndex>(-1))
+#else
+#   error Unsupported platform.
+#endif
+
+TLSIndex CreateTLSIndex();
+bool DestroyTLSIndex(TLSIndex index);
+
+bool SetTLSValue(TLSIndex index, void *value);
+void *GetTLSValue(TLSIndex index);
+
+#endif // COMMON_TLS_H_
diff --git a/src/common/utilities.cpp b/src/common/utilities.cpp
index b1e989b..405f119 100644
--- a/src/common/utilities.cpp
+++ b/src/common/utilities.cpp
@@ -8,77 +8,19 @@
 
 #include "common/utilities.h"
 #include "common/mathutil.h"
-
-#if defined(_WIN32)
-#include <windows.h>
-#endif
+#include "common/platform.h"
 
 #include <set>
 
 namespace gl
 {
 
-int UniformComponentCount(GLenum type)
+int VariableComponentCount(GLenum type)
 {
-    switch (type)
-    {
-      case GL_BOOL:
-      case GL_FLOAT:
-      case GL_INT:
-      case GL_SAMPLER_2D:
-      case GL_SAMPLER_3D:
-      case GL_SAMPLER_CUBE:
-      case GL_SAMPLER_2D_ARRAY:
-      case GL_INT_SAMPLER_2D:
-      case GL_INT_SAMPLER_3D:
-      case GL_INT_SAMPLER_CUBE:
-      case GL_INT_SAMPLER_2D_ARRAY:
-      case GL_UNSIGNED_INT_SAMPLER_2D:
-      case GL_UNSIGNED_INT_SAMPLER_3D:
-      case GL_UNSIGNED_INT_SAMPLER_CUBE:
-      case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
-      case GL_SAMPLER_2D_SHADOW:
-      case GL_SAMPLER_CUBE_SHADOW:
-      case GL_SAMPLER_2D_ARRAY_SHADOW:
-      case GL_UNSIGNED_INT:
-        return 1;
-      case GL_BOOL_VEC2:
-      case GL_FLOAT_VEC2:
-      case GL_INT_VEC2:
-      case GL_UNSIGNED_INT_VEC2:
-        return 2;
-      case GL_INT_VEC3:
-      case GL_FLOAT_VEC3:
-      case GL_BOOL_VEC3:
-      case GL_UNSIGNED_INT_VEC3:
-        return 3;
-      case GL_BOOL_VEC4:
-      case GL_FLOAT_VEC4:
-      case GL_INT_VEC4:
-      case GL_UNSIGNED_INT_VEC4:
-      case GL_FLOAT_MAT2:
-        return 4;
-      case GL_FLOAT_MAT2x3:
-      case GL_FLOAT_MAT3x2:
-        return 6;
-      case GL_FLOAT_MAT2x4:
-      case GL_FLOAT_MAT4x2:
-        return 8;
-      case GL_FLOAT_MAT3:
-        return 9;
-      case GL_FLOAT_MAT3x4:
-      case GL_FLOAT_MAT4x3:
-        return 12;
-      case GL_FLOAT_MAT4:
-        return 16;
-      default:
-        UNREACHABLE();
-    }
-
-    return 0;
+    return VariableRowCount(type) * VariableColumnCount(type);
 }
 
-GLenum UniformComponentType(GLenum type)
+GLenum VariableComponentType(GLenum type)
 {
     switch(type)
     {
@@ -133,7 +75,7 @@
     return GL_NONE;
 }
 
-size_t UniformComponentSize(GLenum type)
+size_t VariableComponentSize(GLenum type)
 {
     switch(type)
     {
@@ -147,18 +89,18 @@
     return 0;
 }
 
-size_t UniformInternalSize(GLenum type)
+size_t VariableInternalSize(GLenum type)
 {
     // Expanded to 4-element vectors
-    return UniformComponentSize(UniformComponentType(type)) * VariableRowCount(type) * 4;
+    return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
 }
 
-size_t UniformExternalSize(GLenum type)
+size_t VariableExternalSize(GLenum type)
 {
-    return UniformComponentSize(UniformComponentType(type)) * UniformComponentCount(type);
+    return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
 }
 
-GLenum UniformBoolVectorType(GLenum type)
+GLenum VariableBoolVectorType(GLenum type)
 {
     switch (type)
     {
@@ -212,6 +154,8 @@
       case GL_SAMPLER_3D:
       case GL_SAMPLER_CUBE:
       case GL_SAMPLER_2D_ARRAY:
+      case GL_SAMPLER_EXTERNAL_OES:
+      case GL_SAMPLER_2D_RECT_ARB:
       case GL_INT_SAMPLER_2D:
       case GL_INT_SAMPLER_3D:
       case GL_INT_SAMPLER_CUBE:
@@ -262,6 +206,8 @@
       case GL_INT_SAMPLER_3D:
       case GL_INT_SAMPLER_CUBE:
       case GL_INT_SAMPLER_2D_ARRAY:
+      case GL_SAMPLER_EXTERNAL_OES:
+      case GL_SAMPLER_2D_RECT_ARB:
       case GL_UNSIGNED_INT_SAMPLER_2D:
       case GL_UNSIGNED_INT_SAMPLER_3D:
       case GL_UNSIGNED_INT_SAMPLER_CUBE:
@@ -365,7 +311,7 @@
     return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
 }
 
-int AttributeRegisterCount(GLenum type)
+int VariableRegisterCount(GLenum type)
 {
     return IsMatrixType(type) ? VariableColumnCount(type) : 1;
 }
@@ -395,24 +341,6 @@
     return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
 }
 
-bool IsInternalTextureTarget(GLenum target, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
-    }
-    else if (clientVersion == 3)
-    {
-        return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) ||
-               target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
 bool IsTriangleMode(GLenum drawMode)
 {
     switch (drawMode)
@@ -432,11 +360,88 @@
     return false;
 }
 
+// [OpenGL ES SL 3.00.4] Section 11 p. 120
+// Vertex Outs/Fragment Ins packing priorities
+int VariableSortOrder(GLenum type)
+{
+    switch (type)
+    {
+      // 1. Arrays of mat4 and mat4
+      // Non-square matrices of type matCxR consume the same space as a square
+      // matrix of type matN where N is the greater of C and R
+      case GL_FLOAT_MAT4:
+      case GL_FLOAT_MAT2x4:
+      case GL_FLOAT_MAT3x4:
+      case GL_FLOAT_MAT4x2:
+      case GL_FLOAT_MAT4x3:
+        return 0;
+
+      // 2. Arrays of mat2 and mat2 (since they occupy full rows)
+      case GL_FLOAT_MAT2:
+        return 1;
+
+      // 3. Arrays of vec4 and vec4
+      case GL_FLOAT_VEC4:
+      case GL_INT_VEC4:
+      case GL_BOOL_VEC4:
+      case GL_UNSIGNED_INT_VEC4:
+        return 2;
+
+      // 4. Arrays of mat3 and mat3
+      case GL_FLOAT_MAT3:
+      case GL_FLOAT_MAT2x3:
+      case GL_FLOAT_MAT3x2:
+        return 3;
+
+      // 5. Arrays of vec3 and vec3
+      case GL_FLOAT_VEC3:
+      case GL_INT_VEC3:
+      case GL_BOOL_VEC3:
+      case GL_UNSIGNED_INT_VEC3:
+        return 4;
+
+      // 6. Arrays of vec2 and vec2
+      case GL_FLOAT_VEC2:
+      case GL_INT_VEC2:
+      case GL_BOOL_VEC2:
+      case GL_UNSIGNED_INT_VEC2:
+        return 5;
+
+      // 7. Single component types
+      case GL_FLOAT:
+      case GL_INT:
+      case GL_BOOL:
+      case GL_UNSIGNED_INT:
+      case GL_SAMPLER_2D:
+      case GL_SAMPLER_CUBE:
+      case GL_SAMPLER_EXTERNAL_OES:
+      case GL_SAMPLER_2D_RECT_ARB:
+      case GL_SAMPLER_2D_ARRAY:
+      case GL_SAMPLER_3D:
+      case GL_INT_SAMPLER_2D:
+      case GL_INT_SAMPLER_3D:
+      case GL_INT_SAMPLER_CUBE:
+      case GL_INT_SAMPLER_2D_ARRAY:
+      case GL_UNSIGNED_INT_SAMPLER_2D:
+      case GL_UNSIGNED_INT_SAMPLER_3D:
+      case GL_UNSIGNED_INT_SAMPLER_CUBE:
+      case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+      case GL_SAMPLER_2D_SHADOW:
+      case GL_SAMPLER_2D_ARRAY_SHADOW:
+      case GL_SAMPLER_CUBE_SHADOW:
+        return 6;
+
+      default:
+        UNREACHABLE();
+        return 0;
+    }
+}
+
 }
 
 std::string getTempPath()
 {
-#if defined (_WIN32)
+#ifdef ANGLE_PLATFORM_WINDOWS
     char path[MAX_PATH];
     DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
     if (pathLen == 0)
diff --git a/src/common/utilities.h b/src/common/utilities.h
index f69e33a..a823184 100644
--- a/src/common/utilities.h
+++ b/src/common/utilities.h
@@ -9,36 +9,32 @@
 #ifndef LIBGLESV2_UTILITIES_H
 #define LIBGLESV2_UTILITIES_H
 
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
+#include "angle_gl.h"
 #include <string>
 #include <math.h>
 
 namespace gl
 {
 
-int UniformComponentCount(GLenum type);
-GLenum UniformComponentType(GLenum type);
-size_t UniformComponentSize(GLenum type);
-size_t UniformInternalSize(GLenum type);
-size_t UniformExternalSize(GLenum type);
-GLenum UniformBoolVectorType(GLenum type);
+int VariableComponentCount(GLenum type);
+GLenum VariableComponentType(GLenum type);
+size_t VariableComponentSize(GLenum type);
+size_t VariableInternalSize(GLenum type);
+size_t VariableExternalSize(GLenum type);
+GLenum VariableBoolVectorType(GLenum type);
 int VariableRowCount(GLenum type);
 int VariableColumnCount(GLenum type);
 bool IsSampler(GLenum type);
 bool IsMatrixType(GLenum type);
 GLenum TransposeMatrixType(GLenum type);
-int AttributeRegisterCount(GLenum type);
+int VariableRegisterCount(GLenum type);
 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix);
 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix);
+int VariableSortOrder(GLenum type);
 
 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
 
 bool IsCubemapTextureTarget(GLenum target);
-bool IsInternalTextureTarget(GLenum target, GLuint clientVersion);
 
 bool IsTriangleMode(GLenum drawMode);
 
diff --git a/src/compiler.gypi b/src/compiler.gypi
index df62d11..dadc4ca 100644
--- a/src/compiler.gypi
+++ b/src/compiler.gypi
@@ -3,13 +3,207 @@
 # found in the LICENSE file.
 
 {
+    'variables':
+    {
+        # This file list is shared with the GN build.
+        'angle_translator_lib_sources':
+        [
+            '../include/EGL/egl.h',
+            '../include/EGL/eglext.h',
+            '../include/EGL/eglplatform.h',
+            '../include/GLES2/gl2.h',
+            '../include/GLES2/gl2ext.h',
+            '../include/GLES2/gl2platform.h',
+            '../include/GLES3/gl3.h',
+            '../include/GLES3/gl3ext.h',
+            '../include/GLES3/gl3platform.h',
+            '../include/GLSLANG/ShaderLang.h',
+            '../include/GLSLANG/ShaderVars.h',
+            '../include/KHR/khrplatform.h',
+            '../include/angle_gl.h',
+            'common/RefCountObject.cpp',
+            'common/RefCountObject.h',
+            'common/angleutils.h',
+            'common/blocklayout.cpp',
+            'common/blocklayout.h',
+            'common/debug.cpp',
+            'common/debug.h',
+            'common/event_tracer.cpp',
+            'common/event_tracer.h',
+            'common/mathutil.cpp',
+            'common/mathutil.h',
+            'common/platform.h',
+            'common/tls.cpp',
+            'common/tls.h',
+            'common/utilities.cpp',
+            'common/utilities.h',
+            'common/version.h',
+            'compiler/translator/BaseTypes.h',
+            'compiler/translator/BuiltInFunctionEmulator.cpp',
+            'compiler/translator/BuiltInFunctionEmulator.h',
+            'compiler/translator/CodeGen.cpp',
+            'compiler/translator/Common.h',
+            'compiler/translator/Compiler.cpp',
+            'compiler/translator/Compiler.h',
+            'compiler/translator/ConstantUnion.h',
+            'compiler/translator/DetectCallDepth.cpp',
+            'compiler/translator/DetectCallDepth.h',
+            'compiler/translator/DetectDiscontinuity.cpp',
+            'compiler/translator/DetectDiscontinuity.h',
+            'compiler/translator/Diagnostics.cpp',
+            'compiler/translator/Diagnostics.h',
+            'compiler/translator/DirectiveHandler.cpp',
+            'compiler/translator/DirectiveHandler.h',
+            'compiler/translator/ExtensionBehavior.h',
+            'compiler/translator/FlagStd140Structs.cpp',
+            'compiler/translator/FlagStd140Structs.h',
+            'compiler/translator/ForLoopUnroll.cpp',
+            'compiler/translator/ForLoopUnroll.h',
+            'compiler/translator/HashNames.h',
+            'compiler/translator/InfoSink.cpp',
+            'compiler/translator/InfoSink.h',
+            'compiler/translator/Initialize.cpp',
+            'compiler/translator/Initialize.h',
+            'compiler/translator/InitializeDll.cpp',
+            'compiler/translator/InitializeDll.h',
+            'compiler/translator/InitializeGlobals.h',
+            'compiler/translator/InitializeParseContext.cpp',
+            'compiler/translator/InitializeParseContext.h',
+            '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',
+            'compiler/translator/NodeSearch.h',
+            'compiler/translator/OutputESSL.cpp',
+            'compiler/translator/OutputESSL.h',
+            'compiler/translator/OutputGLSL.cpp',
+            'compiler/translator/OutputGLSL.h',
+            'compiler/translator/OutputGLSLBase.cpp',
+            'compiler/translator/OutputGLSLBase.h',
+            'compiler/translator/OutputHLSL.cpp',
+            'compiler/translator/OutputHLSL.h',
+            'compiler/translator/ParseContext.cpp',
+            'compiler/translator/ParseContext.h',
+            'compiler/translator/PoolAlloc.cpp',
+            'compiler/translator/PoolAlloc.h',
+            'compiler/translator/Pragma.h',
+            'compiler/translator/QualifierAlive.cpp',
+            'compiler/translator/QualifierAlive.h',
+            'compiler/translator/RegenerateStructNames.cpp',
+            'compiler/translator/RegenerateStructNames.h',
+            'compiler/translator/RemoveTree.cpp',
+            'compiler/translator/RemoveTree.h',
+            'compiler/translator/RenameFunction.h',
+            'compiler/translator/RewriteElseBlocks.cpp',
+            'compiler/translator/RewriteElseBlocks.h',
+            'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
+            'compiler/translator/ScalarizeVecAndMatConstructorArgs.h',
+            'compiler/translator/SearchSymbol.cpp',
+            'compiler/translator/SearchSymbol.h',
+            'compiler/translator/StructureHLSL.cpp',
+            'compiler/translator/StructureHLSL.h',
+            'compiler/translator/SymbolTable.cpp',
+            'compiler/translator/SymbolTable.h',
+            'compiler/translator/TranslatorESSL.cpp',
+            'compiler/translator/TranslatorESSL.h',
+            'compiler/translator/TranslatorGLSL.cpp',
+            'compiler/translator/TranslatorGLSL.h',
+            'compiler/translator/TranslatorHLSL.cpp',
+            'compiler/translator/TranslatorHLSL.h',
+            'compiler/translator/Types.cpp',
+            'compiler/translator/Types.h',
+            'compiler/translator/UnfoldShortCircuit.cpp',
+            'compiler/translator/UnfoldShortCircuit.h',
+            'compiler/translator/UnfoldShortCircuitAST.cpp',
+            'compiler/translator/UnfoldShortCircuitAST.h',
+            'compiler/translator/UniformHLSL.cpp',
+            'compiler/translator/UniformHLSL.h',
+            'compiler/translator/UtilsHLSL.cpp',
+            'compiler/translator/UtilsHLSL.h',
+            'compiler/translator/ValidateLimitations.cpp',
+            'compiler/translator/ValidateLimitations.h',
+            'compiler/translator/ValidateOutputs.cpp',
+            'compiler/translator/ValidateOutputs.h',
+            'compiler/translator/VariableInfo.cpp',
+            'compiler/translator/VariableInfo.h',
+            'compiler/translator/VariablePacker.cpp',
+            'compiler/translator/VariablePacker.h',
+            'compiler/translator/VersionGLSL.cpp',
+            'compiler/translator/VersionGLSL.h',
+            'compiler/translator/compilerdebug.cpp',
+            'compiler/translator/compilerdebug.h',
+            'compiler/translator/depgraph/DependencyGraph.cpp',
+            'compiler/translator/depgraph/DependencyGraph.h',
+            'compiler/translator/depgraph/DependencyGraphBuilder.cpp',
+            'compiler/translator/depgraph/DependencyGraphBuilder.h',
+            'compiler/translator/depgraph/DependencyGraphOutput.cpp',
+            'compiler/translator/depgraph/DependencyGraphOutput.h',
+            'compiler/translator/depgraph/DependencyGraphTraverse.cpp',
+            'compiler/translator/glslang.h',
+            'compiler/translator/glslang.l',
+            'compiler/translator/glslang.y',
+            'compiler/translator/glslang_lex.cpp',
+            'compiler/translator/glslang_tab.cpp',
+            'compiler/translator/glslang_tab.h',
+            'compiler/translator/intermOut.cpp',
+            'compiler/translator/intermediate.h',
+            'compiler/translator/length_limits.h',
+            'compiler/translator/parseConst.cpp',
+            'compiler/translator/timing/RestrictFragmentShaderTiming.cpp',
+            'compiler/translator/timing/RestrictFragmentShaderTiming.h',
+            'compiler/translator/timing/RestrictVertexShaderTiming.cpp',
+            'compiler/translator/timing/RestrictVertexShaderTiming.h',
+            'compiler/translator/util.cpp',
+            'compiler/translator/util.h',
+            'third_party/compiler/ArrayBoundsClamper.cpp',
+            'third_party/compiler/ArrayBoundsClamper.h',
+        ],
+        'angle_preprocessor_sources':
+        [
+            'compiler/preprocessor/DiagnosticsBase.cpp',
+            'compiler/preprocessor/DiagnosticsBase.h',
+            'compiler/preprocessor/DirectiveHandlerBase.cpp',
+            'compiler/preprocessor/DirectiveHandlerBase.h',
+            'compiler/preprocessor/DirectiveParser.cpp',
+            'compiler/preprocessor/DirectiveParser.h',
+            'compiler/preprocessor/ExpressionParser.cpp',
+            'compiler/preprocessor/ExpressionParser.h',
+            'compiler/preprocessor/ExpressionParser.y',
+            'compiler/preprocessor/Input.cpp',
+            'compiler/preprocessor/Input.h',
+            'compiler/preprocessor/Lexer.cpp',
+            'compiler/preprocessor/Lexer.h',
+            'compiler/preprocessor/Macro.cpp',
+            'compiler/preprocessor/Macro.h',
+            'compiler/preprocessor/MacroExpander.cpp',
+            'compiler/preprocessor/MacroExpander.h',
+            'compiler/preprocessor/Preprocessor.cpp',
+            'compiler/preprocessor/Preprocessor.h',
+            'compiler/preprocessor/SourceLocation.h',
+            'compiler/preprocessor/Token.cpp',
+            'compiler/preprocessor/Token.h',
+            'compiler/preprocessor/Tokenizer.cpp',
+            'compiler/preprocessor/Tokenizer.h',
+            'compiler/preprocessor/Tokenizer.l',
+            'compiler/preprocessor/numeric_lex.h',
+            'compiler/preprocessor/pp_utils.h',
+        ],
+    },
+    # Everything below this is duplicated in the GN build. If you change
+    # anything also change angle/BUILD.gn
     'targets':
     [
         {
             'target_name': 'preprocessor',
             'type': 'static_library',
             'includes': [ '../build/common_defines.gypi', ],
-            'sources': [ '<!@(python <(angle_path)/enumerate_files.py compiler/preprocessor -types *.cpp *.h *.y *.l )' ],
+            'sources': [ '<@(angle_preprocessor_sources)', ],
         },
         {
             'target_name': 'translator_lib',
@@ -21,24 +215,15 @@
                 '.',
                 '../include',
             ],
+            'defines':
+            [
+                # define the static translator to indicate exported
+                # classes are (in fact) locally defined
+                'ANGLE_TRANSLATOR_STATIC',
+            ],
             'sources':
             [
-                '<!@(python <(angle_path)/enumerate_files.py \
-                     -dirs compiler/translator third_party/compiler common ../include \
-                     -excludes compiler/translator/ShaderLang.cpp \
-                     -types *.cpp *.h *.y *.l)',
-            ],
-            'conditions':
-            [
-                ['OS=="win"',
-                    {
-                        'msvs_disabled_warnings': [ 4267 ],
-                        'sources/': [ [ 'exclude', 'compiler/translator/ossource_posix.cpp' ], ],
-                    },
-                    { # else: posix
-                        'sources/': [ [ 'exclude', 'compiler/translator/ossource_win.cpp' ], ],
-                    }
-                ],
+                '<@(angle_translator_lib_sources)',
             ],
             'msvs_settings':
             {
@@ -65,7 +250,8 @@
             ],
             'sources':
             [
-                'compiler/translator/ShaderLang.cpp'
+                'compiler/translator/ShaderLang.cpp',
+                'compiler/translator/ShaderVars.cpp'
             ],
         },
 
@@ -92,7 +278,8 @@
             },
             'sources':
             [
-                'compiler/translator/ShaderLang.cpp'
+                'compiler/translator/ShaderLang.cpp',
+                'compiler/translator/ShaderVars.cpp'
             ],
         },
     ],
diff --git a/src/compiler/translator/BaseTypes.h b/src/compiler/translator/BaseTypes.h
index ba9ef5e..324b066 100644
--- a/src/compiler/translator/BaseTypes.h
+++ b/src/compiler/translator/BaseTypes.h
@@ -69,40 +69,9 @@
     EbtStruct,
     EbtInterfaceBlock,
     EbtAddress,            // should be deprecated??
-    EbtInvariant          // used as a type when qualifying a previously declared variable as being invariant
 };
 
-inline const char* getBasicString(TBasicType t)
-{
-    switch (t)
-    {
-      case EbtVoid:                 return "void";                 break;
-      case EbtFloat:                return "float";                break;
-      case EbtInt:                  return "int";                  break;
-      case EbtUInt:                 return "uint";                 break;
-      case EbtBool:                 return "bool";                 break;
-      case EbtSampler2D:            return "sampler2D";            break;
-      case EbtSampler3D:            return "sampler3D";            break;
-      case EbtSamplerCube:          return "samplerCube";          break;
-      case EbtSamplerExternalOES:   return "samplerExternalOES";   break;
-      case EbtSampler2DRect:        return "sampler2DRect";        break;
-      case EbtSampler2DArray:       return "sampler2DArray";       break;
-      case EbtISampler2D:           return "isampler2D";           break;
-      case EbtISampler3D:           return "isampler3D";           break;
-      case EbtISamplerCube:         return "isamplerCube";         break;
-      case EbtISampler2DArray:      return "isampler2DArray";      break;
-      case EbtUSampler2D:           return "usampler2D";           break;
-      case EbtUSampler3D:           return "usampler3D";           break;
-      case EbtUSamplerCube:         return "usamplerCube";         break;
-      case EbtUSampler2DArray:      return "usampler2DArray";      break;
-      case EbtSampler2DShadow:      return "sampler2DShadow";      break;
-      case EbtSamplerCubeShadow:    return "samplerCubeShadow";    break;
-      case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
-      case EbtStruct:               return "structure";            break;
-      case EbtInterfaceBlock:       return "interface block";      break;
-      default:                      return "unknown type";
-    }
-}
+const char* getBasicString(TBasicType t);
 
 inline bool IsSampler(TBasicType type)
 {
diff --git a/src/compiler/translator/BuiltInFunctionEmulator.cpp b/src/compiler/translator/BuiltInFunctionEmulator.cpp
index afbc169..0e8239c 100644
--- a/src/compiler/translator/BuiltInFunctionEmulator.cpp
+++ b/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -4,8 +4,8 @@
 // found in the LICENSE file.
 //
 
+#include "angle_gl.h"
 #include "compiler/translator/BuiltInFunctionEmulator.h"
-
 #include "compiler/translator/SymbolTable.h"
 
 namespace {
@@ -243,7 +243,7 @@
                 default:
                     return true;
             };
-            const TIntermSequence& sequence = node->getSequence();
+            const TIntermSequence& sequence = *(node->getSequence());
             // Right now we only handle built-in functions with two parameters.
             if (sequence.size() != 2)
                 return true;
@@ -265,9 +265,9 @@
 
 }  // anonymous namepsace
 
-BuiltInFunctionEmulator::BuiltInFunctionEmulator(ShShaderType shaderType)
+BuiltInFunctionEmulator::BuiltInFunctionEmulator(sh::GLenum shaderType)
 {
-    if (shaderType == SH_FRAGMENT_SHADER) {
+    if (shaderType == GL_FRAGMENT_SHADER) {
         mFunctionMask = kFunctionEmulationFragmentMask;
         mFunctionSource = kFunctionEmulationFragmentSource;
     } else {
diff --git a/src/compiler/translator/BuiltInFunctionEmulator.h b/src/compiler/translator/BuiltInFunctionEmulator.h
index 9367b55..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
@@ -17,7 +17,7 @@
 //
 class BuiltInFunctionEmulator {
 public:
-    BuiltInFunctionEmulator(ShShaderType shaderType);
+    BuiltInFunctionEmulator(sh::GLenum shaderType);
     // Records that a function is called by the shader and might needs to be
     // emulated.  If the function's group is not in mFunctionGroupFilter, this
     // becomes an no-op.
diff --git a/src/compiler/translator/CodeGen.cpp b/src/compiler/translator/CodeGen.cpp
index c35dbdc..71056f4 100644
--- a/src/compiler/translator/CodeGen.cpp
+++ b/src/compiler/translator/CodeGen.cpp
@@ -14,7 +14,7 @@
 // a subclass of TCompiler.
 //
 TCompiler* ConstructCompiler(
-    ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
+    sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
 {
     switch (output) {
     case SH_ESSL_OUTPUT:
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 402715b..368cd2a 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -5,14 +5,16 @@
 //
 
 #include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/Compiler.h"
 #include "compiler/translator/DetectCallDepth.h"
 #include "compiler/translator/ForLoopUnroll.h"
 #include "compiler/translator/Initialize.h"
 #include "compiler/translator/InitializeParseContext.h"
 #include "compiler/translator/InitializeVariables.h"
 #include "compiler/translator/ParseContext.h"
+#include "compiler/translator/RegenerateStructNames.h"
 #include "compiler/translator/RenameFunction.h"
-#include "compiler/translator/ShHandle.h"
+#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
 #include "compiler/translator/UnfoldShortCircuitAST.h"
 #include "compiler/translator/ValidateLimitations.h"
 #include "compiler/translator/ValidateOutputs.h"
@@ -22,6 +24,8 @@
 #include "compiler/translator/timing/RestrictFragmentShaderTiming.h"
 #include "compiler/translator/timing/RestrictVertexShaderTiming.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
+#include "angle_gl.h"
+#include "common/utilities.h"
 
 bool IsWebGLBasedSpec(ShShaderSpec spec)
 {
@@ -92,7 +96,7 @@
     allocator.popAll();
 }
 
-TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
+TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
     : shaderType(type),
       shaderSpec(spec),
       outputType(output),
@@ -112,7 +116,7 @@
 bool TCompiler::Init(const ShBuiltInResources& resources)
 {
     shaderVersion = 100;
-    maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
+    maxUniformVectors = (shaderType == GL_VERTEX_SHADER) ?
         resources.MaxVertexUniformVectors :
         resources.MaxFragmentUniformVectors;
     maxExpressionComplexity = resources.MaxExpressionComplexity;
@@ -187,7 +191,7 @@
         if (success)
             success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0);
 
-        if (success && shaderVersion == 300 && shaderType == SH_FRAGMENT_SHADER)
+        if (success && shaderVersion == 300 && shaderType == GL_FRAGMENT_SHADER)
             success = validateOutputs(root);
 
         if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
@@ -225,7 +229,7 @@
         if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
             arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
 
-        if (success && shaderType == SH_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION))
+        if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION))
             initializeGLPosition(root);
 
         if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
@@ -247,11 +251,24 @@
                     infoSink.info << "too many uniforms";
                 }
             }
-            if (success && shaderType == SH_VERTEX_SHADER &&
+            if (success && shaderType == GL_VERTEX_SHADER &&
                 (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE))
                 initializeVaryingsWithoutStaticUse(root);
         }
 
+        if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
+        {
+            ScalarizeVecAndMatConstructorArgs scalarizer(
+                shaderType, fragmentPrecisionHigh);
+            root->traverse(&scalarizer);
+        }
+
+        if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
+        {
+            RegenerateStructNames gen(symbolTable, shaderVersion);
+            root->traverse(&gen);
+        }
+
         if (success && (compileOptions & SH_INTERMEDIATE_TREE))
             intermediate.outputTree(root);
 
@@ -294,10 +311,10 @@
 
     switch(shaderType)
     {
-      case SH_FRAGMENT_SHADER:
+      case GL_FRAGMENT_SHADER:
         symbolTable.setDefaultPrecision(integer, EbpMedium);
         break;
-      case SH_VERTEX_SHADER:
+      case GL_VERTEX_SHADER:
         symbolTable.setDefaultPrecision(integer, EbpHigh);
         symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
         break;
@@ -355,9 +372,13 @@
     infoSink.obj.erase();
     infoSink.debug.erase();
 
-    attribs.clear();
+    attributes.clear();
+    outputVariables.clear();
     uniforms.clear();
+    expandedUniforms.clear();
     varyings.clear();
+    expandedVaryings.clear();
+    interfaceBlocks.clear();
 
     builtInFunctionEmulator.Cleanup();
 
@@ -418,7 +439,7 @@
         return false;
     }
 
-    if (shaderType == SH_FRAGMENT_SHADER)
+    if (shaderType == GL_FRAGMENT_SHADER)
     {
         TDependencyGraph graph(root);
 
@@ -481,14 +502,24 @@
 
 void TCompiler::collectVariables(TIntermNode* root)
 {
-    CollectVariables collect(attribs, uniforms, varyings, 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.
+    sh::ExpandVariables(uniforms, &expandedUniforms);
+    sh::ExpandVariables(varyings, &expandedVaryings);
 }
 
 bool TCompiler::enforcePackingRestrictions()
 {
     VariablePacker packer;
-    return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
+    return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms);
 }
 
 void TCompiler::initializeGLPosition(TIntermNode* root)
@@ -506,43 +537,16 @@
     InitializeVariables::InitVariableInfoList variables;
     for (size_t ii = 0; ii < varyings.size(); ++ii)
     {
-        const TVariableInfo& varying = varyings[ii];
+        const sh::Varying& varying = varyings[ii];
         if (varying.staticUse)
             continue;
-        unsigned char primarySize = 1, secondarySize = 1;
-        switch (varying.type)
-        {
-          case SH_FLOAT:
-            break;
-          case SH_FLOAT_VEC2:
-            primarySize = 2;
-            break;
-          case SH_FLOAT_VEC3:
-            primarySize = 3;
-            break;
-          case SH_FLOAT_VEC4:
-            primarySize = 4;
-            break;
-          case SH_FLOAT_MAT2:
-            primarySize = 2;
-            secondarySize = 2;
-            break;
-          case SH_FLOAT_MAT3:
-            primarySize = 3;
-            secondarySize = 3;
-            break;
-          case SH_FLOAT_MAT4:
-            primarySize = 4;
-            secondarySize = 4;
-            break;
-          default:
-            ASSERT(false);
-        }
-        TType type(EbtFloat, EbpUndefined, EvqVaryingOut, primarySize, secondarySize, varying.isArray);
+        unsigned char primarySize = static_cast<unsigned char>(gl::VariableColumnCount(varying.type));
+        unsigned char secondarySize = static_cast<unsigned char>(gl::VariableRowCount(varying.type));
+        TType type(EbtFloat, EbpUndefined, EvqVaryingOut, primarySize, secondarySize, varying.isArray());
         TString name = varying.name.c_str();
-        if (varying.isArray)
+        if (varying.isArray())
         {
-            type.setArraySize(varying.size);
+            type.setArraySize(varying.arraySize);
             name = name.substr(0, name.find_first_of('['));
         }
 
diff --git a/src/compiler/translator/ShHandle.h b/src/compiler/translator/Compiler.h
similarity index 82%
rename from src/compiler/translator/ShHandle.h
rename to src/compiler/translator/Compiler.h
index bb6a60c..ca0c157 100644
--- a/src/compiler/translator/ShHandle.h
+++ b/src/compiler/translator/Compiler.h
@@ -52,9 +52,10 @@
 // The base class for the machine dependent compiler to derive from
 // for managing object code from the compile.
 //
-class TCompiler : public TShHandleBase {
-public:
-    TCompiler(ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
+class TCompiler : public TShHandleBase
+{
+  public:
+    TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
     virtual ~TCompiler();
     virtual TCompiler* getAsCompiler() { return this; }
 
@@ -66,9 +67,14 @@
     // Get results of the last compilation.
     int getShaderVersion() const { return shaderVersion; }
     TInfoSink& getInfoSink() { return infoSink; }
-    const TVariableInfoList& getAttribs() const { return attribs; }
-    const TVariableInfoList& getUniforms() const { return uniforms; }
-    const TVariableInfoList& getVaryings() const { return varyings; }
+
+    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::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
+    const std::vector<sh::Varying> &getVaryings() const { return varyings; }
+    const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
+    const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
 
     ShHashFunction64 getHashFunction() const { return hashFunction; }
     NameMap& getNameMap() { return nameMap; }
@@ -77,8 +83,11 @@
     ShShaderOutput getOutputType() const { return outputType; }
     std::string getBuiltInResourcesString() const { return builtInResourcesString; }
 
-protected:
-    ShShaderType getShaderType() const { return shaderType; }
+    // Get the resources set by InitBuiltInSymbolTable
+    const ShBuiltInResources& getResources() const;
+
+  protected:
+    sh::GLenum getShaderType() const { return shaderType; }
     // Initialize symbol-table with built-in symbols.
     bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
     // Compute the string representation of the built-in resources
@@ -115,22 +124,28 @@
     bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph);
     // Returns true if the shader does not use samplers.
     bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
-    // Returns true if the shader does not use sampler dependent values to affect control 
+    // Returns true if the shader does not use sampler dependent values to affect control
     // flow or in operations whose time can depend on the input values.
     bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
     // Return true if the maximum expression complexity is below the limit.
     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;
     const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
 
-private:
-    ShShaderType shaderType;
+    std::vector<sh::Attribute> attributes;
+    std::vector<sh::Attribute> outputVariables;
+    std::vector<sh::Uniform> uniforms;
+    std::vector<sh::ShaderVariable> expandedUniforms;
+    std::vector<sh::Varying> varyings;
+    std::vector<sh::ShaderVariable> expandedVaryings;
+    std::vector<sh::InterfaceBlock> interfaceBlocks;
+
+  private:
+    sh::GLenum shaderType;
     ShShaderSpec shaderSpec;
     ShShaderOutput outputType;
 
@@ -155,9 +170,6 @@
     // Results of compilation.
     int shaderVersion;
     TInfoSink infoSink;  // Output sink.
-    TVariableInfoList attribs;  // Active attributes in the compiled shader.
-    TVariableInfoList uniforms;  // Active uniforms in the compiled shader.
-    TVariableInfoList varyings;  // Varyings in the compiled shader.
 
     // name hashing.
     ShHashFunction64 hashFunction;
@@ -169,12 +181,12 @@
 // and the machine dependent code.
 //
 // The machine dependent code should derive from the classes
-// above. Then Construct*() and Delete*() will create and 
+// above. Then Construct*() and Delete*() will create and
 // destroy the machine dependent objects, which contain the
 // above machine independent information.
 //
 TCompiler* ConstructCompiler(
-    ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
+    sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
 void DeleteCompiler(TCompiler*);
 
 #endif // _SHHANDLE_INCLUDED_
diff --git a/src/compiler/translator/ConstantUnion.h b/src/compiler/translator/ConstantUnion.h
index 5fdba61..5e86c64 100644
--- a/src/compiler/translator/ConstantUnion.h
+++ b/src/compiler/translator/ConstantUnion.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -18,6 +18,67 @@
         type = EbtVoid;
     }
 
+    bool cast(TBasicType newType, const ConstantUnion &constant)
+    {
+        switch (newType)
+        {
+          case EbtFloat:
+            switch (constant.type)
+            {
+              case EbtInt:   setFConst(static_cast<float>(constant.getIConst())); break;
+              case EbtUInt:  setFConst(static_cast<float>(constant.getUConst())); break;
+              case EbtBool:  setFConst(static_cast<float>(constant.getBConst())); break;
+              case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
+              default:       return false;
+            }
+            break;
+          case EbtInt:
+            switch (constant.type)
+            {
+              case EbtInt:   setIConst(static_cast<int>(constant.getIConst())); break;
+              case EbtUInt:  setIConst(static_cast<int>(constant.getUConst())); break;
+              case EbtBool:  setIConst(static_cast<int>(constant.getBConst())); break;
+              case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
+              default:       return false;
+            }
+            break;
+          case EbtUInt:
+            switch (constant.type)
+            {
+              case EbtInt:   setUConst(static_cast<unsigned int>(constant.getIConst())); break;
+              case EbtUInt:  setUConst(static_cast<unsigned int>(constant.getUConst())); break;
+              case EbtBool:  setUConst(static_cast<unsigned int>(constant.getBConst())); break;
+              case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
+              default:       return false;
+            }
+            break;
+          case EbtBool:
+            switch (constant.type)
+            {
+              case EbtInt:   setBConst(constant.getIConst() != 0);    break;
+              case EbtUInt:  setBConst(constant.getUConst() != 0);    break;
+              case EbtBool:  setBConst(constant.getBConst());         break;
+              case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
+              default:       return false;
+            }
+            break;
+          case EbtStruct:    // Struct fields don't get cast
+            switch (constant.type)
+            {
+              case EbtInt:   setIConst(constant.getIConst()); break;
+              case EbtUInt:  setUConst(constant.getUConst()); break;
+              case EbtBool:  setBConst(constant.getBConst()); break;
+              case EbtFloat: setFConst(constant.getFConst()); break;
+              default:       return false;
+            }
+            break;
+          default:
+            return false;
+        }
+
+        return true;
+    }
+
     void setIConst(int i) {iConst = i; type = EbtInt; }
     void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
     void setFConst(float f) {fConst = f; type = EbtFloat; }
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/ForLoopUnroll.cpp b/src/compiler/translator/ForLoopUnroll.cpp
index 5cb5164..f3be20d 100644
--- a/src/compiler/translator/ForLoopUnroll.cpp
+++ b/src/compiler/translator/ForLoopUnroll.cpp
@@ -43,8 +43,8 @@
         // Check if loop index type is integer.
         // This is called after ValidateLimitations pass, so all the calls
         // should be valid. See ValidateLimitations::validateForLoopInit().
-        TIntermSequence& declSeq = node->getInit()->getAsAggregate()->getSequence();
-        TIntermSymbol* symbol = declSeq[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
+        TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence();
+        TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
         if (symbol->getBasicType() == EbtInt)
             node->setUnrollFlag(true);
     }
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 27e96f4..10b21e6 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -12,9 +12,10 @@
 
 #include "compiler/translator/Initialize.h"
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
+#include "angle_gl.h"
 
-void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)
+void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)
 {
     TType *float1 = new TType(EbtFloat);
     TType *float2 = new TType(EbtFloat, 2);
@@ -362,7 +363,7 @@
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeGradEXT", samplerCube, float3, float3, float3);
     }
 
-    if (type == SH_FRAGMENT_SHADER)
+    if (type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, float1);
@@ -396,7 +397,7 @@
         }
     }
 
-    if(type == SH_VERTEX_SHADER)
+    if(type == GL_VERTEX_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, float1);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, float1);
@@ -426,7 +427,7 @@
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
 
-    if (type == SH_FRAGMENT_SHADER)
+    if (type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1);
@@ -447,7 +448,7 @@
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3, float1);
 
-    if (type == SH_FRAGMENT_SHADER)
+    if (type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4, float1);
@@ -462,7 +463,7 @@
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
 
-    if(type == SH_FRAGMENT_SHADER)
+    if(type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "dFdx", float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "dFdx", float2);
@@ -485,7 +486,7 @@
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2);
 
-    if(type == SH_FRAGMENT_SHADER)
+    if(type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, float1);
@@ -498,7 +499,7 @@
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2);
 
-    if(type == SH_FRAGMENT_SHADER)
+    if(type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2, float1);
@@ -566,10 +567,10 @@
     fields->push_back(diff);
     TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
     TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
-    symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters);
+    symbolTable.insert(COMMON_BUILTINS, depthRangeParameters);
     TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
     depthRange->setQualifier(EvqUniform);
-    symbolTable.insert(COMMON_BUILTINS, *depthRange);
+    symbolTable.insert(COMMON_BUILTINS, depthRange);
 
     //
     // Implementation dependent built-in constants.
@@ -594,7 +595,7 @@
     symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", resources.MaxProgramTexelOffset);
 }
 
-void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
+void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
                       const ShBuiltInResources &resources,
                       TSymbolTable &symbolTable)
 {
@@ -603,32 +604,32 @@
     // the built-in header files.
     //
     switch(type) {
-    case SH_FRAGMENT_SHADER:
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
+    case GL_FRAGMENT_SHADER:
+        symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
+        symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
+        symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
 
         //
         // In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available.
         // Instead, css_MixColor and css_ColorMatrix are available.
         //
         if (spec != SH_CSS_SHADERS_SPEC) {
-            symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
-            symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
+            symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
+            symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
             if (resources.EXT_frag_depth) {
-                symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
+                symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
                 symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_FragDepthEXT", "GL_EXT_frag_depth");
             }
         } else {
-            symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal,      4)));
-            symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal,      4, 4)));
+            symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal,      4)));
+            symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal,      4, 4)));
         }
 
         break;
 
-    case SH_VERTEX_SHADER:
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition,    4)));
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
+    case GL_VERTEX_SHADER:
+        symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition,    4)));
+        symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
         break;
 
     default: assert(false && "Language not supported");
@@ -694,9 +695,9 @@
 
     // Map language-specific operators.
     switch(type) {
-    case SH_VERTEX_SHADER:
+    case GL_VERTEX_SHADER:
         break;
-    case SH_FRAGMENT_SHADER:
+    case GL_FRAGMENT_SHADER:
         if (resources.OES_standard_derivatives)
         {
             symbolTable.relateToOperator(ESSL1_BUILTINS, "dFdx",   EOpDFdx);
@@ -730,12 +731,12 @@
 
     // Finally add resource-specific variables.
     switch(type) {
-    case SH_FRAGMENT_SHADER:
+    case GL_FRAGMENT_SHADER:
         if (spec != SH_CSS_SHADERS_SPEC) {
             // Set up gl_FragData.  The array size.
             TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
             fragData.setArraySize(resources.MaxDrawBuffers);
-            symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData"), fragData));
+            symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
         }
         break;
     default: break;
diff --git a/src/compiler/translator/Initialize.h b/src/compiler/translator/Initialize.h
index b564286..cc1862c 100644
--- a/src/compiler/translator/Initialize.h
+++ b/src/compiler/translator/Initialize.h
@@ -8,12 +8,12 @@
 #define _INITIALIZE_INCLUDED_
 
 #include "compiler/translator/Common.h"
-#include "compiler/translator/ShHandle.h"
+#include "compiler/translator/Compiler.h"
 #include "compiler/translator/SymbolTable.h"
 
-void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table);
+void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table);
 
-void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
+void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
                       const ShBuiltInResources& resources,
                       TSymbolTable& symbolTable);
 
diff --git a/src/compiler/translator/InitializeDll.cpp b/src/compiler/translator/InitializeDll.cpp
index 43f8178..c984306 100644
--- a/src/compiler/translator/InitializeDll.cpp
+++ b/src/compiler/translator/InitializeDll.cpp
@@ -5,10 +5,12 @@
 //
 
 #include "compiler/translator/InitializeDll.h"
-
 #include "compiler/translator/InitializeGlobals.h"
 #include "compiler/translator/InitializeParseContext.h"
-#include "compiler/translator/osinclude.h"
+
+#include "common/platform.h"
+
+#include <assert.h>
 
 bool InitProcess()
 {
diff --git a/src/compiler/translator/InitializeParseContext.cpp b/src/compiler/translator/InitializeParseContext.cpp
index b4defae..c35cedb 100644
--- a/src/compiler/translator/InitializeParseContext.cpp
+++ b/src/compiler/translator/InitializeParseContext.cpp
@@ -6,35 +6,37 @@
 
 #include "compiler/translator/InitializeParseContext.h"
 
-#include "compiler/translator/osinclude.h"
+#include "common/tls.h"
 
-OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+#include <assert.h>
+
+TLSIndex GlobalParseContextIndex = TLS_INVALID_INDEX;
 
 bool InitializeParseContextIndex()
 {
-    assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
+    assert(GlobalParseContextIndex == TLS_INVALID_INDEX);
 
-    GlobalParseContextIndex = OS_AllocTLSIndex();
-    return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
+    GlobalParseContextIndex = CreateTLSIndex();
+    return GlobalParseContextIndex != TLS_INVALID_INDEX;
 }
 
 void FreeParseContextIndex()
 {
-    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+    assert(GlobalParseContextIndex != TLS_INVALID_INDEX);
 
-    OS_FreeTLSIndex(GlobalParseContextIndex);
-    GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+    DestroyTLSIndex(GlobalParseContextIndex);
+    GlobalParseContextIndex = TLS_INVALID_INDEX;
 }
 
 void SetGlobalParseContext(TParseContext* context)
 {
-    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
-    OS_SetTLSValue(GlobalParseContextIndex, context);
+    assert(GlobalParseContextIndex != TLS_INVALID_INDEX);
+    SetTLSValue(GlobalParseContextIndex, context);
 }
 
 TParseContext* GetGlobalParseContext()
 {
-    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
-    return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
+    assert(GlobalParseContextIndex != TLS_INVALID_INDEX);
+    return static_cast<TParseContext*>(GetTLSValue(GlobalParseContextIndex));
 }
 
diff --git a/src/compiler/translator/InitializeVariables.cpp b/src/compiler/translator/InitializeVariables.cpp
index 115c561..0e3e2eb 100644
--- a/src/compiler/translator/InitializeVariables.cpp
+++ b/src/compiler/translator/InitializeVariables.cpp
@@ -10,7 +10,7 @@
 namespace
 {
 
-TIntermConstantUnion* constructFloatConstUnionNode(const TType& type)
+TIntermConstantUnion *constructFloatConstUnionNode(const TType &type)
 {
     TType myType = type;
     unsigned char size = myType.getNominalSize();
@@ -26,7 +26,7 @@
     return node;
 }
 
-TIntermConstantUnion* constructIndexNode(int index)
+TIntermConstantUnion *constructIndexNode(int index)
 {
     ConstantUnion *u = new ConstantUnion[1];
     u[0].setIConst(index);
@@ -38,7 +38,7 @@
 
 }  // namespace anonymous
 
-bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate* node)
+bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node)
 {
     bool visitChildren = !mCodeInserted;
     switch (node->getOp())
@@ -51,17 +51,17 @@
         ASSERT(visit == PreVisit);
         if (node->getName() == "main(")
         {
-            TIntermSequence &sequence = node->getSequence();
-            ASSERT((sequence.size() == 1) || (sequence.size() == 2));
+            TIntermSequence *sequence = node->getSequence();
+            ASSERT((sequence->size() == 1) || (sequence->size() == 2));
             TIntermAggregate *body = NULL;
-            if (sequence.size() == 1)
+            if (sequence->size() == 1)
             {
                 body = new TIntermAggregate(EOpSequence);
-                sequence.push_back(body);
+                sequence->push_back(body);
             }
             else
             {
-                body = sequence[1]->getAsAggregate();
+                body = (*sequence)[1]->getAsAggregate();
             }
             ASSERT(body);
             insertInitCode(body->getSequence());
@@ -76,18 +76,18 @@
     return visitChildren;
 }
 
-void InitializeVariables::insertInitCode(TIntermSequence& sequence)
+void InitializeVariables::insertInitCode(TIntermSequence *sequence)
 {
     for (size_t ii = 0; ii < mVariables.size(); ++ii)
     {
-        const InitVariableInfo& varInfo = mVariables[ii];
+        const InitVariableInfo &varInfo = mVariables[ii];
 
         if (varInfo.type.isArray())
         {
             for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index)
             {
                 TIntermBinary *assign = new TIntermBinary(EOpAssign);
-                sequence.insert(sequence.begin(), assign);
+                sequence->insert(sequence->begin(), assign);
 
                 TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
                 TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
@@ -104,7 +104,7 @@
         else
         {
             TIntermBinary *assign = new TIntermBinary(EOpAssign);
-            sequence.insert(sequence.begin(), assign);
+            sequence->insert(sequence->begin(), assign);
             TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
             assign->setLeft(symbol);
             TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
diff --git a/src/compiler/translator/InitializeVariables.h b/src/compiler/translator/InitializeVariables.h
index 1cd6d7e..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
 {
@@ -17,7 +17,7 @@
         TString name;
         TType type;
 
-        InitVariableInfo(const TString& _name, const TType& _type)
+        InitVariableInfo(const TString &_name, const TType &_type)
             : name(_name),
               type(_type)
         {
@@ -25,23 +25,23 @@
     };
     typedef TVector<InitVariableInfo> InitVariableInfoList;
 
-    InitializeVariables(const InitVariableInfoList& vars)
+    InitializeVariables(const InitVariableInfoList &vars)
         : mCodeInserted(false),
           mVariables(vars)
     {
     }
 
   protected:
-    virtual bool visitBinary(Visit visit, TIntermBinary* node) { return false; }
-    virtual bool visitUnary(Visit visit, TIntermUnary* node) { return false; }
-    virtual bool visitSelection(Visit visit, TIntermSelection* node) { return false; }
-    virtual bool visitLoop(Visit visit, TIntermLoop* node) { return false; }
-    virtual bool visitBranch(Visit visit, TIntermBranch* node) { return false; }
+    virtual bool visitBinary(Visit, TIntermBinary *node) { return false; }
+    virtual bool visitUnary(Visit, TIntermUnary *node) { return false; }
+    virtual bool visitSelection(Visit, TIntermSelection *node) { return false; }
+    virtual bool visitLoop(Visit, TIntermLoop *node) { return false; }
+    virtual bool visitBranch(Visit, TIntermBranch *node) { return false; }
 
     virtual bool visitAggregate(Visit visit, TIntermAggregate* node);
 
   private:
-    void insertInitCode(TIntermSequence& sequence);
+    void insertInitCode(TIntermSequence *sequence);
 
     InitVariableInfoList mVariables;
     bool mCodeInserted;
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/IntermNode.h b/src/compiler/translator/IntermNode.h
new file mode 100644
index 0000000..ec440da
--- /dev/null
+++ b/src/compiler/translator/IntermNode.h
@@ -0,0 +1,772 @@
+//
+// 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.
+//
+
+//
+// Definition of the in-memory high-level intermediate representation
+// of shaders.  This is a tree that parser creates.
+//
+// Nodes in the tree are defined as a hierarchy of classes derived from
+// TIntermNode. Each is a node in a tree.  There is no preset branching factor;
+// each node can have it's own type of list of children.
+//
+
+#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
+#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+#include <algorithm>
+#include <queue>
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/Types.h"
+#include "compiler/translator/ConstantUnion.h"
+
+//
+// Operators used by the high-level (parse tree) representation.
+//
+enum TOperator
+{
+    EOpNull,            // if in a node, should only mean a node is still being built
+    EOpSequence,        // denotes a list of statements, or parameters, etc.
+    EOpFunctionCall,
+    EOpFunction,        // For function definition
+    EOpParameters,      // an aggregate listing the parameters to a function
+
+    EOpDeclaration,
+    EOpInvariantDeclaration, // Specialized declarations for attributing invariance
+    EOpPrototype,
+
+    //
+    // Unary operators
+    //
+
+    EOpNegative,
+    EOpLogicalNot,
+    EOpVectorLogicalNot,
+
+    EOpPostIncrement,
+    EOpPostDecrement,
+    EOpPreIncrement,
+    EOpPreDecrement,
+
+    //
+    // binary operations
+    //
+
+    EOpAdd,
+    EOpSub,
+    EOpMul,
+    EOpDiv,
+    EOpEqual,
+    EOpNotEqual,
+    EOpVectorEqual,
+    EOpVectorNotEqual,
+    EOpLessThan,
+    EOpGreaterThan,
+    EOpLessThanEqual,
+    EOpGreaterThanEqual,
+    EOpComma,
+
+    EOpVectorTimesScalar,
+    EOpVectorTimesMatrix,
+    EOpMatrixTimesVector,
+    EOpMatrixTimesScalar,
+
+    EOpLogicalOr,
+    EOpLogicalXor,
+    EOpLogicalAnd,
+
+    EOpIndexDirect,
+    EOpIndexIndirect,
+    EOpIndexDirectStruct,
+    EOpIndexDirectInterfaceBlock,
+
+    EOpVectorSwizzle,
+
+    //
+    // Built-in functions potentially mapped to operators
+    //
+
+    EOpRadians,
+    EOpDegrees,
+    EOpSin,
+    EOpCos,
+    EOpTan,
+    EOpAsin,
+    EOpAcos,
+    EOpAtan,
+
+    EOpPow,
+    EOpExp,
+    EOpLog,
+    EOpExp2,
+    EOpLog2,
+    EOpSqrt,
+    EOpInverseSqrt,
+
+    EOpAbs,
+    EOpSign,
+    EOpFloor,
+    EOpCeil,
+    EOpFract,
+    EOpMod,
+    EOpMin,
+    EOpMax,
+    EOpClamp,
+    EOpMix,
+    EOpStep,
+    EOpSmoothStep,
+
+    EOpLength,
+    EOpDistance,
+    EOpDot,
+    EOpCross,
+    EOpNormalize,
+    EOpFaceForward,
+    EOpReflect,
+    EOpRefract,
+
+    EOpDFdx,            // Fragment only, OES_standard_derivatives extension
+    EOpDFdy,            // Fragment only, OES_standard_derivatives extension
+    EOpFwidth,          // Fragment only, OES_standard_derivatives extension
+
+    EOpMatrixTimesMatrix,
+
+    EOpAny,
+    EOpAll,
+
+    //
+    // Branch
+    //
+
+    EOpKill,            // Fragment only
+    EOpReturn,
+    EOpBreak,
+    EOpContinue,
+
+    //
+    // Constructors
+    //
+
+    EOpConstructInt,
+    EOpConstructUInt,
+    EOpConstructBool,
+    EOpConstructFloat,
+    EOpConstructVec2,
+    EOpConstructVec3,
+    EOpConstructVec4,
+    EOpConstructBVec2,
+    EOpConstructBVec3,
+    EOpConstructBVec4,
+    EOpConstructIVec2,
+    EOpConstructIVec3,
+    EOpConstructIVec4,
+    EOpConstructUVec2,
+    EOpConstructUVec3,
+    EOpConstructUVec4,
+    EOpConstructMat2,
+    EOpConstructMat3,
+    EOpConstructMat4,
+    EOpConstructStruct,
+
+    //
+    // moves
+    //
+
+    EOpAssign,
+    EOpInitialize,
+    EOpAddAssign,
+    EOpSubAssign,
+    EOpMulAssign,
+    EOpVectorTimesMatrixAssign,
+    EOpVectorTimesScalarAssign,
+    EOpMatrixTimesScalarAssign,
+    EOpMatrixTimesMatrixAssign,
+    EOpDivAssign
+};
+
+class TIntermTraverser;
+class TIntermAggregate;
+class TIntermBinary;
+class TIntermUnary;
+class TIntermConstantUnion;
+class TIntermSelection;
+class TIntermTyped;
+class TIntermSymbol;
+class TIntermLoop;
+class TInfoSink;
+class TIntermRaw;
+
+//
+// Base class for the tree nodes
+//
+class TIntermNode
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TIntermNode()
+    {
+        // TODO: Move this to TSourceLoc constructor
+        // after getting rid of TPublicType.
+        mLine.first_file = mLine.last_file = 0;
+        mLine.first_line = mLine.last_line = 0;
+    }
+    virtual ~TIntermNode() { }
+
+    const TSourceLoc &getLine() const { return mLine; }
+    void setLine(const TSourceLoc &l) { mLine = l; }
+
+    virtual void traverse(TIntermTraverser *) = 0;
+    virtual TIntermTyped *getAsTyped() { return 0; }
+    virtual TIntermConstantUnion *getAsConstantUnion() { return 0; }
+    virtual TIntermAggregate *getAsAggregate() { return 0; }
+    virtual TIntermBinary *getAsBinaryNode() { return 0; }
+    virtual TIntermUnary *getAsUnaryNode() { return 0; }
+    virtual TIntermSelection *getAsSelectionNode() { return 0; }
+    virtual TIntermSymbol *getAsSymbolNode() { return 0; }
+    virtual TIntermLoop *getAsLoopNode() { return 0; }
+    virtual TIntermRaw *getAsRawNode() { return 0; }
+
+    // Replace a child node. Return true if |original| is a child
+    // node and it is replaced; otherwise, return false.
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement) = 0;
+
+    // For traversing a tree in no particular order, but using
+    // heap memory.
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const = 0;
+
+  protected:
+    TSourceLoc mLine;
+};
+
+//
+// This is just to help yacc.
+//
+struct TIntermNodePair
+{
+    TIntermNode *node1;
+    TIntermNode *node2;
+};
+
+//
+// Intermediate class for nodes that have a type.
+//
+class TIntermTyped : public TIntermNode
+{
+  public:
+    TIntermTyped(const TType &t) : mType(t)  { }
+    virtual TIntermTyped *getAsTyped() { return this; }
+
+    virtual bool hasSideEffects() const = 0;
+
+    void setType(const TType &t) { mType = t; }
+    const TType &getType() const { return mType; }
+    TType *getTypePointer() { return &mType; }
+
+    TBasicType getBasicType() const { return mType.getBasicType(); }
+    TQualifier getQualifier() const { return mType.getQualifier(); }
+    TPrecision getPrecision() const { return mType.getPrecision(); }
+    int getCols() const { return mType.getCols(); }
+    int getRows() const { return mType.getRows(); }
+    int getNominalSize() const { return mType.getNominalSize(); }
+    int getSecondarySize() const { return mType.getSecondarySize(); }
+
+    bool isInterfaceBlock() const { return mType.isInterfaceBlock(); }
+    bool isMatrix() const { return mType.isMatrix(); }
+    bool isArray()  const { return mType.isArray(); }
+    bool isVector() const { return mType.isVector(); }
+    bool isScalar() const { return mType.isScalar(); }
+    bool isScalarInt() const { return mType.isScalarInt(); }
+    const char *getBasicString() const { return mType.getBasicString(); }
+    const char *getQualifierString() const { return mType.getQualifierString(); }
+    TString getCompleteString() const { return mType.getCompleteString(); }
+
+    int getArraySize() const { return mType.getArraySize(); }
+
+  protected:
+    TType mType;
+};
+
+//
+// Handle for, do-while, and while loops.
+//
+enum TLoopType
+{
+    ELoopFor,
+    ELoopWhile,
+    ELoopDoWhile
+};
+
+class TIntermLoop : public TIntermNode
+{
+  public:
+    TIntermLoop(TLoopType type,
+                TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr,
+                TIntermNode *body)
+        : mType(type),
+          mInit(init),
+          mCond(cond),
+          mExpr(expr),
+          mBody(body),
+          mUnrollFlag(false) { }
+
+    virtual TIntermLoop *getAsLoopNode() { return this; }
+    virtual void traverse(TIntermTraverser *);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    TLoopType getType() const { return mType; }
+    TIntermNode *getInit() { return mInit; }
+    TIntermTyped *getCondition() { return mCond; }
+    TIntermTyped *getExpression() { return mExpr; }
+    TIntermNode *getBody() { return mBody; }
+
+    void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
+    bool getUnrollFlag() const { return mUnrollFlag; }
+
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+
+  protected:
+    TLoopType mType;
+    TIntermNode *mInit;  // for-loop initialization
+    TIntermTyped *mCond; // loop exit condition
+    TIntermTyped *mExpr; // for-loop expression
+    TIntermNode *mBody;  // loop body
+
+    bool mUnrollFlag; // Whether the loop should be unrolled or not.
+};
+
+//
+// Handle break, continue, return, and kill.
+//
+class TIntermBranch : public TIntermNode
+{
+  public:
+    TIntermBranch(TOperator op, TIntermTyped *e)
+        : mFlowOp(op),
+          mExpression(e) { }
+
+    virtual void traverse(TIntermTraverser *);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    TOperator getFlowOp() { return mFlowOp; }
+    TIntermTyped* getExpression() { return mExpression; }
+
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+
+protected:
+    TOperator mFlowOp;
+    TIntermTyped *mExpression;  // non-zero except for "return exp;" statements
+};
+
+//
+// Nodes that correspond to symbols or constants in the source code.
+//
+class TIntermSymbol : public TIntermTyped
+{
+  public:
+    // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym.
+    // If sym comes from per process globalpoolallocator, then it causes increased memory usage
+    // per compile it is essential to use "symbol = sym" to assign to symbol
+    TIntermSymbol(int id, const TString &symbol, const TType &type)
+        : TIntermTyped(type),
+          mId(id)
+    {
+        mSymbol = symbol;
+    }
+
+    virtual bool hasSideEffects() const { return false; }
+
+    int getId() const { return mId; }
+    const TString &getSymbol() const { return mSymbol; }
+
+    void setId(int newId) { mId = newId; }
+
+    virtual void traverse(TIntermTraverser *);
+    virtual TIntermSymbol *getAsSymbolNode() { return this; }
+    virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
+
+  protected:
+    int mId;
+    TString mSymbol;
+};
+
+// A Raw node stores raw code, that the translator will insert verbatim
+// into the output stream. Useful for transformation operations that make
+// complex code that might not fit naturally into the GLSL model.
+class TIntermRaw : public TIntermTyped
+{
+  public:
+    TIntermRaw(const TType &type, const TString &rawText)
+        : TIntermTyped(type),
+          mRawText(rawText) { }
+
+    virtual bool hasSideEffects() const { return false; }
+
+    TString getRawText() const { return mRawText; }
+
+    virtual void traverse(TIntermTraverser *);
+
+    virtual TIntermRaw *getAsRawNode() { return this; }
+    virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
+
+  protected:
+    TString mRawText;
+};
+
+class TIntermConstantUnion : public TIntermTyped
+{
+  public:
+    TIntermConstantUnion(ConstantUnion *unionPointer, const TType &type)
+        : TIntermTyped(type),
+          mUnionArrayPointer(unionPointer) { }
+
+    virtual bool hasSideEffects() const { return false; }
+
+    ConstantUnion *getUnionArrayPointer() const { return mUnionArrayPointer; }
+
+    int getIConst(size_t index) const
+    {
+        return mUnionArrayPointer ? mUnionArrayPointer[index].getIConst() : 0;
+    }
+    unsigned int getUConst(size_t index) const
+    {
+        return mUnionArrayPointer ? mUnionArrayPointer[index].getUConst() : 0;
+    }
+    float getFConst(size_t index) const
+    {
+        return mUnionArrayPointer ? mUnionArrayPointer[index].getFConst() : 0.0f;
+    }
+    bool getBConst(size_t index) const
+    {
+        return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false;
+    }
+
+    virtual TIntermConstantUnion *getAsConstantUnion()  { return this; }
+    virtual void traverse(TIntermTraverser *);
+    virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+
+    TIntermTyped *fold(TOperator, TIntermTyped *, TInfoSink &);
+
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
+
+  protected:
+    ConstantUnion *mUnionArrayPointer;
+};
+
+//
+// Intermediate class for node types that hold operators.
+//
+class TIntermOperator : public TIntermTyped
+{
+  public:
+    TOperator getOp() const { return mOp; }
+    void setOp(TOperator op) { mOp = op; }
+
+    bool isAssignment() const;
+    bool isConstructor() const;
+
+    virtual bool hasSideEffects() const { return isAssignment(); }
+
+  protected:
+    TIntermOperator(TOperator op)
+        : TIntermTyped(TType(EbtFloat, EbpUndefined)),
+          mOp(op) {}
+    TIntermOperator(TOperator op, const TType &type)
+        : TIntermTyped(type),
+          mOp(op) {}
+
+    TOperator mOp;
+};
+
+//
+// Nodes for all the basic binary math operators.
+//
+class TIntermBinary : public TIntermOperator
+{
+  public:
+    TIntermBinary(TOperator op)
+        : TIntermOperator(op),
+          mAddIndexClamp(false) {}
+
+    virtual TIntermBinary *getAsBinaryNode() { return this; }
+    virtual void traverse(TIntermTraverser *);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    virtual bool hasSideEffects() const
+    {
+        return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
+    }
+
+    void setLeft(TIntermTyped *node) { mLeft = node; }
+    void setRight(TIntermTyped *node) { mRight = node; }
+    TIntermTyped *getLeft() const { return mLeft; }
+    TIntermTyped *getRight() const { return mRight; }
+    bool promote(TInfoSink &);
+
+    void setAddIndexClamp() { mAddIndexClamp = true; }
+    bool getAddIndexClamp() { return mAddIndexClamp; }
+
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+
+  protected:
+    TIntermTyped* mLeft;
+    TIntermTyped* mRight;
+
+    // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
+    bool mAddIndexClamp;
+};
+
+//
+// Nodes for unary math operators.
+//
+class TIntermUnary : public TIntermOperator
+{
+  public:
+    TIntermUnary(TOperator op, const TType &type)
+        : TIntermOperator(op, type),
+          mOperand(NULL),
+          mUseEmulatedFunction(false) {}
+    TIntermUnary(TOperator op)
+        : TIntermOperator(op),
+          mOperand(NULL),
+          mUseEmulatedFunction(false) {}
+
+    virtual void traverse(TIntermTraverser *);
+    virtual TIntermUnary *getAsUnaryNode() { return this; }
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    virtual bool hasSideEffects() const
+    {
+        return isAssignment() || mOperand->hasSideEffects();
+    }
+
+    void setOperand(TIntermTyped *operand) { mOperand = operand; }
+    TIntermTyped *getOperand() { return mOperand; }
+    bool promote(TInfoSink &);
+
+    void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
+    bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
+
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+
+  protected:
+    TIntermTyped *mOperand;
+
+    // If set to true, replace the built-in function call with an emulated one
+    // to work around driver bugs.
+    bool mUseEmulatedFunction;
+};
+
+typedef TVector<TIntermNode *> TIntermSequence;
+typedef TVector<int> TQualifierList;
+
+//
+// Nodes that operate on an arbitrary sized set of children.
+//
+class TIntermAggregate : public TIntermOperator
+{
+  public:
+    TIntermAggregate()
+        : TIntermOperator(EOpNull),
+          mUserDefined(false),
+          mUseEmulatedFunction(false) { }
+    TIntermAggregate(TOperator op)
+        : TIntermOperator(op),
+          mUseEmulatedFunction(false) { }
+    ~TIntermAggregate() { }
+
+    virtual TIntermAggregate *getAsAggregate() { return this; }
+    virtual void traverse(TIntermTraverser *);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    // Conservatively assume function calls and other aggregate operators have side-effects
+    virtual bool hasSideEffects() const { return true; }
+
+    TIntermSequence *getSequence() { return &mSequence; }
+
+    void setName(const TString &name) { mName = name; }
+    const TString &getName() const { return mName; }
+
+    void setUserDefined() { mUserDefined = true; }
+    bool isUserDefined() const { return mUserDefined; }
+
+    void setOptimize(bool optimize) { mOptimize = optimize; }
+    bool getOptimize() const { return mOptimize; }
+    void setDebug(bool debug) { mDebug = debug; }
+    bool getDebug() const { return mDebug; }
+
+    void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
+    bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
+
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+
+  protected:
+    TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
+    TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
+    TIntermSequence mSequence;
+    TString mName;
+    bool mUserDefined; // used for user defined function names
+
+    bool mOptimize;
+    bool mDebug;
+
+    // If set to true, replace the built-in function call with an emulated one
+    // to work around driver bugs.
+    bool mUseEmulatedFunction;
+};
+
+//
+// For if tests.  Simplified since there is no switch statement.
+//
+class TIntermSelection : public TIntermTyped
+{
+  public:
+    TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB)
+        : TIntermTyped(TType(EbtVoid, EbpUndefined)),
+          mCondition(cond),
+          mTrueBlock(trueB),
+          mFalseBlock(falseB) {}
+    TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB,
+                     const TType &type)
+        : TIntermTyped(type),
+          mCondition(cond),
+          mTrueBlock(trueB),
+          mFalseBlock(falseB) {}
+
+    virtual void traverse(TIntermTraverser *);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    // Conservatively assume selections have side-effects
+    virtual bool hasSideEffects() const { return true; }
+
+    bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
+    TIntermNode *getCondition() const { return mCondition; }
+    TIntermNode *getTrueBlock() const { return mTrueBlock; }
+    TIntermNode *getFalseBlock() const { return mFalseBlock; }
+    TIntermSelection *getAsSelectionNode() { return this; }
+
+    virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+
+protected:
+    TIntermTyped *mCondition;
+    TIntermNode *mTrueBlock;
+    TIntermNode *mFalseBlock;
+};
+
+enum Visit
+{
+    PreVisit,
+    InVisit,
+    PostVisit
+};
+
+//
+// For traversing the tree.  User should derive from this,
+// put their traversal specific data in it, and then pass
+// it to a Traverse method.
+//
+// When using this, just fill in the methods for nodes you want visited.
+// Return false from a pre-visit to skip visiting that node's subtree.
+//
+class TIntermTraverser
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    // TODO(zmo): remove default values.
+    TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false,
+                     bool rightToLeft = false)
+        : preVisit(preVisit),
+          inVisit(inVisit),
+          postVisit(postVisit),
+          rightToLeft(rightToLeft),
+          mDepth(0),
+          mMaxDepth(0) {}
+    virtual ~TIntermTraverser() {}
+
+    virtual void visitSymbol(TIntermSymbol *) {}
+    virtual void visitRaw(TIntermRaw *) {}
+    virtual void visitConstantUnion(TIntermConstantUnion *) {}
+    virtual bool visitBinary(Visit, TIntermBinary *) { return true; }
+    virtual bool visitUnary(Visit, TIntermUnary *) { return true; }
+    virtual bool visitSelection(Visit, TIntermSelection *) { return true; }
+    virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; }
+    virtual bool visitLoop(Visit, TIntermLoop *) { return true; }
+    virtual bool visitBranch(Visit, TIntermBranch *) { return true; }
+
+    int getMaxDepth() const { return mMaxDepth; }
+
+    void incrementDepth(TIntermNode *current)
+    {
+        mDepth++;
+        mMaxDepth = std::max(mMaxDepth, mDepth);
+        mPath.push_back(current);
+    }
+
+    void decrementDepth()
+    {
+        mDepth--;
+        mPath.pop_back();
+    }
+
+    TIntermNode *getParentNode()
+    {
+        return mPath.size() == 0 ? NULL : mPath.back();
+    }
+
+    // Return the original name if hash function pointer is NULL;
+    // otherwise return the hashed name.
+    static TString hash(const TString& name, ShHashFunction64 hashFunction);
+
+    const bool preVisit;
+    const bool inVisit;
+    const bool postVisit;
+    const bool rightToLeft;
+
+  protected:
+    int mDepth;
+    int mMaxDepth;
+
+    // All the nodes from root to the current node's parent during traversing.
+    TVector<TIntermNode *> mPath;
+};
+
+//
+// For traversing the tree, and computing max depth.
+// Takes a maximum depth limit to prevent stack overflow.
+//
+class TMaxDepthTraverser : public TIntermTraverser
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TMaxDepthTraverser(int depthLimit)
+        : TIntermTraverser(true, true, false, false),
+          mDepthLimit(depthLimit) { }
+
+    virtual bool visitBinary(Visit, TIntermBinary *) { return depthCheck(); }
+    virtual bool visitUnary(Visit, TIntermUnary *) { return depthCheck(); }
+    virtual bool visitSelection(Visit, TIntermSelection *) { return depthCheck(); }
+    virtual bool visitAggregate(Visit, TIntermAggregate *) { return depthCheck(); }
+    virtual bool visitLoop(Visit, TIntermLoop *) { return depthCheck(); }
+    virtual bool visitBranch(Visit, TIntermBranch *) { return depthCheck(); }
+
+protected:
+    bool depthCheck() const { return mMaxDepth < mDepthLimit; }
+
+    int mDepthLimit;
+};
+
+#endif  // COMPILER_TRANSLATOR_INTERMEDIATE_H_
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index 69f87c3..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
@@ -55,25 +55,25 @@
 
         if (it->rightToLeft)
         {
-            if (right)
-                right->traverse(it);
+            if (mRight)
+                mRight->traverse(it);
 
             if (it->inVisit)
                 visit = it->visitBinary(InVisit, this);
 
-            if (visit && left)
-                left->traverse(it);
+            if (visit && mLeft)
+                mLeft->traverse(it);
         }
         else
         {
-            if (left)
-                left->traverse(it);
+            if (mLeft)
+                mLeft->traverse(it);
 
             if (it->inVisit)
                 visit = it->visitBinary(InVisit, this);
 
-            if (visit && right)
-                right->traverse(it);
+            if (visit && mRight)
+                mRight->traverse(it);
         }
 
         it->decrementDepth();
@@ -99,7 +99,7 @@
 
     if (visit) {
         it->incrementDepth(this);
-        operand->traverse(it);
+        mOperand->traverse(it);
         it->decrementDepth();
     }
 
@@ -123,26 +123,28 @@
 
         if (it->rightToLeft)
         {
-            for (TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++)
+            for (TIntermSequence::reverse_iterator sit = mSequence.rbegin();
+                 sit != mSequence.rend(); sit++)
             {
                 (*sit)->traverse(it);
 
                 if (visit && it->inVisit)
                 {
-                    if (*sit != sequence.front())
+                    if (*sit != mSequence.front())
                         visit = it->visitAggregate(InVisit, this);
                 }
             }
         }
         else
         {
-            for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+            for (TIntermSequence::iterator sit = mSequence.begin();
+                 sit != mSequence.end(); sit++)
             {
                 (*sit)->traverse(it);
 
                 if (visit && it->inVisit)
                 {
-                    if (*sit != sequence.back())
+                    if (*sit != mSequence.back())
                         visit = it->visitAggregate(InVisit, this);
                 }
             }
@@ -165,20 +167,24 @@
     if (it->preVisit)
         visit = it->visitSelection(PreVisit, this);
 
-    if (visit) {
+    if (visit)
+    {
         it->incrementDepth(this);
-        if (it->rightToLeft) {
-            if (falseBlock)
-                falseBlock->traverse(it);
-            if (trueBlock)
-                trueBlock->traverse(it);
-            condition->traverse(it);
-        } else {
-            condition->traverse(it);
-            if (trueBlock)
-                trueBlock->traverse(it);
-            if (falseBlock)
-                falseBlock->traverse(it);
+        if (it->rightToLeft)
+        {
+            if (mFalseBlock)
+                mFalseBlock->traverse(it);
+            if (mTrueBlock)
+                mTrueBlock->traverse(it);
+            mCondition->traverse(it);
+        }
+        else
+        {
+            mCondition->traverse(it);
+            if (mTrueBlock)
+                mTrueBlock->traverse(it);
+            if (mFalseBlock)
+                mFalseBlock->traverse(it);
         }
         it->decrementDepth();
     }
@@ -203,31 +209,31 @@
 
         if (it->rightToLeft)
         {
-            if (expr)
-                expr->traverse(it);
+            if (mExpr)
+                mExpr->traverse(it);
 
-            if (body)
-                body->traverse(it);
+            if (mBody)
+                mBody->traverse(it);
 
-            if (cond)
-                cond->traverse(it);
+            if (mCond)
+                mCond->traverse(it);
 
-            if (init)
-                init->traverse(it);
+            if (mInit)
+                mInit->traverse(it);
         }
         else
         {
-            if (init)
-                init->traverse(it);
+            if (mInit)
+                mInit->traverse(it);
 
-            if (cond)
-                cond->traverse(it);
+            if (mCond)
+                mCond->traverse(it);
 
-            if (body)
-                body->traverse(it);
+            if (mBody)
+                mBody->traverse(it);
 
-            if (expr)
-                expr->traverse(it);
+            if (mExpr)
+                mExpr->traverse(it);
         }
 
         it->decrementDepth();
@@ -247,9 +253,9 @@
     if (it->preVisit)
         visit = it->visitBranch(PreVisit, this);
 
-    if (visit && expression) {
+    if (visit && mExpression) {
         it->incrementDepth(this);
-        expression->traverse(it);
+        mExpression->traverse(it);
         it->decrementDepth();
     }
 
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index 9df2afc..ef4f833 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -12,124 +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"
 
-bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray);
-
-static TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
-{
-    return left > right ? left : right;
-}
-
-const char* getOperatorString(TOperator op)
-{
-    switch (op) {
-      case EOpInitialize: return "=";
-      case EOpAssign: return "=";
-      case EOpAddAssign: return "+=";
-      case EOpSubAssign: return "-=";
-      case EOpDivAssign: return "/=";
-
-      // Fall-through.
-      case EOpMulAssign: 
-      case EOpVectorTimesMatrixAssign:
-      case EOpVectorTimesScalarAssign:
-      case EOpMatrixTimesScalarAssign:
-      case EOpMatrixTimesMatrixAssign: return "*=";
-
-      // Fall-through.
-      case EOpIndexDirect:
-      case EOpIndexIndirect: return "[]";
-
-      case EOpIndexDirectStruct:
-      case EOpIndexDirectInterfaceBlock: return ".";
-      case EOpVectorSwizzle: return ".";
-      case EOpAdd: return "+";
-      case EOpSub: return "-";
-      case EOpMul: return "*";
-      case EOpDiv: return "/";
-      case EOpMod: UNIMPLEMENTED(); break;
-      case EOpEqual: return "==";
-      case EOpNotEqual: return "!=";
-      case EOpLessThan: return "<";
-      case EOpGreaterThan: return ">";
-      case EOpLessThanEqual: return "<=";
-      case EOpGreaterThanEqual: return ">=";
-
-      // Fall-through.
-      case EOpVectorTimesScalar:
-      case EOpVectorTimesMatrix:
-      case EOpMatrixTimesVector:
-      case EOpMatrixTimesScalar:
-      case EOpMatrixTimesMatrix: return "*";
-
-      case EOpLogicalOr: return "||";
-      case EOpLogicalXor: return "^^";
-      case EOpLogicalAnd: return "&&";
-      case EOpNegative: return "-";
-      case EOpVectorLogicalNot: return "not";
-      case EOpLogicalNot: return "!";
-      case EOpPostIncrement: return "++";
-      case EOpPostDecrement: return "--";
-      case EOpPreIncrement: return "++";
-      case EOpPreDecrement: return "--";
-
-      // Fall-through.
-      case EOpConvIntToBool:
-      case EOpConvUIntToBool:
-      case EOpConvFloatToBool: return "bool";
- 
-      // Fall-through.
-      case EOpConvBoolToFloat:
-      case EOpConvUIntToFloat:
-      case EOpConvIntToFloat: return "float";
- 
-      // Fall-through.
-      case EOpConvFloatToInt:
-      case EOpConvUIntToInt:
-      case EOpConvBoolToInt: return "int";
-
-      // Fall-through.
-      case EOpConvIntToUInt:
-      case EOpConvFloatToUInt:
-      case EOpConvBoolToUInt: return "uint";
-
-      case EOpRadians: return "radians";
-      case EOpDegrees: return "degrees";
-      case EOpSin: return "sin";
-      case EOpCos: return "cos";
-      case EOpTan: return "tan";
-      case EOpAsin: return "asin";
-      case EOpAcos: return "acos";
-      case EOpAtan: return "atan";
-      case EOpExp: return "exp";
-      case EOpLog: return "log";
-      case EOpExp2: return "exp2";
-      case EOpLog2: return "log2";
-      case EOpSqrt: return "sqrt";
-      case EOpInverseSqrt: return "inversesqrt";
-      case EOpAbs: return "abs";
-      case EOpSign: return "sign";
-      case EOpFloor: return "floor";
-      case EOpCeil: return "ceil";
-      case EOpFract: return "fract";
-      case EOpLength: return "length";
-      case EOpNormalize: return "normalize";
-      case EOpDFdx: return "dFdx";
-      case EOpDFdy: return "dFdy";
-      case EOpFwidth: return "fwidth";
-      case EOpAny: return "any";
-      case EOpAll: return "all";
-
-      default: break;
-    }
-    return "";
-}
-
 ////////////////////////////////////////////////////////////////////////////
 //
 // First set of functions are to help build the intermediate representation.
@@ -143,9 +29,10 @@
 //
 // Returns the added node.
 //
-TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TSourceLoc& line)
+TIntermSymbol *TIntermediate::addSymbol(
+    int id, const TString &name, const TType &type, const TSourceLoc &line)
 {
-    TIntermSymbol* node = new TIntermSymbol(id, name, type);
+    TIntermSymbol *node = new TIntermSymbol(id, name, type);
     node->setLine(line);
 
     return node;
@@ -156,76 +43,71 @@
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
+TIntermTyped *TIntermediate::addBinaryMath(
+    TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
 {
-    switch (op) {
-        case EOpEqual:
-        case EOpNotEqual:
-            if (left->isArray())
-                return 0;
-            break;
-        case EOpLessThan:
-        case EOpGreaterThan:
-        case EOpLessThanEqual:
-        case EOpGreaterThanEqual:
-            if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) {
-                return 0;
-            }
-            break;
-        case EOpLogicalOr:
-        case EOpLogicalXor:
-        case EOpLogicalAnd:
-            if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) {
-                return 0;
-            }
-            break;
-        case EOpAdd:
-        case EOpSub:
-        case EOpDiv:
-        case EOpMul:
-            if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
-                return 0;
-        default: break;
+    switch (op)
+    {
+      case EOpEqual:
+      case EOpNotEqual:
+        if (left->isArray())
+            return NULL;
+        break;
+      case EOpLessThan:
+      case EOpGreaterThan:
+      case EOpLessThanEqual:
+      case EOpGreaterThanEqual:
+        if (left->isMatrix() || left->isArray() || left->isVector() ||
+            left->getBasicType() == EbtStruct)
+        {
+            return NULL;
+        }
+        break;
+      case EOpLogicalOr:
+      case EOpLogicalXor:
+      case EOpLogicalAnd:
+        if (left->getBasicType() != EbtBool ||
+            left->isMatrix() || left->isArray() || left->isVector())
+        {
+            return NULL;
+        }
+        break;
+      case EOpAdd:
+      case EOpSub:
+      case EOpDiv:
+      case EOpMul:
+        if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
+            return NULL;
+      default:
+        break;
     }
 
-    //
-    // First try converting the children to compatible types.
-    //
-    if (left->getType().getStruct() && right->getType().getStruct()) {
-        if (left->getType() != right->getType())
-            return 0;
-    } else {
-        TIntermTyped* child = addConversion(op, left->getType(), right);
-        if (child)
-            right = child;
-        else {
-            child = addConversion(op, right->getType(), left);
-            if (child)
-                left = child;
-            else
-                return 0;
-        }
+    if (left->getBasicType() != right->getBasicType())
+    {
+        return NULL;
     }
 
     //
     // Need a new node holding things together then.  Make
     // one and promote it to the right type.
     //
-    TIntermBinary* node = new TIntermBinary(op);
+    TIntermBinary *node = new TIntermBinary(op);
     node->setLine(line);
 
     node->setLeft(left);
     node->setRight(right);
-    if (!node->promote(infoSink))
-        return 0;
+    if (!node->promote(mInfoSink))
+        return NULL;
 
     //
     // See if we can fold constants.
     //
     TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
     TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
-    if (leftTempConstant && rightTempConstant) {
-        TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
+    if (leftTempConstant && rightTempConstant)
+    {
+        TIntermTyped *typedReturnNode =
+            leftTempConstant->fold(node->getOp(), rightTempConstant, mInfoSink);
 
         if (typedReturnNode)
             return typedReturnNode;
@@ -239,23 +121,24 @@
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
+TIntermTyped *TIntermediate::addAssign(
+    TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
 {
-    //
-    // Like adding binary math, except the conversion can only go
-    // from right to left.
-    //
-    TIntermBinary* node = new TIntermBinary(op);
+    if (left->getType().getStruct() || right->getType().getStruct())
+    {
+        if (left->getType() != right->getType())
+        {
+            return NULL;
+        }
+    }
+
+    TIntermBinary *node = new TIntermBinary(op);
     node->setLine(line);
 
-    TIntermTyped* child = addConversion(op, left->getType(), right);
-    if (child == 0)
-        return 0;
-
     node->setLeft(left);
-    node->setRight(child);
-    if (! node->promote(infoSink))
-        return 0;
+    node->setRight(right);
+    if (!node->promote(mInfoSink))
+        return NULL;
 
     return node;
 }
@@ -267,9 +150,10 @@
 // Returns the added node.
 // The caller should set the type of the returned node.
 //
-TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc& line)
+TIntermTyped *TIntermediate::addIndex(
+    TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &line)
 {
-    TIntermBinary* node = new TIntermBinary(op);
+    TIntermBinary *node = new TIntermBinary(op);
     node->setLine(line);
     node->setLeft(base);
     node->setRight(index);
@@ -284,67 +168,43 @@
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, const TSourceLoc& line)
+TIntermTyped *TIntermediate::addUnaryMath(
+    TOperator op, TIntermNode *childNode, const TSourceLoc &line)
 {
-    TIntermUnary* node;
-    TIntermTyped* child = childNode->getAsTyped();
+    TIntermUnary *node;
+    TIntermTyped *child = childNode->getAsTyped();
 
-    if (child == 0) {
-        infoSink.info.message(EPrefixInternalError, line, "Bad type in AddUnaryMath");
-        return 0;
+    if (child == NULL)
+    {
+        mInfoSink.info.message(EPrefixInternalError, line,
+                               "Bad type in AddUnaryMath");
+        return NULL;
     }
 
-    switch (op) {
-        case EOpLogicalNot:
-            if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
-                return 0;
-            }
-            break;
+    switch (op)
+    {
+      case EOpLogicalNot:
+        if (child->getType().getBasicType() != EbtBool ||
+            child->getType().isMatrix() ||
+            child->getType().isArray() ||
+            child->getType().isVector())
+        {
+            return NULL;
+        }
+        break;
 
-        case EOpPostIncrement:
-        case EOpPreIncrement:
-        case EOpPostDecrement:
-        case EOpPreDecrement:
-        case EOpNegative:
-            if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
-                return 0;
-        default: break;
-    }
-
-    //
-    // Do we need to promote the operand?
-    //
-    // Note: Implicit promotions were removed from the language.
-    //
-    TBasicType newType = EbtVoid;
-    switch (op) {
-        case EOpConstructInt:   newType = EbtInt;   break;
-        case EOpConstructUInt:  newType = EbtUInt;  break;
-        case EOpConstructBool:  newType = EbtBool;  break;
-        case EOpConstructFloat: newType = EbtFloat; break;
-        default: break;
-    }
-
-    if (newType != EbtVoid) {
-        child = addConversion(op, TType(newType, child->getPrecision(), EvqTemporary,
-            child->getNominalSize(),
-            child->getSecondarySize(),
-            child->isArray()),
-            child);
-        if (child == 0)
-            return 0;
-    }
-
-    //
-    // For constructors, we are now done, it's all in the conversion.
-    //
-    switch (op) {
-        case EOpConstructInt:
-        case EOpConstructUInt:
-        case EOpConstructBool:
-        case EOpConstructFloat:
-            return child;
-        default: break;
+      case EOpPostIncrement:
+      case EOpPreIncrement:
+      case EOpPostDecrement:
+      case EOpPreDecrement:
+      case EOpNegative:
+        if (child->getType().getBasicType() == EbtStruct ||
+            child->getType().isArray())
+        {
+            return NULL;
+        }
+      default:
+        break;
     }
 
     TIntermConstantUnion *childTempConstant = 0;
@@ -358,11 +218,12 @@
     node->setLine(line);
     node->setOperand(child);
 
-    if (! node->promote(infoSink))
+    if (!node->promote(mInfoSink))
         return 0;
 
-    if (childTempConstant)  {
-        TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink);
+    if (childTempConstant)
+    {
+        TIntermTyped *newChild = childTempConstant->fold(op, 0, mInfoSink);
 
         if (newChild)
             return newChild;
@@ -381,24 +242,30 @@
 // Returns an aggregate node, which could be the one passed in if
 // it was already an aggregate but no operator was set.
 //
-TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TSourceLoc& line)
+TIntermAggregate *TIntermediate::setAggregateOperator(
+    TIntermNode *node, TOperator op, const TSourceLoc &line)
 {
-    TIntermAggregate* aggNode;
+    TIntermAggregate *aggNode;
 
     //
     // Make sure we have an aggregate.  If not turn it into one.
     //
-    if (node) {
+    if (node)
+    {
         aggNode = node->getAsAggregate();
-        if (aggNode == 0 || aggNode->getOp() != EOpNull) {
+        if (aggNode == NULL || aggNode->getOp() != EOpNull)
+        {
             //
             // Make an aggregate containing this node.
             //
             aggNode = new TIntermAggregate();
-            aggNode->getSequence().push_back(node);
+            aggNode->getSequence()->push_back(node);
         }
-    } else
+    }
+    else
+    {
         aggNode = new TIntermAggregate();
+    }
 
     //
     // Set the operator.
@@ -410,162 +277,30 @@
 }
 
 //
-// Convert one type to another.
-//
-// Returns the node representing the conversion, which could be the same
-// node passed in if no conversion was needed.
-//
-// Return 0 if a conversion can't be done.
-//
-TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node)
-{
-    //
-    // Does the base type allow operation?
-    //
-    if (node->getBasicType() == EbtVoid ||
-        IsSampler(node->getBasicType()))
-    {
-        return 0;
-    }
-
-    //
-    // Otherwise, if types are identical, no problem
-    //
-    if (type == node->getType())
-        return node;
-
-    //
-    // If one's a structure, then no conversions.
-    //
-    if (type.getStruct() || node->getType().getStruct())
-        return 0;
-
-    //
-    // If one's an array, then no conversions.
-    //
-    if (type.isArray() || node->getType().isArray())
-        return 0;
-
-    TBasicType promoteTo;
-
-    switch (op) {
-        //
-        // Explicit conversions
-        //
-        case EOpConstructBool:
-            promoteTo = EbtBool;
-            break;
-        case EOpConstructFloat:
-            promoteTo = EbtFloat;
-            break;
-        case EOpConstructInt:
-            promoteTo = EbtInt;
-            break;
-        case EOpConstructUInt:
-            promoteTo = EbtUInt;
-            break;
-        default:
-            //
-            // implicit conversions were removed from the language.
-            //
-            if (type.getBasicType() != node->getType().getBasicType())
-                return 0;
-            //
-            // Size and structure could still differ, but that's
-            // handled by operator promotion.
-            //
-            return node;
-    }
-
-    if (node->getAsConstantUnion()) {
-
-        return (promoteConstantUnion(promoteTo, node->getAsConstantUnion()));
-    } else {
-
-        //
-        // Add a new newNode for the conversion.
-        //
-        TIntermUnary* newNode = 0;
-
-        TOperator newOp = EOpNull;
-        switch (promoteTo) {
-            case EbtFloat:
-                switch (node->getBasicType()) {
-                    case EbtInt:    newOp = EOpConvIntToFloat;  break;
-                    case EbtUInt:   newOp = EOpConvFloatToUInt; break;
-                    case EbtBool:   newOp = EOpConvBoolToFloat; break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
-                        return 0;
-                }
-                break;
-            case EbtBool:
-                switch (node->getBasicType()) {
-                    case EbtInt:    newOp = EOpConvIntToBool;   break;
-                    case EbtUInt:   newOp = EOpConvBoolToUInt;  break;
-                    case EbtFloat:  newOp = EOpConvFloatToBool; break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
-                        return 0;
-                }
-                break;
-            case EbtInt:
-                switch (node->getBasicType()) {
-                    case EbtUInt:   newOp = EOpConvUIntToInt;  break;
-                    case EbtBool:   newOp = EOpConvBoolToInt;  break;
-                    case EbtFloat:  newOp = EOpConvFloatToInt; break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
-                        return 0;
-                }
-                break;
-            case EbtUInt:
-                switch (node->getBasicType()) {
-                    case EbtInt:    newOp = EOpConvIntToUInt;   break;
-                    case EbtBool:   newOp = EOpConvBoolToUInt;  break;
-                    case EbtFloat:  newOp = EOpConvFloatToUInt; break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
-                        return 0;
-                }
-                break;
-            default:
-                infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion type");
-                return 0;
-        }
-
-        TType type(promoteTo, node->getPrecision(), EvqTemporary, node->getNominalSize(), node->getSecondarySize(), node->isArray());
-        newNode = new TIntermUnary(newOp, type);
-        newNode->setLine(node->getLine());
-        newNode->setOperand(node);
-
-        return newNode;
-    }
-}
-
-//
 // Safe way to combine two nodes into an aggregate.  Works with null pointers,
 // a node that's not a aggregate yet, etc.
 //
 // Returns the resulting aggregate, unless 0 was passed in for
 // both existing nodes.
 //
-TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& line)
+TIntermAggregate *TIntermediate::growAggregate(
+    TIntermNode *left, TIntermNode *right, const TSourceLoc &line)
 {
-    if (left == 0 && right == 0)
-        return 0;
+    if (left == NULL && right == NULL)
+        return NULL;
 
-    TIntermAggregate* aggNode = 0;
+    TIntermAggregate *aggNode = NULL;
     if (left)
         aggNode = left->getAsAggregate();
-    if (!aggNode || aggNode->getOp() != EOpNull) {
+    if (!aggNode || aggNode->getOp() != EOpNull)
+    {
         aggNode = new TIntermAggregate;
         if (left)
-            aggNode->getSequence().push_back(left);
+            aggNode->getSequence()->push_back(left);
     }
 
     if (right)
-        aggNode->getSequence().push_back(right);
+        aggNode->getSequence()->push_back(right);
 
     aggNode->setLine(line);
 
@@ -575,15 +310,16 @@
 //
 // Turn an existing node into an aggregate.
 //
-// Returns an aggregate, unless 0 was passed in for the existing node.
+// Returns an aggregate, unless NULL was passed in for the existing node.
 //
-TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& line)
+TIntermAggregate *TIntermediate::makeAggregate(
+    TIntermNode *node, const TSourceLoc &line)
 {
-    if (node == 0)
-        return 0;
+    if (node == NULL)
+        return NULL;
 
-    TIntermAggregate* aggNode = new TIntermAggregate;
-    aggNode->getSequence().push_back(node);
+    TIntermAggregate *aggNode = new TIntermAggregate;
+    aggNode->getSequence()->push_back(node);
 
     aggNode->setLine(line);
 
@@ -597,32 +333,45 @@
 //
 // Returns the selection node created.
 //
-TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& line)
+TIntermNode *TIntermediate::addSelection(
+    TIntermTyped *cond, TIntermNodePair nodePair, const TSourceLoc &line)
 {
     //
     // For compile time constant selections, prune the code and
     // test now.
     //
 
-    if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
+    if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion())
+    {
         if (cond->getAsConstantUnion()->getBConst(0) == true)
-            return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL;
+        {
+            return nodePair.node1 ? setAggregateOperator(
+                nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL;
+        }
         else
-            return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL;
+        {
+            return nodePair.node2 ? setAggregateOperator(
+                nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL;
+        }
     }
 
-    TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
+    TIntermSelection *node = new TIntermSelection(
+        cond, nodePair.node1, nodePair.node2);
     node->setLine(line);
 
     return node;
 }
 
-
-TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
+TIntermTyped *TIntermediate::addComma(
+    TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
 {
-    if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) {
+    if (left->getType().getQualifier() == EvqConst &&
+        right->getType().getQualifier() == EvqConst)
+    {
         return right;
-    } else {
+    }
+    else
+    {
         TIntermTyped *commaAggregate = growAggregate(left, right, line);
         commaAggregate->getAsAggregate()->setOp(EOpComma);
         commaAggregate->setType(right->getType());
@@ -638,27 +387,24 @@
 //
 // Returns the selection node created, or 0 if one could not be.
 //
-TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& line)
+TIntermTyped *TIntermediate::addSelection(
+    TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock,
+    const TSourceLoc &line)
 {
-    //
-    // Get compatible types.
-    //
-    TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
-    if (child)
-        falseBlock = child;
-    else {
-        child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
-        if (child)
-            trueBlock = child;
-        else
-            return 0;
+    if (!cond || !trueBlock || !falseBlock ||
+        trueBlock->getType() != falseBlock->getType())
+    {
+        return NULL;
     }
 
     //
     // See if all the operands are constant, then fold it otherwise not.
     //
 
-    if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
+    if (cond->getAsConstantUnion() &&
+        trueBlock->getAsConstantUnion() &&
+        falseBlock->getAsConstantUnion())
+    {
         if (cond->getAsConstantUnion()->getBConst(0))
             return trueBlock;
         else
@@ -668,7 +414,8 @@
     //
     // Make a selection node.
     //
-    TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
+    TIntermSelection *node = new TIntermSelection(
+        cond, trueBlock, falseBlock, trueBlock->getType());
     node->getTypePointer()->setQualifier(EvqTemporary);
     node->setLine(line);
 
@@ -681,29 +428,33 @@
 // Returns the constant union node created.
 //
 
-TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, const TSourceLoc& line)
+TIntermConstantUnion *TIntermediate::addConstantUnion(
+    ConstantUnion *unionArrayPointer, const TType &t, const TSourceLoc &line)
 {
-    TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
+    TIntermConstantUnion *node = new TIntermConstantUnion(unionArrayPointer, t);
     node->setLine(line);
 
     return node;
 }
 
-TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& line)
+TIntermTyped *TIntermediate::addSwizzle(
+    TVectorFields &fields, const TSourceLoc &line)
 {
 
-    TIntermAggregate* node = new TIntermAggregate(EOpSequence);
+    TIntermAggregate *node = new TIntermAggregate(EOpSequence);
 
     node->setLine(line);
-    TIntermConstantUnion* constIntNode;
-    TIntermSequence &sequenceVector = node->getSequence();
-    ConstantUnion* unionArray;
+    TIntermConstantUnion *constIntNode;
+    TIntermSequence *sequenceVector = node->getSequence();
+    ConstantUnion *unionArray;
 
-    for (int i = 0; i < fields.num; i++) {
+    for (int i = 0; i < fields.num; i++)
+    {
         unionArray = new ConstantUnion[1];
         unionArray->setIConst(fields.offsets[i]);
-        constIntNode = addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), line);
-        sequenceVector.push_back(constIntNode);
+        constIntNode = addConstantUnion(
+            unionArray, TType(EbtInt, EbpUndefined, EvqConst), line);
+        sequenceVector->push_back(constIntNode);
     }
 
     return node;
@@ -712,9 +463,11 @@
 //
 // Create loop nodes.
 //
-TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, const TSourceLoc& line)
+TIntermNode *TIntermediate::addLoop(
+    TLoopType type, TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr,
+    TIntermNode *body, const TSourceLoc &line)
 {
-    TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
+    TIntermNode *node = new TIntermLoop(type, init, cond, expr, body);
     node->setLine(line);
 
     return node;
@@ -723,14 +476,16 @@
 //
 // Add branches.
 //
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& line)
+TIntermBranch* TIntermediate::addBranch(
+    TOperator branchOp, const TSourceLoc &line)
 {
     return addBranch(branchOp, 0, line);
 }
 
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& line)
+TIntermBranch* TIntermediate::addBranch(
+    TOperator branchOp, TIntermTyped *expression, const TSourceLoc &line)
 {
-    TIntermBranch* node = new TIntermBranch(branchOp, expression);
+    TIntermBranch *node = new TIntermBranch(branchOp, expression);
     node->setLine(line);
 
     return node;
@@ -740,15 +495,15 @@
 // This is to be executed once the final root is put on top by the parsing
 // process.
 //
-bool TIntermediate::postProcess(TIntermNode* root)
+bool TIntermediate::postProcess(TIntermNode *root)
 {
-    if (root == 0)
+    if (root == NULL)
         return true;
 
     //
     // First, finish off the top level sequence, if any
     //
-    TIntermAggregate* aggRoot = root->getAsAggregate();
+    TIntermAggregate *aggRoot = root->getAsAggregate();
     if (aggRoot && aggRoot->getOp() == EOpNull)
         aggRoot->setOp(EOpSequence);
 
@@ -758,1078 +513,8 @@
 //
 // This deletes the tree.
 //
-void TIntermediate::remove(TIntermNode* root)
+void TIntermediate::remove(TIntermNode *root)
 {
     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(init, TIntermNode, original, replacement);
-    REPLACE_IF_IS(cond, TIntermTyped, original, replacement);
-    REPLACE_IF_IS(expr, TIntermTyped, original, replacement);
-    REPLACE_IF_IS(body, TIntermNode, original, replacement);
-    return false;
-}
-
-void TIntermLoop::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
-{
-    if (init)
-    {
-        nodeQueue->push(init);
-    }
-    if (cond)
-    {
-        nodeQueue->push(cond);
-    }
-    if (expr)
-    {
-        nodeQueue->push(expr);
-    }
-    if (body)
-    {
-        nodeQueue->push(body);
-    }
-}
-
-bool TIntermBranch::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(expression, TIntermTyped, original, replacement);
-    return false;
-}
-
-void TIntermBranch::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
-{
-    if (expression)
-    {
-        nodeQueue->push(expression);
-    }
-}
-
-bool TIntermBinary::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(left, TIntermTyped, original, replacement);
-    REPLACE_IF_IS(right, TIntermTyped, original, replacement);
-    return false;
-}
-
-void TIntermBinary::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
-{
-    if (left)
-    {
-        nodeQueue->push(left);
-    }
-    if (right)
-    {
-        nodeQueue->push(right);
-    }
-}
-
-bool TIntermUnary::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(operand, TIntermTyped, original, replacement);
-    return false;
-}
-
-void TIntermUnary::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
-{
-    if (operand)
-    {
-        nodeQueue->push(operand);
-    }
-}
-
-bool TIntermAggregate::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    for (size_t ii = 0; ii < sequence.size(); ++ii)
-    {
-        REPLACE_IF_IS(sequence[ii], TIntermNode, original, replacement);
-    }
-    return false;
-}
-
-void TIntermAggregate::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
-{
-    for (size_t childIndex = 0; childIndex < sequence.size(); childIndex++)
-    {
-        nodeQueue->push(sequence[childIndex]);
-    }
-}
-
-bool TIntermSelection::replaceChildNode(
-    TIntermNode *original, TIntermNode *replacement)
-{
-    REPLACE_IF_IS(condition, TIntermTyped, original, replacement);
-    REPLACE_IF_IS(trueBlock, TIntermNode, original, replacement);
-    REPLACE_IF_IS(falseBlock, TIntermNode, original, replacement);
-    return false;
-}
-
-void TIntermSelection::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
-{
-    if (condition)
-    {
-        nodeQueue->push(condition);
-    }
-    if (trueBlock)
-    {
-        nodeQueue->push(trueBlock);
-    }
-    if (falseBlock)
-    {
-        nodeQueue->push(falseBlock);
-    }
-}
-
-//
-// Say whether or not an operation node changes the value of a variable.
-//
-bool TIntermOperator::isAssignment() const
-{
-    switch (op) {
-        case EOpPostIncrement:
-        case EOpPostDecrement:
-        case EOpPreIncrement:
-        case EOpPreDecrement:
-        case EOpAssign:
-        case EOpAddAssign:
-        case EOpSubAssign:
-        case EOpMulAssign:
-        case EOpVectorTimesMatrixAssign:
-        case EOpVectorTimesScalarAssign:
-        case EOpMatrixTimesScalarAssign:
-        case EOpMatrixTimesMatrixAssign:
-        case EOpDivAssign:
-            return true;
-        default:
-            return false;
-    }
-}
-
-//
-// returns true if the operator is for one of the constructors
-//
-bool TIntermOperator::isConstructor() const
-{
-    switch (op) {
-        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 (op) {
-        case EOpLogicalNot:
-            if (operand->getBasicType() != EbtBool)
-                return false;
-            break;
-        case EOpNegative:
-        case EOpPostIncrement:
-        case EOpPostDecrement:
-        case EOpPreIncrement:
-        case EOpPreDecrement:
-            if (operand->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 (operand->getBasicType() != EbtFloat)
-                return false;
-    }
-
-    setType(operand->getType());
-    type.setQualifier(EvqTemporary);
-
-    return true;
-}
-
-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;
-    }
-}
-
-//
-// 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 (left->isArray() || right->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 (left->getBasicType() != right->getBasicType())
-        return false;
-
-    //
-    // Base assumption:  just make the type the same as the left
-    // operand.  Then only deviations from this need be coded.
-    //
-    setType(left->getType());
-
-    // The result gets promoted to the highest precision.
-    TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
-    getTypePointer()->setPrecision(higherPrecision);
-
-    // Binary operations results in temporary variables unless both
-    // operands are const.
-    if (left->getQualifier() != EvqConst || right->getQualifier() != EvqConst)
-    {
-        getTypePointer()->setQualifier(EvqTemporary);
-    }
-
-    const int nominalSize = std::max(left->getNominalSize(), right->getNominalSize());
-
-    //
-    // All scalars or structs. Code after this test assumes this case is removed!
-    //
-    if (nominalSize == 1)
-    {
-        switch (op)
-        {
-            //
-            // 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 (left->getBasicType() != EbtBool || right->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 = left->getBasicType();
-    switch (op)
-    {
-        case EOpMul:
-            if (!left->isMatrix() && right->isMatrix())
-            {
-                if (left->isVector())
-                {
-                    op = EOpVectorTimesMatrix;
-                    setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), 1));
-                }
-                else
-                {
-                    op = EOpMatrixTimesScalar;
-                    setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), right->getRows()));
-                }
-            }
-            else if (left->isMatrix() && !right->isMatrix())
-            {
-                if (right->isVector())
-                {
-                    op = EOpMatrixTimesVector;
-                    setType(TType(basicType, higherPrecision, EvqTemporary, left->getRows(), 1));
-                }
-                else
-                {
-                    op = EOpMatrixTimesScalar;
-                }
-            }
-            else if (left->isMatrix() && right->isMatrix())
-            {
-                op = EOpMatrixTimesMatrix;
-                setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), left->getRows()));
-            }
-            else if (!left->isMatrix() && !right->isMatrix())
-            {
-                if (left->isVector() && right->isVector())
-                {
-                    // leave as component product
-                }
-                else if (left->isVector() || right->isVector())
-                {
-                    op = EOpVectorTimesScalar;
-                    setType(TType(basicType, higherPrecision, EvqTemporary, nominalSize, 1));
-                }
-            }
-            else
-            {
-                infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
-                return false;
-            }
-
-            if (!validateMultiplication(op, left->getType(), right->getType()))
-            {
-                return false;
-            }
-            break;
-
-        case EOpMulAssign:
-            if (!left->isMatrix() && right->isMatrix())
-            {
-                if (left->isVector())
-                {
-                    op = EOpVectorTimesMatrixAssign;
-                }
-                else
-                {
-                    return false;
-                }
-            }
-            else if (left->isMatrix() && !right->isMatrix())
-            {
-                if (right->isVector())
-                {
-                    return false;
-                }
-                else
-                {
-                    op = EOpMatrixTimesScalarAssign;
-                }
-            }
-            else if (left->isMatrix() && right->isMatrix())
-            {
-                op = EOpMatrixTimesMatrixAssign;
-                setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), left->getRows()));
-            }
-            else if (!left->isMatrix() && !right->isMatrix())
-            {
-                if (left->isVector() && right->isVector())
-                {
-                    // leave as component product
-                }
-                else if (left->isVector() || right->isVector())
-                {
-                    if (! left->isVector())
-                        return false;
-                    op = EOpVectorTimesScalarAssign;
-                    setType(TType(basicType, higherPrecision, EvqTemporary, left->getNominalSize(), 1));
-                }
-            }
-            else
-            {
-                infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
-                return false;
-            }
-
-            if (!validateMultiplication(op, left->getType(), right->getType()))
-            {
-                return false;
-            }
-            break;
-
-        case EOpAssign:
-        case EOpInitialize:
-        case EOpAdd:
-        case EOpSub:
-        case EOpDiv:
-        case EOpAddAssign:
-        case EOpSubAssign:
-        case EOpDivAssign:
-            {
-                if ((left->isMatrix() && right->isVector()) ||
-                    (left->isVector() && right->isMatrix()))
-                    return false;
-
-                // Are the sizes compatible?
-                if (left->getNominalSize() != right->getNominalSize() || left->getSecondarySize() != right->getSecondarySize())
-                {
-                    // If the nominal size of operands do not match:
-                    // One of them must be scalar.
-                    if (!left->isScalar() && !right->isScalar())
-                        return false;
-
-                    // Operator cannot be of type pure assignment.
-                    if (op == EOpAssign || op == EOpInitialize)
-                        return false;
-                }
-
-                const int secondarySize = std::max(left->getSecondarySize(), right->getSecondarySize());
-
-                setType(TType(basicType, higherPrecision, EvqTemporary, nominalSize, secondarySize));
-            }
-            break;
-
-        case EOpEqual:
-        case EOpNotEqual:
-        case EOpLessThan:
-        case EOpGreaterThan:
-        case EOpLessThanEqual:
-        case EOpGreaterThanEqual:
-            if ((left->getNominalSize() != right->getNominalSize()) ||
-                (left->getSecondarySize() != right->getSecondarySize()))
-                return false;
-            setType(TType(EbtBool, EbpUndefined));
-            break;
-
-        default:
-            return false;
-    }
-    
-    return true;
-}
-
-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;
-}
-
-//
-// 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 0;
-
-    size_t objectSize = getType().getObjectSize();
-
-    if (constantNode)
-    {
-        // binary operations
-        TIntermConstantUnion *node = constantNode->getAsConstantUnion();
-        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
-        TType returnType = getType();
-
-        if (!rightUnionArray)
-            return 0;
-
-        // 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 = 0;
-        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 0;
-                }
-
-                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 0;
-                    }
-                }
-            }
-            break;
-
-          case EOpMatrixTimesVector:
-            {
-                if (node->getBasicType() != EbtFloat)
-                {
-                    infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix times vector");
-                    return 0;
-                }
-
-                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 0;
-                }
-
-                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 0;
-        }
-        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 0;
-                }
-                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 0;
-                }
-                break;
-
-              default:
-                return 0;
-            }
-        }
-        newNode = new TIntermConstantUnion(tempConstArray, getType());
-        newNode->setLine(getLine());
-        return newNode;
-    }
-}
-
-TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
-{
-    size_t size = node->getType().getObjectSize();
-
-    ConstantUnion *leftUnionArray = new ConstantUnion[size];
-
-    for (size_t i=0; i < size; i++) {
-
-        switch (promoteTo) {
-            case EbtFloat:
-                switch (node->getType().getBasicType()) {
-                    case EbtInt:
-                        leftUnionArray[i].setFConst(static_cast<float>(node->getIConst(i)));
-                        break;
-                    case EbtUInt:
-                        leftUnionArray[i].setFConst(static_cast<float>(node->getUConst(i)));
-                        break;
-                    case EbtBool:
-                        leftUnionArray[i].setFConst(static_cast<float>(node->getBConst(i)));
-                        break;
-                    case EbtFloat:
-                        leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
-                        break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
-                        return 0;
-                }
-                break;
-            case EbtInt:
-                switch (node->getType().getBasicType()) {
-                    case EbtInt:
-                        leftUnionArray[i].setIConst(static_cast<int>(node->getIConst(i)));
-                        break;
-                    case EbtUInt:
-                        leftUnionArray[i].setIConst(static_cast<int>(node->getUConst(i)));
-                        break;
-                    case EbtBool:
-                        leftUnionArray[i].setIConst(static_cast<int>(node->getBConst(i)));
-                        break;
-                    case EbtFloat:
-                        leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
-                        break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
-                        return 0;
-                }
-                break;
-            case EbtUInt:
-                switch (node->getType().getBasicType()) {
-                    case EbtInt:
-                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getIConst(i)));
-                        break;
-                    case EbtUInt:
-                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getUConst(i)));
-                        break;
-                    case EbtBool:
-                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getBConst(i)));
-                        break;
-                    case EbtFloat:
-                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getFConst(i)));
-                        break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
-                        return 0;
-                }
-                break;
-            case EbtBool:
-                switch (node->getType().getBasicType()) {
-                    case EbtInt:
-                        leftUnionArray[i].setBConst(node->getIConst(i) != 0);
-                        break;
-                    case EbtUInt:
-                        leftUnionArray[i].setBConst(node->getUConst(i) != 0);
-                        break;
-                    case EbtBool:
-                        leftUnionArray[i].setBConst(node->getBConst(i));
-                        break;
-                    case EbtFloat:
-                        leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
-                        break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
-                        return 0;
-                }
-
-                break;
-            default:
-                infoSink.info.message(EPrefixInternalError, node->getLine(), "Incorrect data type found");
-                return 0;
-        }
-
-    }
-
-    const TType& t = node->getType();
-
-    return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.getSecondarySize(), t.isArray()), node->getLine());
-}
-
-// 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/Intermediate.h
new file mode 100644
index 0000000..3b7e7bd
--- /dev/null
+++ b/src/compiler/translator/Intermediate.h
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
+#define COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
+
+#include "compiler/translator/IntermNode.h"
+
+struct TVectorFields
+{
+    int offsets[4];
+    int num;
+};
+
+//
+// Set of helper functions to help parse and build the tree.
+//
+class TInfoSink;
+class TIntermediate
+{
+  public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TIntermediate(TInfoSink &i)
+        : mInfoSink(i) { }
+
+    TIntermSymbol *addSymbol(
+        int id, const TString &, const TType &, const TSourceLoc &);
+    TIntermTyped *addBinaryMath(
+        TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
+    TIntermTyped *addAssign(
+        TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
+    TIntermTyped *addIndex(
+        TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
+    TIntermTyped *addUnaryMath(
+        TOperator op, TIntermNode *child, const TSourceLoc &);
+    TIntermAggregate *growAggregate(
+        TIntermNode *left, TIntermNode *right, const TSourceLoc &);
+    TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &);
+    TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &);
+    TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &);
+    TIntermTyped *addSelection(
+        TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &);
+    TIntermTyped *addComma(
+        TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
+    TIntermConstantUnion *addConstantUnion(ConstantUnion *, const TType &, const TSourceLoc &);
+    // TODO(zmo): Get rid of default value.
+    bool parseConstTree(const TSourceLoc &, TIntermNode *, ConstantUnion *,
+                        TOperator, TType, bool singleConstantParam = false);
+    TIntermNode *addLoop(TLoopType, TIntermNode *, TIntermTyped *, TIntermTyped *,
+                         TIntermNode *, const TSourceLoc &);
+    TIntermBranch *addBranch(TOperator, const TSourceLoc &);
+    TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
+    TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
+    bool postProcess(TIntermNode *);
+    void remove(TIntermNode *);
+    void outputTree(TIntermNode *);
+
+  private:
+    void operator=(TIntermediate &); // prevent assignments
+
+    TInfoSink & mInfoSink;
+};
+
+#endif  // COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
diff --git a/src/compiler/translator/LoopInfo.cpp b/src/compiler/translator/LoopInfo.cpp
index 226f1b2..d931a18 100644
--- a/src/compiler/translator/LoopInfo.cpp
+++ b/src/compiler/translator/LoopInfo.cpp
@@ -93,9 +93,9 @@
 
     // Here we assume all the operations are valid, because the loop node is
     // already validated in ValidateLimitations.
-    TIntermSequence &declSeq =
+    TIntermSequence *declSeq =
         node->getInit()->getAsAggregate()->getSequence();
-    TIntermBinary *declInit = declSeq[0]->getAsBinaryNode();
+    TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
     TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
 
     mId = symbol->getId();
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 6995594..6d07ccc 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -55,8 +55,6 @@
       mSymbolTable(symbolTable),
       mShaderVersion(shaderVersion)
 {
-    // Set up global scope.
-    mDeclaredStructs.push_back(ScopedDeclaredStructs());
 }
 
 void TOutputGLSLBase::writeTriplet(
@@ -83,14 +81,21 @@
 {
     TInfoSinkBase &out = objSink();
     TQualifier qualifier = type.getQualifier();
-    // TODO(alokp): Validate qualifier for variable declarations.
     if (qualifier != EvqTemporary && qualifier != EvqGlobal)
+    {
         out << type.getQualifierString() << " ";
+    }
     // Declare the struct if we have not done so already.
     if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
     {
-        declareStruct(type.getStruct());
-        mDeclaredStructs[mDeclaredStructs.size() - 1].push_back(type.getStruct());
+        TStructure *structure = type.getStruct();
+
+        declareStruct(structure);
+
+        if (!structure->name().empty())
+        {
+            mDeclaredStructs.insert(structure->uniqueId());
+        }
     }
     else
     {
@@ -293,8 +298,8 @@
         {
             out << ".";
             TIntermAggregate *rightChild = node->getRight()->getAsAggregate();
-            TIntermSequence &sequence = rightChild->getSequence();
-            for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
+            TIntermSequence *sequence = rightChild->getSequence();
+            for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); ++sit)
             {
                 TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
                 ASSERT(element->getBasicType() == EbtInt);
@@ -398,67 +403,6 @@
       case EOpPreIncrement: preString = "(++"; break;
       case EOpPreDecrement: preString = "(--"; break;
 
-      case EOpConvIntToBool:
-      case EOpConvFloatToBool:
-        switch (node->getOperand()->getType().getNominalSize())
-        {
-          case 1:
-            preString =  "bool(";
-            break;
-          case 2:
-            preString = "bvec2(";
-            break;
-          case 3:
-            preString = "bvec3(";
-            break;
-          case 4:
-            preString = "bvec4(";
-            break;
-          default:
-            UNREACHABLE();
-        }
-        break;
-      case EOpConvBoolToFloat:
-      case EOpConvIntToFloat:
-        switch (node->getOperand()->getType().getNominalSize())
-        {
-          case 1:
-            preString = "float(";
-            break;
-          case 2:
-            preString = "vec2(";
-            break;
-          case 3:
-            preString = "vec3(";
-            break;
-          case 4:
-            preString = "vec4(";
-            break;
-          default:
-            UNREACHABLE();
-        }
-        break;
-      case EOpConvFloatToInt:
-      case EOpConvBoolToInt:
-        switch (node->getOperand()->getType().getNominalSize())
-        {
-          case 1:
-            preString = "int(";
-            break;
-          case 2:
-            preString = "ivec2(";
-            break;
-          case 3:
-            preString = "ivec3(";
-            break;
-          case 4:
-            preString = "ivec4(";
-            break;
-          default:
-            UNREACHABLE();
-        }
-        break;
-
       case EOpRadians:
         preString = "radians(";
         break;
@@ -601,15 +545,14 @@
     {
       case EOpSequence:
         // Scope the sequences except when at the global scope.
-        if (depth > 0)
+        if (mDepth > 0)
         {
             out << "{\n";
-            pushDeclaredStructsScope();
         }
 
         incrementDepth(node);
-        for (TIntermSequence::const_iterator iter = node->getSequence().begin();
-             iter != node->getSequence().end(); ++iter)
+        for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+             iter != node->getSequence()->end(); ++iter)
         {
             TIntermNode *node = *iter;
             ASSERT(node != NULL);
@@ -621,9 +564,8 @@
         decrementDepth();
 
         // Scope the sequences except when at the global scope.
-        if (depth > 0)
+        if (mDepth > 0)
         {
-            popDeclaredStructsScope();
             out << "}\n";
         }
         visitChildren = false;
@@ -635,7 +577,7 @@
         out << " " << hashName(node->getName());
 
         out << "(";
-        writeFunctionParameters(node->getSequence());
+        writeFunctionParameters(*(node->getSequence()));
         out << ")";
 
         visitChildren = false;
@@ -650,7 +592,7 @@
         // Function definition node contains one or two children nodes
         // representing function parameters and function body. The latter
         // is not present in case of empty function bodies.
-        const TIntermSequence &sequence = node->getSequence();
+        const TIntermSequence &sequence = *(node->getSequence());
         ASSERT((sequence.size() == 1) || (sequence.size() == 2));
         TIntermSequence::const_iterator seqIter = sequence.begin();
 
@@ -683,7 +625,7 @@
         // Function parameters.
         ASSERT(visit == PreVisit);
         out << "(";
-        writeFunctionParameters(node->getSequence());
+        writeFunctionParameters(*(node->getSequence()));
         out << ")";
         visitChildren = false;
         break;
@@ -691,7 +633,7 @@
         // Variable declaration.
         if (visit == PreVisit)
         {
-            const TIntermSequence &sequence = node->getSequence();
+            const TIntermSequence &sequence = *(node->getSequence());
             const TIntermTyped *variable = sequence.front()->getAsTyped();
             writeVariableType(variable->getType());
             out << " ";
@@ -707,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;
@@ -873,10 +826,10 @@
         else
         {
             // Need to put a one-iteration loop here to handle break.
-            TIntermSequence &declSeq =
+            TIntermSequence *declSeq =
                 node->getInit()->getAsAggregate()->getSequence();
             TIntermSymbol *indexSymbol =
-                declSeq[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
+                (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
             TString name = hashVariableName(indexSymbol->getSymbol());
             out << "for (int " << name << " = 0; "
                 << name << " < 1; "
@@ -1035,17 +988,12 @@
 bool TOutputGLSLBase::structDeclared(const TStructure *structure) const
 {
     ASSERT(structure);
-    ASSERT(mDeclaredStructs.size() > 0);
-    for (size_t ii = mDeclaredStructs.size(); ii > 0; --ii)
+    if (structure->name().empty())
     {
-        const ScopedDeclaredStructs &scope = mDeclaredStructs[ii - 1];
-        for (size_t jj = 0; jj < scope.size(); ++jj)
-        {
-            if (scope[jj]->equals(*structure))
-                return true;
-        }
+        return false;
     }
-    return false;
+
+    return (mDeclaredStructs.count(structure->uniqueId()) > 0);
 }
 
 void TOutputGLSLBase::declareStruct(const TStructure *structure)
@@ -1067,14 +1015,3 @@
     out << "}";
 }
 
-void TOutputGLSLBase::pushDeclaredStructsScope()
-{
-    mDeclaredStructs.push_back(ScopedDeclaredStructs());
-}
-
-void TOutputGLSLBase::popDeclaredStructsScope()
-{
-    // We should never pop the global scope.
-    ASSERT(mDeclaredStructs.size() >= 2);
-    mDeclaredStructs.pop_back();
-}
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index ae40f85..e5174f5 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -7,9 +7,9 @@
 #ifndef CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
 #define CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
 
-#include <vector>
+#include <set>
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/LoopInfo.h"
 #include "compiler/translator/ParseContext.h"
 
@@ -56,22 +56,14 @@
   private:
     bool structDeclared(const TStructure *structure) const;
     void declareStruct(const TStructure *structure);
-    void pushDeclaredStructsScope();
-    void popDeclaredStructsScope();
 
     void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction);
 
     TInfoSinkBase &mObjSink;
     bool mDeclaringVariables;
 
-    // Structs are declared as the tree is traversed. This list contains all
-    // the structs already declared within a scope. It is maintained so that
-    // a struct is declared only once within a scope.
-    typedef std::vector<TStructure *> ScopedDeclaredStructs;
-    // This vector contains all the structs from the global scope to the
-    // current scope.  When the traverser exits a scope, the scope is discarded. 
-    typedef std::vector<ScopedDeclaredStructs> DeclaredStructs;
-    DeclaredStructs mDeclaredStructs;
+    // This set contains all the ids of the structs from every scope.
+    std::set<int> mDeclaredStructs;
 
     // Stack of loops that need to be unrolled.
     TLoopStack mLoopUnrollStack;
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 5cc2c14..a5ea715 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -17,6 +17,11 @@
 #include "compiler/translator/FlagStd140Structs.h"
 #include "compiler/translator/NodeSearch.h"
 #include "compiler/translator/RewriteElseBlocks.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/util.h"
+#include "compiler/translator/UniformHLSL.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/TranslatorHLSL.h"
 
 #include <algorithm>
 #include <cfloat>
@@ -69,18 +74,6 @@
     return name + "(";
 }
 
-const char *RegisterPrefix(const TType &type)
-{
-    if (IsSampler(type.getBasicType()))
-    {
-        return "s";
-    }
-    else
-    {
-        return "c";
-    }
-}
-
 bool OutputHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
 {
     if (sampler < rhs.sampler) return true;
@@ -101,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;
@@ -134,6 +129,7 @@
     mUsesDiscardRewriting = false;
     mUsesNestedBreak = false;
 
+    const ShBuiltInResources &resources = parentTranslator->getResources();
     mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
 
     mUniqueIndex = 0;
@@ -145,41 +141,43 @@
 
     mExcessiveLoopIndex = NULL;
 
+    mStructureHLSL = new StructureHLSL;
+    mUniformHLSL = new UniformHLSL(mStructureHLSL, parentTranslator);
+
     if (mOutputType == SH_HLSL9_OUTPUT)
     {
-        if (mContext.shaderType == SH_FRAGMENT_SHADER)
+        if (mContext.shaderType == GL_FRAGMENT_SHADER)
         {
-            mUniformRegister = 3;   // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront
+            // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront
+            mUniformHLSL->reserveUniformRegisters(3);
         }
         else
         {
-            mUniformRegister = 2;   // Reserve registers for dx_DepthRange and dx_ViewAdjust
+            // Reserve registers for dx_DepthRange and dx_ViewAdjust
+            mUniformHLSL->reserveUniformRegisters(2);
         }
     }
-    else
-    {
-        mUniformRegister = 0;
-    }
 
-    mSamplerRegister = 0;
-    mInterfaceBlockRegister = 2; // Reserve registers for the default uniform block and driver constants
-    mPaddingCounter = 0;
+    // Reserve registers for the default uniform block and driver constants
+    mUniformHLSL->reserveInterfaceBlockRegisters(2);
 }
 
 OutputHLSL::~OutputHLSL()
 {
-    delete mUnfoldShortCircuit;
+    SafeDelete(mUnfoldShortCircuit);
+    SafeDelete(mStructureHLSL);
+    SafeDelete(mUniformHLSL);
 }
 
 void OutputHLSL::output()
 {
-    mContainsLoopDiscontinuity = mContext.shaderType == SH_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
+    mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
     const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
     makeFlaggedStructMaps(flaggedStructs);
 
     // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
     // use a vertex attribute as a condition, and some related computation in the else block.
-    if (mOutputType == SH_HLSL9_OUTPUT && mContext.shaderType == SH_VERTEX_SHADER)
+    if (mOutputType == SH_HLSL9_OUTPUT && mContext.shaderType == GL_VERTEX_SHADER)
     {
         RewriteElseBlocks(mContext.treeRoot);
     }
@@ -218,29 +216,14 @@
     return mBody;
 }
 
-const std::vector<gl::Uniform> &OutputHLSL::getUniforms()
+const std::map<std::string, unsigned int> &OutputHLSL::getInterfaceBlockRegisterMap() const
 {
-    return mActiveUniforms;
+    return mUniformHLSL->getInterfaceBlockRegisterMap();
 }
 
-const std::vector<gl::InterfaceBlock> &OutputHLSL::getInterfaceBlocks() const
+const std::map<std::string, unsigned int> &OutputHLSL::getUniformRegisterMap() const
 {
-    return mActiveInterfaceBlocks;
-}
-
-const std::vector<gl::Attribute> &OutputHLSL::getOutputVariables() const
-{
-    return mActiveOutputVariables;
-}
-
-const std::vector<gl::Attribute> &OutputHLSL::getAttributes() const
-{
-    return mActiveAttributes;
-}
-
-const std::vector<gl::Varying> &OutputHLSL::getVaryings() const
-{
-    return mActiveVaryings;
+    return mUniformHLSL->getUniformRegisterMap();
 }
 
 int OutputHLSL::vectorSize(const TType &type) const
@@ -251,267 +234,6 @@
     return elementSize * arraySize;
 }
 
-TString OutputHLSL::interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field)
-{
-    if (interfaceBlock.hasInstanceName())
-    {
-        return interfaceBlock.name() + "." + field.name();
-    }
-    else
-    {
-        return field.name();
-    }
-}
-
-TString OutputHLSL::decoratePrivate(const TString &privateText)
-{
-    return "dx_" + privateText;
-}
-
-TString OutputHLSL::interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlock)
-{
-    return decoratePrivate(interfaceBlock.name()) + "_type";
-}
-
-TString OutputHLSL::interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex)
-{
-    if (!interfaceBlock.hasInstanceName())
-    {
-        return "";
-    }
-    else if (interfaceBlock.isArray())
-    {
-        return decoratePrivate(interfaceBlock.instanceName()) + "_" + str(arrayIndex);
-    }
-    else
-    {
-        return decorate(interfaceBlock.instanceName());
-    }
-}
-
-TString OutputHLSL::interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
-{
-    const TType &fieldType = *field.type();
-    const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
-    ASSERT(matrixPacking != EmpUnspecified);
-
-    if (fieldType.isMatrix())
-    {
-        // Use HLSL row-major packing for GLSL column-major matrices
-        const TString &matrixPackString = (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
-        return matrixPackString + " " + typeString(fieldType);
-    }
-    else if (fieldType.getStruct())
-    {
-        // Use HLSL row-major packing for GLSL column-major matrices
-        return structureTypeName(*fieldType.getStruct(), matrixPacking == EmpColumnMajor, blockStorage == EbsStd140);
-    }
-    else
-    {
-        return typeString(fieldType);
-    }
-}
-
-TString OutputHLSL::interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage)
-{
-    TString hlsl;
-
-    int elementIndex = 0;
-
-    for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++)
-    {
-        const TField &field = *interfaceBlock.fields()[typeIndex];
-        const TType &fieldType = *field.type();
-
-        if (blockStorage == EbsStd140)
-        {
-            // 2 and 3 component vector types in some cases need pre-padding
-            hlsl += std140PrePaddingString(fieldType, &elementIndex);
-        }
-
-        hlsl += "    " + interfaceBlockFieldTypeString(field, blockStorage) +
-                " " + decorate(field.name()) + arrayString(fieldType) + ";\n";
-
-        // must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff
-        if (blockStorage == EbsStd140)
-        {
-            const bool useHLSLRowMajorPacking = (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
-            hlsl += std140PostPaddingString(fieldType, useHLSLRowMajorPacking);
-        }
-    }
-
-    return hlsl;
-}
-
-TString OutputHLSL::interfaceBlockStructString(const TInterfaceBlock &interfaceBlock)
-{
-    const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
-
-    return "struct " + interfaceBlockStructNameString(interfaceBlock) + "\n"
-           "{\n" +
-           interfaceBlockFieldString(interfaceBlock, blockStorage) +
-           "};\n\n";
-}
-
-TString OutputHLSL::interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex)
-{
-    const TString &arrayIndexString =  (arrayIndex != GL_INVALID_INDEX ? decorate(str(arrayIndex)) : "");
-    const TString &blockName = interfaceBlock.name() + arrayIndexString;
-    TString hlsl;
-
-    hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n"
-            "{\n";
-
-    if (interfaceBlock.hasInstanceName())
-    {
-        hlsl += "    " + interfaceBlockStructNameString(interfaceBlock) + " " + interfaceBlockInstanceString(interfaceBlock, arrayIndex) + ";\n";
-    }
-    else
-    {
-        const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
-        hlsl += interfaceBlockFieldString(interfaceBlock, blockStorage);
-    }
-
-    hlsl += "};\n\n";
-
-    return hlsl;
-}
-
-TString OutputHLSL::std140PrePaddingString(const TType &type, int *elementIndex)
-{
-    if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
-    {
-        // no padding needed, HLSL will align the field to a new register
-        *elementIndex = 0;
-        return "";
-    }
-
-    const GLenum glType = glVariableType(type);
-    const int numComponents = gl::UniformComponentCount(glType);
-
-    if (numComponents >= 4)
-    {
-        // no padding needed, HLSL will align the field to a new register
-        *elementIndex = 0;
-        return "";
-    }
-
-    if (*elementIndex + numComponents > 4)
-    {
-        // no padding needed, HLSL will align the field to a new register
-        *elementIndex = numComponents;
-        return "";
-    }
-
-    TString padding;
-
-    const int alignment = numComponents == 3 ? 4 : numComponents;
-    const int paddingOffset = (*elementIndex % alignment);
-
-    if (paddingOffset != 0)
-    {
-        // padding is neccessary
-        for (int paddingIndex = paddingOffset; paddingIndex < alignment; paddingIndex++)
-        {
-            padding += "    float pad_" + str(mPaddingCounter++) + ";\n";
-        }
-
-        *elementIndex += (alignment - paddingOffset);
-    }
-
-    *elementIndex += numComponents;
-    *elementIndex %= 4;
-
-    return padding;
-}
-
-TString OutputHLSL::std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking)
-{
-    if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
-    {
-        return "";
-    }
-
-    int numComponents = 0;
-
-    if (type.isMatrix())
-    {
-        // This method can also be called from structureString, which does not use layout qualifiers.
-        // Thus, use the method parameter for determining the matrix packing.
-        //
-        // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
-        // wish to always transpose GL matrices to play well with HLSL's matrix array indexing.
-        //
-        const bool isRowMajorMatrix = !useHLSLRowMajorPacking;
-        const GLenum glType = glVariableType(type);
-        numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
-    }
-    else if (type.getStruct())
-    {
-        const TString &structName = structureTypeName(*type.getStruct(), useHLSLRowMajorPacking, true);
-        numComponents = mStd140StructElementIndexes[structName];
-
-        if (numComponents == 0)
-        {
-            return "";
-        }
-    }
-    else
-    {
-        const GLenum glType = glVariableType(type);
-        numComponents = gl::UniformComponentCount(glType);
-    }
-
-    TString padding;
-    for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
-    {
-        padding += "    float pad_" + str(mPaddingCounter++) + ";\n";
-    }
-    return padding;
-}
-
-// Use the same layout for packed and shared
-void setBlockLayout(gl::InterfaceBlock *interfaceBlock, gl::BlockLayoutType newLayout)
-{
-    interfaceBlock->layout = newLayout;
-    interfaceBlock->blockInfo.clear();
-
-    switch (newLayout)
-    {
-      case gl::BLOCKLAYOUT_SHARED:
-      case gl::BLOCKLAYOUT_PACKED:
-        {
-            gl::HLSLBlockEncoder hlslEncoder(&interfaceBlock->blockInfo, gl::HLSLBlockEncoder::ENCODE_PACKED);
-            hlslEncoder.encodeInterfaceBlockFields(interfaceBlock->fields);
-            interfaceBlock->dataSize = hlslEncoder.getBlockSize();
-        }
-        break;
-
-      case gl::BLOCKLAYOUT_STANDARD:
-        {
-            gl::Std140BlockEncoder stdEncoder(&interfaceBlock->blockInfo);
-            stdEncoder.encodeInterfaceBlockFields(interfaceBlock->fields);
-            interfaceBlock->dataSize = stdEncoder.getBlockSize();
-        }
-        break;
-
-      default:
-        UNREACHABLE();
-        break;
-    }
-}
-
-gl::BlockLayoutType convertBlockLayoutType(TLayoutBlockStorage blockStorage)
-{
-    switch (blockStorage)
-    {
-      case EbsPacked: return gl::BLOCKLAYOUT_PACKED;
-      case EbsShared: return gl::BLOCKLAYOUT_SHARED;
-      case EbsStd140: return gl::BLOCKLAYOUT_STANDARD;
-      default: UNREACHABLE(); return gl::BLOCKLAYOUT_SHARED;
-    }
-}
-
 TString OutputHLSL::structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName)
 {
     TString init;
@@ -535,7 +257,7 @@
     for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
     {
         const TField &field = *fields[fieldIndex];
-        const TString &fieldName = rhsStructName + "." + decorate(field.name());
+        const TString &fieldName = rhsStructName + "." + Decorate(field.name());
         const TType &fieldType = *field.type();
 
         if (fieldType.getStruct())
@@ -557,88 +279,10 @@
 {
     TInfoSinkBase &out = mHeader;
 
-    TString uniforms;
-    TString interfaceBlocks;
     TString varyings;
     TString attributes;
     TString flaggedStructs;
 
-    for (ReferencedSymbols::const_iterator uniformIt = mReferencedUniforms.begin(); uniformIt != mReferencedUniforms.end(); uniformIt++)
-    {
-        const TIntermSymbol &uniform = *uniformIt->second;
-        const TType &type = uniform.getType();
-        const TString &name = uniform.getSymbol();
-
-        int registerIndex = declareUniformAndAssignRegister(type, name);
-
-        if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType()))   // Also declare the texture
-        {
-            uniforms += "uniform " + samplerString(type) + " sampler_" + decorateUniform(name, type) + arrayString(type) + 
-                        " : register(s" + str(registerIndex) + ");\n";
-
-            uniforms += "uniform " + textureString(type) + " texture_" + decorateUniform(name, type) + arrayString(type) +
-                        " : register(t" + str(registerIndex) + ");\n";
-        }
-        else
-        {
-            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, if relevant, will not
-            // be taken into account.
-            const TString &typeName = ((structure && !structure->name().empty()) ?
-                                        structureTypeName(*structure, false, false) : typeString(type));
-
-            const TString &registerString = TString("register(") + RegisterPrefix(type) + str(registerIndex) + ")";
-
-            uniforms += "uniform " + typeName + " " + decorateUniform(name, type) + arrayString(type) + " : " + registerString + ";\n";
-        }
-    }
-
-    for (ReferencedSymbols::const_iterator interfaceBlockIt = mReferencedInterfaceBlocks.begin(); interfaceBlockIt != mReferencedInterfaceBlocks.end(); interfaceBlockIt++)
-    {
-        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());
-        gl::InterfaceBlock activeBlock(interfaceBlock.name().c_str(), arraySize, mInterfaceBlockRegister);
-        for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++)
-        {
-            const TField &field = *fieldList[typeIndex];
-            const TString &fullUniformName = interfaceBlockFieldString(interfaceBlock, field);
-            declareInterfaceBlockField(*field.type(), fullUniformName, activeBlock.fields);
-        }
-
-        mInterfaceBlockRegister += std::max(1u, arraySize);
-
-        gl::BlockLayoutType blockLayoutType = convertBlockLayoutType(interfaceBlock.blockStorage());
-        setBlockLayout(&activeBlock, blockLayoutType);
-
-        if (interfaceBlock.matrixPacking() == EmpRowMajor)
-        {
-            activeBlock.isRowMajorLayout = true;
-        }
-
-        mActiveInterfaceBlocks.push_back(activeBlock);
-
-        if (interfaceBlock.hasInstanceName())
-        {
-            interfaceBlocks += interfaceBlockStructString(interfaceBlock);
-        }
-
-        if (arraySize > 0)
-        {
-            for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
-            {
-                interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex + arrayIndex, arrayIndex);
-            }
-        }
-        else
-        {
-            interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex, GL_INVALID_INDEX);
-        }
-    }
-
     for (std::map<TIntermTyped*, TString>::const_iterator flaggedStructIt = mFlaggedStructMappedNames.begin(); flaggedStructIt != mFlaggedStructMappedNames.end(); flaggedStructIt++)
     {
         TIntermTyped *structNode = flaggedStructIt->first;
@@ -646,7 +290,7 @@
         const TStructure &structure = *structNode->getType().getStruct();
         const TString &originalName = mFlaggedStructOriginalNames[structNode];
 
-        flaggedStructs += "static " + decorate(structure.name()) + " " + mappedName + " =\n";
+        flaggedStructs += "static " + Decorate(structure.name()) + " " + mappedName + " =\n";
         flaggedStructs += structInitializerString(0, structure, originalName);
         flaggedStructs += "\n";
     }
@@ -657,10 +301,8 @@
         const TString &name = varying->second->getSymbol();
 
         // 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);
+        varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) + " " +
+                    Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
     }
 
     for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
@@ -668,22 +310,13 @@
         const TType &type = attribute->second->getType();
         const TString &name = attribute->second->getSymbol();
 
-        attributes += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
-
-        gl::Attribute attributeVar(glVariableType(type), glVariablePrecision(type), name.c_str(),
-                               (unsigned int)type.getArraySize(), type.getLayoutQualifier().location);
-        mActiveAttributes.push_back(attributeVar);
+        attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
     }
 
-    for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++)
-    {
-        out << *structDeclaration;
-    }
+    out << mStructureHLSL->structsHeader();
 
-    for (Constructors::iterator constructor = mConstructors.begin(); constructor != mConstructors.end(); constructor++)
-    {
-        out << *constructor;
-    }
+    out << mUniformHLSL->uniformsHeader(mOutputType, mReferencedUniforms);
+    out << mUniformHLSL->interfaceBlocksHeader(mReferencedInterfaceBlocks);
 
     if (mUsesDiscardRewriting)
     {
@@ -695,7 +328,7 @@
         out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
     }
 
-    if (mContext.shaderType == SH_FRAGMENT_SHADER)
+    if (mContext.shaderType == GL_FRAGMENT_SHADER)
     {
         TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
         const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire));
@@ -710,14 +343,9 @@
             {
                 const TString &variableName = outputVariableIt->first;
                 const TType &variableType = outputVariableIt->second->getType();
-                const TLayoutQualifier &layoutQualifier = variableType.getLayoutQualifier();
 
-                out << "static " + typeString(variableType) + " out_" + variableName + arrayString(variableType) +
+                out << "static " + TypeString(variableType) + " out_" + variableName + ArrayString(variableType) +
                        " = " + initializer(variableType) + ";\n";
-
-                gl::Attribute outputVar(glVariableType(variableType), glVariablePrecision(variableType), variableName.c_str(),
-                                    (unsigned int)variableType.getArraySize(), layoutQualifier.location);
-                mActiveOutputVariables.push_back(outputVar);
             }
         }
         else
@@ -819,22 +447,13 @@
             out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
                    "\n";
         }
-        
-        out <<  uniforms;
-        out << "\n";
 
-        if (!interfaceBlocks.empty())
+        if (!flaggedStructs.empty())
         {
-            out << interfaceBlocks;
+            out << "// Std140 Structures accessed by value\n";
             out << "\n";
-
-            if (!flaggedStructs.empty())
-            {
-                out << "// Std140 Structures accessed by value\n";
-                out << "\n";
-                out << flaggedStructs;
-                out << "\n";
-            }
+            out << flaggedStructs;
+            out << "\n";
         }
 
         if (usingMRTExtension && mNumRenderTargets > 1)
@@ -858,7 +477,7 @@
         out <<  attributes;
         out << "\n"
                "static float4 gl_Position = float4(0, 0, 0, 0);\n";
-        
+
         if (mUsesPointSize)
         {
             out << "static float gl_PointSize = float(1);\n";
@@ -908,21 +527,12 @@
                    "\n";
         }
 
-        out << uniforms;
-        out << "\n";
-        
-        if (!interfaceBlocks.empty())
+        if (!flaggedStructs.empty())
         {
-            out << interfaceBlocks;
+            out << "// Std140 Structures accessed by value\n";
             out << "\n";
-
-            if (!flaggedStructs.empty())
-            {
-                out << "// Std140 Structures accessed by value\n";
-                out << "\n";
-                out << flaggedStructs;
-                out << "\n";
-            }
+            out << flaggedStructs;
+            out << "\n";
         }
     }
 
@@ -1392,7 +1002,7 @@
                   case 3: out << "int4("; break;
                   default: UNREACHABLE();
                 }
-            
+
                 // Convert from normalized floating-point to integer
                 if (textureFunction->method != TextureFunction::FETCH)
                 {
@@ -1427,7 +1037,7 @@
             }
 
             TString proj = "";   // Only used for projected textures
-        
+
             if (textureFunction->proj)
             {
                 switch(textureFunction->coords)
@@ -1611,7 +1221,7 @@
                "}\n"
                "\n";
     }
-    
+
     if (mUsesMod3v)
     {
         out << "float3 mod(float3 x, float3 y)\n"
@@ -1791,17 +1401,17 @@
                 mReferencedUniforms[name] = node;
             }
 
-            out << decorateUniform(name, nodeType);
+            out << DecorateUniform(name, nodeType);
         }
         else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
         {
             mReferencedAttributes[name] = node;
-            out << decorate(name);
+            out << Decorate(name);
         }
-        else if (isVarying(qualifier))
+        else if (IsVarying(qualifier))
         {
             mReferencedVaryings[name] = node;
-            out << decorate(name);
+            out << Decorate(name);
         }
         else if (qualifier == EvqFragmentOut)
         {
@@ -1849,7 +1459,7 @@
         }
         else
         {
-            out << decorate(name);
+            out << Decorate(name);
         }
     }
 }
@@ -1920,7 +1530,7 @@
         {
             out << " = mul(";
             node->getLeft()->traverse(this);
-            out << ", transpose(";   
+            out << ", transpose(";
         }
         else
         {
@@ -1936,7 +1546,7 @@
         {
             out << " = mul(";
             node->getLeft()->traverse(this);
-            out << ", ";   
+            out << ", ";
         }
         else
         {
@@ -1953,10 +1563,8 @@
                 {
                     TInterfaceBlock* interfaceBlock = leftType.getInterfaceBlock();
                     const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0);
-
                     mReferencedInterfaceBlocks[interfaceBlock->instanceName()] = node->getLeft()->getAsSymbolNode();
-                    out << interfaceBlockInstanceString(*interfaceBlock, arrayIndex);
-
+                    out << mUniformHLSL->interfaceBlockInstanceString(*interfaceBlock, arrayIndex);
                     return false;
                 }
             }
@@ -1977,7 +1585,7 @@
             const TStructure* structure = node->getLeft()->getType().getStruct();
             const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
             const TField* field = structure->fields()[index->getIConst(0)];
-            out << "." + decorateField(field->name(), *structure);
+            out << "." + DecorateField(field->name(), *structure);
 
             return false;
         }
@@ -1988,7 +1596,7 @@
             const TInterfaceBlock* interfaceBlock = node->getLeft()->getType().getInterfaceBlock();
             const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
             const TField* field = interfaceBlock->fields()[index->getIConst(0)];
-            out << "." + decorate(field->name());
+            out << "." + Decorate(field->name());
 
             return false;
         }
@@ -2002,9 +1610,9 @@
 
             if (swizzle)
             {
-                TIntermSequence &sequence = swizzle->getSequence();
+                TIntermSequence *sequence = swizzle->getSequence();
 
-                for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+                for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
                 {
                     TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
 
@@ -2065,9 +1673,9 @@
                 const TField *field = fields[i];
 
                 node->getLeft()->traverse(this);
-                out << "." + decorateField(field->name(), structure) + " == ";
+                out << "." + DecorateField(field->name(), structure) + " == ";
                 node->getRight()->traverse(this);
-                out << "." + decorateField(field->name(), structure);
+                out << "." + DecorateField(field->name(), structure);
 
                 if (i < fields.size() - 1)
                 {
@@ -2138,61 +1746,13 @@
 {
     switch (node->getOp())
     {
-      case EOpNegative:         outputTriplet(visit, "(-", "", ")");  break;
-      case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")");  break;
-      case EOpLogicalNot:       outputTriplet(visit, "(!", "", ")");  break;
-      case EOpPostIncrement:    outputTriplet(visit, "(", "", "++)"); break;
-      case EOpPostDecrement:    outputTriplet(visit, "(", "", "--)"); break;
-      case EOpPreIncrement:     outputTriplet(visit, "(++", "", ")"); break;
-      case EOpPreDecrement:     outputTriplet(visit, "(--", "", ")"); break;
-      case EOpConvIntToBool:
-      case EOpConvUIntToBool:
-      case EOpConvFloatToBool:
-        switch (node->getOperand()->getType().getNominalSize())
-        {
-          case 1:    outputTriplet(visit, "bool(", "", ")");  break;
-          case 2:    outputTriplet(visit, "bool2(", "", ")"); break;
-          case 3:    outputTriplet(visit, "bool3(", "", ")"); break;
-          case 4:    outputTriplet(visit, "bool4(", "", ")"); break;
-          default: UNREACHABLE();
-        }
-        break;
-      case EOpConvBoolToFloat:
-      case EOpConvIntToFloat:
-      case EOpConvUIntToFloat:
-        switch (node->getOperand()->getType().getNominalSize())
-        {
-          case 1:    outputTriplet(visit, "float(", "", ")");  break;
-          case 2:    outputTriplet(visit, "float2(", "", ")"); break;
-          case 3:    outputTriplet(visit, "float3(", "", ")"); break;
-          case 4:    outputTriplet(visit, "float4(", "", ")"); break;
-          default: UNREACHABLE();
-        }
-        break;
-      case EOpConvFloatToInt:
-      case EOpConvBoolToInt:
-      case EOpConvUIntToInt:
-        switch (node->getOperand()->getType().getNominalSize())
-        {
-          case 1:    outputTriplet(visit, "int(", "", ")");  break;
-          case 2:    outputTriplet(visit, "int2(", "", ")"); break;
-          case 3:    outputTriplet(visit, "int3(", "", ")"); break;
-          case 4:    outputTriplet(visit, "int4(", "", ")"); break;
-          default: UNREACHABLE();
-        }
-        break;
-      case EOpConvFloatToUInt:
-      case EOpConvBoolToUInt:
-      case EOpConvIntToUInt:
-        switch (node->getOperand()->getType().getNominalSize())
-        {
-          case 1:    outputTriplet(visit, "uint(", "", ")");  break;
-          case 2:    outputTriplet(visit, "uint2(", "", ")");  break;
-          case 3:    outputTriplet(visit, "uint3(", "", ")");  break;
-          case 4:    outputTriplet(visit, "uint4(", "", ")");  break;
-          default: UNREACHABLE();
-        }
-        break;
+      case EOpNegative:         outputTriplet(visit, "(-", "", ")");         break;
+      case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")");         break;
+      case EOpLogicalNot:       outputTriplet(visit, "(!", "", ")");         break;
+      case EOpPostIncrement:    outputTriplet(visit, "(", "", "++)");        break;
+      case EOpPostDecrement:    outputTriplet(visit, "(", "", "--)");        break;
+      case EOpPreIncrement:     outputTriplet(visit, "(++", "", ")");        break;
+      case EOpPreDecrement:     outputTriplet(visit, "(--", "", ")");        break;
       case EOpRadians:          outputTriplet(visit, "radians(", "", ")");   break;
       case EOpDegrees:          outputTriplet(visit, "degrees(", "", ")");   break;
       case EOpSin:              outputTriplet(visit, "sin(", "", ")");       break;
@@ -2266,7 +1826,7 @@
                 out << "{\n";
             }
 
-            for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++)
+            for (TIntermSequence::iterator sit = node->getSequence()->begin(); sit != node->getSequence()->end(); sit++)
             {
                 outputLineDirective((*sit)->getLine().first_line);
 
@@ -2286,14 +1846,16 @@
       case EOpDeclaration:
         if (visit == PreVisit)
         {
-            TIntermSequence &sequence = node->getSequence();
-            TIntermTyped *variable = sequence[0]->getAsTyped();
+            TIntermSequence *sequence = node->getSequence();
+            TIntermTyped *variable = (*sequence)[0]->getAsTyped();
 
             if (variable && (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal))
             {
-                if (variable->getType().getStruct())
+                TStructure *structure = variable->getType().getStruct();
+
+                if (structure)
                 {
-                    addConstructor(variable->getType(), structNameString(*variable->getType().getStruct()), NULL);
+                    mStructureHLSL->addConstructor(variable->getType(), StructNameString(*structure), NULL);
                 }
 
                 if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "")   // Variable declaration
@@ -2303,16 +1865,16 @@
                         out << "static ";
                     }
 
-                    out << typeString(variable->getType()) + " ";
+                    out << TypeString(variable->getType()) + " ";
 
-                    for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+                    for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
                     {
                         TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
 
                         if (symbol)
                         {
                             symbol->traverse(this);
-                            out << arrayString(symbol->getType());
+                            out << ArrayString(symbol->getType());
                             out << " = " + initializer(symbol->getType());
                         }
                         else
@@ -2320,7 +1882,7 @@
                             (*sit)->traverse(this);
                         }
 
-                        if (*sit != sequence.back())
+                        if (*sit != sequence->back())
                         {
                             out << ", ";
                         }
@@ -2332,9 +1894,9 @@
                 }
                 else UNREACHABLE();
             }
-            else if (variable && isVaryingOut(variable->getQualifier()))
+            else if (variable && IsVaryingOut(variable->getQualifier()))
             {
-                for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+                for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
                 {
                     TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
 
@@ -2357,22 +1919,25 @@
             out << ", ";
         }
         break;
+      case EOpInvariantDeclaration:
+        // Do not do any translation
+        return false;
       case EOpPrototype:
         if (visit == PreVisit)
         {
-            out << typeString(node->getType()) << " " << decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "(");
+            out << TypeString(node->getType()) << " " << Decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "(");
 
-            TIntermSequence &arguments = node->getSequence();
+            TIntermSequence *arguments = node->getSequence();
 
-            for (unsigned int i = 0; i < arguments.size(); i++)
+            for (unsigned int i = 0; i < arguments->size(); i++)
             {
-                TIntermSymbol *symbol = arguments[i]->getAsSymbolNode();
+                TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode();
 
                 if (symbol)
                 {
                     out << argumentString(symbol);
 
-                    if (i < arguments.size() - 1)
+                    if (i < arguments->size() - 1)
                     {
                         out << ", ";
                     }
@@ -2398,7 +1963,7 @@
         {
             TString name = TFunction::unmangleName(node->getName());
 
-            out << typeString(node->getType()) << " ";
+            out << TypeString(node->getType()) << " ";
 
             if (name == "main")
             {
@@ -2406,26 +1971,28 @@
             }
             else
             {
-                out << decorate(name) << (mOutputLod0Function ? "Lod0(" : "(");
+                out << Decorate(name) << (mOutputLod0Function ? "Lod0(" : "(");
             }
 
-            TIntermSequence &sequence = node->getSequence();
-            TIntermSequence &arguments = sequence[0]->getAsAggregate()->getSequence();
+            TIntermSequence *sequence = node->getSequence();
+            TIntermSequence *arguments = (*sequence)[0]->getAsAggregate()->getSequence();
 
-            for (unsigned int i = 0; i < arguments.size(); i++)
+            for (unsigned int i = 0; i < arguments->size(); i++)
             {
-                TIntermSymbol *symbol = arguments[i]->getAsSymbolNode();
+                TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode();
 
                 if (symbol)
                 {
-                    if (symbol->getType().getStruct())
+                    TStructure *structure = symbol->getType().getStruct();
+
+                    if (structure)
                     {
-                        addConstructor(symbol->getType(), structNameString(*symbol->getType().getStruct()), NULL);
+                        mStructureHLSL->addConstructor(symbol->getType(), StructNameString(*structure), NULL);
                     }
 
                     out << argumentString(symbol);
 
-                    if (i < arguments.size() - 1)
+                    if (i < arguments->size() - 1)
                     {
                         out << ", ";
                     }
@@ -2435,14 +2002,14 @@
 
             out << ")\n"
                 "{\n";
-            
-            if (sequence.size() > 1)
+
+            if (sequence->size() > 1)
             {
                 mInsideFunction = true;
-                sequence[1]->traverse(this);
+                (*sequence)[1]->traverse(this);
                 mInsideFunction = false;
             }
-            
+
             out << "}\n";
 
             if (mContainsLoopDiscontinuity && !mOutputLod0Function)
@@ -2462,19 +2029,19 @@
         {
             TString name = TFunction::unmangleName(node->getName());
             bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function;
-            TIntermSequence &arguments = node->getSequence();
+            TIntermSequence *arguments = node->getSequence();
 
             if (node->isUserDefined())
             {
-                out << decorate(name) << (lod0 ? "Lod0(" : "(");
+                out << Decorate(name) << (lod0 ? "Lod0(" : "(");
             }
             else
             {
-                TBasicType samplerType = arguments[0]->getAsTyped()->getType().getBasicType();
+                TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType();
 
                 TextureFunction textureFunction;
                 textureFunction.sampler = samplerType;
-                textureFunction.coords = arguments[1]->getAsTyped()->getNominalSize();
+                textureFunction.coords = (*arguments)[1]->getAsTyped()->getNominalSize();
                 textureFunction.method = TextureFunction::IMPLICIT;
                 textureFunction.proj = false;
                 textureFunction.offset = false;
@@ -2564,9 +2131,9 @@
                         mandatoryArgumentCount++;
                     }
 
-                    bool bias = (arguments.size() > mandatoryArgumentCount);   // Bias argument is optional
+                    bool bias = (arguments->size() > mandatoryArgumentCount);   // Bias argument is optional
 
-                    if (lod0 || mContext.shaderType == SH_VERTEX_SHADER)
+                    if (lod0 || mContext.shaderType == GL_VERTEX_SHADER)
                     {
                         if (bias)
                         {
@@ -2588,7 +2155,7 @@
                 out << textureFunction.name();
             }
 
-            for (TIntermSequence::iterator arg = arguments.begin(); arg != arguments.end(); arg++)
+            for (TIntermSequence::iterator arg = arguments->begin(); arg != arguments->end(); arg++)
             {
                 if (mOutputType == SH_HLSL11_OUTPUT && IsSampler((*arg)->getAsTyped()->getBasicType()))
                 {
@@ -2599,7 +2166,7 @@
 
                 (*arg)->traverse(this);
 
-                if (arg < arguments.end() - 1)
+                if (arg < arguments->end() - 1)
                 {
                     out << ", ";
                 }
@@ -2610,87 +2177,30 @@
             return false;
         }
         break;
-      case EOpParameters:       outputTriplet(visit, "(", ", ", ")\n{\n");             break;
-      case EOpConstructFloat:
-        addConstructor(node->getType(), "vec1", &node->getSequence());
-        outputTriplet(visit, "vec1(", "", ")");
-        break;
-      case EOpConstructVec2:
-        addConstructor(node->getType(), "vec2", &node->getSequence());
-        outputTriplet(visit, "vec2(", ", ", ")");
-        break;
-      case EOpConstructVec3:
-        addConstructor(node->getType(), "vec3", &node->getSequence());
-        outputTriplet(visit, "vec3(", ", ", ")");
-        break;
-      case EOpConstructVec4:
-        addConstructor(node->getType(), "vec4", &node->getSequence());
-        outputTriplet(visit, "vec4(", ", ", ")");
-        break;
-      case EOpConstructBool:
-        addConstructor(node->getType(), "bvec1", &node->getSequence());
-        outputTriplet(visit, "bvec1(", "", ")");
-        break;
-      case EOpConstructBVec2:
-        addConstructor(node->getType(), "bvec2", &node->getSequence());
-        outputTriplet(visit, "bvec2(", ", ", ")");
-        break;
-      case EOpConstructBVec3:
-        addConstructor(node->getType(), "bvec3", &node->getSequence());
-        outputTriplet(visit, "bvec3(", ", ", ")");
-        break;
-      case EOpConstructBVec4:
-        addConstructor(node->getType(), "bvec4", &node->getSequence());
-        outputTriplet(visit, "bvec4(", ", ", ")");
-        break;
-      case EOpConstructInt:
-        addConstructor(node->getType(), "ivec1", &node->getSequence());
-        outputTriplet(visit, "ivec1(", "", ")");
-        break;
-      case EOpConstructIVec2:
-        addConstructor(node->getType(), "ivec2", &node->getSequence());
-        outputTriplet(visit, "ivec2(", ", ", ")");
-        break;
-      case EOpConstructIVec3:
-        addConstructor(node->getType(), "ivec3", &node->getSequence());
-        outputTriplet(visit, "ivec3(", ", ", ")");
-        break;
-      case EOpConstructIVec4:
-        addConstructor(node->getType(), "ivec4", &node->getSequence());
-        outputTriplet(visit, "ivec4(", ", ", ")");
-        break;
-      case EOpConstructUInt:
-        addConstructor(node->getType(), "uvec1", &node->getSequence());
-        outputTriplet(visit, "uvec1(", "", ")");
-        break;
-      case EOpConstructUVec2:
-        addConstructor(node->getType(), "uvec2", &node->getSequence());
-        outputTriplet(visit, "uvec2(", ", ", ")");
-        break;
-      case EOpConstructUVec3:
-        addConstructor(node->getType(), "uvec3", &node->getSequence());
-        outputTriplet(visit, "uvec3(", ", ", ")");
-        break;
-      case EOpConstructUVec4:
-        addConstructor(node->getType(), "uvec4", &node->getSequence());
-        outputTriplet(visit, "uvec4(", ", ", ")");
-        break;
-      case EOpConstructMat2:
-        addConstructor(node->getType(), "mat2", &node->getSequence());
-        outputTriplet(visit, "mat2(", ", ", ")");
-        break;
-      case EOpConstructMat3:
-        addConstructor(node->getType(), "mat3", &node->getSequence());
-        outputTriplet(visit, "mat3(", ", ", ")");
-        break;
-      case EOpConstructMat4: 
-        addConstructor(node->getType(), "mat4", &node->getSequence());
-        outputTriplet(visit, "mat4(", ", ", ")");
-        break;
+      case EOpParameters:       outputTriplet(visit, "(", ", ", ")\n{\n");                                break;
+      case EOpConstructFloat:   outputConstructor(visit, node->getType(), "vec1", node->getSequence());  break;
+      case EOpConstructVec2:    outputConstructor(visit, node->getType(), "vec2", node->getSequence());  break;
+      case EOpConstructVec3:    outputConstructor(visit, node->getType(), "vec3", node->getSequence());  break;
+      case EOpConstructVec4:    outputConstructor(visit, node->getType(), "vec4", node->getSequence());  break;
+      case EOpConstructBool:    outputConstructor(visit, node->getType(), "bvec1", node->getSequence()); break;
+      case EOpConstructBVec2:   outputConstructor(visit, node->getType(), "bvec2", node->getSequence()); break;
+      case EOpConstructBVec3:   outputConstructor(visit, node->getType(), "bvec3", node->getSequence()); break;
+      case EOpConstructBVec4:   outputConstructor(visit, node->getType(), "bvec4", node->getSequence()); break;
+      case EOpConstructInt:     outputConstructor(visit, node->getType(), "ivec1", node->getSequence()); break;
+      case EOpConstructIVec2:   outputConstructor(visit, node->getType(), "ivec2", node->getSequence()); break;
+      case EOpConstructIVec3:   outputConstructor(visit, node->getType(), "ivec3", node->getSequence()); break;
+      case EOpConstructIVec4:   outputConstructor(visit, node->getType(), "ivec4", node->getSequence()); break;
+      case EOpConstructUInt:    outputConstructor(visit, node->getType(), "uvec1", node->getSequence()); break;
+      case EOpConstructUVec2:   outputConstructor(visit, node->getType(), "uvec2", node->getSequence()); break;
+      case EOpConstructUVec3:   outputConstructor(visit, node->getType(), "uvec3", node->getSequence()); break;
+      case EOpConstructUVec4:   outputConstructor(visit, node->getType(), "uvec4", node->getSequence()); break;
+      case EOpConstructMat2:    outputConstructor(visit, node->getType(), "mat2", node->getSequence());  break;
+      case EOpConstructMat3:    outputConstructor(visit, node->getType(), "mat3", node->getSequence());  break;
+      case EOpConstructMat4:    outputConstructor(visit, node->getType(), "mat4", node->getSequence());  break;
       case EOpConstructStruct:
         {
-            const TString &structName = structNameString(*node->getType().getStruct());
-            addConstructor(node->getType(), structName, &node->getSequence());
+            const TString &structName = StructNameString(*node->getType().getStruct());
+            mStructureHLSL->addConstructor(node->getType(), structName, node->getSequence());
             outputTriplet(visit, structName + "_ctor(", ", ", ")");
         }
         break;
@@ -2703,8 +2213,8 @@
       case EOpMod:
         {
             // We need to look at the number of components in both arguments
-            const int modValue = node->getSequence()[0]->getAsTyped()->getNominalSize() * 10
-                               + node->getSequence()[1]->getAsTyped()->getNominalSize();
+            const int modValue = (*node->getSequence())[0]->getAsTyped()->getNominalSize() * 10 +
+                (*node->getSequence())[1]->getAsTyped()->getNominalSize();
             switch (modValue)
             {
               case 11: mUsesMod1 = true; break;
@@ -2722,8 +2232,8 @@
         break;
       case EOpPow:              outputTriplet(visit, "pow(", ", ", ")");               break;
       case EOpAtan:
-        ASSERT(node->getSequence().size() == 2);   // atan(x) is a unary operator
-        switch (node->getSequence()[0]->getAsTyped()->getNominalSize())
+        ASSERT(node->getSequence()->size() == 2);   // atan(x) is a unary operator
+        switch ((*node->getSequence())[0]->getAsTyped()->getNominalSize())
         {
           case 1: mUsesAtan2_1 = true; break;
           case 2: mUsesAtan2_2 = true; break;
@@ -2744,7 +2254,7 @@
       case EOpCross:         outputTriplet(visit, "cross(", ", ", ")");         break;
       case EOpFaceForward:
         {
-            switch (node->getSequence()[0]->getAsTyped()->getNominalSize())   // Number of components in the first argument
+            switch ((*node->getSequence())[0]->getAsTyped()->getNominalSize())   // Number of components in the first argument
             {
             case 1: mUsesFaceforward1 = true; break;
             case 2: mUsesFaceforward2 = true; break;
@@ -2752,7 +2262,7 @@
             case 4: mUsesFaceforward4 = true; break;
             default: UNREACHABLE();
             }
-            
+
             outputTriplet(visit, "faceforward(", ", ", ")");
         }
         break;
@@ -2782,7 +2292,7 @@
         node->getCondition()->traverse(this);
 
         out << ")\n";
-        
+
         outputLineDirective(node->getLine().first_line);
         out << "{\n";
 
@@ -2865,7 +2375,7 @@
     else
     {
         out << "{for(";
-        
+
         if (node->getInit())
         {
             node->getInit()->traverse(this);
@@ -2886,7 +2396,7 @@
         }
 
         out << ")\n";
-        
+
         outputLineDirective(node->getLine().first_line);
         out << "{\n";
     }
@@ -2995,7 +2505,7 @@
         }
         else
         {
-            for (TIntermSequence::iterator sit = aggregate->getSequence().begin(); sit != aggregate->getSequence().end(); sit++)
+            for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
             {
                 if (!isSingleStatement(*sit))
                 {
@@ -3032,8 +2542,8 @@
 
         if (init)
         {
-            TIntermSequence &sequence = init->getSequence();
-            TIntermTyped *variable = sequence[0]->getAsTyped();
+            TIntermSequence *sequence = init->getSequence();
+            TIntermTyped *variable = (*sequence)[0]->getAsTyped();
 
             if (variable && variable->getQualifier() == EvqTemporary)
             {
@@ -3061,7 +2571,7 @@
     if (index != NULL && node->getCondition())
     {
         TIntermBinary *test = node->getCondition()->getAsBinaryNode();
-        
+
         if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
         {
             TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();
@@ -3082,7 +2592,7 @@
     {
         TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
         TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
-        
+
         if (binaryTerminal)
         {
             TOperator op = binaryTerminal->getOp();
@@ -3162,7 +2672,7 @@
                 {
                     mExcessiveLoopIndex = NULL;   // Stops setting the Break flag
                 }
-                
+
                 // for(int index = initial; index < clampedLimit; index += increment)
 
                 out << "for(";
@@ -3180,7 +2690,7 @@
                 out << " += ";
                 out << increment;
                 out << ")\n";
-                
+
                 outputLineDirective(node->getLine().first_line);
                 out << "{\n";
 
@@ -3202,7 +2712,7 @@
                 initial += MAX_LOOP_ITERATIONS * increment;
                 iterations -= MAX_LOOP_ITERATIONS;
             }
-            
+
             out << "}";
 
             mExcessiveLoopIndex = restoreIndex;
@@ -3244,7 +2754,7 @@
         {
             mBody << " \"" << mContext.sourcePath << "\"";
         }
-        
+
         mBody << "\n";
     }
 }
@@ -3261,181 +2771,16 @@
     }
     else
     {
-        name = decorate(name);
+        name = Decorate(name);
     }
 
     if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType()))
     {
-        return qualifierString(qualifier) + " " + textureString(type) + " texture_" + name + arrayString(type) + ", " +
-               qualifierString(qualifier) + " " + samplerString(type) + " sampler_" + name + arrayString(type);        
+        return QualifierString(qualifier) + " " + TextureString(type) + " texture_" + name + ArrayString(type) + ", " +
+               QualifierString(qualifier) + " " + SamplerString(type) + " sampler_" + name + ArrayString(type);
     }
 
-    return qualifierString(qualifier) + " " + typeString(type) + " " + name + arrayString(type);
-}
-
-TString OutputHLSL::interpolationString(TQualifier qualifier)
-{
-    switch(qualifier)
-    {
-      case EvqVaryingIn:           return "";
-      case EvqFragmentIn:          return "";
-      case EvqInvariantVaryingIn:  return "";
-      case EvqSmoothIn:            return "linear";
-      case EvqFlatIn:              return "nointerpolation";
-      case EvqCentroidIn:          return "centroid";
-      case EvqVaryingOut:          return "";
-      case EvqVertexOut:           return "";
-      case EvqInvariantVaryingOut: return "";
-      case EvqSmoothOut:           return "linear";
-      case EvqFlatOut:             return "nointerpolation";
-      case EvqCentroidOut:         return "centroid";
-      default: UNREACHABLE();
-    }
-
-    return "";
-}
-
-TString OutputHLSL::qualifierString(TQualifier qualifier)
-{
-    switch(qualifier)
-    {
-      case EvqIn:            return "in";
-      case EvqOut:           return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined
-      case EvqInOut:         return "inout";
-      case EvqConstReadOnly: return "const";
-      default: UNREACHABLE();
-    }
-
-    return "";
-}
-
-TString OutputHLSL::typeString(const TType &type)
-{
-    const TStructure* structure = type.getStruct();
-    if (structure)
-    {
-        const TString& typeName = structure->name();
-        if (typeName != "")
-        {
-            return structNameString(*type.getStruct());
-        }
-        else   // Nameless structure, define in place
-        {
-            return structureString(*structure, false, false);
-        }
-    }
-    else if (type.isMatrix())
-    {
-        int cols = type.getCols();
-        int rows = type.getRows();
-        return "float" + str(cols) + "x" + str(rows);
-    }
-    else
-    {
-        switch (type.getBasicType())
-        {
-          case EbtFloat:
-            switch (type.getNominalSize())
-            {
-              case 1: return "float";
-              case 2: return "float2";
-              case 3: return "float3";
-              case 4: return "float4";
-            }
-          case EbtInt:
-            switch (type.getNominalSize())
-            {
-              case 1: return "int";
-              case 2: return "int2";
-              case 3: return "int3";
-              case 4: return "int4";
-            }
-          case EbtUInt:
-            switch (type.getNominalSize())
-            {
-              case 1: return "uint";
-              case 2: return "uint2";
-              case 3: return "uint3";
-              case 4: return "uint4";
-            }
-          case EbtBool:
-            switch (type.getNominalSize())
-            {
-              case 1: return "bool";
-              case 2: return "bool2";
-              case 3: return "bool3";
-              case 4: return "bool4";
-            }
-          case EbtVoid:
-            return "void";
-          case EbtSampler2D:
-          case EbtISampler2D:
-          case EbtUSampler2D:
-          case EbtSampler2DArray:
-          case EbtISampler2DArray:
-          case EbtUSampler2DArray:
-            return "sampler2D";
-          case EbtSamplerCube:
-          case EbtISamplerCube:
-          case EbtUSamplerCube:
-            return "samplerCUBE";
-          case EbtSamplerExternalOES:
-            return "sampler2D";
-          default:
-            break;
-        }
-    }
-
-    UNREACHABLE();
-    return "<unknown type>";
-}
-
-TString OutputHLSL::textureString(const TType &type)
-{
-    switch (type.getBasicType())
-    {
-      case EbtSampler2D:            return "Texture2D";
-      case EbtSamplerCube:          return "TextureCube";
-      case EbtSamplerExternalOES:   return "Texture2D";
-      case EbtSampler2DArray:       return "Texture2DArray";
-      case EbtSampler3D:            return "Texture3D";
-      case EbtISampler2D:           return "Texture2D<int4>";
-      case EbtISampler3D:           return "Texture3D<int4>";
-      case EbtISamplerCube:         return "Texture2DArray<int4>";
-      case EbtISampler2DArray:      return "Texture2DArray<int4>";
-      case EbtUSampler2D:           return "Texture2D<uint4>";
-      case EbtUSampler3D:           return "Texture3D<uint4>";
-      case EbtUSamplerCube:         return "Texture2DArray<uint4>";
-      case EbtUSampler2DArray:      return "Texture2DArray<uint4>";
-      case EbtSampler2DShadow:      return "Texture2D";
-      case EbtSamplerCubeShadow:    return "TextureCube";
-      case EbtSampler2DArrayShadow: return "Texture2DArray";
-      default: UNREACHABLE();
-    }
-    
-    return "<unknown texture type>";
-}
-
-TString OutputHLSL::samplerString(const TType &type)
-{
-    if (IsShadowSampler(type.getBasicType()))
-    {
-        return "SamplerComparisonState";
-    }
-    else
-    {
-        return "SamplerState";
-    }
-}
-
-TString OutputHLSL::arrayString(const TType &type)
-{
-    if (!type.isArray())
-    {
-        return "";
-    }
-
-    return "[" + str(type.getArraySize()) + "]";
+    return QualifierString(qualifier) + " " + TypeString(type) + " " + name + ArrayString(type);
 }
 
 TString OutputHLSL::initializer(const TType &type)
@@ -3456,290 +2801,24 @@
     return "{" + string + "}";
 }
 
-TString OutputHLSL::structureString(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing)
+void OutputHLSL::outputConstructor(Visit visit, const TType &type, const TString &name, const TIntermSequence *parameters)
 {
-    const TFieldList &fields = structure.fields();
-    const bool isNameless = (structure.name() == "");
-    const TString &structName = structureTypeName(structure, useHLSLRowMajorPacking, useStd140Packing);
-    const TString declareString = (isNameless ? "struct" : "struct " + structName);
+    TInfoSinkBase &out = mBody;
 
-    TString string;
-    string += declareString + "\n"
-              "{\n";
-
-    int elementIndex = 0;
-
-    for (unsigned int i = 0; i < fields.size(); i++)
+    if (visit == PreVisit)
     {
-        const TField &field = *fields[i];
-        const TType &fieldType = *field.type();
-        const TStructure *fieldStruct = fieldType.getStruct();
-        const TString &fieldTypeString = fieldStruct ? structureTypeName(*fieldStruct, useHLSLRowMajorPacking, useStd140Packing) : typeString(fieldType);
+        mStructureHLSL->addConstructor(type, name, parameters);
 
-        if (useStd140Packing)
-        {
-            string += std140PrePaddingString(*field.type(), &elementIndex);
-        }
-
-        string += "    " + fieldTypeString + " " + decorateField(field.name(), structure) + arrayString(fieldType) + ";\n";
-
-        if (useStd140Packing)
-        {
-            string += std140PostPaddingString(*field.type(), useHLSLRowMajorPacking);
-        }
+        out << name + "(";
     }
-
-    // Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable
-    string += (isNameless ? "} " : "};\n");
-
-    // Add remaining element index to the global map, for use with nested structs in standard layouts
-    if (useStd140Packing)
+    else if (visit == InVisit)
     {
-        mStd140StructElementIndexes[structName] = elementIndex;
+        out << ", ";
     }
-
-    return string;
-}
-
-TString OutputHLSL::structureTypeName(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing)
-{
-    if (structure.name() == "")
+    else if (visit == PostVisit)
     {
-        return "";
+        out << ")";
     }
-
-    TString prefix = "";
-
-    // Structs packed with row-major matrices in HLSL are prefixed with "rm"
-    // GLSL column-major maps to HLSL row-major, and the converse is true
-
-    if (useStd140Packing)
-    {
-        prefix += "std";
-    }
-
-    if (useHLSLRowMajorPacking)
-    {
-        if (prefix != "") prefix += "_";
-        prefix += "rm";
-    }
-
-    return prefix + structNameString(structure);
-}
-
-void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
-{
-    if (name == "")
-    {
-        return;   // Nameless structures don't have constructors
-    }
-
-    if (type.getStruct() && mStructNames.find(name) != mStructNames.end())
-    {
-        return;   // Already added
-    }
-
-    TType ctorType = type;
-    ctorType.clearArrayness();
-    ctorType.setPrecision(EbpHigh);
-    ctorType.setQualifier(EvqTemporary);
-
-    typedef std::vector<TType> ParameterArray;
-    ParameterArray ctorParameters;
-
-    const TStructure* structure = type.getStruct();
-    if (structure)
-    {
-        mStructNames.insert(name);
-
-        const TString &structString = structureString(*structure, false, false);
-
-        if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end())
-        {
-            // Add row-major packed struct for interface blocks
-            TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
-                                     structureString(*structure, true, false) +
-                                     "#pragma pack_matrix(column_major)\n";
-
-            TString std140String = structureString(*structure, false, true);
-            TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
-                                           structureString(*structure, true, true) +
-                                           "#pragma pack_matrix(column_major)\n";
-
-            mStructDeclarations.push_back(structString);
-            mStructDeclarations.push_back(rowMajorString);
-            mStructDeclarations.push_back(std140String);
-            mStructDeclarations.push_back(std140RowMajorString);
-        }
-
-        const TFieldList &fields = structure->fields();
-        for (unsigned int i = 0; i < fields.size(); i++)
-        {
-            ctorParameters.push_back(*fields[i]->type());
-        }
-    }
-    else if (parameters)
-    {
-        for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++)
-        {
-            ctorParameters.push_back((*parameter)->getAsTyped()->getType());
-        }
-    }
-    else UNREACHABLE();
-
-    TString constructor;
-
-    if (ctorType.getStruct())
-    {
-        constructor += name + " " + name + "_ctor(";
-    }
-    else   // Built-in type
-    {
-        constructor += typeString(ctorType) + " " + name + "(";
-    }
-
-    for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
-    {
-        const TType &type = ctorParameters[parameter];
-
-        constructor += typeString(type) + " x" + str(parameter) + arrayString(type);
-
-        if (parameter < ctorParameters.size() - 1)
-        {
-            constructor += ", ";
-        }
-    }
-
-    constructor += ")\n"
-                   "{\n";
-
-    if (ctorType.getStruct())
-    {
-        constructor += "    " + name + " structure = {";
-    }
-    else
-    {
-        constructor += "    return " + typeString(ctorType) + "(";
-    }
-
-    if (ctorType.isMatrix() && ctorParameters.size() == 1)
-    {
-        int rows = ctorType.getRows();
-        int cols = ctorType.getCols();
-        const TType &parameter = ctorParameters[0];
-
-        if (parameter.isScalar())
-        {
-            for (int row = 0; row < rows; row++)
-            {
-                for (int col = 0; col < cols; col++)
-                {
-                    constructor += TString((row == col) ? "x0" : "0.0");
-                    
-                    if (row < rows - 1 || col < cols - 1)
-                    {
-                        constructor += ", ";
-                    }
-                }
-            }
-        }
-        else if (parameter.isMatrix())
-        {
-            for (int row = 0; row < rows; row++)
-            {
-                for (int col = 0; col < cols; col++)
-                {
-                    if (row < parameter.getRows() && col < parameter.getCols())
-                    {
-                        constructor += TString("x0") + "[" + str(row) + "]" + "[" + str(col) + "]";
-                    }
-                    else
-                    {
-                        constructor += TString((row == col) ? "1.0" : "0.0");
-                    }
-
-                    if (row < rows - 1 || col < cols - 1)
-                    {
-                        constructor += ", ";
-                    }
-                }
-            }
-        }
-        else UNREACHABLE();
-    }
-    else
-    {
-        size_t remainingComponents = ctorType.getObjectSize();
-        size_t parameterIndex = 0;
-
-        while (remainingComponents > 0)
-        {
-            const TType &parameter = ctorParameters[parameterIndex];
-            const size_t parameterSize = parameter.getObjectSize();
-            bool moreParameters = parameterIndex + 1 < ctorParameters.size();
-
-            constructor += "x" + str(parameterIndex);
-
-            if (parameter.isScalar())
-            {
-                remainingComponents -= parameter.getObjectSize();
-            }
-            else if (parameter.isVector())
-            {
-                if (remainingComponents == parameterSize || moreParameters)
-                {
-                    ASSERT(parameterSize <= remainingComponents);
-                    remainingComponents -= parameterSize;
-                }
-                else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
-                {
-                    switch (remainingComponents)
-                    {
-                      case 1: constructor += ".x";    break;
-                      case 2: constructor += ".xy";   break;
-                      case 3: constructor += ".xyz";  break;
-                      case 4: constructor += ".xyzw"; break;
-                      default: UNREACHABLE();
-                    }
-
-                    remainingComponents = 0;
-                }
-                else UNREACHABLE();
-            }
-            else if (parameter.isMatrix() || parameter.getStruct())
-            {
-                ASSERT(remainingComponents == parameterSize || moreParameters);
-                ASSERT(parameterSize <= remainingComponents);
-                
-                remainingComponents -= parameterSize;
-            }
-            else UNREACHABLE();
-
-            if (moreParameters)
-            {
-                parameterIndex++;
-            }
-
-            if (remainingComponents)
-            {
-                constructor += ", ";
-            }
-        }
-    }
-
-    if (ctorType.getStruct())
-    {
-        constructor += "};\n"
-                       "    return structure;\n"
-                       "}\n";
-    }
-    else
-    {
-        constructor += ");\n"
-                       "}\n";
-    }
-
-    mConstructors.insert(constructor);
 }
 
 const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const ConstantUnion *constUnion)
@@ -3749,14 +2828,13 @@
     const TStructure* structure = type.getStruct();
     if (structure)
     {
-        out << structNameString(*structure) + "_ctor(";
-        
+        out << StructNameString(*structure) + "_ctor(";
+
         const TFieldList& fields = structure->fields();
 
         for (size_t i = 0; i < fields.size(); i++)
         {
             const TType *fieldType = fields[i]->type();
-
             constUnion = writeConstantUnion(*fieldType, constUnion);
 
             if (i != fields.size() - 1)
@@ -3771,10 +2849,10 @@
     {
         size_t size = type.getObjectSize();
         bool writeType = size > 1;
-        
+
         if (writeType)
         {
-            out << typeString(type) << "(";
+            out << TypeString(type) << "(";
         }
 
         for (size_t i = 0; i < size; i++, constUnion++)
@@ -3803,386 +2881,4 @@
     return constUnion;
 }
 
-TString OutputHLSL::structNameString(const TStructure &structure)
-{
-    if (structure.name().empty())
-    {
-        return "";
-    }
-
-    return "ss_" + str(structure.uniqueId()) + structure.name();
-}
-
-TString OutputHLSL::decorate(const TString &string)
-{
-    if (string.compare(0, 3, "gl_") != 0 && string.compare(0, 3, "dx_") != 0)
-    {
-        return "_" + string;
-    }
-    
-    return string;
-}
-
-TString OutputHLSL::decorateUniform(const TString &string, const TType &type)
-{
-    if (type.getBasicType() == EbtSamplerExternalOES)
-    {
-        return "ex_" + string;
-    }
-    
-    return decorate(string);
-}
-
-TString OutputHLSL::decorateField(const TString &string, const TStructure &structure)
-{
-    if (structure.name().compare(0, 3, "gl_") != 0)
-    {
-        return decorate(string);
-    }
-
-    return string;
-}
-
-void OutputHLSL::declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output)
-{
-    const TStructure *structure = type.getStruct();
-
-    if (!structure)
-    {
-        const bool isRowMajorMatrix = (type.isMatrix() && type.getLayoutQualifier().matrixPacking == EmpRowMajor);
-        gl::InterfaceBlockField field(glVariableType(type), glVariablePrecision(type), name.c_str(),
-                                      (unsigned int)type.getArraySize(), isRowMajorMatrix);
-        output.push_back(field);
-   }
-    else
-    {
-        gl::InterfaceBlockField structField(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), false);
-
-        const TFieldList &fields = structure->fields();
-
-        for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
-        {
-            TField *field = fields[fieldIndex];
-            TType *fieldType = field->type();
-
-            // make sure to copy matrix packing information
-            fieldType->setLayoutQualifier(type.getLayoutQualifier());
-
-            declareInterfaceBlockField(*fieldType, field->name(), structField.fields);
-        }
-
-        output.push_back(structField);
-    }
-}
-
-gl::Uniform OutputHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform>& output)
-{
-    const TStructure *structure = type.getStruct();
-
-    if (!structure)
-    {
-        gl::Uniform uniform(glVariableType(type), glVariablePrecision(type), name.c_str(),
-                            (unsigned int)type.getArraySize(), (unsigned int)registerIndex, 0);
-        output.push_back(uniform);
-
-        return uniform;
-   }
-    else
-    {
-        gl::Uniform structUniform(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(),
-                                  (unsigned int)registerIndex, GL_INVALID_INDEX);
-
-        const TFieldList &fields = structure->fields();
-
-        for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
-        {
-            TField *field = fields[fieldIndex];
-            TType *fieldType = field->type();
-
-            declareUniformToList(*fieldType, field->name(), GL_INVALID_INDEX, structUniform.fields);
-        }
-
-        // assign register offset information -- this will override the information in any sub-structures.
-        HLSLVariableGetRegisterInfo(registerIndex, &structUniform, mOutputType);
-
-        output.push_back(structUniform);
-
-        return structUniform;
-    }
-}
-
-gl::InterpolationType getInterpolationType(TQualifier qualifier)
-{
-    switch (qualifier)
-    {
-      case EvqFlatIn:
-      case EvqFlatOut:
-        return gl::INTERPOLATION_FLAT;
-
-      case EvqSmoothIn:
-      case EvqSmoothOut:
-      case EvqVertexOut:
-      case EvqFragmentIn:
-      case EvqVaryingIn:
-      case EvqVaryingOut:
-        return gl::INTERPOLATION_SMOOTH;
-
-      case EvqCentroidIn:
-      case EvqCentroidOut:
-        return gl::INTERPOLATION_CENTROID;
-
-      default: UNREACHABLE();
-        return gl::INTERPOLATION_SMOOTH;
-    }
-}
-
-void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut)
-{
-    const TStructure *structure = type.getStruct();
-
-    gl::InterpolationType interpolation = getInterpolationType(baseTypeQualifier);
-    if (!structure)
-    {
-        gl::Varying varying(glVariableType(type), glVariablePrecision(type), name.c_str(), (unsigned int)type.getArraySize(), interpolation);
-        fieldsOut.push_back(varying);
-    }
-    else
-    {
-        gl::Varying structVarying(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), interpolation);
-        const TFieldList &fields = structure->fields();
-
-        structVarying.structName = structure->name().c_str();
-
-        for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
-        {
-            const TField &field = *fields[fieldIndex];
-            declareVaryingToList(*field.type(), baseTypeQualifier, field.name(), structVarying.fields);
-        }
-
-        fieldsOut.push_back(structVarying);
-    }
-}
-
-int OutputHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
-{
-    int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
-
-    const gl::Uniform &uniform = declareUniformToList(type, name, registerIndex, mActiveUniforms);
-
-    if (IsSampler(type.getBasicType()))
-    {
-        mSamplerRegister += gl::HLSLVariableRegisterCount(uniform, mOutputType);
-    }
-    else
-    {
-        mUniformRegister += gl::HLSLVariableRegisterCount(uniform, mOutputType);
-    }
-
-    return registerIndex;
-}
-
-GLenum OutputHLSL::glVariableType(const TType &type)
-{
-    if (type.getBasicType() == EbtFloat)
-    {
-        if (type.isScalar())
-        {
-            return GL_FLOAT;
-        }
-        else if (type.isVector())
-        {
-            switch(type.getNominalSize())
-            {
-              case 2: return GL_FLOAT_VEC2;
-              case 3: return GL_FLOAT_VEC3;
-              case 4: return GL_FLOAT_VEC4;
-              default: UNREACHABLE();
-            }
-        }
-        else if (type.isMatrix())
-        {
-            switch (type.getCols())
-            {
-              case 2:
-                switch(type.getRows())
-                {
-                  case 2: return GL_FLOAT_MAT2;
-                  case 3: return GL_FLOAT_MAT2x3;
-                  case 4: return GL_FLOAT_MAT2x4;
-                  default: UNREACHABLE();
-                }
-
-              case 3:
-                switch(type.getRows())
-                {
-                  case 2: return GL_FLOAT_MAT3x2;
-                  case 3: return GL_FLOAT_MAT3;
-                  case 4: return GL_FLOAT_MAT3x4;
-                  default: UNREACHABLE();
-                }
-
-              case 4:
-                switch(type.getRows())
-                {
-                  case 2: return GL_FLOAT_MAT4x2;
-                  case 3: return GL_FLOAT_MAT4x3;
-                  case 4: return GL_FLOAT_MAT4;
-                  default: UNREACHABLE();
-                }
-
-              default: UNREACHABLE();
-            }
-        }
-        else UNREACHABLE();
-    }
-    else if (type.getBasicType() == EbtInt)
-    {
-        if (type.isScalar())
-        {
-            return GL_INT;
-        }
-        else if (type.isVector())
-        {
-            switch(type.getNominalSize())
-            {
-              case 2: return GL_INT_VEC2;
-              case 3: return GL_INT_VEC3;
-              case 4: return GL_INT_VEC4;
-              default: UNREACHABLE();
-            }
-        }
-        else UNREACHABLE();
-    }
-    else if (type.getBasicType() == EbtUInt)
-    {
-        if (type.isScalar())
-        {
-            return GL_UNSIGNED_INT;
-        }
-        else if (type.isVector())
-        {
-            switch(type.getNominalSize())
-            {
-              case 2: return GL_UNSIGNED_INT_VEC2;
-              case 3: return GL_UNSIGNED_INT_VEC3;
-              case 4: return GL_UNSIGNED_INT_VEC4;
-              default: UNREACHABLE();
-            }
-        }
-        else UNREACHABLE();
-    }
-    else if (type.getBasicType() == EbtBool)
-    {
-        if (type.isScalar())
-        {
-            return GL_BOOL;
-        }
-        else if (type.isVector())
-        {
-            switch(type.getNominalSize())
-            {
-              case 2: return GL_BOOL_VEC2;
-              case 3: return GL_BOOL_VEC3;
-              case 4: return GL_BOOL_VEC4;
-              default: UNREACHABLE();
-            }
-        }
-        else UNREACHABLE();
-    }
-
-    switch(type.getBasicType())
-    {
-      case EbtSampler2D:            return GL_SAMPLER_2D;
-      case EbtSampler3D:            return GL_SAMPLER_3D;
-      case EbtSamplerCube:          return GL_SAMPLER_CUBE;
-      case EbtSampler2DArray:       return GL_SAMPLER_2D_ARRAY;
-      case EbtISampler2D:           return GL_INT_SAMPLER_2D;
-      case EbtISampler3D:           return GL_INT_SAMPLER_3D;
-      case EbtISamplerCube:         return GL_INT_SAMPLER_CUBE;
-      case EbtISampler2DArray:      return GL_INT_SAMPLER_2D_ARRAY;
-      case EbtUSampler2D:           return GL_UNSIGNED_INT_SAMPLER_2D;
-      case EbtUSampler3D:           return GL_UNSIGNED_INT_SAMPLER_3D;
-      case EbtUSamplerCube:         return GL_UNSIGNED_INT_SAMPLER_CUBE;
-      case EbtUSampler2DArray:      return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
-      case EbtSampler2DShadow:      return GL_SAMPLER_2D_SHADOW;
-      case EbtSamplerCubeShadow:    return GL_SAMPLER_CUBE_SHADOW;
-      case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW;
-      default: UNREACHABLE();
-    }
-
-    return GL_NONE;
-}
-
-GLenum OutputHLSL::glVariablePrecision(const TType &type)
-{
-    if (type.getBasicType() == EbtFloat)
-    {
-        switch (type.getPrecision())
-        {
-          case EbpHigh:   return GL_HIGH_FLOAT;
-          case EbpMedium: return GL_MEDIUM_FLOAT;
-          case EbpLow:    return GL_LOW_FLOAT;
-          case EbpUndefined:
-            // Should be defined as the default precision by the parser
-          default: UNREACHABLE();
-        }
-    }
-    else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
-    {
-        switch (type.getPrecision())
-        {
-          case EbpHigh:   return GL_HIGH_INT;
-          case EbpMedium: return GL_MEDIUM_INT;
-          case EbpLow:    return GL_LOW_INT;
-          case EbpUndefined:
-            // Should be defined as the default precision by the parser
-          default: UNREACHABLE();
-        }
-    }
-
-    // Other types (boolean, sampler) don't have a precision
-    return GL_NONE;
-}
-
-bool OutputHLSL::isVaryingOut(TQualifier qualifier)
-{
-    switch(qualifier)
-    {
-      case EvqVaryingOut:
-      case EvqInvariantVaryingOut:
-      case EvqSmoothOut:
-      case EvqFlatOut:
-      case EvqCentroidOut:
-      case EvqVertexOut:
-        return true;
-
-      default: break;
-    }
-
-    return false;
-}
-
-bool OutputHLSL::isVaryingIn(TQualifier qualifier)
-{
-    switch(qualifier)
-    {
-      case EvqVaryingIn:
-      case EvqInvariantVaryingIn:
-      case EvqSmoothIn:
-      case EvqFlatIn:
-      case EvqCentroidIn:
-      case EvqFragmentIn:
-        return true;
-
-      default: break;
-    }
-
-    return false;
-}
-
-bool OutputHLSL::isVarying(TQualifier qualifier)
-{
-    return isVaryingIn(qualifier) || isVaryingOut(qualifier);
-}
-
 }
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index ab5a90b..bec0247 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -11,44 +11,33 @@
 #include <set>
 #include <map>
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
+#include "angle_gl.h"
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/ParseContext.h"
-#include "common/shadervars.h"
 
 namespace sh
 {
 class UnfoldShortCircuit;
+class StructureHLSL;
+class UniformHLSL;
+
+typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
 
 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<gl::Uniform> &getUniforms();
-    const std::vector<gl::InterfaceBlock> &getInterfaceBlocks() const;
-    const std::vector<gl::Attribute> &getOutputVariables() const;
-    const std::vector<gl::Attribute> &getAttributes() const;
-    const std::vector<gl::Varying> &getVaryings() const;
 
-    TString typeString(const TType &type);
-    TString textureString(const TType &type);
-    TString samplerString(const TType &type);
-    TString interpolationString(TQualifier qualifier);
-    TString structureString(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
-    TString structureTypeName(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
-    static TString qualifierString(TQualifier qualifier);
-    static TString arrayString(const TType &type);
+    const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const;
+    const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
+
     static TString initializer(const TType &type);
-    static TString decorate(const TString &string);                      // Prepends an underscore to avoid naming clashes
-    static TString decorateUniform(const TString &string, const TType &type);
-    static TString decorateField(const TString &string, const TStructure &structure);
 
   protected:
     void header();
@@ -72,11 +61,9 @@
     TString argumentString(const TIntermSymbol *symbol);
     int vectorSize(const TType &type) const;
 
-    void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters);
+    void outputConstructor(Visit visit, const TType &type, const TString &name, const TIntermSequence *parameters);
     const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion);
 
-    TString structNameString(const TStructure &structure);
-
     TParseContext &mContext;
     const ShShaderOutput mOutputType;
     UnfoldShortCircuit *mUnfoldShortCircuit;
@@ -87,13 +74,15 @@
     TInfoSinkBase mBody;
     TInfoSinkBase mFooter;
 
-    typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
     ReferencedSymbols mReferencedUniforms;
     ReferencedSymbols mReferencedInterfaceBlocks;
     ReferencedSymbols mReferencedAttributes;
     ReferencedSymbols mReferencedVaryings;
     ReferencedSymbols mReferencedOutputVariables;
 
+    StructureHLSL *mStructureHLSL;
+    UniformHLSL *mUniformHLSL;
+
     struct TextureFunction
     {
         enum Method
@@ -152,15 +141,6 @@
 
     int mNumRenderTargets;
 
-    typedef std::set<TString> Constructors;
-    Constructors mConstructors;
-
-    typedef std::set<TString> StructNames;
-    StructNames mStructNames;
-
-    typedef std::list<TString> StructDeclarations;
-    StructDeclarations mStructDeclarations;
-
     int mUniqueIndex;   // For creating unique names
 
     bool mContainsLoopDiscontinuity;
@@ -170,51 +150,14 @@
 
     TIntermSymbol *mExcessiveLoopIndex;
 
-    int mUniformRegister;
-    int mInterfaceBlockRegister;
-    int mSamplerRegister;
-    int mPaddingCounter;
-
-    TString registerString(TIntermSymbol *operand);
-    int samplerRegister(TIntermSymbol *sampler);
-    int uniformRegister(TIntermSymbol *uniform);
-    void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output);
-    gl::Uniform declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform>& output);
-    void declareUniform(const TType &type, const TString &name, int index);
-    void declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut);
-
-    // Returns the uniform's register index
-    int declareUniformAndAssignRegister(const TType &type, const TString &name);
-
-    TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field);
-    TString decoratePrivate(const TString &privateText);
-    TString interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlockType);
-    TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
-    TString interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage);
-    TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage);
-    TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock);
-    TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex);
-    TString std140PrePaddingString(const TType &type, int *elementIndex);
-    TString std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking);
     TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName);
-    
-    static GLenum glVariableType(const TType &type);
-    static GLenum glVariablePrecision(const TType &type);
-    static bool isVaryingIn(TQualifier qualifier);
-    static bool isVaryingOut(TQualifier qualifier);
-    static bool isVarying(TQualifier qualifier);
 
-    std::vector<gl::Uniform> mActiveUniforms;
-    std::vector<gl::InterfaceBlock> mActiveInterfaceBlocks;
-    std::vector<gl::Attribute> mActiveOutputVariables;
-    std::vector<gl::Attribute> mActiveAttributes;
-    std::vector<gl::Varying> mActiveVaryings;
-    std::map<TString, int> mStd140StructElementIndexes;
     std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
     std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
 
     void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
 };
+
 }
 
 #endif   // COMPILER_OUTPUTHLSL_H_
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index f900966..ff0a496 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -286,21 +286,21 @@
 
                 TIntermTyped* rightNode = binaryNode->getRight();
                 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
-                
-                for (TIntermSequence::iterator p = aggrNode->getSequence().begin(); 
-                                               p != aggrNode->getSequence().end(); p++) {
+
+                for (TIntermSequence::iterator p = aggrNode->getSequence()->begin();
+                                               p != aggrNode->getSequence()->end(); p++) {
                     int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
-                    offset[value]++;     
+                    offset[value]++;
                     if (offset[value] > 1) {
                         error(line, " l-value of swizzle cannot have duplicate components", op);
 
                         return true;
                     }
                 }
-            } 
+            }
 
             return errorReturn;
-        default: 
+        default:
             break;
         }
         error(line, " l-value required", op);
@@ -804,7 +804,7 @@
         if (type.arraySize)
             variable->getType().setArraySize(type.arraySize);
 
-        if (! symbolTable.declare(*variable)) {
+        if (! symbolTable.declare(variable)) {
             delete variable;
             error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str());
             return true;
@@ -884,7 +884,7 @@
 
     variable = new TVariable(&identifier, TType(type));
 
-    if (! symbolTable.declare(*variable)) {
+    if (! symbolTable.declare(variable)) {
         error(line, "redefinition", variable->getName().c_str());
         delete variable;
         variable = 0;
@@ -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)
 {
@@ -1066,7 +1107,7 @@
         // add variable to symbol table
         //
         variable = new TVariable(&identifier, type);
-        if (! symbolTable.declare(*variable)) {
+        if (! symbolTable.declare(variable)) {
             error(line, "redefinition", variable->getName().c_str());
             return true;
             // don't delete variable, it's used by error recovery, and the pool 
@@ -1142,8 +1183,8 @@
 
     // check if all the child nodes are constants so that they can be inserted into 
     // the parent node
-    TIntermSequence &sequence = aggrNode->getSequence() ;
-    for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
+    TIntermSequence *sequence = aggrNode->getSequence() ;
+    for (TIntermSequence::iterator p = sequence->begin(); p != sequence->end(); ++p) {
         if (!(*p)->getAsTyped()->getAsConstantUnion())
             return false;
     }
@@ -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);
 
@@ -1531,81 +1598,40 @@
 //
 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
 //
-TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc& line)
+TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line)
 {
-    if (node == 0)
-        return 0;
+    TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
 
-    TIntermAggregate* aggrNode = node->getAsAggregate();
-    
-    TFieldList::const_iterator memberTypes;
+    if (!aggregateArguments)
+    {
+        aggregateArguments = new TIntermAggregate;
+        aggregateArguments->getSequence()->push_back(arguments);
+    }
+
     if (op == EOpConstructStruct)
-        memberTypes = type->getStruct()->fields().begin();
-    
-    TType elementType = *type;
-    if (type->isArray())
-        elementType.clearArrayness();
+    {
+        const TFieldList &fields = type->getStruct()->fields();
+        TIntermSequence *args = aggregateArguments->getSequence();
 
-    bool singleArg;
-    if (aggrNode) {
-        if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
-            singleArg = true;
-        else
-            singleArg = false;
-    } else
-        singleArg = true;
+        for (size_t i = 0; i < fields.size(); i++)
+        {
+            if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type())
+            {
+                error(line, "Structure constructor arguments do not match structure fields", "Error");
+                recover();
 
-    TIntermTyped *newNode;
-    if (singleArg) {
-        // If structure constructor or array constructor is being called 
-        // for only one parameter inside the structure, we need to call constructStruct function once.
-        if (type->isArray())
-            newNode = constructStruct(node, &elementType, 1, node->getLine(), false);
-        else if (op == EOpConstructStruct)
-            newNode = constructStruct(node, (*memberTypes)->type(), 1, node->getLine(), false);
-        else
-            newNode = constructBuiltIn(type, op, node, node->getLine(), false);
-
-        if (newNode && newNode->getAsAggregate()) {
-            TIntermTyped* constConstructor = foldConstConstructor(newNode->getAsAggregate(), *type);
-            if (constConstructor)
-                return constConstructor;
-        }
-
-        return newNode;
-    }
-    
-    //
-    // Handle list of arguments.
-    //
-    TIntermSequence &sequenceVector = aggrNode->getSequence() ;    // Stores the information about the parameter to the constructor
-    // if the structure constructor contains more than one parameter, then construct
-    // each parameter
-    
-    int paramCount = 0;  // keeps a track of the constructor parameter number being checked    
-    
-    // for each parameter to the constructor call, check to see if the right type is passed or convert them 
-    // to the right type if possible (and allowed).
-    // for structure constructors, just check if the right type is passed, no conversion is allowed.
-    
-    for (TIntermSequence::iterator p = sequenceVector.begin(); 
-                                   p != sequenceVector.end(); p++, paramCount++) {
-        if (type->isArray())
-            newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
-        else if (op == EOpConstructStruct)
-            newNode = constructStruct(*p, (memberTypes[paramCount])->type(), paramCount+1, node->getLine(), true);
-        else
-            newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
-        
-        if (newNode) {
-            *p = newNode;
+                return 0;
+            }
         }
     }
 
-    TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, line);
-    TIntermTyped* constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
+    // Turn the argument list itself into a constructor
+    TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
+    TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
     if (constConstructor)
+    {
         return constConstructor;
+    }
 
     return constructor;
 }
@@ -1617,7 +1643,7 @@
     if (canBeFolded) {
         bool returnVal = false;
         ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
-        if (aggrNode->getSequence().size() == 1)  {
+        if (aggrNode->getSequence()->size() == 1)  {
             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
         }
         else {
@@ -1632,102 +1658,6 @@
     return 0;
 }
 
-// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
-// for the parameter to the constructor (passed to this function). Essentially, it converts
-// the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a 
-// float, then float is converted to int.
-//
-// Returns 0 for an error or the constructed node.
-//
-TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, const TSourceLoc& line, bool subset)
-{
-    TIntermTyped* newNode;
-    TOperator basicOp;
-
-    //
-    // First, convert types as needed.
-    //
-    switch (op) {
-    case EOpConstructVec2:
-    case EOpConstructVec3:
-    case EOpConstructVec4:
-    case EOpConstructMat2:
-    case EOpConstructMat3:
-    case EOpConstructMat4:
-    case EOpConstructFloat:
-        basicOp = EOpConstructFloat;
-        break;
-
-    case EOpConstructIVec2:
-    case EOpConstructIVec3:
-    case EOpConstructIVec4:
-    case EOpConstructInt:
-        basicOp = EOpConstructInt;
-        break;
-
-    case EOpConstructUVec2:
-    case EOpConstructUVec3:
-    case EOpConstructUVec4:
-    case EOpConstructUInt:
-        basicOp = EOpConstructUInt;
-        break;
-
-    case EOpConstructBVec2:
-    case EOpConstructBVec3:
-    case EOpConstructBVec4:
-    case EOpConstructBool:
-        basicOp = EOpConstructBool;
-        break;
-
-    default:
-        error(line, "unsupported construction", "");
-        recover();
-
-        return 0;
-    }
-    newNode = intermediate.addUnaryMath(basicOp, node, node->getLine());
-    if (newNode == 0) {
-        error(line, "can't convert", "constructor");
-        return 0;
-    }
-
-    //
-    // Now, if there still isn't an operation to do the construction, and we need one, add one.
-    //
-    
-    // Otherwise, skip out early.
-    if (subset || (newNode != node && newNode->getType() == *type))
-        return newNode;
-
-    // setAggregateOperator will insert a new node for the constructor, as needed.
-    return intermediate.setAggregateOperator(newNode, op, line);
-}
-
-// This function tests for the type of the parameters to the structures constructors. Raises
-// an error message if the expected type does not match the parameter passed to the constructor.
-//
-// Returns 0 for an error or the input node itself if the expected and the given parameter types match.
-//
-TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, const TSourceLoc& line, bool subset)
-{
-    if (*type == node->getAsTyped()->getType()) {
-        if (subset)
-            return node->getAsTyped();
-        else
-            return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line);
-    } else {
-        std::stringstream extraInfoStream;
-        extraInfoStream << "cannot convert parameter " << paramCount 
-                        << " from '" << node->getAsTyped()->getType().getBasicString()
-                        << "' to '" << type->getBasicString() << "'";
-        std::string extraInfo = extraInfoStream.str();
-        error(line, "", "constructor", extraInfo.c_str());
-        recover();
-    }
-
-    return 0;
-}
-
 //
 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
@@ -1911,7 +1841,7 @@
     }
 
     TSymbol* blockNameSymbol = new TInterfaceBlockName(&blockName);
-    if (!symbolTable.declare(*blockNameSymbol)) {
+    if (!symbolTable.declare(blockNameSymbol)) {
         error(nameLine, "redefinition", blockName.c_str(), "interface block name");
         recover();
     }
@@ -1991,7 +1921,7 @@
             TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
             fieldVariable->setQualifier(typeQualifier.qualifier);
 
-            if (!symbolTable.declare(*fieldVariable)) {
+            if (!symbolTable.declare(fieldVariable)) {
                 error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
                 recover();
             }
@@ -2003,7 +1933,7 @@
         TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
         instanceTypeDef->setQualifier(typeQualifier.qualifier);
 
-        if (!symbolTable.declare(*instanceTypeDef)) {
+        if (!symbolTable.declare(instanceTypeDef)) {
             error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
             recover();
         }
@@ -2592,7 +2522,7 @@
             recover();
         }
         TVariable* userTypeDef = new TVariable(structName, *structureType, true);
-        if (!symbolTable.declare(*userTypeDef)) {
+        if (!symbolTable.declare(userTypeDef)) {
             error(nameLine, "redefinition", structName->c_str(), "struct");
             recover();
         }
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 3cd4b91..1f4cbde 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -1,15 +1,15 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 #ifndef _PARSER_HELPER_INCLUDED_
 #define _PARSER_HELPER_INCLUDED_
 
+#include "compiler/translator/Compiler.h"
 #include "compiler/translator/Diagnostics.h"
 #include "compiler/translator/DirectiveHandler.h"
-#include "compiler/translator/localintermediate.h"
-#include "compiler/translator/ShHandle.h"
+#include "compiler/translator/Intermediate.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/preprocessor/Preprocessor.h"
 
@@ -25,7 +25,7 @@
 // they can be passed to the parser without needing a global.
 //
 struct TParseContext {
-    TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
+    TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, sh::GLenum type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
             intermediate(interm),
             symbolTable(symt),
             shaderType(type),
@@ -47,7 +47,7 @@
             scanner(NULL) {  }
     TIntermediate& intermediate; // to hold and build a parse tree
     TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
-    ShShaderType shaderType;              // vertex or fragment language (future: pack or unpack)
+    sh::GLenum shaderType;              // vertex or fragment language (future: pack or unpack)
     ShShaderSpec shaderSpec;              // The language specification compiler conforms to - GLES2 or WebGL.
     int shaderVersion;
     int compileOptions;
@@ -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);
@@ -133,8 +138,6 @@
     TFunction *addConstructorFunc(TPublicType publicType);
     TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
     TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
-    TIntermTyped* constructStruct(TIntermNode*, TType*, int, const TSourceLoc&, bool subset);
-    TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, const TSourceLoc&, bool subset);
     TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
     TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&);
     TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line);
diff --git a/src/compiler/translator/PoolAlloc.cpp b/src/compiler/translator/PoolAlloc.cpp
index abe7026..887cb66 100644
--- a/src/compiler/translator/PoolAlloc.cpp
+++ b/src/compiler/translator/PoolAlloc.cpp
@@ -6,43 +6,44 @@
 
 #include "compiler/translator/PoolAlloc.h"
 
-#ifndef _MSC_VER
-#include <stdint.h>
-#endif
-#include <stdio.h>
-
-#include "common/angleutils.h"
 #include "compiler/translator/InitializeGlobals.h"
-#include "compiler/translator/osinclude.h"
 
-OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
+#include "common/platform.h"
+#include "common/angleutils.h"
+#include "common/tls.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+
+TLSIndex PoolIndex = TLS_INVALID_INDEX;
 
 bool InitializePoolIndex()
 {
-    assert(PoolIndex == OS_INVALID_TLS_INDEX);
+    assert(PoolIndex == TLS_INVALID_INDEX);
 
-    PoolIndex = OS_AllocTLSIndex();
-    return PoolIndex != OS_INVALID_TLS_INDEX;
+    PoolIndex = CreateTLSIndex();
+    return PoolIndex != TLS_INVALID_INDEX;
 }
 
 void FreePoolIndex()
 {
-    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+    assert(PoolIndex != TLS_INVALID_INDEX);
 
-    OS_FreeTLSIndex(PoolIndex);
-    PoolIndex = OS_INVALID_TLS_INDEX;
+    DestroyTLSIndex(PoolIndex);
+    PoolIndex = TLS_INVALID_INDEX;
 }
 
 TPoolAllocator* GetGlobalPoolAllocator()
 {
-    assert(PoolIndex != OS_INVALID_TLS_INDEX);
-    return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
+    assert(PoolIndex != TLS_INVALID_INDEX);
+    return static_cast<TPoolAllocator*>(GetTLSValue(PoolIndex));
 }
 
 void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
 {
-    assert(PoolIndex != OS_INVALID_TLS_INDEX);
-    OS_SetTLSValue(PoolIndex, poolAllocator);
+    assert(PoolIndex != TLS_INVALID_INDEX);
+    SetTLSValue(PoolIndex, poolAllocator);
 }
 
 //
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.cpp b/src/compiler/translator/RegenerateStructNames.cpp
new file mode 100644
index 0000000..767b180
--- /dev/null
+++ b/src/compiler/translator/RegenerateStructNames.cpp
@@ -0,0 +1,82 @@
+//
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/RegenerateStructNames.h"
+#include "compiler/translator/compilerdebug.h"
+
+void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol)
+{
+    ASSERT(symbol);
+    TType *type = symbol->getTypePointer();
+    ASSERT(type);
+    TStructure *userType = type->getStruct();
+    if (!userType)
+        return;
+
+    if (mSymbolTable.findBuiltIn(userType->name(), mShaderVersion))
+    {
+        // Built-in struct, do not touch it.
+        return;
+    }
+
+    int uniqueId = userType->uniqueId();
+
+    ASSERT(mScopeDepth > 0);
+    if (mScopeDepth == 1)
+    {
+        // If a struct is defined at global scope, we don't map its name.
+        // This is because at global level, the struct might be used to
+        // declare a uniform, so the same name needs to stay the same for
+        // vertex/fragment shaders. However, our mapping uses internal ID,
+        // which will be different for the same struct in vertex/fragment
+        // shaders.
+        // This is OK because names for any structs defined in other scopes
+        // will begin with "_webgl", which is reserved. So there will be
+        // no conflicts among unmapped struct names from global scope and
+        // mapped struct names from other scopes.
+        // However, we need to keep track of these global structs, so if a
+        // variable is used in a local scope, we don't try to modify the
+        // struct name through that variable.
+        mDeclaredGlobalStructs.insert(uniqueId);
+        return;
+    }
+    if (mDeclaredGlobalStructs.count(uniqueId) > 0)
+        return;
+    // Map {name} to _webgl_struct_{uniqueId}_{name}.
+    const char kPrefix[] = "_webgl_struct_";
+    if (userType->name().find(kPrefix) == 0)
+    {
+        // The name has already been regenerated.
+        return;
+    }
+    std::string id = Str(uniqueId);
+    TString tmp = kPrefix + TString(id.c_str());
+    tmp += "_" + userType->name();
+    userType->setName(tmp);
+}
+
+bool RegenerateStructNames::visitAggregate(Visit, TIntermAggregate *aggregate)
+{
+    ASSERT(aggregate);
+    switch (aggregate->getOp())
+    {
+      case EOpSequence:
+        ++mScopeDepth;
+        {
+            TIntermSequence &sequence = *(aggregate->getSequence());
+            for (size_t ii = 0; ii < sequence.size(); ++ii)
+            {
+                TIntermNode *node = sequence[ii];
+                ASSERT(node != NULL);
+                node->traverse(this);
+            }
+        }
+        --mScopeDepth;
+        return false;
+      default:
+        return true;
+    }
+}
diff --git a/src/compiler/translator/RegenerateStructNames.h b/src/compiler/translator/RegenerateStructNames.h
new file mode 100644
index 0000000..ac87600
--- /dev/null
+++ b/src/compiler/translator/RegenerateStructNames.h
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
+#define COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
+
+#include "compiler/translator/Intermediate.h"
+#include "compiler/translator/SymbolTable.h"
+
+#include <set>
+
+class RegenerateStructNames : public TIntermTraverser
+{
+  public:
+    RegenerateStructNames(const TSymbolTable &symbolTable,
+                          int shaderVersion)
+        : mSymbolTable(symbolTable),
+          mShaderVersion(shaderVersion),
+          mScopeDepth(0) {}
+
+  protected:
+    virtual void visitSymbol(TIntermSymbol *);
+    virtual bool visitAggregate(Visit, TIntermAggregate *);
+
+  private:
+    const TSymbolTable &mSymbolTable;
+    int mShaderVersion;
+
+    // Indicating the depth of the current scope.
+    // The global scope is 1.
+    int mScopeDepth;
+
+    // If a struct's declared globally, push its ID in this set.
+    std::set<int> mDeclaredGlobalStructs;
+};
+
+#endif  // COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
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.cpp b/src/compiler/translator/RewriteElseBlocks.cpp
index 46e510c..b03beb5 100644
--- a/src/compiler/translator/RewriteElseBlocks.cpp
+++ b/src/compiler/translator/RewriteElseBlocks.cpp
@@ -14,6 +14,24 @@
 namespace sh
 {
 
+namespace
+{
+
+class ElseBlockRewriter : public TIntermTraverser
+{
+  public:
+    ElseBlockRewriter();
+
+  protected:
+    bool visitAggregate(Visit visit, TIntermAggregate *aggregate);
+
+  private:
+    int mTemporaryIndex;
+    const TType *mFunctionType;
+
+    TIntermNode *rewriteSelection(TIntermSelection *selection);
+};
+
 TIntermSymbol *MakeNewTemporary(const TString &name, TBasicType type)
 {
     TType variableType(type, EbpHigh, EvqInternal);
@@ -49,9 +67,9 @@
       case EOpSequence:
         if (visit == PostVisit)
         {
-            for (size_t statementIndex = 0; statementIndex != node->getSequence().size(); statementIndex++)
+            for (size_t statementIndex = 0; statementIndex != node->getSequence()->size(); statementIndex++)
             {
-                TIntermNode *statement = node->getSequence()[statementIndex];
+                TIntermNode *statement = (*node->getSequence())[statementIndex];
                 TIntermSelection *selection = statement->getAsSelectionNode();
                 if (selection && selection->getFalseBlock() != NULL)
                 {
@@ -63,7 +81,7 @@
                         delete elseIfBranch;
                     }
 
-                    node->getSequence()[statementIndex] = rewriteSelection(selection);
+                    (*node->getSequence())[statementIndex] = rewriteSelection(selection);
                     delete selection;
                 }
             }
@@ -83,46 +101,54 @@
 
 TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
 {
-    ASSERT(selection->getFalseBlock() != NULL);
+    ASSERT(selection != NULL);
 
     TString temporaryName = "cond_" + str(mTemporaryIndex++);
     TIntermTyped *typedCondition = selection->getCondition()->getAsTyped();
     TType resultType(EbtBool, EbpUndefined);
-    TIntermSymbol *conditionSymbolA = MakeNewTemporary(temporaryName, EbtBool);
-    TIntermSymbol *conditionSymbolB = MakeNewTemporary(temporaryName, EbtBool);
-    TIntermSymbol *conditionSymbolC = MakeNewTemporary(temporaryName, EbtBool);
-    TIntermBinary *storeCondition = MakeNewBinary(EOpInitialize, conditionSymbolA,
+    TIntermSymbol *conditionSymbolInit = MakeNewTemporary(temporaryName, EbtBool);
+    TIntermBinary *storeCondition = MakeNewBinary(EOpInitialize, conditionSymbolInit,
                                                   typedCondition, resultType);
-    TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolB);
     TIntermNode *negatedElse = NULL;
 
-    // crbug.com/346463
-    // D3D generates error messages claiming a function has no return value, when rewriting
-    // an if-else clause that returns something non-void in a function. By appending dummy
-    // returns (that are unreachable) we can silence this compile error.
-    if (mFunctionType && mFunctionType->getBasicType() != EbtVoid)
+    TIntermSelection *falseBlock = NULL;
+
+    if (selection->getFalseBlock())
     {
-        TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() :
-            mFunctionType->getBasicString();
-        TString rawText = "return (" + typeString + ")0";
-        negatedElse = new TIntermRaw(*mFunctionType, rawText);
+        // crbug.com/346463
+        // D3D generates error messages claiming a function has no return value, when rewriting
+        // an if-else clause that returns something non-void in a function. By appending dummy
+        // returns (that are unreachable) we can silence this compile error.
+        if (mFunctionType && mFunctionType->getBasicType() != EbtVoid)
+        {
+            TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() :
+                mFunctionType->getBasicString();
+            TString rawText = "return (" + typeString + ")0";
+            negatedElse = new TIntermRaw(*mFunctionType, rawText);
+        }
+
+        TIntermSymbol *conditionSymbolElse = MakeNewTemporary(temporaryName, EbtBool);
+        TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse);
+        falseBlock = new TIntermSelection(negatedCondition,
+                                          selection->getFalseBlock(), negatedElse);
     }
 
-    TIntermSelection *falseBlock = new TIntermSelection(negatedCondition,
-                                                        selection->getFalseBlock(), negatedElse);
-    TIntermSelection *newIfElse = new TIntermSelection(conditionSymbolC,
-                                                       selection->getTrueBlock(), falseBlock);
+    TIntermSymbol *conditionSymbolSel = MakeNewTemporary(temporaryName, EbtBool);
+    TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel,
+                                                          selection->getTrueBlock(), falseBlock);
 
     TIntermAggregate *declaration = new TIntermAggregate(EOpDeclaration);
-    declaration->getSequence().push_back(storeCondition);
+    declaration->getSequence()->push_back(storeCondition);
 
     TIntermAggregate *block = new TIntermAggregate(EOpSequence);
-    block->getSequence().push_back(declaration);
-    block->getSequence().push_back(newIfElse);
+    block->getSequence()->push_back(declaration);
+    block->getSequence()->push_back(newSelection);
 
     return block;
 }
 
+}
+
 void RewriteElseBlocks(TIntermNode *node)
 {
     ElseBlockRewriter rewriter;
diff --git a/src/compiler/translator/RewriteElseBlocks.h b/src/compiler/translator/RewriteElseBlocks.h
index 172928f..d87baea 100644
--- a/src/compiler/translator/RewriteElseBlocks.h
+++ b/src/compiler/translator/RewriteElseBlocks.h
@@ -10,26 +10,11 @@
 #ifndef COMPILER_REWRITE_ELSE_BLOCKS_H_
 #define COMPILER_REWRITE_ELSE_BLOCKS_H_
 
-#include "compiler/translator/intermediate.h"
+#include "compiler/translator/IntermNode.h"
 
 namespace sh
 {
 
-class ElseBlockRewriter : public TIntermTraverser
-{
-  public:
-    ElseBlockRewriter();
-
-  protected:
-    bool visitAggregate(Visit visit, TIntermAggregate *aggregate);
-
-  private:
-    int mTemporaryIndex;
-    const TType *mFunctionType;
-
-    TIntermNode *rewriteSelection(TIntermSelection *selection);
-};
-
 void RewriteElseBlocks(TIntermNode *node);
 
 }
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
new file mode 100644
index 0000000..8857ad5
--- /dev/null
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
@@ -0,0 +1,277 @@
+//
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
+#include "compiler/translator/compilerdebug.h"
+
+#include <algorithm>
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+
+namespace
+{
+
+bool ContainsMatrixNode(const TIntermSequence &sequence)
+{
+    for (size_t ii = 0; ii < sequence.size(); ++ii)
+    {
+        TIntermTyped *node = sequence[ii]->getAsTyped();
+        if (node && node->isMatrix())
+            return true;
+    }
+    return false;
+}
+
+bool ContainsVectorNode(const TIntermSequence &sequence)
+{
+    for (size_t ii = 0; ii < sequence.size(); ++ii)
+    {
+        TIntermTyped *node = sequence[ii]->getAsTyped();
+        if (node && node->isVector())
+            return true;
+    }
+    return false;
+}
+
+TIntermConstantUnion *ConstructIndexNode(int index)
+{
+    ConstantUnion *u = new ConstantUnion[1];
+    u[0].setIConst(index);
+
+    TType type(EbtInt, EbpUndefined, EvqConst, 1);
+    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+    return node;
+}
+
+TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index)
+{
+    TIntermBinary *binary = new TIntermBinary(EOpIndexDirect);
+    binary->setLeft(symbolNode);
+    TIntermConstantUnion *indexNode = ConstructIndexNode(index);
+    binary->setRight(indexNode);
+    return binary;
+}
+
+TIntermBinary *ConstructMatrixIndexBinaryNode(
+    TIntermSymbol *symbolNode, int colIndex, int rowIndex)
+{
+    TIntermBinary *colVectorNode =
+        ConstructVectorIndexBinaryNode(symbolNode, colIndex);
+
+    TIntermBinary *binary = new TIntermBinary(EOpIndexDirect);
+    binary->setLeft(colVectorNode);
+    TIntermConstantUnion *rowIndexNode = ConstructIndexNode(rowIndex);
+    binary->setRight(rowIndexNode);
+    return binary;
+}
+
+}  // namespace anonymous
+
+bool ScalarizeVecAndMatConstructorArgs::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+    if (visit == PreVisit)
+    {
+        switch (node->getOp())
+        {
+          case EOpSequence:
+            mSequenceStack.push_back(TIntermSequence());
+            {
+                for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+                     iter != node->getSequence()->end(); ++iter)
+                {
+                    TIntermNode *child = *iter;
+                    ASSERT(child != NULL);
+                    child->traverse(this);
+                    mSequenceStack.back().push_back(child);
+                }
+            }
+            if (mSequenceStack.back().size() > node->getSequence()->size())
+            {
+                node->getSequence()->clear();
+                *(node->getSequence()) = mSequenceStack.back();
+            }
+            mSequenceStack.pop_back();
+            return false;
+          case EOpConstructVec2:
+          case EOpConstructVec3:
+          case EOpConstructVec4:
+          case EOpConstructBVec2:
+          case EOpConstructBVec3:
+          case EOpConstructBVec4:
+          case EOpConstructIVec2:
+          case EOpConstructIVec3:
+          case EOpConstructIVec4:
+            if (ContainsMatrixNode(*(node->getSequence())))
+                scalarizeArgs(node, false, true);
+            break;
+          case EOpConstructMat2:
+          case EOpConstructMat3:
+          case EOpConstructMat4:
+            if (ContainsVectorNode(*(node->getSequence())))
+                scalarizeArgs(node, true, false);
+            break;
+          default:
+            break;
+        }
+    }
+    return true;
+}
+
+void ScalarizeVecAndMatConstructorArgs::scalarizeArgs(
+    TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix)
+{
+    ASSERT(aggregate);
+    int size = 0;
+    switch (aggregate->getOp())
+    {
+      case EOpConstructVec2:
+      case EOpConstructBVec2:
+      case EOpConstructIVec2:
+        size = 2;
+        break;
+      case EOpConstructVec3:
+      case EOpConstructBVec3:
+      case EOpConstructIVec3:
+        size = 3;
+        break;
+      case EOpConstructVec4:
+      case EOpConstructBVec4:
+      case EOpConstructIVec4:
+      case EOpConstructMat2:
+        size = 4;
+        break;
+      case EOpConstructMat3:
+        size = 9;
+        break;
+      case EOpConstructMat4:
+        size = 16;
+        break;
+      default:
+        break;
+    }
+    TIntermSequence *sequence = aggregate->getSequence();
+    TIntermSequence original(*sequence);
+    sequence->clear();
+    for (size_t ii = 0; ii < original.size(); ++ii)
+    {
+        ASSERT(size > 0);
+        TIntermTyped *node = original[ii]->getAsTyped();
+        ASSERT(node);
+        TString varName = createTempVariable(node);
+        if (node->isScalar())
+        {
+            TIntermSymbol *symbolNode =
+                new TIntermSymbol(-1, varName, node->getType());
+            sequence->push_back(symbolNode);
+            size--;
+        }
+        else if (node->isVector())
+        {
+            if (scalarizeVector)
+            {
+                int repeat = std::min(size, node->getNominalSize());
+                size -= repeat;
+                for (int index = 0; index < repeat; ++index)
+                {
+                    TIntermSymbol *symbolNode =
+                        new TIntermSymbol(-1, varName, node->getType());
+                    TIntermBinary *newNode = ConstructVectorIndexBinaryNode(
+                        symbolNode, index);
+                    sequence->push_back(newNode);
+                }
+            }
+            else
+            {
+                TIntermSymbol *symbolNode =
+                    new TIntermSymbol(-1, varName, node->getType());
+                sequence->push_back(symbolNode);
+                size -= node->getNominalSize();
+            }
+        }
+        else
+        {
+            ASSERT(node->isMatrix());
+            if (scalarizeMatrix)
+            {
+                int colIndex = 0, rowIndex = 0;
+                int repeat = std::min(size, node->getCols() * node->getRows());
+                size -= repeat;
+                while (repeat > 0)
+                {
+                    TIntermSymbol *symbolNode =
+                        new TIntermSymbol(-1, varName, node->getType());
+                    TIntermBinary *newNode = ConstructMatrixIndexBinaryNode(
+                        symbolNode, colIndex, rowIndex);
+                    sequence->push_back(newNode);
+                    rowIndex++;
+                    if (rowIndex >= node->getRows())
+                    {
+                        rowIndex = 0;
+                        colIndex++;
+                    }
+                    repeat--;
+                }
+            }
+            else
+            {
+                TIntermSymbol *symbolNode =
+                    new TIntermSymbol(-1, varName, node->getType());
+                sequence->push_back(symbolNode);
+                size -= node->getCols() * node->getRows();
+            }
+        }
+    }
+}
+
+TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *original)
+{
+    TString tempVarName = "_webgl_tmp_";
+    if (original->isScalar())
+    {
+        tempVarName += "scalar_";
+    }
+    else if (original->isVector())
+    {
+        tempVarName += "vec_";
+    }
+    else
+    {
+        ASSERT(original->isMatrix());
+        tempVarName += "mat_";
+    }
+    tempVarName += Str(mTempVarCount).c_str();
+    mTempVarCount++;
+
+    ASSERT(original);
+    TType type = original->getType();
+    type.setQualifier(EvqTemporary);
+
+    if (mShaderType == GL_FRAGMENT_SHADER &&
+        type.getBasicType() == EbtFloat &&
+        type.getPrecision() == EbpUndefined)
+    {
+        // We use the highest available precision for the temporary variable
+        // to avoid computing the actual precision using the rules defined
+        // in GLSL ES 1.0 Section 4.5.2.
+        type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
+    }
+
+    TIntermBinary *init = new TIntermBinary(EOpInitialize);
+    TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
+    init->setLeft(symbolNode);
+    init->setRight(original);
+    init->setType(type);
+
+    TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration);
+    decl->getSequence()->push_back(init);
+
+    ASSERT(mSequenceStack.size() > 0);
+    TIntermSequence &sequence = mSequenceStack.back();
+    sequence.push_back(decl);
+
+    return tempVarName;
+}
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
new file mode 100644
index 0000000..7c6d09c
--- /dev/null
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
@@ -0,0 +1,47 @@
+//
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
+#define COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
+
+#include "compiler/translator/IntermNode.h"
+
+class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser
+{
+  public:
+    ScalarizeVecAndMatConstructorArgs(sh::GLenum shaderType,
+                                      bool fragmentPrecisionHigh)
+        : mTempVarCount(0),
+          mShaderType(shaderType),
+          mFragmentPrecisionHigh(fragmentPrecisionHigh) {}
+
+  protected:
+    virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
+
+  private:
+    void scalarizeArgs(TIntermAggregate *aggregate,
+                       bool scalarizeVector, bool scalarizeMatrix);
+
+    // If we have the following code:
+    //   mat4 m(0);
+    //   vec4 v(1, m);
+    // We will rewrite to:
+    //   mat4 m(0);
+    //   mat4 _webgl_tmp_mat_0 = m;
+    //   vec4 v(1, _webgl_tmp_mat_0[0][0], _webgl_tmp_mat_0[0][1], _webgl_tmp_mat_0[0][2]);
+    // This function is to create nodes for "mat4 _webgl_tmp_mat_0 = m;" and insert it to
+    // the code sequence.
+    // Return the temporary variable name.
+    TString createTempVariable(TIntermTyped *original);
+
+    std::vector<TIntermSequence> mSequenceStack;
+    int mTempVarCount;
+
+    sh::GLenum mShaderType;
+    bool mFragmentPrecisionHigh;
+};
+
+#endif  // COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
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/ShaderLang.cpp b/src/compiler/translator/ShaderLang.cpp
index bf0587a..20ce716 100644
--- a/src/compiler/translator/ShaderLang.cpp
+++ b/src/compiler/translator/ShaderLang.cpp
@@ -11,20 +11,33 @@
 
 #include "GLSLANG/ShaderLang.h"
 
+#include "compiler/translator/Compiler.h"
 #include "compiler/translator/InitializeDll.h"
 #include "compiler/translator/length_limits.h"
-#include "compiler/translator/ShHandle.h"
 #include "compiler/translator/TranslatorHLSL.h"
 #include "compiler/translator/VariablePacker.h"
+#include "angle_gl.h"
 
-static bool isInitialized = false;
+namespace
+{
+
+enum ShaderVariableType
+{
+    SHADERVAR_UNIFORM,
+    SHADERVAR_VARYING,
+    SHADERVAR_ATTRIBUTE,
+    SHADERVAR_OUTPUTVARIABLE,
+    SHADERVAR_INTERFACEBLOCK
+};
+    
+bool isInitialized = false;
 
 //
 // This is the platform independent interface between an OGL driver
 // and the shading language compiler.
 //
 
-static bool checkVariableMaxLengths(const ShHandle handle,
+static bool CheckVariableMaxLengths(const ShHandle handle,
                                     size_t expectedValue)
 {
     size_t activeUniformLimit = 0;
@@ -38,13 +51,107 @@
             expectedValue == varyingLimit);
 }
 
-static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
+bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
 {
     size_t mappedNameMaxLength = 0;
     ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
     return (expectedValue == mappedNameMaxLength);
 }
 
+template <typename VarT>
+const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
+{
+    if (index < 0 || static_cast<size_t>(index) >= infoList.size())
+    {
+        return NULL;
+    }
+
+    return &infoList[index];
+}
+
+const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
+{
+    switch (varType)
+    {
+      case SH_ACTIVE_ATTRIBUTES:
+        return ReturnVariable(compiler->getAttributes(), index);
+      case SH_ACTIVE_UNIFORMS:
+        return ReturnVariable(compiler->getExpandedUniforms(), index);
+      case SH_VARYINGS:
+        return ReturnVariable(compiler->getExpandedVaryings(), index);
+      default:
+        UNREACHABLE();
+        return NULL;
+    }
+}
+
+ShPrecisionType ConvertPrecision(sh::GLenum precision)
+{
+    switch (precision)
+    {
+      case GL_HIGH_FLOAT:
+      case GL_HIGH_INT:
+        return SH_PRECISION_HIGHP;
+      case GL_MEDIUM_FLOAT:
+      case GL_MEDIUM_INT:
+        return SH_PRECISION_MEDIUMP;
+      case GL_LOW_FLOAT:
+      case GL_LOW_INT:
+        return SH_PRECISION_LOWP;
+      default:
+        return SH_PRECISION_UNDEFINED;
+    }
+}
+
+template <typename VarT>
+const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
+
+template <>
+const std::vector<sh::Uniform> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
+{
+    return &compiler->getUniforms();
+}
+
+template <>
+const std::vector<sh::Varying> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
+{
+    return &compiler->getVaryings();
+}
+
+template <>
+const std::vector<sh::Attribute> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType)
+{
+    return (variableType == SHADERVAR_ATTRIBUTE ?
+        &compiler->getAttributes() :
+        &compiler->getOutputVariables());
+}
+
+template <>
+const std::vector<sh::InterfaceBlock> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
+{
+    return &compiler->getInterfaceBlocks();
+}
+
+template <typename VarT>
+const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariableType variableType)
+{
+    if (!handle)
+    {
+        return NULL;
+    }
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+    TCompiler* compiler = base->getAsCompiler();
+    if (!compiler)
+    {
+        return NULL;
+    }
+
+    return GetVariableList<VarT>(compiler, variableType);
+}
+
+}
+
 //
 // Driver must call this first, once, before doing any other compiler operations.
 // Subsequent calls to this function are no-op.
@@ -115,7 +222,7 @@
 //
 // Driver calls these to create and destroy compiler objects.
 //
-ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
+ShHandle ShConstructCompiler(sh::GLenum type, ShShaderSpec spec,
                              ShShaderOutput output,
                              const ShBuiltInResources* resources)
 {
@@ -204,19 +311,19 @@
         *params = compiler->getInfoSink().obj.size() + 1;
         break;
     case SH_ACTIVE_UNIFORMS:
-        *params = compiler->getUniforms().size();
+        *params = compiler->getExpandedUniforms().size();
         break;
     case SH_ACTIVE_UNIFORM_MAX_LENGTH:
         *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
         break;
     case SH_ACTIVE_ATTRIBUTES:
-        *params = compiler->getAttribs().size();
+        *params = compiler->getAttributes().size();
         break;
     case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
         *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
         break;
     case SH_VARYINGS:
-        *params = compiler->getVaryings().size();
+        *params = compiler->getExpandedVaryings().size();
         break;
     case SH_VARYING_MAX_LENGTH:
         *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
@@ -293,7 +400,7 @@
                        int index,
                        size_t* length,
                        int* size,
-                       ShDataType* type,
+                       sh::GLenum* type,
                        ShPrecisionType* precision,
                        int* staticUse,
                        char* name,
@@ -310,47 +417,32 @@
     if (compiler == 0)
         return;
 
-    const TVariableInfoList& varList =
-        varType == SH_ACTIVE_ATTRIBUTES ? compiler->getAttribs() :
-            (varType == SH_ACTIVE_UNIFORMS ? compiler->getUniforms() :
-                compiler->getVaryings());
-    if (index < 0 || index >= static_cast<int>(varList.size()))
+    const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index);
+    if (!varInfo)
+    {
         return;
-
-    const TVariableInfo& varInfo = varList[index];
-    if (length) *length = varInfo.name.size();
-    *size = varInfo.size;
-    *type = varInfo.type;
-    switch (varInfo.precision) {
-    case EbpLow:
-        *precision = SH_PRECISION_LOWP;
-        break;
-    case EbpMedium:
-        *precision = SH_PRECISION_MEDIUMP;
-        break;
-    case EbpHigh:
-        *precision = SH_PRECISION_HIGHP;
-        break;
-    default:
-        // Some types does not support precision, for example, boolean.
-        *precision = SH_PRECISION_UNDEFINED;
-        break;
     }
-    *staticUse = varInfo.staticUse ? 1 : 0;
+
+    if (length) *length = varInfo->name.size();
+    *size = varInfo->elementCount();
+    *type = varInfo->type;
+    *precision = ConvertPrecision(varInfo->precision);
+    *staticUse = varInfo->staticUse ? 1 : 0;
 
     // This size must match that queried by
     // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
     // in ShGetInfo, below.
     size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-    ASSERT(checkVariableMaxLengths(handle, variableLength));
-    strncpy(name, varInfo.name.c_str(), variableLength);
+    ASSERT(CheckVariableMaxLengths(handle, variableLength));
+    strncpy(name, varInfo->name.c_str(), variableLength);
     name[variableLength - 1] = 0;
-    if (mappedName) {
+    if (mappedName)
+    {
         // This size must match that queried by
         // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
         size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-        ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
-        strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
+        ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength));
+        strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
         mappedName[maxMappedNameLength - 1] = 0;
     }
 }
@@ -398,34 +490,29 @@
     hashedName[len - 1] = '\0';
 }
 
-void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
+const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
 {
-    if (!handle || !params)
-        return;
+    return GetShaderVariables<sh::Uniform>(handle, SHADERVAR_UNIFORM);
+}
 
-    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TranslatorHLSL* translator = base->getAsTranslatorHLSL();
-    if (!translator) return;
+const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle)
+{
+    return GetShaderVariables<sh::Varying>(handle, SHADERVAR_VARYING);
+}
 
-    switch(pname)
-    {
-    case SH_ACTIVE_UNIFORMS_ARRAY:
-        *params = (void*)&translator->getUniforms();
-        break;
-    case SH_ACTIVE_INTERFACE_BLOCKS_ARRAY:
-        *params = (void*)&translator->getInterfaceBlocks();
-        break;
-    case SH_ACTIVE_OUTPUT_VARIABLES_ARRAY:
-        *params = (void*)&translator->getOutputVariables();
-        break;
-    case SH_ACTIVE_ATTRIBUTES_ARRAY:
-        *params = (void*)&translator->getAttributes();
-        break;
-    case SH_ACTIVE_VARYINGS_ARRAY:
-        *params = (void*)&translator->getVaryings();
-        break;
-    default: UNREACHABLE();
-    }
+const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle)
+{
+    return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_ATTRIBUTE);
+}
+
+const std::vector<sh::Attribute> *ShGetOutputVariables(const ShHandle handle)
+{
+    return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_OUTPUTVARIABLE);
+}
+
+const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
+{
+    return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
 }
 
 int ShCheckVariablesWithinPackingLimits(
@@ -434,12 +521,62 @@
     if (varInfoArraySize == 0)
         return 1;
     ASSERT(varInfoArray);
-    TVariableInfoList variables;
+    std::vector<sh::ShaderVariable> variables;
     for (size_t ii = 0; ii < varInfoArraySize; ++ii)
     {
-        TVariableInfo var(varInfoArray[ii].type, varInfoArray[ii].size);
+        sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size);
         variables.push_back(var);
     }
     VariablePacker packer;
     return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
 }
+
+bool ShGetInterfaceBlockRegister(const ShHandle handle,
+                                 const char *interfaceBlockName,
+                                 unsigned int *indexOut)
+{
+    if (!handle || !interfaceBlockName || !indexOut)
+    {
+        return false;
+    }
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+    TranslatorHLSL* translator = base->getAsTranslatorHLSL();
+    if (!translator)
+    {
+        return false;
+    }
+
+    if (!translator->hasInterfaceBlock(interfaceBlockName))
+    {
+        return false;
+    }
+
+    *indexOut = translator->getInterfaceBlockRegister(interfaceBlockName);
+    return true;
+}
+
+bool ShGetUniformRegister(const ShHandle handle,
+                          const char *uniformName,
+                          unsigned int *indexOut)
+{
+    if (!handle || !uniformName || !indexOut)
+    {
+        return false;
+    }
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+    TranslatorHLSL* translator = base->getAsTranslatorHLSL();
+    if (!translator)
+    {
+        return false;
+    }
+
+    if (!translator->hasUniform(uniformName))
+    {
+        return false;
+    }
+
+    *indexOut = translator->getUniformRegister(uniformName);
+    return true;
+}
diff --git a/src/compiler/translator/ShaderVars.cpp b/src/compiler/translator/ShaderVars.cpp
new file mode 100644
index 0000000..822c558
--- /dev/null
+++ b/src/compiler/translator/ShaderVars.cpp
@@ -0,0 +1,166 @@
+//
+// 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.
+//
+// ShaderVars.cpp:
+//  Methods for GL variable types (varyings, uniforms, etc)
+//
+
+#include <GLSLANG/ShaderLang.h>
+
+namespace sh
+{
+
+ShaderVariable::ShaderVariable()
+    : type(0),
+      precision(0),
+      arraySize(0),
+      staticUse(false)
+{}
+
+ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn)
+    : type(typeIn),
+      precision(0),
+      arraySize(arraySizeIn),
+      staticUse(false)
+{}
+
+ShaderVariable::~ShaderVariable()
+{}
+
+ShaderVariable::ShaderVariable(const ShaderVariable &other)
+    : type(other.type),
+      precision(other.precision),
+      name(other.name),
+      mappedName(other.mappedName),
+      arraySize(other.arraySize),
+      staticUse(other.staticUse),
+      fields(other.fields),
+      structName(other.structName)
+{}
+
+ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
+{
+    type = other.type;
+    precision = other.precision;
+    name = other.name;
+    mappedName = other.mappedName;
+    arraySize = other.arraySize;
+    staticUse = other.staticUse;
+    fields = other.fields;
+    structName = other.structName;
+    return *this;
+}
+
+Uniform::Uniform()
+{}
+
+Uniform::~Uniform()
+{}
+
+Uniform::Uniform(const Uniform &other)
+    : ShaderVariable(other)
+{}
+
+Uniform &Uniform::operator=(const Uniform &other)
+{
+    ShaderVariable::operator=(other);
+    return *this;
+}
+
+Attribute::Attribute()
+    : location(-1)
+{}
+
+Attribute::~Attribute()
+{}
+
+Attribute::Attribute(const Attribute &other)
+    : ShaderVariable(other),
+      location(other.location)
+{}
+
+Attribute &Attribute::operator=(const Attribute &other)
+{
+    ShaderVariable::operator=(other);
+    location = other.location;
+    return *this;
+}
+
+InterfaceBlockField::InterfaceBlockField()
+    : isRowMajorLayout(false)
+{}
+
+InterfaceBlockField::~InterfaceBlockField()
+{}
+
+InterfaceBlockField::InterfaceBlockField(const InterfaceBlockField &other)
+    : ShaderVariable(other),
+      isRowMajorLayout(other.isRowMajorLayout)
+{}
+
+InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &other)
+{
+    ShaderVariable::operator=(other);
+    isRowMajorLayout = other.isRowMajorLayout;
+    return *this;
+}
+
+Varying::Varying()
+    : interpolation(INTERPOLATION_SMOOTH),
+      isInvariant(false)
+{}
+
+Varying::~Varying()
+{}
+
+Varying::Varying(const Varying &other)
+    : ShaderVariable(other),
+      interpolation(other.interpolation),
+      isInvariant(other.isInvariant)
+{}
+
+Varying &Varying::operator=(const Varying &other)
+{
+    ShaderVariable::operator=(other);
+    interpolation = other.interpolation;
+    isInvariant = other.isInvariant;
+    return *this;
+}
+
+InterfaceBlock::InterfaceBlock()
+    : arraySize(0),
+      layout(BLOCKLAYOUT_PACKED),
+      isRowMajorLayout(false),
+      staticUse(false)
+{}
+
+InterfaceBlock::~InterfaceBlock()
+{}
+
+InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
+    : name(other.name),
+      mappedName(other.mappedName),
+      instanceName(other.instanceName),
+      arraySize(other.arraySize),
+      layout(other.layout),
+      isRowMajorLayout(other.isRowMajorLayout),
+      staticUse(other.staticUse),
+      fields(other.fields)
+{}
+
+InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
+{
+    name = other.name;
+    mappedName = other.mappedName;
+    instanceName = other.instanceName;
+    arraySize = other.arraySize;
+    layout = other.layout;
+    isRowMajorLayout = other.isRowMajorLayout;
+    staticUse = other.staticUse;
+    fields = other.fields;
+    return *this;
+}
+
+}
diff --git a/src/compiler/translator/StructureHLSL.cpp b/src/compiler/translator/StructureHLSL.cpp
new file mode 100644
index 0000000..48929af
--- /dev/null
+++ b/src/compiler/translator/StructureHLSL.cpp
@@ -0,0 +1,490 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// StructureHLSL.cpp:
+//   Definitions of methods for HLSL translation of GLSL structures.
+//
+
+#include "compiler/translator/StructureHLSL.h"
+#include "common/utilities.h"
+#include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/Types.h"
+#include "compiler/translator/util.h"
+#include "compiler/translator/UtilsHLSL.h"
+
+namespace sh
+{
+
+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())
+    {
+        // no padding needed, HLSL will align the field to a new register
+        mElementIndex = 0;
+        return 0;
+    }
+
+    const GLenum glType = GLVariableType(type);
+    const int numComponents = gl::VariableComponentCount(glType);
+
+    if (numComponents >= 4)
+    {
+        // no padding needed, HLSL will align the field to a new register
+        mElementIndex = 0;
+        return 0;
+    }
+
+    if (mElementIndex + numComponents > 4)
+    {
+        // no padding needed, HLSL will align the field to a new register
+        mElementIndex = numComponents;
+        return 0;
+    }
+
+    const int alignment = numComponents == 3 ? 4 : numComponents;
+    const int paddingOffset = (mElementIndex % alignment);
+    const int paddingCount = (paddingOffset != 0 ? (alignment - paddingOffset) : 0);
+
+    mElementIndex += paddingCount;
+    mElementIndex += numComponents;
+    mElementIndex %= 4;
+
+    return paddingCount;
+}
+
+TString Std140PaddingHelper::prePaddingString(const TType &type)
+{
+    int paddingCount = prePadding(type);
+
+    TString padding;
+
+    for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
+    {
+        padding += "    float pad_" + next() + ";\n";
+    }
+
+    return padding;
+}
+
+TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRowMajorPacking)
+{
+    if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
+    {
+        return "";
+    }
+
+    int numComponents = 0;
+    TStructure *structure = type.getStruct();
+
+    if (type.isMatrix())
+    {
+        // This method can also be called from structureString, which does not use layout qualifiers.
+        // Thus, use the method parameter for determining the matrix packing.
+        //
+        // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
+        // wish to always transpose GL matrices to play well with HLSL's matrix array indexing.
+        //
+        const bool isRowMajorMatrix = !useHLSLRowMajorPacking;
+        const GLenum glType = GLVariableType(type);
+        numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
+    }
+    else if (structure)
+    {
+        const TString &structName = QualifiedStructNameString(*structure,
+                                                              useHLSLRowMajorPacking, true);
+        numComponents = mStructElementIndexes.find(structName)->second;
+
+        if (numComponents == 0)
+        {
+            return "";
+        }
+    }
+    else
+    {
+        const GLenum glType = GLVariableType(type);
+        numComponents = gl::VariableComponentCount(glType);
+    }
+
+    TString padding;
+    for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
+    {
+        padding += "    float pad_" + next() + ";\n";
+    }
+    return padding;
+}
+
+StructureHLSL::StructureHLSL()
+    : mUniquePaddingCounter(0)
+{}
+
+Std140PaddingHelper StructureHLSL::getPaddingHelper()
+{
+    return Std140PaddingHelper(mStd140StructElementIndexes, &mUniquePaddingCounter);
+}
+
+TString StructureHLSL::defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing)
+{
+    if (useStd140Packing)
+    {
+        Std140PaddingHelper padHelper = getPaddingHelper();
+        return define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper);
+    }
+    else
+    {
+        return define(structure, useHLSLRowMajorPacking, useStd140Packing, NULL);
+    }
+}
+
+TString StructureHLSL::defineNameless(const TStructure &structure)
+{
+    return define(structure, false, false, NULL);
+}
+
+TString StructureHLSL::define(const TStructure &structure, bool useHLSLRowMajorPacking,
+                              bool useStd140Packing, Std140PaddingHelper *padHelper)
+{
+    const TFieldList &fields = structure.fields();
+    const bool isNameless = (structure.name() == "");
+    const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking,
+                                                          useStd140Packing);
+    const TString declareString = (isNameless ? "struct" : "struct " + structName);
+
+    TString string;
+    string += declareString + "\n"
+              "{\n";
+
+    for (unsigned int i = 0; i < fields.size(); i++)
+    {
+        const TField &field = *fields[i];
+        const TType &fieldType = *field.type();
+        const TStructure *fieldStruct = fieldType.getStruct();
+        const TString &fieldTypeString = fieldStruct ?
+                                         QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
+                                                                   useStd140Packing) :
+                                         TypeString(fieldType);
+
+        if (padHelper)
+        {
+            string += padHelper->prePaddingString(fieldType);
+        }
+
+        string += "    " + fieldTypeString + " " + DecorateField(field.name(), structure) + ArrayString(fieldType) + ";\n";
+
+        if (padHelper)
+        {
+            string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking);
+        }
+    }
+
+    // Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable
+    string += (isNameless ? "} " : "};\n");
+
+    return string;
+}
+
+void StructureHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
+{
+    if (name == "")
+    {
+        return;   // Nameless structures don't have constructors
+    }
+
+    if (type.getStruct() && mStructNames.find(name) != mStructNames.end())
+    {
+        return;   // Already added
+    }
+
+    TType ctorType = type;
+    ctorType.clearArrayness();
+    ctorType.setPrecision(EbpHigh);
+    ctorType.setQualifier(EvqTemporary);
+
+    typedef std::vector<TType> ParameterArray;
+    ParameterArray ctorParameters;
+
+    const TStructure* structure = type.getStruct();
+    if (structure)
+    {
+        mStructNames.insert(name);
+
+        // Add element index
+        storeStd140ElementIndex(*structure, false);
+        storeStd140ElementIndex(*structure, true);
+
+        const TString &structString = defineQualified(*structure, false, false);
+
+        if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end())
+        {
+            // Add row-major packed struct for interface blocks
+            TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
+                defineQualified(*structure, true, false) +
+                "#pragma pack_matrix(column_major)\n";
+
+            TString std140String = defineQualified(*structure, false, true);
+            TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
+                defineQualified(*structure, true, true) +
+                "#pragma pack_matrix(column_major)\n";
+
+            mStructDeclarations.push_back(structString);
+            mStructDeclarations.push_back(rowMajorString);
+            mStructDeclarations.push_back(std140String);
+            mStructDeclarations.push_back(std140RowMajorString);
+        }
+
+        const TFieldList &fields = structure->fields();
+        for (unsigned int i = 0; i < fields.size(); i++)
+        {
+            ctorParameters.push_back(*fields[i]->type());
+        }
+    }
+    else if (parameters)
+    {
+        for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++)
+        {
+            ctorParameters.push_back((*parameter)->getAsTyped()->getType());
+        }
+    }
+    else UNREACHABLE();
+
+    TString constructor;
+
+    if (ctorType.getStruct())
+    {
+        constructor += name + " " + name + "_ctor(";
+    }
+    else   // Built-in type
+    {
+        constructor += TypeString(ctorType) + " " + name + "(";
+    }
+
+    for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
+    {
+        const TType &type = ctorParameters[parameter];
+
+        constructor += TypeString(type) + " x" + str(parameter) + ArrayString(type);
+
+        if (parameter < ctorParameters.size() - 1)
+        {
+            constructor += ", ";
+        }
+    }
+
+    constructor += ")\n"
+                   "{\n";
+
+    if (ctorType.getStruct())
+    {
+        constructor += "    " + name + " structure = {";
+    }
+    else
+    {
+        constructor += "    return " + TypeString(ctorType) + "(";
+    }
+
+    if (ctorType.isMatrix() && ctorParameters.size() == 1)
+    {
+        int rows = ctorType.getRows();
+        int cols = ctorType.getCols();
+        const TType &parameter = ctorParameters[0];
+
+        if (parameter.isScalar())
+        {
+            for (int col = 0; col < cols; col++)
+            {
+                for (int row = 0; row < rows; row++)
+                {
+                    constructor += TString((row == col) ? "x0" : "0.0");
+
+                    if (row < rows - 1 || col < cols - 1)
+                    {
+                        constructor += ", ";
+                    }
+                }
+            }
+        }
+        else if (parameter.isMatrix())
+        {
+            for (int col = 0; col < cols; col++)
+            {
+                for (int row = 0; row < rows; row++)
+                {
+                    if (row < parameter.getRows() && col < parameter.getCols())
+                    {
+                        constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]";
+                    }
+                    else
+                    {
+                        constructor += TString((row == col) ? "1.0" : "0.0");
+                    }
+
+                    if (row < rows - 1 || col < cols - 1)
+                    {
+                        constructor += ", ";
+                    }
+                }
+            }
+        }
+        else
+        {
+            ASSERT(rows == 2 && cols == 2 && parameter.isVector() && parameter.getNominalSize() == 4);
+
+            constructor += "x0";
+        }
+    }
+    else
+    {
+        size_t remainingComponents = ctorType.getObjectSize();
+        size_t parameterIndex = 0;
+
+        while (remainingComponents > 0)
+        {
+            const TType &parameter = ctorParameters[parameterIndex];
+            const size_t parameterSize = parameter.getObjectSize();
+            bool moreParameters = parameterIndex + 1 < ctorParameters.size();
+
+            constructor += "x" + str(parameterIndex);
+
+            if (ctorType.getStruct())
+            {
+                ASSERT(remainingComponents == parameterSize || moreParameters);
+                ASSERT(parameterSize <= remainingComponents);
+
+                remainingComponents -= parameterSize;
+            }
+            else if (parameter.isScalar())
+            {
+                remainingComponents -= parameter.getObjectSize();
+            }
+            else if (parameter.isVector())
+            {
+                if (remainingComponents == parameterSize || moreParameters)
+                {
+                    ASSERT(parameterSize <= remainingComponents);
+                    remainingComponents -= parameterSize;
+                }
+                else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
+                {
+                    switch (remainingComponents)
+                    {
+                      case 1: constructor += ".x";    break;
+                      case 2: constructor += ".xy";   break;
+                      case 3: constructor += ".xyz";  break;
+                      case 4: constructor += ".xyzw"; break;
+                      default: UNREACHABLE();
+                    }
+
+                    remainingComponents = 0;
+                }
+                else UNREACHABLE();
+            }
+            else if (parameter.isMatrix())
+            {
+                int column = 0;
+                while (remainingComponents > 0 && column < parameter.getCols())
+                {
+                    constructor += "[" + str(column) + "]";
+
+                    if (remainingComponents < static_cast<size_t>(parameter.getRows()))
+                    {
+                        switch (remainingComponents)
+                        {
+                          case 1:  constructor += ".x";    break;
+                          case 2:  constructor += ".xy";   break;
+                          case 3:  constructor += ".xyz";  break;
+                          default: UNREACHABLE();
+                        }
+
+                        remainingComponents = 0;
+                    }
+                    else
+                    {
+                        remainingComponents -= parameter.getRows();
+
+                        if (remainingComponents > 0)
+                        {
+                            constructor += ", x" + str(parameterIndex);
+                        }
+                    }
+
+                    column++;
+                }
+            }
+            else UNREACHABLE();
+
+            if (moreParameters)
+            {
+                parameterIndex++;
+            }
+
+            if (remainingComponents)
+            {
+                constructor += ", ";
+            }
+        }
+    }
+
+    if (ctorType.getStruct())
+    {
+        constructor += "};\n"
+                        "    return structure;\n"
+                        "}\n";
+    }
+    else
+    {
+        constructor += ");\n"
+                       "}\n";
+    }
+
+    mConstructors.insert(constructor);
+}
+
+std::string StructureHLSL::structsHeader() const
+{
+    TInfoSinkBase out;
+
+    for (size_t structIndex = 0; structIndex < mStructDeclarations.size(); structIndex++)
+    {
+        out << mStructDeclarations[structIndex];
+    }
+
+    for (Constructors::const_iterator constructor = mConstructors.begin();
+         constructor != mConstructors.end();
+         constructor++)
+    {
+        out << *constructor;
+    }
+
+    return out.str();
+}
+
+void StructureHLSL::storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking)
+{
+    Std140PaddingHelper padHelper = getPaddingHelper();
+    const TFieldList &fields = structure.fields();
+
+    for (unsigned int i = 0; i < fields.size(); i++)
+    {
+        padHelper.prePadding(*fields[i]->type());
+    }
+
+    // Add remaining element index to the global map, for use with nested structs in standard layouts
+    const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true);
+    mStd140StructElementIndexes[structName] = padHelper.elementIndex();
+}
+
+}
diff --git a/src/compiler/translator/StructureHLSL.h b/src/compiler/translator/StructureHLSL.h
new file mode 100644
index 0000000..ed002fe
--- /dev/null
+++ b/src/compiler/translator/StructureHLSL.h
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// StructureHLSL.h:
+//   Interfaces of methods for HLSL translation of GLSL structures.
+//
+
+#ifndef TRANSLATOR_STRUCTUREHLSL_H_
+#define TRANSLATOR_STRUCTUREHLSL_H_
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/IntermNode.h"
+
+#include <set>
+
+class TInfoSinkBase;
+class TScopeBracket;
+
+namespace sh
+{
+
+// This helper class assists structure and interface block definitions in determining
+// how to pack std140 structs within HLSL's packing rules.
+class Std140PaddingHelper
+{
+  public:
+    explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
+                                 unsigned *uniqueCounter);
+
+    int elementIndex() const { return mElementIndex; }
+    int prePadding(const TType &type);
+    TString prePaddingString(const TType &type);
+    TString postPaddingString(const TType &type, bool useHLSLRowMajorPacking);
+
+  private:
+    TString next();
+
+    unsigned *mPaddingCounter;
+    int mElementIndex;
+    const std::map<TString, int> &mStructElementIndexes;
+};
+
+class StructureHLSL
+{
+  public:
+    StructureHLSL();
+
+    void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters);
+    std::string structsHeader() const;
+
+    TString defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
+    static TString defineNameless(const TStructure &structure);
+
+    Std140PaddingHelper getPaddingHelper();
+
+  private:
+    unsigned mUniquePaddingCounter;
+
+    std::map<TString, int> mStd140StructElementIndexes;
+
+    typedef std::set<TString> StructNames;
+    StructNames mStructNames;
+
+    typedef std::set<TString> Constructors;
+    Constructors mConstructors;
+
+    typedef std::vector<TString> StructDeclarations;
+    StructDeclarations mStructDeclarations;
+
+    void storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking);
+    static TString define(const TStructure &structure, bool useHLSLRowMajorPacking,
+                         bool useStd140Packing, Std140PaddingHelper *padHelper);
+};
+
+}
+
+#endif // COMPILER_STRUCTUREHLSL_H_
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index aa5933d..028da21 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -38,21 +38,16 @@
         delete (*it).second;
 }
 
-bool TSymbolTableLevel::insert(const TString &name, TSymbol &symbol)
+bool TSymbolTableLevel::insert(TSymbol *symbol)
 {
-    symbol.setUniqueId(TSymbolTable::nextUniqueId());
+    symbol->setUniqueId(TSymbolTable::nextUniqueId());
 
     // returning true means symbol was added to the table
-    tInsertResult result = level.insert(tLevelPair(name, &symbol));
+    tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
 
     return result.second;
 }
 
-bool TSymbolTableLevel::insert(TSymbol &symbol)
-{
-    return insert(symbol.getMangledName(), symbol);
-}
-
 TSymbol *TSymbolTableLevel::find(const TString &name) const
 {
     tLevel::const_iterator it = level.find(name);
@@ -103,7 +98,8 @@
     uniqueId = copyOf.uniqueId;
 }
 
-TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope)
+TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
+                            bool *builtIn, bool *sameScope) const
 {
     int level = currentLevel();
     TSymbol *symbol;
@@ -127,7 +123,8 @@
     return symbol;
 }
 
-TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion)
+TSymbol *TSymbolTable::findBuiltIn(
+    const TString &name, int shaderVersion) const
 {
     for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
     {
@@ -212,10 +209,10 @@
         }
     }
 
-    insert(level, *function);
+    insert(level, function);
 }
 
-TPrecision TSymbolTable::getDefaultPrecision(TBasicType type)
+TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
 {
     if (!SupportsPrecision(type))
         return EbpUndefined;
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 3f932a4..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
@@ -185,7 +185,7 @@
           defined(false)
     {
     }
-    TFunction(const TString *name, TType &retType, TOperator tOp = EOpNull)
+    TFunction(const TString *name, const TType &retType, TOperator tOp = EOpNull)
         : TSymbol(name),
           returnType(retType),
           mangledName(TFunction::mangleName(*name)),
@@ -288,8 +288,7 @@
     }
     ~TSymbolTableLevel();
 
-    bool insert(const TString &name, TSymbol &symbol);
-    bool insert(TSymbol &symbol);
+    bool insert(TSymbol *symbol);
 
     TSymbol *find(const TString &name) const;
 
@@ -298,7 +297,6 @@
 
   protected:
     tLevel level;
-    static int uniqueId; // for unique identification in code generation
 };
 
 enum ESymbolLevel
@@ -325,15 +323,15 @@
     // When the symbol table is initialized with the built-ins, there should
     // 'push' calls, so that built-ins are at level 0 and the shader
     // globals are at level 1.
-    bool isEmpty()
+    bool isEmpty() const
     {
         return table.empty();
     }
-    bool atBuiltInLevel()
+    bool atBuiltInLevel() const
     {
         return currentLevel() <= LAST_BUILTIN_LEVEL;
     }
-    bool atGlobalLevel()
+    bool atGlobalLevel() const
     {
         return currentLevel() <= GLOBAL_LEVEL;
     }
@@ -352,12 +350,12 @@
         precisionStack.pop_back();
     }
 
-    bool declare(TSymbol &symbol)
+    bool declare(TSymbol *symbol)
     {
         return insert(currentLevel(), symbol);
     }
 
-    bool insert(ESymbolLevel level, TSymbol &symbol)
+    bool insert(ESymbolLevel level, TSymbol *symbol)
     {
         return table[level]->insert(symbol);
     }
@@ -367,7 +365,7 @@
         TVariable *constant = new TVariable(
             NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
         constant->getConstPointer()->setIConst(value);
-        return insert(level, *constant);
+        return insert(level, constant);
     }
 
     void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name,
@@ -375,8 +373,8 @@
                        TType *ptype4 = 0, TType *ptype5 = 0);
 
     TSymbol *find(const TString &name, int shaderVersion,
-                  bool *builtIn = NULL, bool *sameScope = NULL);
-    TSymbol *findBuiltIn(const TString &name, int shaderVersion);
+                  bool *builtIn = NULL, bool *sameScope = NULL) const;
+    TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
     
     TSymbolTableLevel *getOuterLevel()
     {
@@ -408,7 +406,7 @@
 
     // Searches down the precisionStack for a precision qualifier
     // for the specified TBasicType
-    TPrecision getDefaultPrecision(TBasicType type);
+    TPrecision getDefaultPrecision(TBasicType type) const;
 
     static int nextUniqueId()
     {
diff --git a/src/compiler/translator/TranslatorESSL.cpp b/src/compiler/translator/TranslatorESSL.cpp
index c956e29..5b99fea 100644
--- a/src/compiler/translator/TranslatorESSL.cpp
+++ b/src/compiler/translator/TranslatorESSL.cpp
@@ -7,8 +7,9 @@
 #include "compiler/translator/TranslatorESSL.h"
 
 #include "compiler/translator/OutputESSL.h"
+#include "angle_gl.h"
 
-TranslatorESSL::TranslatorESSL(ShShaderType type, ShShaderSpec spec)
+TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
     : TCompiler(type, spec, SH_ESSL_OUTPUT) {
 }
 
@@ -20,7 +21,7 @@
 
     // Write emulated built-in functions if needed.
     getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
-        sink, getShaderType() == SH_FRAGMENT_SHADER);
+        sink, getShaderType() == GL_FRAGMENT_SHADER);
 
     // Write array bounds clamping emulation if needed.
     getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
diff --git a/src/compiler/translator/TranslatorESSL.h b/src/compiler/translator/TranslatorESSL.h
index e18f3c2..5576682 100644
--- a/src/compiler/translator/TranslatorESSL.h
+++ b/src/compiler/translator/TranslatorESSL.h
@@ -7,11 +7,11 @@
 #ifndef COMPILER_TRANSLATORESSL_H_
 #define COMPILER_TRANSLATORESSL_H_
 
-#include "compiler/translator/ShHandle.h"
+#include "compiler/translator/Compiler.h"
 
 class TranslatorESSL : public TCompiler {
 public:
-    TranslatorESSL(ShShaderType type, ShShaderSpec spec);
+    TranslatorESSL(sh::GLenum type, ShShaderSpec spec);
 
 protected:
     virtual void translate(TIntermNode* root);
diff --git a/src/compiler/translator/TranslatorGLSL.cpp b/src/compiler/translator/TranslatorGLSL.cpp
index 749d837..4b2aeca 100644
--- a/src/compiler/translator/TranslatorGLSL.cpp
+++ b/src/compiler/translator/TranslatorGLSL.cpp
@@ -9,7 +9,7 @@
 #include "compiler/translator/OutputGLSL.h"
 #include "compiler/translator/VersionGLSL.h"
 
-static void writeVersion(ShShaderType type, TIntermNode* root,
+static void writeVersion(sh::GLenum type, TIntermNode* root,
                          TInfoSinkBase& sink) {
     TVersionGLSL versionGLSL(type);
     root->traverse(&versionGLSL);
@@ -21,7 +21,7 @@
     }
 }
 
-TranslatorGLSL::TranslatorGLSL(ShShaderType type, ShShaderSpec spec)
+TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
     : TCompiler(type, spec, SH_GLSL_OUTPUT) {
 }
 
diff --git a/src/compiler/translator/TranslatorGLSL.h b/src/compiler/translator/TranslatorGLSL.h
index 1e16b26..3c6c2e4 100644
--- a/src/compiler/translator/TranslatorGLSL.h
+++ b/src/compiler/translator/TranslatorGLSL.h
@@ -7,11 +7,11 @@
 #ifndef COMPILER_TRANSLATORGLSL_H_
 #define COMPILER_TRANSLATORGLSL_H_
 
-#include "compiler/translator/ShHandle.h"
+#include "compiler/translator/Compiler.h"
 
 class TranslatorGLSL : public TCompiler {
 public:
-    TranslatorGLSL(ShShaderType type, ShShaderSpec spec);
+    TranslatorGLSL(sh::GLenum type, ShShaderSpec spec);
 
 protected:
     virtual void translate(TIntermNode* root);
diff --git a/src/compiler/translator/TranslatorHLSL.cpp b/src/compiler/translator/TranslatorHLSL.cpp
index da6f980..22bf60e 100644
--- a/src/compiler/translator/TranslatorHLSL.cpp
+++ b/src/compiler/translator/TranslatorHLSL.cpp
@@ -9,21 +9,40 @@
 #include "compiler/translator/InitializeParseContext.h"
 #include "compiler/translator/OutputHLSL.h"
 
-TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
-  : TCompiler(type, spec, output)
+TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+    : TCompiler(type, spec, output)
 {
 }
 
 void TranslatorHLSL::translate(TIntermNode *root)
 {
     TParseContext& parseContext = *GetGlobalParseContext();
-    sh::OutputHLSL outputHLSL(parseContext, getResources(), getOutputType());
+    sh::OutputHLSL outputHLSL(parseContext, this);
 
     outputHLSL.output();
 
-    mActiveUniforms         = outputHLSL.getUniforms();
-    mActiveInterfaceBlocks  = outputHLSL.getInterfaceBlocks();
-    mActiveOutputVariables  = outputHLSL.getOutputVariables();
-    mActiveAttributes       = outputHLSL.getAttributes();
-    mActiveVaryings         = outputHLSL.getVaryings();
+    mInterfaceBlockRegisterMap = outputHLSL.getInterfaceBlockRegisterMap();
+    mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
+}
+
+bool TranslatorHLSL::hasInterfaceBlock(const std::string &interfaceBlockName) const
+{
+    return (mInterfaceBlockRegisterMap.count(interfaceBlockName) > 0);
+}
+
+unsigned int TranslatorHLSL::getInterfaceBlockRegister(const std::string &interfaceBlockName) const
+{
+    ASSERT(hasInterfaceBlock(interfaceBlockName));
+    return mInterfaceBlockRegisterMap.find(interfaceBlockName)->second;
+}
+
+bool TranslatorHLSL::hasUniform(const std::string &uniformName) const
+{
+    return (mUniformRegisterMap.count(uniformName) > 0);
+}
+
+unsigned int TranslatorHLSL::getUniformRegister(const std::string &uniformName) const
+{
+    ASSERT(hasUniform(uniformName));
+    return mUniformRegisterMap.find(uniformName)->second;
 }
diff --git a/src/compiler/translator/TranslatorHLSL.h b/src/compiler/translator/TranslatorHLSL.h
index 8b16587..11a042d 100644
--- a/src/compiler/translator/TranslatorHLSL.h
+++ b/src/compiler/translator/TranslatorHLSL.h
@@ -7,28 +7,25 @@
 #ifndef COMPILER_TRANSLATORHLSL_H_
 #define COMPILER_TRANSLATORHLSL_H_
 
-#include "compiler/translator/ShHandle.h"
-#include "common/shadervars.h"
+#include "compiler/translator/Compiler.h"
 
-class TranslatorHLSL : public TCompiler {
-public:
-    TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
-
+class TranslatorHLSL : public TCompiler
+{
+  public:
+    TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
     virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
-    const std::vector<gl::Uniform> &getUniforms() { return mActiveUniforms; }
-    const std::vector<gl::InterfaceBlock> &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
-    const std::vector<gl::Attribute> &getOutputVariables() { return mActiveOutputVariables; }
-    const std::vector<gl::Attribute> &getAttributes() { return mActiveAttributes; }
-    const std::vector<gl::Varying> &getVaryings() { return mActiveVaryings; }
 
-protected:
+    bool hasInterfaceBlock(const std::string &interfaceBlockName) const;
+    unsigned int getInterfaceBlockRegister(const std::string &interfaceBlockName) const;
+
+    bool hasUniform(const std::string &uniformName) const;
+    unsigned int getUniformRegister(const std::string &uniformName) const;
+
+  protected:
     virtual void translate(TIntermNode* root);
 
-    std::vector<gl::Uniform> mActiveUniforms;
-    std::vector<gl::InterfaceBlock> mActiveInterfaceBlocks;
-    std::vector<gl::Attribute> mActiveOutputVariables;
-    std::vector<gl::Attribute> mActiveAttributes;
-    std::vector<gl::Varying> mActiveVaryings;
+    std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
+    std::map<std::string, unsigned int> mUniformRegisterMap;
 };
 
 #endif  // COMPILER_TRANSLATORHLSL_H_
diff --git a/src/compiler/translator/Types.cpp b/src/compiler/translator/Types.cpp
index 4763920..d36936f 100644
--- a/src/compiler/translator/Types.cpp
+++ b/src/compiler/translator/Types.cpp
@@ -13,6 +13,38 @@
 #include <algorithm>
 #include <climits>
 
+const char* getBasicString(TBasicType t)
+{
+    switch (t)
+    {
+      case EbtVoid:                 return "void";                 break;
+      case EbtFloat:                return "float";                break;
+      case EbtInt:                  return "int";                  break;
+      case EbtUInt:                 return "uint";                 break;
+      case EbtBool:                 return "bool";                 break;
+      case EbtSampler2D:            return "sampler2D";            break;
+      case EbtSampler3D:            return "sampler3D";            break;
+      case EbtSamplerCube:          return "samplerCube";          break;
+      case EbtSamplerExternalOES:   return "samplerExternalOES";   break;
+      case EbtSampler2DRect:        return "sampler2DRect";        break;
+      case EbtSampler2DArray:       return "sampler2DArray";       break;
+      case EbtISampler2D:           return "isampler2D";           break;
+      case EbtISampler3D:           return "isampler3D";           break;
+      case EbtISamplerCube:         return "isamplerCube";         break;
+      case EbtISampler2DArray:      return "isampler2DArray";      break;
+      case EbtUSampler2D:           return "usampler2D";           break;
+      case EbtUSampler3D:           return "usampler3D";           break;
+      case EbtUSamplerCube:         return "usamplerCube";         break;
+      case EbtUSampler2DArray:      return "usampler2DArray";      break;
+      case EbtSampler2DShadow:      return "sampler2DShadow";      break;
+      case EbtSamplerCubeShadow:    return "samplerCubeShadow";    break;
+      case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
+      case EbtStruct:               return "structure";            break;
+      case EbtInterfaceBlock:       return "interface block";      break;
+      default: UNREACHABLE();       return "unknown type";
+    }
+}
+
 TType::TType(const TPublicType &p)
     : type(p.type), precision(p.precision), qualifier(p.qualifier), layoutQualifier(p.layoutQualifier),
       primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize),
@@ -22,57 +54,9 @@
         structure = p.userDef->getStruct();
 }
 
-bool TType::equals(const TType &other) const
-{
-    if (type != other.type || precision != other.precision ||
-        primarySize != other.primarySize || secondarySize != other.secondarySize ||
-        array != other.array || (array && arraySize != other.arraySize) ||
-        interfaceBlock != other.interfaceBlock || structure != other.structure)
-    {
-        return false;
-    }
-    if (interfaceBlock && !interfaceBlock->equals(*(other.interfaceBlock)))
-        return false;
-    if (structure && !structure->equals(*(other.structure)))
-        return false;
-    return true;
-}
-
-bool TField::equals(const TField &other) const
-{
-    ASSERT(mType && mName);
-    ASSERT(other.mType && other.mName);
-    return mType->equals(*(other.mType)) && *mName == *(other.mName);
-}
-
-bool TFieldListCollection::equals(const TFieldListCollection &other) const
-{
-    ASSERT(mName && mFields);
-    ASSERT(other.mName && other.mFields);
-    if (*mName != *(other.mName))
-         return false;
-    if (mFields->size() != other.mFields->size())
-        return false;
-    for (size_t ii = 0; ii < mFields->size(); ++ii)
-    {
-        ASSERT((*mFields)[ii] && (*(other.mFields))[ii]);
-        if (!(*mFields)[ii]->equals(*((*(other.mFields))[ii])))
-            return false;
-    }
-    return true;
-}
-
 bool TStructure::equals(const TStructure &other) const
 {
-    return TFieldListCollection::equals(other);
-}
-
-bool TInterfaceBlock::equals(const TInterfaceBlock &other) const
-{
-    if (!TFieldListCollection::equals(other))
-        return false;
-    // TODO(zmo): do we need to consider mBlockStorage and mMatrixPacking?
-    return mArraySize == other.mArraySize;
+    return (uniqueId() == other.uniqueId());
 }
 
 //
diff --git a/src/compiler/translator/Types.h b/src/compiler/translator/Types.h
index 7629720..075196d 100644
--- a/src/compiler/translator/Types.h
+++ b/src/compiler/translator/Types.h
@@ -48,8 +48,6 @@
         return mLine;
     }
 
-    bool equals(const TField &other) const;
-
   private:
     DISALLOW_COPY_AND_ASSIGN(TField);
     TType *mType;
@@ -100,8 +98,6 @@
     size_t calculateObjectSize() const;
     virtual TString mangledNamePrefix() const = 0;
 
-    bool equals(const TFieldListCollection &other) const;
-
     const TString *mName;
     TFieldList *mFields;
 
@@ -144,6 +140,17 @@
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TStructure);
+
+    // TODO(zmo): Find a way to get rid of the const_cast in function
+    // setName().  At the moment keep this function private so only
+    // friend class RegenerateStructNames may call it.
+    friend class RegenerateStructNames;
+    void setName(const TString &name)
+    {
+        TString *mutableName = const_cast<TString *>(mName);
+        *mutableName = name;
+    }
+
     virtual TString mangledNamePrefix() const
     {
         return "struct-";
@@ -193,8 +200,6 @@
         return mMatrixPacking;
     }
 
-    bool equals(const TInterfaceBlock &other) const;
-
   private:
     DISALLOW_COPY_AND_ASSIGN(TInterfaceBlock);
     virtual TString mangledNamePrefix() const
@@ -385,10 +390,6 @@
         return mangled;
     }
 
-    // This is different from operator== as we also compare
-    // precision here.
-    bool equals(const TType &other) const;
-
     bool sameElementType(const TType &right) const
     {
         return type == right.type &&
diff --git a/src/compiler/translator/UnfoldShortCircuit.cpp b/src/compiler/translator/UnfoldShortCircuit.cpp
index b782611..65f50c4 100644
--- a/src/compiler/translator/UnfoldShortCircuit.cpp
+++ b/src/compiler/translator/UnfoldShortCircuit.cpp
@@ -12,6 +12,7 @@
 
 #include "compiler/translator/InfoSink.h"
 #include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
 
 namespace sh
 {
@@ -117,7 +118,7 @@
     {
         int i = mTemporaryIndex;
 
-        out << mOutputHLSL->typeString(node->getType()) << " s" << i << ";\n";
+        out << TypeString(node->getType()) << " s" << i << ";\n";
 
         out << "{\n";
 
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
new file mode 100644
index 0000000..61b6ed7
--- /dev/null
+++ b/src/compiler/translator/UniformHLSL.cpp
@@ -0,0 +1,281 @@
+//
+// 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.
+//
+// UniformHLSL.cpp:
+//   Methods for GLSL to HLSL translation for uniforms and interface blocks.
+//
+
+#include "OutputHLSL.h"
+#include "common/blocklayout.h"
+#include "common/utilities.h"
+#include "compiler/translator/UniformHLSL.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/util.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/TranslatorHLSL.h"
+
+namespace sh
+{
+
+static const char *UniformRegisterPrefix(const TType &type)
+{
+    if (IsSampler(type.getBasicType()))
+    {
+        return "s";
+    }
+    else
+    {
+        return "c";
+    }
+}
+
+static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
+{
+    const TType &fieldType = *field.type();
+    const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
+    ASSERT(matrixPacking != EmpUnspecified);
+    TStructure *structure = fieldType.getStruct();
+
+    if (fieldType.isMatrix())
+    {
+        // Use HLSL row-major packing for GLSL column-major matrices
+        const TString &matrixPackString = (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
+        return matrixPackString + " " + TypeString(fieldType);
+    }
+    else if (structure)
+    {
+        // Use HLSL row-major packing for GLSL column-major matrices
+        return QualifiedStructNameString(*structure, matrixPacking == EmpColumnMajor,
+            blockStorage == EbsStd140);
+    }
+    else
+    {
+        return TypeString(fieldType);
+    }
+}
+
+static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock)
+{
+    return DecoratePrivate(interfaceBlock.name()) + "_type";
+}
+
+UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator)
+    : mUniformRegister(0),
+      mInterfaceBlockRegister(0),
+      mSamplerRegister(0),
+      mStructureHLSL(structureHLSL),
+      mOutputType(translator->getOutputType()),
+      mUniforms(translator->getUniforms())
+{}
+
+void UniformHLSL::reserveUniformRegisters(unsigned int registerCount)
+{
+    mUniformRegister = registerCount;
+}
+
+void UniformHLSL::reserveInterfaceBlockRegisters(unsigned int registerCount)
+{
+    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);
+
+    const Uniform *uniform = findUniformByName(name);
+    ASSERT(uniform);
+
+    mUniformRegisterMap[uniform->name] = registerIndex;
+
+    unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
+
+    if (gl::IsSampler(uniform->type))
+    {
+        mSamplerRegister += registerCount;
+    }
+    else
+    {
+        mUniformRegister += registerCount;
+    }
+
+    return registerIndex;
+}
+
+TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms)
+{
+    TString uniforms;
+
+    for (ReferencedSymbols::const_iterator uniformIt = referencedUniforms.begin();
+         uniformIt != referencedUniforms.end(); uniformIt++)
+    {
+        const TIntermSymbol &uniform = *uniformIt->second;
+        const TType &type = uniform.getType();
+        const TString &name = uniform.getSymbol();
+
+        unsigned int registerIndex = declareUniformAndAssignRegister(type, name);
+
+        if (outputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType()))   // Also declare the texture
+        {
+            uniforms += "uniform " + SamplerString(type) + " sampler_" + DecorateUniform(name, type) + ArrayString(type) +
+                        " : register(s" + str(registerIndex) + ");\n";
+
+            uniforms += "uniform " + TextureString(type) + " texture_" + DecorateUniform(name, type) + ArrayString(type) +
+                        " : register(t" + str(registerIndex) + ");\n";
+        }
+        else
+        {
+            const TStructure *structure = type.getStruct();
+            // If this is a nameless struct, we need to use its full definition, rather than its (empty) name.
+            // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for 
+            // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers are
+            // permitted.
+            const TString &typeName = ((structure && !structure->name().empty()) ?
+                                        QualifiedStructNameString(*structure, false, false) : TypeString(type));
+
+            const TString &registerString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")";
+
+            uniforms += "uniform " + typeName + " " + DecorateUniform(name, type) + ArrayString(type) + " : " + registerString + ";\n";
+        }
+    }
+
+    return (uniforms.empty() ? "" : ("// Uniforms\n\n" + uniforms));
+}
+
+TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks)
+{
+    TString interfaceBlocks;
+
+    for (ReferencedSymbols::const_iterator interfaceBlockIt = referencedInterfaceBlocks.begin();
+         interfaceBlockIt != referencedInterfaceBlocks.end(); interfaceBlockIt++)
+    {
+        const TType &nodeType = interfaceBlockIt->second->getType();
+        const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock();
+
+        unsigned int arraySize = static_cast<unsigned int>(interfaceBlock.arraySize());
+        unsigned int activeRegister = mInterfaceBlockRegister;
+
+        mInterfaceBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister;
+        mInterfaceBlockRegister += std::max(1u, arraySize);
+
+        // FIXME: interface block field names
+
+        if (interfaceBlock.hasInstanceName())
+        {
+            interfaceBlocks += interfaceBlockStructString(interfaceBlock);
+        }
+
+        if (arraySize > 0)
+        {
+            for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
+            {
+                interfaceBlocks += interfaceBlockString(interfaceBlock, activeRegister + arrayIndex, arrayIndex);
+            }
+        }
+        else
+        {
+            interfaceBlocks += interfaceBlockString(interfaceBlock, activeRegister, GL_INVALID_INDEX);
+        }
+    }
+
+    return (interfaceBlocks.empty() ? "" : ("// Interface Blocks\n\n" + interfaceBlocks));
+}
+
+TString UniformHLSL::interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex)
+{
+    const TString &arrayIndexString =  (arrayIndex != GL_INVALID_INDEX ? Decorate(str(arrayIndex)) : "");
+    const TString &blockName = interfaceBlock.name() + arrayIndexString;
+    TString hlsl;
+
+    hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n"
+            "{\n";
+
+    if (interfaceBlock.hasInstanceName())
+    {
+        hlsl += "    " + InterfaceBlockStructName(interfaceBlock) + " " +
+                interfaceBlockInstanceString(interfaceBlock, arrayIndex) + ";\n";
+    }
+    else
+    {
+        const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+        hlsl += interfaceBlockMembersString(interfaceBlock, blockStorage);
+    }
+
+    hlsl += "};\n\n";
+
+    return hlsl;
+}
+
+TString UniformHLSL::interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex)
+{
+    if (!interfaceBlock.hasInstanceName())
+    {
+        return "";
+    }
+    else if (interfaceBlock.isArray())
+    {
+        return DecoratePrivate(interfaceBlock.instanceName()) + "_" + str(arrayIndex);
+    }
+    else
+    {
+        return Decorate(interfaceBlock.instanceName());
+    }
+}
+
+TString UniformHLSL::interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage)
+{
+    TString hlsl;
+
+    Std140PaddingHelper padHelper = mStructureHLSL->getPaddingHelper();
+
+    for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++)
+    {
+        const TField &field = *interfaceBlock.fields()[typeIndex];
+        const TType &fieldType = *field.type();
+
+        if (blockStorage == EbsStd140)
+        {
+            // 2 and 3 component vector types in some cases need pre-padding
+            hlsl += padHelper.prePaddingString(fieldType);
+        }
+
+        hlsl += "    " + InterfaceBlockFieldTypeString(field, blockStorage) +
+                " " + Decorate(field.name()) + ArrayString(fieldType) + ";\n";
+
+        // must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff
+        if (blockStorage == EbsStd140)
+        {
+            const bool useHLSLRowMajorPacking = (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
+            hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking);
+        }
+    }
+
+    return hlsl;
+}
+
+TString UniformHLSL::interfaceBlockStructString(const TInterfaceBlock &interfaceBlock)
+{
+    const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+
+    return "struct " + InterfaceBlockStructName(interfaceBlock) + "\n"
+           "{\n" +
+           interfaceBlockMembersString(interfaceBlock, blockStorage) +
+           "};\n\n";
+}
+
+}
diff --git a/src/compiler/translator/UniformHLSL.h b/src/compiler/translator/UniformHLSL.h
new file mode 100644
index 0000000..91fa515
--- /dev/null
+++ b/src/compiler/translator/UniformHLSL.h
@@ -0,0 +1,63 @@
+//
+// 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.
+//
+// UniformHLSL.h:
+//   Methods for GLSL to HLSL translation for uniforms and interface blocks.
+//
+
+#ifndef TRANSLATOR_UNIFORMHLSL_H_
+#define TRANSLATOR_UNIFORMHLSL_H_
+
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+class StructureHLSL;
+
+class UniformHLSL
+{
+  public:
+    UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator);
+
+    void reserveUniformRegisters(unsigned int registerCount);
+    void reserveInterfaceBlockRegisters(unsigned int registerCount);
+    TString uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms);
+    TString interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks);
+
+    // Used for direct index references
+    static TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
+
+    const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const
+    {
+        return mInterfaceBlockRegisterMap;
+    }
+    const std::map<std::string, unsigned int> &getUniformRegisterMap() const
+    {
+        return mUniformRegisterMap;
+    }
+
+  private:
+    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);
+
+    unsigned int mUniformRegister;
+    unsigned int mInterfaceBlockRegister;
+    unsigned int mSamplerRegister;
+    StructureHLSL *mStructureHLSL;
+    ShShaderOutput mOutputType;
+
+    const std::vector<Uniform> &mUniforms;
+    std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
+    std::map<std::string, unsigned int> mUniformRegisterMap;
+};
+
+}
+
+#endif // TRANSLATOR_UNIFORMHLSL_H_
diff --git a/src/compiler/translator/UtilsHLSL.cpp b/src/compiler/translator/UtilsHLSL.cpp
new file mode 100644
index 0000000..de0c36c
--- /dev/null
+++ b/src/compiler/translator/UtilsHLSL.cpp
@@ -0,0 +1,243 @@
+//
+// 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.
+//
+// UtilsHLSL.cpp:
+//   Utility methods for GLSL to HLSL translation.
+//
+
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+TString SamplerString(const TType &type)
+{
+    if (IsShadowSampler(type.getBasicType()))
+    {
+        return "SamplerComparisonState";
+    }
+    else
+    {
+        return "SamplerState";
+    }
+}
+
+TString TextureString(const TType &type)
+{
+    switch (type.getBasicType())
+    {
+      case EbtSampler2D:            return "Texture2D";
+      case EbtSamplerCube:          return "TextureCube";
+      case EbtSamplerExternalOES:   return "Texture2D";
+      case EbtSampler2DArray:       return "Texture2DArray";
+      case EbtSampler3D:            return "Texture3D";
+      case EbtISampler2D:           return "Texture2D<int4>";
+      case EbtISampler3D:           return "Texture3D<int4>";
+      case EbtISamplerCube:         return "Texture2DArray<int4>";
+      case EbtISampler2DArray:      return "Texture2DArray<int4>";
+      case EbtUSampler2D:           return "Texture2D<uint4>";
+      case EbtUSampler3D:           return "Texture3D<uint4>";
+      case EbtUSamplerCube:         return "Texture2DArray<uint4>";
+      case EbtUSampler2DArray:      return "Texture2DArray<uint4>";
+      case EbtSampler2DShadow:      return "Texture2D";
+      case EbtSamplerCubeShadow:    return "TextureCube";
+      case EbtSampler2DArrayShadow: return "Texture2DArray";
+      default: UNREACHABLE();
+    }
+
+    return "<unknown texture type>";
+}
+
+TString DecorateUniform(const TString &string, const TType &type)
+{
+    if (type.getBasicType() == EbtSamplerExternalOES)
+    {
+        return "ex_" + string;
+    }
+
+    return Decorate(string);
+}
+
+TString DecorateField(const TString &string, const TStructure &structure)
+{
+    if (structure.name().compare(0, 3, "gl_") != 0)
+    {
+        return Decorate(string);
+    }
+
+    return string;
+}
+
+TString DecoratePrivate(const TString &privateText)
+{
+    return "dx_" + privateText;
+}
+
+TString Decorate(const TString &string)
+{
+    if (string.compare(0, 3, "gl_") != 0)
+    {
+        return "_" + string;
+    }
+
+    return string;
+}
+
+TString TypeString(const TType &type)
+{
+    const TStructure* structure = type.getStruct();
+    if (structure)
+    {
+        const TString& typeName = structure->name();
+        if (typeName != "")
+        {
+            return StructNameString(*structure);
+        }
+        else   // Nameless structure, define in place
+        {
+            return StructureHLSL::defineNameless(*structure);
+        }
+    }
+    else if (type.isMatrix())
+    {
+        int cols = type.getCols();
+        int rows = type.getRows();
+        return "float" + str(cols) + "x" + str(rows);
+    }
+    else
+    {
+        switch (type.getBasicType())
+        {
+          case EbtFloat:
+            switch (type.getNominalSize())
+            {
+              case 1: return "float";
+              case 2: return "float2";
+              case 3: return "float3";
+              case 4: return "float4";
+            }
+          case EbtInt:
+            switch (type.getNominalSize())
+            {
+              case 1: return "int";
+              case 2: return "int2";
+              case 3: return "int3";
+              case 4: return "int4";
+            }
+          case EbtUInt:
+            switch (type.getNominalSize())
+            {
+              case 1: return "uint";
+              case 2: return "uint2";
+              case 3: return "uint3";
+              case 4: return "uint4";
+            }
+          case EbtBool:
+            switch (type.getNominalSize())
+            {
+              case 1: return "bool";
+              case 2: return "bool2";
+              case 3: return "bool3";
+              case 4: return "bool4";
+            }
+          case EbtVoid:
+            return "void";
+          case EbtSampler2D:
+          case EbtISampler2D:
+          case EbtUSampler2D:
+          case EbtSampler2DArray:
+          case EbtISampler2DArray:
+          case EbtUSampler2DArray:
+            return "sampler2D";
+          case EbtSamplerCube:
+          case EbtISamplerCube:
+          case EbtUSamplerCube:
+            return "samplerCUBE";
+          case EbtSamplerExternalOES:
+            return "sampler2D";
+          default:
+            break;
+        }
+    }
+
+    UNREACHABLE();
+    return "<unknown type>";
+}
+
+TString StructNameString(const TStructure &structure)
+{
+    if (structure.name().empty())
+    {
+        return "";
+    }
+
+    return "ss" + str(structure.uniqueId()) + "_" + structure.name();
+}
+
+TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMajorPacking,
+                                  bool useStd140Packing)
+{
+    if (structure.name() == "")
+    {
+        return "";
+    }
+
+    TString prefix = "";
+
+    // Structs packed with row-major matrices in HLSL are prefixed with "rm"
+    // GLSL column-major maps to HLSL row-major, and the converse is true
+
+    if (useStd140Packing)
+    {
+        prefix += "std_";
+    }
+
+    if (useHLSLRowMajorPacking)
+    {
+        prefix += "rm_";
+    }
+
+    return prefix + StructNameString(structure);
+}
+
+TString InterpolationString(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+      case EvqVaryingIn:           return "";
+      case EvqFragmentIn:          return "";
+      case EvqInvariantVaryingIn:  return "";
+      case EvqSmoothIn:            return "linear";
+      case EvqFlatIn:              return "nointerpolation";
+      case EvqCentroidIn:          return "centroid";
+      case EvqVaryingOut:          return "";
+      case EvqVertexOut:           return "";
+      case EvqInvariantVaryingOut: return "";
+      case EvqSmoothOut:           return "linear";
+      case EvqFlatOut:             return "nointerpolation";
+      case EvqCentroidOut:         return "centroid";
+      default: UNREACHABLE();
+    }
+
+    return "";
+}
+
+TString QualifierString(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+      case EvqIn:            return "in";
+      case EvqOut:           return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined
+      case EvqInOut:         return "inout";
+      case EvqConstReadOnly: return "const";
+      default: UNREACHABLE();
+    }
+
+    return "";
+}
+
+}
diff --git a/src/compiler/translator/UtilsHLSL.h b/src/compiler/translator/UtilsHLSL.h
new file mode 100644
index 0000000..aaa3ddf
--- /dev/null
+++ b/src/compiler/translator/UtilsHLSL.h
@@ -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.
+//
+// UtilsHLSL.h:
+//   Utility methods for GLSL to HLSL translation.
+//
+
+#ifndef TRANSLATOR_UTILSHLSL_H_
+#define TRANSLATOR_UTILSHLSL_H_
+
+#include <vector>
+#include "compiler/translator/Types.h"
+
+#include "angle_gl.h"
+
+namespace sh
+{
+
+TString TextureString(const TType &type);
+TString SamplerString(const TType &type);
+// Prepends an underscore to avoid naming clashes
+TString Decorate(const TString &string);
+TString DecorateUniform(const TString &string, const TType &type);
+TString DecorateField(const TString &string, const TStructure &structure);
+TString DecoratePrivate(const TString &privateText);
+TString TypeString(const TType &type);
+TString StructNameString(const TStructure &structure);
+TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMajorPacking,
+                                  bool useStd140Packing);
+TString InterpolationString(TQualifier qualifier);
+TString QualifierString(TQualifier qualifier);
+
+}
+
+#endif // TRANSLATOR_UTILSHLSL_H_
diff --git a/src/compiler/translator/ValidateLimitations.cpp b/src/compiler/translator/ValidateLimitations.cpp
index e96a777..c1a7b75 100644
--- a/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/compiler/translator/ValidateLimitations.cpp
@@ -8,6 +8,7 @@
 #include "compiler/translator/InfoSink.h"
 #include "compiler/translator/InitializeParseContext.h"
 #include "compiler/translator/ParseContext.h"
+#include "angle_gl.h"
 
 namespace
 {
@@ -46,9 +47,95 @@
     TLoopStack& mLoopStack;
 };
 
+const char *GetOperatorString(TOperator op)
+{
+    switch (op)
+    {
+      case EOpInitialize: return "=";
+      case EOpAssign: return "=";
+      case EOpAddAssign: return "+=";
+      case EOpSubAssign: return "-=";
+      case EOpDivAssign: return "/=";
+
+      // Fall-through.
+      case EOpMulAssign:
+      case EOpVectorTimesMatrixAssign:
+      case EOpVectorTimesScalarAssign:
+      case EOpMatrixTimesScalarAssign:
+      case EOpMatrixTimesMatrixAssign: return "*=";
+
+      // Fall-through.
+      case EOpIndexDirect:
+      case EOpIndexIndirect: return "[]";
+
+      case EOpIndexDirectStruct:
+      case EOpIndexDirectInterfaceBlock: return ".";
+      case EOpVectorSwizzle: return ".";
+      case EOpAdd: return "+";
+      case EOpSub: return "-";
+      case EOpMul: return "*";
+      case EOpDiv: return "/";
+      case EOpMod: UNIMPLEMENTED(); break;
+      case EOpEqual: return "==";
+      case EOpNotEqual: return "!=";
+      case EOpLessThan: return "<";
+      case EOpGreaterThan: return ">";
+      case EOpLessThanEqual: return "<=";
+      case EOpGreaterThanEqual: return ">=";
+
+      // Fall-through.
+      case EOpVectorTimesScalar:
+      case EOpVectorTimesMatrix:
+      case EOpMatrixTimesVector:
+      case EOpMatrixTimesScalar:
+      case EOpMatrixTimesMatrix: return "*";
+
+      case EOpLogicalOr: return "||";
+      case EOpLogicalXor: return "^^";
+      case EOpLogicalAnd: return "&&";
+      case EOpNegative: return "-";
+      case EOpVectorLogicalNot: return "not";
+      case EOpLogicalNot: return "!";
+      case EOpPostIncrement: return "++";
+      case EOpPostDecrement: return "--";
+      case EOpPreIncrement: return "++";
+      case EOpPreDecrement: return "--";
+
+      case EOpRadians: return "radians";
+      case EOpDegrees: return "degrees";
+      case EOpSin: return "sin";
+      case EOpCos: return "cos";
+      case EOpTan: return "tan";
+      case EOpAsin: return "asin";
+      case EOpAcos: return "acos";
+      case EOpAtan: return "atan";
+      case EOpExp: return "exp";
+      case EOpLog: return "log";
+      case EOpExp2: return "exp2";
+      case EOpLog2: return "log2";
+      case EOpSqrt: return "sqrt";
+      case EOpInverseSqrt: return "inversesqrt";
+      case EOpAbs: return "abs";
+      case EOpSign: return "sign";
+      case EOpFloor: return "floor";
+      case EOpCeil: return "ceil";
+      case EOpFract: return "fract";
+      case EOpLength: return "length";
+      case EOpNormalize: return "normalize";
+      case EOpDFdx: return "dFdx";
+      case EOpDFdy: return "dFdy";
+      case EOpFwidth: return "fwidth";
+      case EOpAny: return "any";
+      case EOpAll: return "all";
+
+      default: break;
+    }
+    return "";
+}
+
 }  // namespace anonymous
 
-ValidateLimitations::ValidateLimitations(ShShaderType shaderType,
+ValidateLimitations::ValidateLimitations(sh::GLenum shaderType,
                                          TInfoSinkBase &sink)
     : mShaderType(shaderType),
       mSink(sink),
@@ -185,13 +272,13 @@
         return -1;
     }
     // To keep things simple do not allow declaration list.
-    TIntermSequence &declSeq = decl->getSequence();
-    if (declSeq.size() != 1)
+    TIntermSequence *declSeq = decl->getSequence();
+    if (declSeq->size() != 1)
     {
         error(decl->getLine(), "Invalid init declaration", "for");
         return -1;
     }
-    TIntermBinary *declInit = declSeq[0]->getAsBinaryNode();
+    TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
     if ((declInit == NULL) || (declInit->getOp() != EOpInitialize))
     {
         error(decl->getLine(), "Invalid init declaration", "for");
@@ -267,7 +354,7 @@
       default:
         error(binOp->getLine(),
               "Invalid relational operator",
-              getOperatorString(binOp->getOp()));
+              GetOperatorString(binOp->getOp()));
         break;
     }
     // Loop index must be compared with a constant.
@@ -344,7 +431,7 @@
         ASSERT((unOp == NULL) && (binOp != NULL));
         break;
       default:
-        error(expr->getLine(), "Invalid operator", getOperatorString(op));
+        error(expr->getLine(), "Invalid operator", GetOperatorString(op));
         return false;
     }
 
@@ -374,10 +461,10 @@
     // List of param indices for which loop indices are used as argument.
     typedef std::vector<size_t> ParamIndex;
     ParamIndex pIndex;
-    TIntermSequence& params = node->getSequence();
-    for (TIntermSequence::size_type i = 0; i < params.size(); ++i)
+    TIntermSequence *params = node->getSequence();
+    for (TIntermSequence::size_type i = 0; i < params->size(); ++i)
     {
-        TIntermSymbol *symbol = params[i]->getAsSymbolNode();
+        TIntermSymbol *symbol = (*params)[i]->getAsSymbolNode();
         if (symbol && isLoopIndex(symbol))
             pIndex.push_back(i);
     }
@@ -398,9 +485,9 @@
         TQualifier qual = param.type->getQualifier();
         if ((qual == EvqOut) || (qual == EvqInOut))
         {
-            error(params[*i]->getLine(),
+            error((*params)[*i]->getLine(),
                   "Loop index cannot be used as argument to a function out or inout parameter",
-                  params[*i]->getAsSymbolNode()->getSymbol().c_str());
+                  (*params)[*i]->getAsSymbolNode()->getSymbol().c_str());
             valid = false;
         }
     }
@@ -457,7 +544,7 @@
     // The index expession must be a constant-index-expression unless
     // the operand is a uniform in a vertex shader.
     TIntermTyped *operand = node->getLeft();
-    bool skip = (mShaderType == SH_VERTEX_SHADER) &&
+    bool skip = (mShaderType == GL_VERTEX_SHADER) &&
                 (operand->getQualifier() == EvqUniform);
     if (!skip && !isConstIndexExpr(index))
     {
diff --git a/src/compiler/translator/ValidateLimitations.h b/src/compiler/translator/ValidateLimitations.h
index f28995c..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;
@@ -14,7 +14,7 @@
 class ValidateLimitations : public TIntermTraverser
 {
   public:
-    ValidateLimitations(ShShaderType shaderType, TInfoSinkBase &sink);
+    ValidateLimitations(sh::GLenum shaderType, TInfoSinkBase &sink);
 
     int numErrors() const { return mNumErrors; }
 
@@ -47,7 +47,7 @@
     bool isConstIndexExpr(TIntermNode *node);
     bool validateIndexing(TIntermBinary *node);
 
-    ShShaderType mShaderType;
+    sh::GLenum mShaderType;
     TInfoSinkBase &mSink;
     int mNumErrors;
     TLoopStack mLoopStack;
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 d0b1990..f26c156 100644
--- a/src/compiler/translator/VariableInfo.cpp
+++ b/src/compiler/translator/VariableInfo.cpp
@@ -4,242 +4,139 @@
 // found in the LICENSE file.
 //
 
+#include "angle_gl.h"
 #include "compiler/translator/VariableInfo.h"
+#include "compiler/translator/util.h"
+#include "common/utilities.h"
 
-namespace {
-
-TString arrayBrackets(int index)
+namespace sh
 {
-    TStringStream stream;
-    stream << "[" << index << "]";
-    return stream.str();
-}
 
-// Returns the data type for an attribute, uniform, or varying.
-ShDataType getVariableDataType(const TType& type)
+namespace
 {
-    switch (type.getBasicType()) {
-      case EbtFloat:
-          if (type.isMatrix()) {
-              switch (type.getCols())
-              {
-                case 2:
-                  switch (type.getRows())
-                  {
-                    case 2: return SH_FLOAT_MAT2;
-                    case 3: return SH_FLOAT_MAT2x3;
-                    case 4: return SH_FLOAT_MAT2x4;
-                    default: UNREACHABLE();
-                  }
-                case 3:
-                  switch (type.getRows())
-                  {
-                    case 2: return SH_FLOAT_MAT3x2;
-                    case 3: return SH_FLOAT_MAT3;
-                    case 4: return SH_FLOAT_MAT3x4;
-                    default: UNREACHABLE();
-                  }
-                case 4:
-                  switch (type.getRows())
-                  {
-                    case 2: return SH_FLOAT_MAT4x2;
-                    case 3: return SH_FLOAT_MAT4x3;
-                    case 4: return SH_FLOAT_MAT4;
-                    default: UNREACHABLE();
-                  }
-              }
-          } else if (type.isVector()) {
-              switch (type.getNominalSize()) {
-                case 2: return SH_FLOAT_VEC2;
-                case 3: return SH_FLOAT_VEC3;
-                case 4: return SH_FLOAT_VEC4;
-                default: UNREACHABLE();
-              }
-          } else {
-              return SH_FLOAT;
-          }
-      case EbtInt:
-          if (type.isMatrix()) {
-              UNREACHABLE();
-          } else if (type.isVector()) {
-              switch (type.getNominalSize()) {
-                case 2: return SH_INT_VEC2;
-                case 3: return SH_INT_VEC3;
-                case 4: return SH_INT_VEC4;
-                default: UNREACHABLE();
-              }
-          } else {
-              return SH_INT;
-          }
-      case EbtUInt:
-          if (type.isMatrix()) {
-              UNREACHABLE();
-          } else if (type.isVector()) {
-              switch (type.getNominalSize()) {
-                case 2: return SH_UNSIGNED_INT_VEC2;
-                case 3: return SH_UNSIGNED_INT_VEC3;
-                case 4: return SH_UNSIGNED_INT_VEC4;
-                default: UNREACHABLE();
-              }
-          } else {
-              return SH_UNSIGNED_INT;
-          }
-      case EbtBool:
-          if (type.isMatrix()) {
-              UNREACHABLE();
-          } else if (type.isVector()) {
-              switch (type.getNominalSize()) {
-                case 2: return SH_BOOL_VEC2;
-                case 3: return SH_BOOL_VEC3;
-                case 4: return SH_BOOL_VEC4;
-                default: UNREACHABLE();
-              }
-          } else {
-              return SH_BOOL;
-          }
-      case EbtSampler2D: return SH_SAMPLER_2D;
-      case EbtSampler3D: return SH_SAMPLER_3D;
-      case EbtSamplerCube: return SH_SAMPLER_CUBE;
-      case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES;
-      case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB;
-      case EbtSampler2DArray: return SH_SAMPLER_2D_ARRAY;
-      case EbtISampler2D: return SH_INT_SAMPLER_2D;
-      case EbtISampler3D: return SH_INT_SAMPLER_3D;
-      case EbtISamplerCube: return SH_INT_SAMPLER_CUBE;
-      case EbtISampler2DArray: return SH_INT_SAMPLER_2D_ARRAY;
-      case EbtUSampler2D: return SH_UNSIGNED_INT_SAMPLER_2D;
-      case EbtUSampler3D: return SH_UNSIGNED_INT_SAMPLER_3D;
-      case EbtUSamplerCube: return SH_UNSIGNED_INT_SAMPLER_CUBE;
-      case EbtUSampler2DArray: return SH_UNSIGNED_INT_SAMPLER_2D_ARRAY;
-      case EbtSampler2DShadow: return SH_SAMPLER_2D_SHADOW;
-      case EbtSamplerCubeShadow: return SH_SAMPLER_CUBE_SHADOW;
-      case EbtSampler2DArrayShadow: return SH_SAMPLER_2D_ARRAY_SHADOW;
-      default: UNREACHABLE();
+
+TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
+{
+    if (interfaceBlock.hasInstanceName())
+    {
+        return interfaceBlock.name() + "." + field.name();
     }
-    return SH_NONE;
+    else
+    {
+        return field.name();
+    }
 }
 
-void getBuiltInVariableInfo(const TType& type,
-                            const TString& name,
-                            const TString& mappedName,
-                            TVariableInfoList& infoList);
-void getUserDefinedVariableInfo(const TType& type,
-                                const TString& name,
-                                const TString& mappedName,
-                                TVariableInfoList& infoList,
-                                ShHashFunction64 hashFunction);
-
-// Returns info for an attribute, uniform, or varying.
-void getVariableInfo(const TType& type,
-                     const TString& name,
-                     const TString& mappedName,
-                     TVariableInfoList& infoList,
-                     ShHashFunction64 hashFunction)
+BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
 {
-    if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
-        if (type.isArray()) {
-            for (int i = 0; i < type.getArraySize(); ++i) {
-                TString lname = name + arrayBrackets(i);
-                TString lmappedName = mappedName + arrayBrackets(i);
-                getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
+    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())
+    {
+        if (variable.isArray())
+        {
+            for (size_t elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++)
+            {
+                std::string lname = name + ::ArrayString(elementIndex);
+                std::string lmappedName = mappedName + ::ArrayString(elementIndex);
+                ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded);
             }
-        } else {
-            getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
         }
-    } else {
-        getBuiltInVariableInfo(type, name, mappedName, infoList);
+        else
+        {
+            ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded);
+        }
+    }
+    else
+    {
+        ShaderVariable expandedVar = variable;
+
+        expandedVar.name = name;
+        expandedVar.mappedName = mappedName;
+
+        // Mark all expanded fields as used if the parent is used
+        if (markStaticUse)
+        {
+            expandedVar.staticUse = true;
+        }
+
+        if (expandedVar.isArray())
+        {
+            expandedVar.name += "[0]";
+            expandedVar.mappedName += "[0]";
+        }
+
+        expanded->push_back(expandedVar);
     }
 }
 
-void getBuiltInVariableInfo(const TType& type,
-                            const TString& name,
-                            const TString& mappedName,
-                            TVariableInfoList& infoList)
+void ExpandUserDefinedVariable(const ShaderVariable &variable,
+                               const std::string &name,
+                               const std::string &mappedName,
+                               bool markStaticUse,
+                               std::vector<ShaderVariable> *expanded)
 {
-    ASSERT(type.getBasicType() != EbtStruct);
+    ASSERT(variable.isStruct());
 
-    TVariableInfo varInfo;
-    if (type.isArray()) {
-        varInfo.name = (name + "[0]").c_str();
-        varInfo.mappedName = (mappedName + "[0]").c_str();
-        varInfo.size = type.getArraySize();
-        varInfo.isArray = true;
-    } else {
-        varInfo.name = name.c_str();
-        varInfo.mappedName = mappedName.c_str();
-        varInfo.size = 1;
-        varInfo.isArray = false;
-    }
-    varInfo.precision = type.getPrecision();
-    varInfo.type = getVariableDataType(type);
-    infoList.push_back(varInfo);
-}
+    const std::vector<ShaderVariable> &fields = variable.fields;
 
-void getUserDefinedVariableInfo(const TType& type,
-                                const TString& name,
-                                const TString& mappedName,
-                                TVariableInfoList& infoList,
-                                ShHashFunction64 hashFunction)
-{
-    ASSERT(type.getBasicType() == EbtStruct || type.isInterfaceBlock());
-
-    const TFieldList& fields = type.isInterfaceBlock() ?
-        type.getInterfaceBlock()->fields() :
-        type.getStruct()->fields();
-    for (size_t i = 0; i < fields.size(); ++i) {
-        const TType& fieldType = *(fields[i]->type());
-        const TString& fieldName = fields[i]->name();
-        getVariableInfo(fieldType,
-                        name + "." + fieldName,
-                        mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
-                        infoList,
-                        hashFunction);
+    for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
+    {
+        const ShaderVariable &field = fields[fieldIndex];
+        ExpandVariable(field,
+                       name + "." + field.name,
+                       mappedName + "." + field.mappedName,
+                       markStaticUse,
+                       expanded);
     }
 }
 
-TVariableInfo* findVariable(const TType& type,
-                            const TString& name,
-                            TVariableInfoList& infoList)
+template <class VarT>
+VarT *FindVariable(const TString &name,
+                  std::vector<VarT> *infoList)
 {
     // TODO(zmo): optimize this function.
-    TString myName = name;
-    if (type.isArray())
-        myName += "[0]";
-    for (size_t ii = 0; ii < infoList.size(); ++ii)
+    for (size_t ii = 0; ii < infoList->size(); ++ii)
     {
-        if (infoList[ii].name.c_str() == myName)
-            return &(infoList[ii]);
+        if ((*infoList)[ii].name.c_str() == name)
+            return &((*infoList)[ii]);
     }
+
     return NULL;
 }
 
-}  // namespace anonymous
-
-TVariableInfo::TVariableInfo()
-    : type(SH_NONE),
-      size(0),
-      isArray(false),
-      precision(EbpUndefined),
-      staticUse(false)
-{
 }
 
-TVariableInfo::TVariableInfo(ShDataType type, int size)
-    : type(type),
-      size(size),
-      isArray(false),
-      precision(EbpUndefined),
-      staticUse(false)
-{
-}
-
-CollectVariables::CollectVariables(TVariableInfoList& attribs,
-                                   TVariableInfoList& uniforms,
-                                   TVariableInfoList& varyings,
+CollectVariables::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,
                                    ShHashFunction64 hashFunction)
     : mAttribs(attribs),
+      mOutputVariables(outputVariables),
       mUniforms(uniforms),
       mVaryings(varyings),
+      mInterfaceBlocks(interfaceBlocks),
       mPointCoordAdded(false),
       mFrontFacingAdded(false),
       mFragCoordAdded(false),
@@ -252,123 +149,290 @@
 // Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
 // toward varying counting if they are statically used in a fragment
 // shader.
-void CollectVariables::visitSymbol(TIntermSymbol* symbol)
+void CollectVariables::visitSymbol(TIntermSymbol *symbol)
 {
     ASSERT(symbol != NULL);
-    TVariableInfo* var = NULL;
-    switch (symbol->getQualifier())
+    ShaderVariable *var = NULL;
+    const TString &symbolName = symbol->getSymbol();
+
+    if (IsVarying(symbol->getQualifier()))
     {
-    case EvqVaryingOut:
-    case EvqInvariantVaryingOut:
-    case EvqVaryingIn:
-    case EvqInvariantVaryingIn:
-        var = findVariable(symbol->getType(), symbol->getSymbol(), mVaryings);
-        break;
-    case EvqUniform:
-        var = findVariable(symbol->getType(), symbol->getSymbol(), mUniforms);
-        break;
-    case EvqFragCoord:
-        if (!mFragCoordAdded) {
-            TVariableInfo info;
-            info.name = "gl_FragCoord";
-            info.mappedName = "gl_FragCoord";
-            info.type = SH_FLOAT_VEC4;
-            info.size = 1;
-            info.precision = EbpMedium;  // Use mediump as it doesn't really matter.
-            info.staticUse = true;
-	    mVaryings.push_back(info);
-            mFragCoordAdded = true;
+        var = FindVariable(symbolName, mVaryings);
+    }
+    else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
+    {
+        UNREACHABLE();
+    }
+    else
+    {
+        switch (symbol->getQualifier())
+        {
+          case EvqAttribute:
+          case EvqVertexIn:
+            var = FindVariable(symbolName, mAttribs);
+            break;
+          case EvqFragmentOut:
+            var = FindVariable(symbolName, mOutputVariables);
+            break;
+          case EvqUniform:
+            {
+                const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
+                if (interfaceBlock)
+                {
+                    InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
+                    ASSERT(namedBlock);
+                    var = FindVariable(symbolName, &namedBlock->fields);
+
+                    // Set static use on the parent interface block here
+                    namedBlock->staticUse = true;
+
+                }
+                else
+                {
+                    var = FindVariable(symbolName, mUniforms);
+                }
+
+                // It's an internal error to reference an undefined user uniform
+                ASSERT(symbolName.compare(0, 3, "gl_") == 0 || var);
+            }
+            break;
+          case EvqFragCoord:
+            if (!mFragCoordAdded)
+            {
+                Varying info;
+                info.name = "gl_FragCoord";
+                info.mappedName = "gl_FragCoord";
+                info.type = GL_FLOAT_VEC4;
+                info.arraySize = 0;
+                info.precision = GL_MEDIUM_FLOAT;  // Use mediump as it doesn't really matter.
+                info.staticUse = true;
+                mVaryings->push_back(info);
+                mFragCoordAdded = true;
+            }
+            return;
+          case EvqFrontFacing:
+            if (!mFrontFacingAdded)
+            {
+                Varying info;
+                info.name = "gl_FrontFacing";
+                info.mappedName = "gl_FrontFacing";
+                info.type = GL_BOOL;
+                info.arraySize = 0;
+                info.precision = GL_NONE;
+                info.staticUse = true;
+                mVaryings->push_back(info);
+                mFrontFacingAdded = true;
+            }
+            return;
+          case EvqPointCoord:
+            if (!mPointCoordAdded)
+            {
+                Varying info;
+                info.name = "gl_PointCoord";
+                info.mappedName = "gl_PointCoord";
+                info.type = GL_FLOAT_VEC2;
+                info.arraySize = 0;
+                info.precision = GL_MEDIUM_FLOAT;  // Use mediump as it doesn't really matter.
+                info.staticUse = true;
+                mVaryings->push_back(info);
+                mPointCoordAdded = true;
+            }
+            return;
+          default:
+            break;
         }
-        return;
-    case EvqFrontFacing:
-        if (!mFrontFacingAdded) {
-            TVariableInfo info;
-            info.name = "gl_FrontFacing";
-            info.mappedName = "gl_FrontFacing";
-            info.type = SH_BOOL;
-            info.size = 1;
-            info.precision = EbpUndefined;
-            info.staticUse = true;
-	    mVaryings.push_back(info);
-            mFrontFacingAdded = true;
-        }
-        return;
-    case EvqPointCoord:
-        if (!mPointCoordAdded) {
-            TVariableInfo info;
-            info.name = "gl_PointCoord";
-            info.mappedName = "gl_PointCoord";
-            info.type = SH_FLOAT_VEC2;
-            info.size = 1;
-            info.precision = EbpMedium;  // Use mediump as it doesn't really matter.
-            info.staticUse = true;
-	    mVaryings.push_back(info);
-            mPointCoordAdded = true;
-        }
-        return;
-    default:
-        break;
     }
     if (var)
+    {
         var->staticUse = true;
+    }
 }
 
-bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
+class NameHashingTraverser : public GetVariableTraverser
+{
+  public:
+    NameHashingTraverser(ShHashFunction64 hashFunction)
+        : mHashFunction(hashFunction)
+    {}
+
+  private:
+    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();
+    }
+
+    ShHashFunction64 mHashFunction;
+};
+
+// Attributes, which cannot have struct fields, are a special case
+template <>
+void CollectVariables::visitVariable(const TIntermSymbol *variable,
+                                     std::vector<Attribute> *infoList) const
+{
+    ASSERT(variable);
+    const TType &type = variable->getType();
+    ASSERT(!type.getStruct());
+
+    Attribute attribute;
+
+    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();
+    attribute.location = variable->getType().getLayoutQualifier().location;
+
+    infoList->push_back(attribute);
+}
+
+template <>
+void CollectVariables::visitVariable(const TIntermSymbol *variable,
+                                     std::vector<InterfaceBlock> *infoList) const
+{
+    InterfaceBlock interfaceBlock;
+    const TInterfaceBlock *blockType = variable->getType().getInterfaceBlock();
+    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 = (blockType->matrixPacking() == EmpRowMajor);
+    interfaceBlock.layout = GetBlockLayoutType(blockType->blockStorage());
+
+    // Gather field information
+    const TFieldList &fieldList = blockType->fields();
+
+    for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
+    {
+        const TField &field = *fieldList[fieldIndex];
+        const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
+        const TType &fieldType = *field.type();
+
+        GetVariableTraverser traverser;
+        traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
+
+        interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
+    }
+
+    infoList->push_back(interfaceBlock);
+}
+
+template <typename VarT>
+void CollectVariables::visitVariable(const TIntermSymbol *variable,
+                                     std::vector<VarT> *infoList) const
+{
+    NameHashingTraverser traverser(mHashFunction);
+    traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
+}
+
+template <typename VarT>
+void CollectVariables::visitInfoList(const TIntermSequence &sequence,
+                                     std::vector<VarT> *infoList) const
+{
+    for (size_t seqIndex = 0; seqIndex < sequence.size(); seqIndex++)
+    {
+        const TIntermSymbol *variable = sequence[seqIndex]->getAsSymbolNode();
+        // The only case in which the sequence will not contain a
+        // TIntermSymbol node is initialization. It will contain a
+        // TInterBinary node in that case. Since attributes, uniforms,
+        // and varyings cannot be initialized in a shader, we must have
+        // only TIntermSymbol nodes in the sequence.
+        ASSERT(variable != NULL);
+        visitVariable(variable, infoList);
+    }
+}
+
+bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
 {
     bool visitChildren = true;
 
     switch (node->getOp())
     {
-    case EOpDeclaration: {
-        const TIntermSequence& sequence = node->getSequence();
-        TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
-        if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqUniform ||
-            qualifier == EvqVaryingIn || qualifier == EvqVaryingOut ||
-            qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut)
+      case EOpDeclaration:
         {
-            TVariableInfoList *infoList = NULL;
+            const TIntermSequence &sequence = *(node->getSequence());
+            ASSERT(!sequence.empty());
 
-            switch (qualifier)
-            {
-              case EvqAttribute:
-              case EvqVertexIn:
-                infoList = &mAttribs;
-                break;
-              case EvqUniform:
-                infoList = &mUniforms;
-                break;
-              default:
-                infoList = &mVaryings;
-                break;
-            }
+            const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
+            TQualifier qualifier = typedNode.getQualifier();
 
-            for (TIntermSequence::const_iterator i = sequence.begin();
-                 i != sequence.end(); ++i)
+            if (typedNode.getBasicType() == EbtInterfaceBlock)
             {
-                const TIntermSymbol* variable = (*i)->getAsSymbolNode();
-                // The only case in which the sequence will not contain a
-                // TIntermSymbol node is initialization. It will contain a
-                // TInterBinary node in that case. Since attributes, uniforms,
-                // and varyings cannot be initialized in a shader, we must have
-                // only TIntermSymbol nodes in the sequence.
-                ASSERT(variable != NULL);
-                TString processedSymbol;
-                if (mHashFunction == NULL)
-                    processedSymbol = variable->getSymbol();
-                else
-                    processedSymbol = TIntermTraverser::hash(variable->getSymbol(), mHashFunction);
-                getVariableInfo(variable->getType(),
-                                variable->getSymbol(),
-                                processedSymbol,
-                                *infoList,
-                                mHashFunction);
+                visitInfoList(sequence, mInterfaceBlocks);
                 visitChildren = false;
             }
+            else if (qualifier == EvqAttribute || qualifier == EvqVertexIn ||
+                     qualifier == EvqFragmentOut || qualifier == EvqUniform ||
+                     IsVarying(qualifier))
+            {
+                switch (qualifier)
+                {
+                  case EvqAttribute:
+                  case EvqVertexIn:
+                    visitInfoList(sequence, mAttribs);
+                    break;
+                  case EvqFragmentOut:
+                    visitInfoList(sequence, mOutputVariables);
+                    break;
+                  case EvqUniform:
+                    visitInfoList(sequence, mUniforms);
+                    break;
+                  default:
+                    visitInfoList(sequence, mVaryings);
+                    break;
+                }
+
+                visitChildren = false;
+            }
+            break;
         }
-        break;
-    }
-    default: break;
+      default: break;
     }
 
     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<ShaderVariable> *expanded)
+{
+    for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
+    {
+        const ShaderVariable &variable = compact[variableIndex];
+        ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded);
+    }
+}
+
+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 fc9e153..5ac4c46 100644
--- a/src/compiler/translator/VariableInfo.h
+++ b/src/compiler/translator/VariableInfo.h
@@ -7,39 +7,42 @@
 #ifndef COMPILER_VARIABLE_INFO_H_
 #define COMPILER_VARIABLE_INFO_H_
 
-#include "compiler/translator/intermediate.h"
+#include <GLSLANG/ShaderLang.h>
 
-// Provides information about a variable.
-// It is currently being used to store info about active attribs and uniforms.
-struct TVariableInfo {
-    TVariableInfo(ShDataType type, int size);
-    TVariableInfo();
+#include "compiler/translator/IntermNode.h"
 
-    TPersistString name;
-    TPersistString mappedName;
-    ShDataType type;
-    int size;
-    bool isArray;
-    TPrecision precision;
-    bool staticUse;
-};
-typedef std::vector<TVariableInfo> TVariableInfoList;
+namespace sh
+{
 
 // Traverses intermediate tree to collect all attributes, uniforms, varyings.
-class CollectVariables : public TIntermTraverser {
-public:
-    CollectVariables(TVariableInfoList& attribs,
-                     TVariableInfoList& uniforms,
-                     TVariableInfoList& varyings,
+class CollectVariables : public TIntermTraverser
+{
+  public:
+    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*);
-    virtual bool visitAggregate(Visit, TIntermAggregate*);
+    virtual void visitSymbol(TIntermSymbol *symbol);
+    virtual bool visitAggregate(Visit, TIntermAggregate *node);
+    virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode);
 
-private:
-    TVariableInfoList& mAttribs;
-    TVariableInfoList& mUniforms;
-    TVariableInfoList& mVaryings;
+  private:
+    template <typename VarT>
+    void visitVariable(const TIntermSymbol *variable, std::vector<VarT> *infoList) const;
+
+    template <typename VarT>
+    void visitInfoList(const TIntermSequence &sequence, std::vector<VarT> *infoList) const;
+
+    std::vector<Attribute> *mAttribs;
+    std::vector<Attribute> *mOutputVariables;
+    std::vector<Uniform> *mUniforms;
+    std::vector<Varying> *mVaryings;
+    std::vector<InterfaceBlock> *mInterfaceBlocks;
+
+    std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
 
     bool mPointCoordAdded;
     bool mFrontFacingAdded;
@@ -48,4 +51,11 @@
     ShHashFunction64 mHashFunction;
 };
 
+// Expand struct variables to flattened lists of split variables
+template <typename VarT>
+void ExpandVariables(const std::vector<VarT> &compact,
+                     std::vector<ShaderVariable> *expanded);
+
+}
+
 #endif  // COMPILER_VARIABLE_INFO_H_
diff --git a/src/compiler/translator/VariablePacker.cpp b/src/compiler/translator/VariablePacker.cpp
index 6390e30..e690521 100644
--- a/src/compiler/translator/VariablePacker.cpp
+++ b/src/compiler/translator/VariablePacker.cpp
@@ -3,140 +3,81 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-#include "compiler/translator/VariablePacker.h"
 
 #include <algorithm>
-#include "compiler/translator/ShHandle.h"
 
-namespace {
-int GetSortOrder(ShDataType type)
+#include "angle_gl.h"
+
+#include "compiler/translator/VariablePacker.h"
+#include "common/utilities.h"
+
+int VariablePacker::GetNumComponentsPerRow(sh::GLenum type)
 {
-    switch (type) {
-        case SH_FLOAT_MAT4:
-        case SH_FLOAT_MAT2x4:
-        case SH_FLOAT_MAT3x4:
-        case SH_FLOAT_MAT4x2:
-        case SH_FLOAT_MAT4x3:
-            return 0;
-        case SH_FLOAT_MAT2:
-            return 1;
-        case SH_FLOAT_VEC4:
-        case SH_INT_VEC4:
-        case SH_BOOL_VEC4:
-            return 2;
-        case SH_FLOAT_MAT3:
-        case SH_FLOAT_MAT2x3:
-        case SH_FLOAT_MAT3x2:
-            return 3;
-        case SH_FLOAT_VEC3:
-        case SH_INT_VEC3:
-        case SH_BOOL_VEC3:
-            return 4;
-        case SH_FLOAT_VEC2:
-        case SH_INT_VEC2:
-        case SH_BOOL_VEC2:
-            return 5;
-        case SH_FLOAT:
-        case SH_INT:
-        case SH_BOOL:
-        case SH_SAMPLER_2D:
-        case SH_SAMPLER_CUBE:
-        case SH_SAMPLER_EXTERNAL_OES:
-        case SH_SAMPLER_2D_RECT_ARB:
-            return 6;
-        default:
-            ASSERT(false);
-            return 7;
-    }
-}
-}    // namespace
-
-int VariablePacker::GetNumComponentsPerRow(ShDataType type)
-{
-    switch (type) {
-        case SH_FLOAT_MAT4:
-        case SH_FLOAT_MAT2:
-        case SH_FLOAT_MAT2x4:
-        case SH_FLOAT_MAT3x4:
-        case SH_FLOAT_MAT4x2:
-        case SH_FLOAT_MAT4x3:
-        case SH_FLOAT_VEC4:
-        case SH_INT_VEC4:
-        case SH_BOOL_VEC4:
-            return 4;
-        case SH_FLOAT_MAT3:
-        case SH_FLOAT_MAT2x3:
-        case SH_FLOAT_MAT3x2:
-        case SH_FLOAT_VEC3:
-        case SH_INT_VEC3:
-        case SH_BOOL_VEC3:
-            return 3;
-        case SH_FLOAT_VEC2:
-        case SH_INT_VEC2:
-        case SH_BOOL_VEC2:
-            return 2;
-        case SH_FLOAT:
-        case SH_INT:
-        case SH_BOOL:
-        case SH_SAMPLER_2D:
-        case SH_SAMPLER_CUBE:
-        case SH_SAMPLER_EXTERNAL_OES:
-        case SH_SAMPLER_2D_RECT_ARB:
-            return 1;
-        default:
-            ASSERT(false);
-            return 5;
-    }
-}
-
-int VariablePacker::GetNumRows(ShDataType type)
-{
-    switch (type) {
-        case SH_FLOAT_MAT4:
-        case SH_FLOAT_MAT2x4:
-        case SH_FLOAT_MAT3x4:
-        case SH_FLOAT_MAT4x3:
-        case SH_FLOAT_MAT4x2:
-            return 4;
-        case SH_FLOAT_MAT3:
-        case SH_FLOAT_MAT2x3:
-        case SH_FLOAT_MAT3x2:
-            return 3;
-        case SH_FLOAT_MAT2:
-            return 2;
-        case SH_FLOAT_VEC4:
-        case SH_INT_VEC4:
-        case SH_BOOL_VEC4:
-        case SH_FLOAT_VEC3:
-        case SH_INT_VEC3:
-        case SH_BOOL_VEC3:
-        case SH_FLOAT_VEC2:
-        case SH_INT_VEC2:
-        case SH_BOOL_VEC2:
-        case SH_FLOAT:
-        case SH_INT:
-        case SH_BOOL:
-        case SH_SAMPLER_2D:
-        case SH_SAMPLER_CUBE:
-        case SH_SAMPLER_EXTERNAL_OES:
-        case SH_SAMPLER_2D_RECT_ARB:
-            return 1;
-        default:
-            ASSERT(false);
-            return 100000;
-    }
-}
-
-struct TVariableInfoComparer {
-    bool operator()(const TVariableInfo& lhs, const TVariableInfo& rhs) const
+    switch (type)
     {
-        int lhsSortOrder = GetSortOrder(lhs.type);
-        int rhsSortOrder = GetSortOrder(rhs.type);
+      case GL_FLOAT_MAT4:
+      case GL_FLOAT_MAT2:
+      case GL_FLOAT_MAT2x4:
+      case GL_FLOAT_MAT3x4:
+      case GL_FLOAT_MAT4x2:
+      case GL_FLOAT_MAT4x3:
+      case GL_FLOAT_VEC4:
+      case GL_INT_VEC4:
+      case GL_BOOL_VEC4:
+      case GL_UNSIGNED_INT_VEC4:
+        return 4;
+      case GL_FLOAT_MAT3:
+      case GL_FLOAT_MAT2x3:
+      case GL_FLOAT_MAT3x2:
+      case GL_FLOAT_VEC3:
+      case GL_INT_VEC3:
+      case GL_BOOL_VEC3:
+      case GL_UNSIGNED_INT_VEC3:
+        return 3;
+      case GL_FLOAT_VEC2:
+      case GL_INT_VEC2:
+      case GL_BOOL_VEC2:
+      case GL_UNSIGNED_INT_VEC2:
+        return 2;
+      default:
+        ASSERT(gl::VariableComponentCount(type) == 1);
+        return 1;
+    }
+}
+
+int VariablePacker::GetNumRows(sh::GLenum type)
+{
+    switch (type)
+    {
+      case GL_FLOAT_MAT4:
+      case GL_FLOAT_MAT2x4:
+      case GL_FLOAT_MAT3x4:
+      case GL_FLOAT_MAT4x3:
+      case GL_FLOAT_MAT4x2:
+        return 4;
+      case GL_FLOAT_MAT3:
+      case GL_FLOAT_MAT2x3:
+      case GL_FLOAT_MAT3x2:
+        return 3;
+      case GL_FLOAT_MAT2:
+        return 2;
+      default:
+        ASSERT(gl::VariableRowCount(type) == 1);
+        return 1;
+    }
+}
+
+struct TVariableInfoComparer
+{
+    bool operator()(const sh::ShaderVariable &lhs, const sh::ShaderVariable &rhs) const
+    {
+        int lhsSortOrder = gl::VariableSortOrder(lhs.type);
+        int rhsSortOrder = gl::VariableSortOrder(rhs.type);
         if (lhsSortOrder != rhsSortOrder) {
             return lhsSortOrder < rhsSortOrder;
         }
         // Sort by largest first.
-        return lhs.size > rhs.size;
+        return lhs.arraySize > rhs.arraySize;
     }
 };
 
@@ -207,18 +148,20 @@
     return true;
 }
 
-bool VariablePacker::CheckVariablesWithinPackingLimits(int maxVectors, const TVariableInfoList& in_variables)
+template <typename VarT>
+bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int maxVectors,
+                                                       const std::vector<VarT> &in_variables)
 {
     ASSERT(maxVectors > 0);
     maxRows_ = maxVectors;
     topNonFullRow_ = 0;
     bottomNonFullRow_ = maxRows_ - 1;
-    TVariableInfoList variables(in_variables);
+    std::vector<VarT> variables(in_variables);
 
     // Check whether each variable fits in the available vectors.
     for (size_t i = 0; i < variables.size(); i++) {
-        const TVariableInfo& variable = variables[i];
-        if (variable.size > maxVectors / GetNumRows(variable.type)) {
+        const sh::ShaderVariable &variable = variables[i];
+        if (variable.elementCount() > maxVectors / GetNumRows(variable.type)) {
             return false;
         }
     }
@@ -232,11 +175,11 @@
     // Packs the 4 column variables.
     size_t ii = 0;
     for (; ii < variables.size(); ++ii) {
-        const TVariableInfo& variable = variables[ii];
+        const sh::ShaderVariable &variable = variables[ii];
         if (GetNumComponentsPerRow(variable.type) != 4) {
             break;
         }
-        topNonFullRow_ += GetNumRows(variable.type) * variable.size;
+        topNonFullRow_ += GetNumRows(variable.type) * variable.elementCount();
     }
 
     if (topNonFullRow_ > maxRows_) {
@@ -246,11 +189,11 @@
     // Packs the 3 column variables.
     int num3ColumnRows = 0;
     for (; ii < variables.size(); ++ii) {
-        const TVariableInfo& variable = variables[ii];
+        const sh::ShaderVariable &variable = variables[ii];
         if (GetNumComponentsPerRow(variable.type) != 3) {
             break;
         }
-        num3ColumnRows += GetNumRows(variable.type) * variable.size;
+        num3ColumnRows += GetNumRows(variable.type) * variable.elementCount();
     }
 
     if (topNonFullRow_ + num3ColumnRows > maxRows_) {
@@ -265,11 +208,11 @@
     int rowsAvailableInColumns01 = twoColumnRowsAvailable;
     int rowsAvailableInColumns23 = twoColumnRowsAvailable;
     for (; ii < variables.size(); ++ii) {
-        const TVariableInfo& variable = variables[ii];
+        const sh::ShaderVariable &variable = variables[ii];
         if (GetNumComponentsPerRow(variable.type) != 2) {
             break;
         }
-        int numRows = GetNumRows(variable.type) * variable.size;
+        int numRows = GetNumRows(variable.type) * variable.elementCount();
         if (numRows <= rowsAvailableInColumns01) {
             rowsAvailableInColumns01 -= numRows;
         } else if (numRows <= rowsAvailableInColumns23) {
@@ -289,9 +232,9 @@
 
     // Packs the 1 column variables.
     for (; ii < variables.size(); ++ii) {
-        const TVariableInfo& variable = variables[ii];
+        const sh::ShaderVariable &variable = variables[ii];
         ASSERT(1 == GetNumComponentsPerRow(variable.type));
-        int numRows = GetNumRows(variable.type) * variable.size;
+        int numRows = GetNumRows(variable.type) * variable.elementCount();
         int smallestColumn = -1;
         int smallestSize = maxRows_ + 1;
         int topRow = -1;
@@ -319,5 +262,8 @@
     return true;
 }
 
-
-
+// Instantiate all possible variable packings
+template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::ShaderVariable> &);
+template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Attribute> &);
+template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Uniform> &);
+template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Varying> &);
diff --git a/src/compiler/translator/VariablePacker.h b/src/compiler/translator/VariablePacker.h
index fd60908..1de5332 100644
--- a/src/compiler/translator/VariablePacker.h
+++ b/src/compiler/translator/VariablePacker.h
@@ -8,23 +8,23 @@
 #define _VARIABLEPACKER_INCLUDED_
 
 #include <vector>
-#include "compiler/translator/ShHandle.h"
+#include "compiler/translator/VariableInfo.h"
 
 class VariablePacker {
  public:
     // Returns true if the passed in variables pack in maxVectors following
     // the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
-    bool CheckVariablesWithinPackingLimits(
-        int maxVectors,
-        const TVariableInfoList& in_variables);
+    template <typename VarT>
+    bool CheckVariablesWithinPackingLimits(unsigned int maxVectors,
+                                           const std::vector<VarT> &in_variables);
 
     // Gets how many components in a row a data type takes.
-    static int GetNumComponentsPerRow(ShDataType type);
+    static int GetNumComponentsPerRow(sh::GLenum type);
 
     // Gets how many rows a data type takes.
-    static int GetNumRows(ShDataType type);
+    static int GetNumRows(sh::GLenum type);
 
- private:
+  private:
     static const int kNumColumns = 4;
     static const unsigned kColumnMask = (1 << kNumColumns) - 1;
 
diff --git a/src/compiler/translator/VersionGLSL.cpp b/src/compiler/translator/VersionGLSL.cpp
index dd11f99..8edbd00 100644
--- a/src/compiler/translator/VersionGLSL.cpp
+++ b/src/compiler/translator/VersionGLSL.cpp
@@ -35,104 +35,84 @@
 //    - invariant gl_Position;
 //    - varying vec3 color; invariant color;
 //
-TVersionGLSL::TVersionGLSL(ShShaderType type)
-    : mShaderType(type),
-      mVersion(GLSL_VERSION_110)
+TVersionGLSL::TVersionGLSL(sh::GLenum type)
+    : mVersion(GLSL_VERSION_110)
 {
 }
 
-void TVersionGLSL::visitSymbol(TIntermSymbol* node)
+void TVersionGLSL::visitSymbol(TIntermSymbol *node)
 {
     if (node->getSymbol() == "gl_PointCoord")
         updateVersion(GLSL_VERSION_120);
 }
 
-void TVersionGLSL::visitConstantUnion(TIntermConstantUnion*)
-{
-}
-
-bool TVersionGLSL::visitBinary(Visit, TIntermBinary*)
-{
-    return true;
-}
-
-bool TVersionGLSL::visitUnary(Visit, TIntermUnary*)
-{
-    return true;
-}
-
-bool TVersionGLSL::visitSelection(Visit, TIntermSelection*)
-{
-    return true;
-}
-
-bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node)
+bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
 {
     bool visitChildren = true;
 
-    switch (node->getOp()) {
+    switch (node->getOp())
+    {
       case EOpSequence:
         // We need to visit sequence children to get to global or inner scope.
         visitChildren = true;
         break;
-      case EOpDeclaration: {
-        const TIntermSequence& sequence = node->getSequence();
-        TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
-        if ((qualifier == EvqInvariantVaryingIn) ||
-            (qualifier == EvqInvariantVaryingOut)) {
-            updateVersion(GLSL_VERSION_120);
-        }
-        break;
-      }
-      case EOpParameters: {
-        const TIntermSequence& params = node->getSequence();
-        for (TIntermSequence::const_iterator iter = params.begin();
-             iter != params.end(); ++iter)
+      case EOpDeclaration:
         {
-            const TIntermTyped* param = (*iter)->getAsTyped();
-            if (param->isArray())
+            const TIntermSequence &sequence = *(node->getSequence());
+            TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
+            if ((qualifier == EvqInvariantVaryingIn) ||
+                (qualifier == EvqInvariantVaryingOut))
             {
-                TQualifier qualifier = param->getQualifier();
-                if ((qualifier == EvqOut) || (qualifier ==  EvqInOut))
+                updateVersion(GLSL_VERSION_120);
+            }
+            break;
+        }
+      case EOpInvariantDeclaration:
+        updateVersion(GLSL_VERSION_120);
+        break;
+      case EOpParameters:
+        {
+            const TIntermSequence &params = *(node->getSequence());
+            for (TIntermSequence::const_iterator iter = params.begin();
+                 iter != params.end(); ++iter)
+            {
+                const TIntermTyped *param = (*iter)->getAsTyped();
+                if (param->isArray())
                 {
-                    updateVersion(GLSL_VERSION_120);
-                    break;
+                    TQualifier qualifier = param->getQualifier();
+                    if ((qualifier == EvqOut) || (qualifier ==  EvqInOut))
+                    {
+                        updateVersion(GLSL_VERSION_120);
+                        break;
+                    }
                 }
             }
+            // Fully processed. No need to visit children.
+            visitChildren = false;
+            break;
         }
-        // Fully processed. No need to visit children.
-        visitChildren = false;
-        break;
-      }
       case EOpConstructMat2:
       case EOpConstructMat3:
-      case EOpConstructMat4: {
-        const TIntermSequence& sequence = node->getSequence();
-        if (sequence.size() == 1) {
-          TIntermTyped* typed = sequence.front()->getAsTyped();
-          if (typed && typed->isMatrix()) {
-            updateVersion(GLSL_VERSION_120);
-          }
+      case EOpConstructMat4:
+        {
+            const TIntermSequence &sequence = *(node->getSequence());
+            if (sequence.size() == 1)
+            {
+                TIntermTyped *typed = sequence.front()->getAsTyped();
+                if (typed && typed->isMatrix())
+                {
+                    updateVersion(GLSL_VERSION_120);
+                }
+            }
+            break;
         }
+      default:
         break;
-      }
-
-      default: break;
     }
 
     return visitChildren;
 }
 
-bool TVersionGLSL::visitLoop(Visit, TIntermLoop*)
-{
-    return true;
-}
-
-bool TVersionGLSL::visitBranch(Visit, TIntermBranch*)
-{
-    return true;
-}
-
 void TVersionGLSL::updateVersion(int version)
 {
     mVersion = std::max(version, mVersion);
diff --git a/src/compiler/translator/VersionGLSL.h b/src/compiler/translator/VersionGLSL.h
index 8a401c4..30f5a13 100644
--- a/src/compiler/translator/VersionGLSL.h
+++ b/src/compiler/translator/VersionGLSL.h
@@ -4,10 +4,10 @@
 // found in the LICENSE file.
 //
 
-#ifndef COMPILER_VERSIONGLSL_H_
-#define COMPILER_VERSIONGLSL_H_
+#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.
@@ -24,9 +24,10 @@
 //   - array as "out" function parameters
 //
 // TODO: ES3 equivalent versions of GLSL
-class TVersionGLSL : public TIntermTraverser {
-public:
-    TVersionGLSL(ShShaderType type);
+class TVersionGLSL : public TIntermTraverser
+{
+  public:
+    TVersionGLSL(sh::GLenum type);
 
     // Returns 120 if the following is used the shader:
     // - "invariant",
@@ -36,21 +37,14 @@
     // Else 110 is returned.
     int getVersion() { return mVersion; }
 
-    virtual void visitSymbol(TIntermSymbol*);
-    virtual void visitConstantUnion(TIntermConstantUnion*);
-    virtual bool visitBinary(Visit, TIntermBinary*);
-    virtual bool visitUnary(Visit, TIntermUnary*);
-    virtual bool visitSelection(Visit, TIntermSelection*);
-    virtual bool visitAggregate(Visit, TIntermAggregate*);
-    virtual bool visitLoop(Visit, TIntermLoop*);
-    virtual bool visitBranch(Visit, TIntermBranch*);
+    virtual void visitSymbol(TIntermSymbol *);
+    virtual bool visitAggregate(Visit, TIntermAggregate *);
 
-protected:
+  protected:
     void updateVersion(int version);
 
-private:
-    ShShaderType mShaderType;
+  private:
     int mVersion;
 };
 
-#endif  // COMPILER_VERSIONGLSL_H_
+#endif  // COMPILER_TRANSLATOR_VERSIONGLSL_H_
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/depgraph/DependencyGraphBuilder.cpp b/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp
index d5f2cba..1aeb822 100644
--- a/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp
+++ b/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp
@@ -6,24 +6,32 @@
 
 #include "compiler/translator/depgraph/DependencyGraphBuilder.h"
 
-void TDependencyGraphBuilder::build(TIntermNode* node, TDependencyGraph* graph)
+void TDependencyGraphBuilder::build(TIntermNode *node, TDependencyGraph *graph)
 {
     TDependencyGraphBuilder builder(graph);
     builder.build(node);
 }
 
-bool TDependencyGraphBuilder::visitAggregate(Visit visit, TIntermAggregate* intermAggregate)
+bool TDependencyGraphBuilder::visitAggregate(
+    Visit visit, TIntermAggregate *intermAggregate)
 {
-    switch (intermAggregate->getOp()) {
-        case EOpFunction: visitFunctionDefinition(intermAggregate); break;
-        case EOpFunctionCall: visitFunctionCall(intermAggregate); break;
-        default: visitAggregateChildren(intermAggregate); break;
+    switch (intermAggregate->getOp())
+    {
+      case EOpFunction:
+        visitFunctionDefinition(intermAggregate);
+        break;
+      case EOpFunctionCall:
+        visitFunctionCall(intermAggregate);
+        break;
+      default:
+        visitAggregateChildren(intermAggregate);
+        break;
     }
-
     return false;
 }
 
-void TDependencyGraphBuilder::visitFunctionDefinition(TIntermAggregate* intermAggregate)
+void TDependencyGraphBuilder::visitFunctionDefinition(
+    TIntermAggregate *intermAggregate)
 {
     // Currently, we do not support user defined functions.
     if (intermAggregate->getName() != "main(")
@@ -34,64 +42,71 @@
 
 // Takes an expression like "f(x)" and creates a dependency graph like
 // "x -> argument 0 -> function call".
-void TDependencyGraphBuilder::visitFunctionCall(TIntermAggregate* intermFunctionCall)
+void TDependencyGraphBuilder::visitFunctionCall(
+    TIntermAggregate *intermFunctionCall)
 {
-    TGraphFunctionCall* functionCall = mGraph->createFunctionCall(intermFunctionCall);
+    TGraphFunctionCall *functionCall =
+        mGraph->createFunctionCall(intermFunctionCall);
 
     // Run through the function call arguments.
     int argumentNumber = 0;
-    TIntermSequence& intermArguments = intermFunctionCall->getSequence();
-    for (TIntermSequence::const_iterator iter = intermArguments.begin();
-         iter != intermArguments.end();
+    TIntermSequence *intermArguments = intermFunctionCall->getSequence();
+    for (TIntermSequence::const_iterator iter = intermArguments->begin();
+         iter != intermArguments->end();
          ++iter, ++argumentNumber)
     {
         TNodeSetMaintainer nodeSetMaintainer(this);
 
-        TIntermNode* intermArgument = *iter;
+        TIntermNode *intermArgument = *iter;
         intermArgument->traverse(this);
 
-        if (TParentNodeSet* argumentNodes = mNodeSets.getTopSet()) {
-            TGraphArgument* argument = mGraph->createArgument(intermFunctionCall, argumentNumber);
+        if (TParentNodeSet *argumentNodes = mNodeSets.getTopSet())
+        {
+            TGraphArgument *argument = mGraph->createArgument(
+                intermFunctionCall, argumentNumber);
             connectMultipleNodesToSingleNode(argumentNodes, argument);
             argument->addDependentNode(functionCall);
         }
     }
 
-    // Push the leftmost symbol of this function call into the current set of dependent symbols to
-    // represent the result of this function call.
+    // Push the leftmost symbol of this function call into the current set of
+    // dependent symbols to represent the result of this function call.
     // Thus, an expression like "y = f(x)" will yield a dependency graph like
     // "x -> argument 0 -> function call -> y".
-    // This line essentially passes the function call node back up to an earlier visitAssignment
-    // call, which will create the connection "function call -> y".
+    // This line essentially passes the function call node back up to an earlier
+    // visitAssignment call, which will create the connection "function call -> y".
     mNodeSets.insertIntoTopSet(functionCall);
 }
 
-void TDependencyGraphBuilder::visitAggregateChildren(TIntermAggregate* intermAggregate)
+void TDependencyGraphBuilder::visitAggregateChildren(
+    TIntermAggregate *intermAggregate)
 {
-    TIntermSequence& sequence = intermAggregate->getSequence();
-    for(TIntermSequence::const_iterator iter = sequence.begin(); iter != sequence.end(); ++iter)
+    TIntermSequence *sequence = intermAggregate->getSequence();
+    for (TIntermSequence::const_iterator iter = sequence->begin();
+         iter != sequence->end(); ++iter)
     {
-        TIntermNode* intermChild = *iter;
+        TIntermNode *intermChild = *iter;
         intermChild->traverse(this);
     }
 }
 
-void TDependencyGraphBuilder::visitSymbol(TIntermSymbol* intermSymbol)
+void TDependencyGraphBuilder::visitSymbol(TIntermSymbol *intermSymbol)
 {
-    // Push this symbol into the set of dependent symbols for the current assignment or condition
-    // that we are traversing.
-    TGraphSymbol* symbol = mGraph->getOrCreateSymbol(intermSymbol);
+    // Push this symbol into the set of dependent symbols for the current
+    // assignment or condition that we are traversing.
+    TGraphSymbol *symbol = mGraph->getOrCreateSymbol(intermSymbol);
     mNodeSets.insertIntoTopSet(symbol);
 
-    // If this symbol is the current leftmost symbol under an assignment, replace the previous
-    // leftmost symbol with this symbol.
-    if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree) {
+    // If this symbol is the current leftmost symbol under an assignment, replace
+    // the previous leftmost symbol with this symbol.
+    if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree)
+    {
         mLeftmostSymbols.pop();
         mLeftmostSymbols.push(symbol);
     }
 }
 
-bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary* intermBinary)
+bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary *intermBinary)
 {
     TOperator op = intermBinary->getOp();
     if (op == EOpInitialize || intermBinary->isAssignment())
@@ -104,13 +119,13 @@
     return false;
 }
 
-void TDependencyGraphBuilder::visitAssignment(TIntermBinary* intermAssignment)
+void TDependencyGraphBuilder::visitAssignment(TIntermBinary *intermAssignment)
 {
-    TIntermTyped* intermLeft = intermAssignment->getLeft();
+    TIntermTyped *intermLeft = intermAssignment->getLeft();
     if (!intermLeft)
         return;
 
-    TGraphSymbol* leftmostSymbol = NULL;
+    TGraphSymbol *leftmostSymbol = NULL;
 
     {
         TNodeSetMaintainer nodeSetMaintainer(this);
@@ -120,88 +135,100 @@
             intermLeft->traverse(this);
             leftmostSymbol = mLeftmostSymbols.top();
 
-            // After traversing the left subtree of this assignment, we should have found a real
-            // leftmost symbol, and the leftmost symbol should not be a placeholder.
+            // After traversing the left subtree of this assignment, we should
+            // have found a real leftmost symbol, and the leftmost symbol should
+            // not be a placeholder.
             ASSERT(leftmostSymbol != &mLeftSubtree);
             ASSERT(leftmostSymbol != &mRightSubtree);
         }
 
-        if (TIntermTyped* intermRight = intermAssignment->getRight()) {
+        if (TIntermTyped *intermRight = intermAssignment->getRight())
+        {
             TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
             intermRight->traverse(this);
         }
 
-        if (TParentNodeSet* assignmentNodes = mNodeSets.getTopSet())
+        if (TParentNodeSet *assignmentNodes = mNodeSets.getTopSet())
             connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol);
     }
 
-    // Push the leftmost symbol of this assignment into the current set of dependent symbols to
-    // represent the result of this assignment.
-    // An expression like "a = (b = c)" will yield a dependency graph like "c -> b -> a".
-    // This line essentially passes the leftmost symbol of the nested assignment ("b" in this
-    // example) back up to the earlier visitAssignment call for the outer assignment, which will
-    // create the connection "b -> a".
+    // Push the leftmost symbol of this assignment into the current set of dependent
+    // symbols to represent the result of this assignment.
+    // An expression like "a = (b = c)" will yield a dependency graph like
+    // "c -> b -> a".
+    // This line essentially passes the leftmost symbol of the nested assignment
+    // ("b" in this example) back up to the earlier visitAssignment call for the
+    // outer assignment, which will create the connection "b -> a".
     mNodeSets.insertIntoTopSet(leftmostSymbol);
 }
 
-void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary* intermLogicalOp)
+void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary *intermLogicalOp)
 {
-    if (TIntermTyped* intermLeft = intermLogicalOp->getLeft()) {
+    if (TIntermTyped *intermLeft = intermLogicalOp->getLeft())
+    {
         TNodeSetPropagatingMaintainer nodeSetMaintainer(this);
 
         intermLeft->traverse(this);
-        if (TParentNodeSet* leftNodes = mNodeSets.getTopSet()) {
-            TGraphLogicalOp* logicalOp = mGraph->createLogicalOp(intermLogicalOp);
+        if (TParentNodeSet *leftNodes = mNodeSets.getTopSet())
+        {
+            TGraphLogicalOp *logicalOp = mGraph->createLogicalOp(intermLogicalOp);
             connectMultipleNodesToSingleNode(leftNodes, logicalOp);
         }
     }
 
-    if (TIntermTyped* intermRight = intermLogicalOp->getRight()) {
+    if (TIntermTyped *intermRight = intermLogicalOp->getRight())
+    {
         TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
         intermRight->traverse(this);
     }
 }
 
-void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary* intermBinary)
+void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary *intermBinary)
 {
-    if (TIntermTyped* intermLeft = intermBinary->getLeft())
+    if (TIntermTyped *intermLeft = intermBinary->getLeft())
         intermLeft->traverse(this);
 
-    if (TIntermTyped* intermRight = intermBinary->getRight()) {
+    if (TIntermTyped *intermRight = intermBinary->getRight())
+    {
         TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
         intermRight->traverse(this);
     }
 }
 
-bool TDependencyGraphBuilder::visitSelection(Visit visit, TIntermSelection* intermSelection)
+bool TDependencyGraphBuilder::visitSelection(
+    Visit visit, TIntermSelection *intermSelection)
 {
-    if (TIntermNode* intermCondition = intermSelection->getCondition()) {
+    if (TIntermNode *intermCondition = intermSelection->getCondition())
+    {
         TNodeSetMaintainer nodeSetMaintainer(this);
 
         intermCondition->traverse(this);
-        if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) {
-            TGraphSelection* selection = mGraph->createSelection(intermSelection);
+        if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet())
+        {
+            TGraphSelection *selection = mGraph->createSelection(intermSelection);
             connectMultipleNodesToSingleNode(conditionNodes, selection);
         }
     }
 
-    if (TIntermNode* intermTrueBlock = intermSelection->getTrueBlock())
+    if (TIntermNode *intermTrueBlock = intermSelection->getTrueBlock())
         intermTrueBlock->traverse(this);
 
-    if (TIntermNode* intermFalseBlock = intermSelection->getFalseBlock())
+    if (TIntermNode *intermFalseBlock = intermSelection->getFalseBlock())
         intermFalseBlock->traverse(this);
 
     return false;
 }
 
-bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop* intermLoop)
+bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop *intermLoop)
 {
-    if (TIntermTyped* intermCondition = intermLoop->getCondition()) {
+    if (TIntermTyped *intermCondition = intermLoop->getCondition())
+    {
         TNodeSetMaintainer nodeSetMaintainer(this);
 
         intermCondition->traverse(this);
-        if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) {
-            TGraphLoop* loop = mGraph->createLoop(intermLoop);
+        if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet())
+        {
+            TGraphLoop *loop = mGraph->createLoop(intermLoop);
             connectMultipleNodesToSingleNode(conditionNodes, loop);
         }
     }
@@ -209,19 +236,20 @@
     if (TIntermNode* intermBody = intermLoop->getBody())
         intermBody->traverse(this);
 
-    if (TIntermTyped* intermExpression = intermLoop->getExpression())
+    if (TIntermTyped *intermExpression = intermLoop->getExpression())
         intermExpression->traverse(this);
 
     return false;
 }
 
 
-void TDependencyGraphBuilder::connectMultipleNodesToSingleNode(TParentNodeSet* nodes,
-                                                               TGraphNode* node) const
+void TDependencyGraphBuilder::connectMultipleNodesToSingleNode(
+    TParentNodeSet *nodes, TGraphNode *node) const
 {
-    for (TParentNodeSet::const_iterator iter = nodes->begin(); iter != nodes->end(); ++iter)
+    for (TParentNodeSet::const_iterator iter = nodes->begin();
+         iter != nodes->end(); ++iter)
     {
-        TGraphParentNode* currentNode = *iter;
+        TGraphParentNode *currentNode = *iter;
         currentNode->addDependentNode(node);
     }
 }
diff --git a/src/compiler/translator/depgraph/DependencyGraphBuilder.h b/src/compiler/translator/depgraph/DependencyGraphBuilder.h
index 3e928fb..b76f075 100644
--- a/src/compiler/translator/depgraph/DependencyGraphBuilder.h
+++ b/src/compiler/translator/depgraph/DependencyGraphBuilder.h
@@ -4,55 +4,58 @@
 // found in the LICENSE file.
 //
 
-#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
-#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
+#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
+#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
 
 #include "compiler/translator/depgraph/DependencyGraph.h"
 
 //
-// Creates a dependency graph of symbols, function calls, conditions etc. by traversing a
-// intermediate tree.
+// Creates a dependency graph of symbols, function calls, conditions etc. by
+// traversing a intermediate tree.
 //
-class TDependencyGraphBuilder : public TIntermTraverser {
-public:
-    static void build(TIntermNode* node, TDependencyGraph* graph);
+class TDependencyGraphBuilder : public TIntermTraverser
+{
+  public:
+    static void build(TIntermNode *node, TDependencyGraph *graph);
 
-    virtual void visitSymbol(TIntermSymbol*);
-    virtual bool visitBinary(Visit visit, TIntermBinary*);
-    virtual bool visitSelection(Visit visit, TIntermSelection*);
-    virtual bool visitAggregate(Visit visit, TIntermAggregate*);
-    virtual bool visitLoop(Visit visit, TIntermLoop*);
+    virtual void visitSymbol(TIntermSymbol *);
+    virtual bool visitBinary(Visit visit, TIntermBinary *);
+    virtual bool visitSelection(Visit visit, TIntermSelection *);
+    virtual bool visitAggregate(Visit visit, TIntermAggregate *);
+    virtual bool visitLoop(Visit visit, TIntermLoop *);
 
-private:
-    typedef std::stack<TGraphSymbol*> TSymbolStack;
-    typedef std::set<TGraphParentNode*> TParentNodeSet;
+  private:
+    typedef std::stack<TGraphSymbol *> TSymbolStack;
+    typedef std::set<TGraphParentNode *> TParentNodeSet;
 
     //
     // For collecting the dependent nodes of assignments, conditions, etc.
     // while traversing the intermediate tree.
     //
-    // This data structure is stack of sets. Each set contains dependency graph parent nodes.
+    // This data structure is stack of sets. Each set contains dependency graph
+    // parent nodes.
     //
-    class TNodeSetStack {
-    public:
+    class TNodeSetStack
+    {
+      public:
         TNodeSetStack() {};
         ~TNodeSetStack() { clear(); }
 
         // This should only be called after a pushSet.
         // Returns NULL if the top set is empty.
-        TParentNodeSet* getTopSet() const
+        TParentNodeSet *getTopSet() const
         {
-            ASSERT(!nodeSets.empty());
-            TParentNodeSet* topSet = nodeSets.top();
+            ASSERT(!mNodeSets.empty());
+            TParentNodeSet *topSet = mNodeSets.top();
             return !topSet->empty() ? topSet : NULL;
         }
 
-        void pushSet() { nodeSets.push(new TParentNodeSet()); }
+        void pushSet() { mNodeSets.push(new TParentNodeSet()); }
         void popSet()
         {
-            ASSERT(!nodeSets.empty());
-            delete nodeSets.top();
-            nodeSets.pop();
+            ASSERT(!mNodeSets.empty());
+            delete mNodeSets.top();
+            mNodeSets.pop();
         }
 
         // Pops the top set and adds its contents to the new top set.
@@ -60,12 +63,13 @@
         // If there is no set below the top set, the top set is just deleted.
         void popSetIntoNext()
         {
-            ASSERT(!nodeSets.empty());
-            TParentNodeSet* oldTopSet = nodeSets.top();
-            nodeSets.pop();
+            ASSERT(!mNodeSets.empty());
+            TParentNodeSet *oldTopSet = mNodeSets.top();
+            mNodeSets.pop();
 
-            if (!nodeSets.empty()) {
-                TParentNodeSet* newTopSet = nodeSets.top();
+            if (!mNodeSets.empty())
+            {
+                TParentNodeSet *newTopSet = mNodeSets.top();
                 newTopSet->insert(oldTopSet->begin(), oldTopSet->end());
             }
 
@@ -76,106 +80,120 @@
         // This can be called when there is no top set if we are visiting
         // symbols that are not under an assignment or condition.
         // We don't need to track those symbols.
-        void insertIntoTopSet(TGraphParentNode* node)
+        void insertIntoTopSet(TGraphParentNode *node)
         {
-            if (nodeSets.empty())
+            if (mNodeSets.empty())
                 return;
 
-            nodeSets.top()->insert(node);
+            mNodeSets.top()->insert(node);
         }
 
         void clear()
         {
-            while (!nodeSets.empty())
+            while (!mNodeSets.empty())
                 popSet();
         }
 
-    private:
-        typedef std::stack<TParentNodeSet*> TParentNodeSetStack;
+      private:
+        typedef std::stack<TParentNodeSet *> TParentNodeSetStack;
 
-        TParentNodeSetStack nodeSets;
+        TParentNodeSetStack mNodeSets;
     };
 
     //
     // An instance of this class pushes a new node set when instantiated.
     // When the instance goes out of scope, it and pops the node set.
     //
-    class TNodeSetMaintainer {
-    public:
-        TNodeSetMaintainer(TDependencyGraphBuilder* factory)
-            : sets(factory->mNodeSets) { sets.pushSet(); }
-        ~TNodeSetMaintainer() { sets.popSet(); }
-    protected:
-        TNodeSetStack& sets;
+    class TNodeSetMaintainer
+    {
+      public:
+        TNodeSetMaintainer(TDependencyGraphBuilder *factory)
+            : mSets(factory->mNodeSets)
+        {
+            mSets.pushSet();
+        }
+        ~TNodeSetMaintainer() { mSets.popSet(); }
+      protected:
+        TNodeSetStack &mSets;
     };
 
     //
     // An instance of this class pushes a new node set when instantiated.
-    // When the instance goes out of scope, it and pops the top node set and adds its contents to
-    // the new top node set.
+    // When the instance goes out of scope, it and pops the top node set and adds
+    // its contents to the new top node set.
     //
-    class TNodeSetPropagatingMaintainer {
-    public:
-        TNodeSetPropagatingMaintainer(TDependencyGraphBuilder* factory)
-            : sets(factory->mNodeSets) { sets.pushSet(); }
-        ~TNodeSetPropagatingMaintainer() { sets.popSetIntoNext(); }
-    protected:
-        TNodeSetStack& sets;
+    class TNodeSetPropagatingMaintainer
+    {
+      public:
+        TNodeSetPropagatingMaintainer(TDependencyGraphBuilder *factory)
+            : mSets(factory->mNodeSets)
+        {
+            mSets.pushSet();
+        }
+        ~TNodeSetPropagatingMaintainer() { mSets.popSetIntoNext(); }
+      protected:
+        TNodeSetStack &mSets;
     };
 
     //
-    // An instance of this class keeps track of the leftmost symbol while we're exploring an
-    // assignment.
-    // It will push the placeholder symbol kLeftSubtree when instantiated under a left subtree,
-    // and kRightSubtree under a right subtree.
-    // When it goes out of scope, it will pop the leftmost symbol at the top of the scope.
-    // During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with a real symbol.
-    // kRightSubtree will never be replaced by a real symbol because we are tracking the leftmost
-    // symbol.
+    // An instance of this class keeps track of the leftmost symbol while we're
+    // exploring an assignment.
+    // It will push the placeholder symbol kLeftSubtree when instantiated under a
+    // left subtree, and kRightSubtree under a right subtree.
+    // When it goes out of scope, it will pop the leftmost symbol at the top of the
+    // scope.
+    // During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with
+    // a real symbol.
+    // kRightSubtree will never be replaced by a real symbol because we are tracking
+    // the leftmost symbol.
     //
-    class TLeftmostSymbolMaintainer {
-    public:
-        TLeftmostSymbolMaintainer(TDependencyGraphBuilder* factory, TGraphSymbol& subtree)
-            : leftmostSymbols(factory->mLeftmostSymbols)
+    class TLeftmostSymbolMaintainer
+    {
+      public:
+        TLeftmostSymbolMaintainer(
+            TDependencyGraphBuilder *factory, TGraphSymbol &subtree)
+            : mLeftmostSymbols(factory->mLeftmostSymbols)
         {
-            needsPlaceholderSymbol = leftmostSymbols.empty() || leftmostSymbols.top() != &subtree;
-            if (needsPlaceholderSymbol)
-                leftmostSymbols.push(&subtree);
+            mNeedsPlaceholderSymbol =
+                mLeftmostSymbols.empty() || mLeftmostSymbols.top() != &subtree;
+            if (mNeedsPlaceholderSymbol)
+                mLeftmostSymbols.push(&subtree);
         }
 
         ~TLeftmostSymbolMaintainer()
         {
-            if (needsPlaceholderSymbol)
-                leftmostSymbols.pop();
+            if (mNeedsPlaceholderSymbol)
+                mLeftmostSymbols.pop();
         }
 
-    protected:
-        TSymbolStack& leftmostSymbols;
-        bool needsPlaceholderSymbol;
+      protected:
+        TSymbolStack& mLeftmostSymbols;
+        bool mNeedsPlaceholderSymbol;
     };
 
-    TDependencyGraphBuilder(TDependencyGraph* graph)
-        : TIntermTraverser(true, false, false)
-        , mLeftSubtree(NULL)
-        , mRightSubtree(NULL)
-        , mGraph(graph) {}
-    void build(TIntermNode* intermNode) { intermNode->traverse(this); }
+    TDependencyGraphBuilder(TDependencyGraph *graph)
+        : TIntermTraverser(true, false, false),
+          mLeftSubtree(NULL),
+          mRightSubtree(NULL),
+          mGraph(graph) {}
+    void build(TIntermNode *intermNode) { intermNode->traverse(this); }
 
-    void connectMultipleNodesToSingleNode(TParentNodeSet* nodes, TGraphNode* node) const;
+    void connectMultipleNodesToSingleNode(
+        TParentNodeSet *nodes, TGraphNode *node) const;
 
-    void visitAssignment(TIntermBinary*);
-    void visitLogicalOp(TIntermBinary*);
-    void visitBinaryChildren(TIntermBinary*);
-    void visitFunctionDefinition(TIntermAggregate*);
-    void visitFunctionCall(TIntermAggregate* intermFunctionCall);
-    void visitAggregateChildren(TIntermAggregate*);
+    void visitAssignment(TIntermBinary *);
+    void visitLogicalOp(TIntermBinary *);
+    void visitBinaryChildren(TIntermBinary *);
+    void visitFunctionDefinition(TIntermAggregate *);
+    void visitFunctionCall(TIntermAggregate *intermFunctionCall);
+    void visitAggregateChildren(TIntermAggregate *);
 
     TGraphSymbol mLeftSubtree;
     TGraphSymbol mRightSubtree;
 
-    TDependencyGraph* mGraph;
+    TDependencyGraph *mGraph;
     TNodeSetStack mNodeSets;
     TSymbolStack mLeftmostSymbols;
 };
 
-#endif  // COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
+#endif  // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index 8ebf2d1..5c945ad 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -34,6 +34,7 @@
 #pragma warning(disable: 4701)
 #endif
 
+#include "angle_gl.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/ParseContext.h"
 #include "GLSLANG/ShaderLang.h"
@@ -106,14 +107,14 @@
   } while (0)
 
 #define VERTEX_ONLY(S, L) {  \
-    if (context->shaderType != SH_VERTEX_SHADER) {  \
+    if (context->shaderType != GL_VERTEX_SHADER) {  \
         context->error(L, " supported in vertex shaders only ", S);  \
         context->recover();  \
     }  \
 }
 
 #define FRAG_ONLY(S, L) {  \
-    if (context->shaderType != SH_FRAGMENT_SHADER) {  \
+    if (context->shaderType != GL_FRAGMENT_SHADER) {  \
         context->error(L, " supported in fragment shaders only ", S);  \
         context->recover();  \
     }  \
@@ -208,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)
         {
@@ -411,7 +381,7 @@
                     for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
                         qual = fnCandidate->getParam(i).type->getQualifier();
                         if (qual == EvqOut || qual == EvqInOut) {
-                            if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
+                            if (context->lValueErrorCheck($$->getLine(), "assign", (*($$->getAsAggregate()->getSequence()))[i]->getAsTyped())) {
                                 context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
                                 context->recover();
                             }
@@ -815,12 +785,13 @@
         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 == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
+        if (($2 == EbpHigh) && (context->shaderType == GL_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
             context->error(@1, "precision is not supported in fragment shader", "highp");
             context->recover();
         }
@@ -887,7 +858,8 @@
         else
         {
             // Insert the unmangled name to detect potential future redefinition as a variable.
-            context->symbolTable.getOuterLevel()->insert($1->getName(), *$1);
+            TFunction *function = new TFunction(NewPoolTString($1->getName().c_str()), $1->getReturnType());
+            context->symbolTable.getOuterLevel()->insert(function);
         }
 
         //
@@ -899,7 +871,7 @@
 
         // We're at the inner scope level of the function's arguments and body statement.
         // Add the function prototype to the surrounding scope instead.
-        context->symbolTable.getOuterLevel()->insert(*$$.function);
+        context->symbolTable.getOuterLevel()->insert($$.function);
     }
     ;
 
@@ -1100,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);
     }
     ;
 
@@ -1161,7 +1119,7 @@
         ES2_ONLY("varying", @1);
         if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying"))
             context->recover();
-        if (context->shaderType == SH_VERTEX_SHADER)
+        if (context->shaderType == GL_VERTEX_SHADER)
             $$.setBasic(EbtVoid, EvqVaryingOut, @1);
         else
             $$.setBasic(EbtVoid, EvqVaryingIn, @1);
@@ -1170,7 +1128,7 @@
         ES2_ONLY("varying", @1);
         if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
             context->recover();
-        if (context->shaderType == SH_VERTEX_SHADER)
+        if (context->shaderType == GL_VERTEX_SHADER)
             $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1);
         else
             $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1);
@@ -1209,29 +1167,29 @@
     }
     | IN_QUAL {
         ES3_ONLY("in", @1, "storage qualifier");
-        $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
+        $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
     }
     | OUT_QUAL {
         ES3_ONLY("out", @1, "storage qualifier");
-        $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
+        $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
     }
     | CENTROID IN_QUAL {
         ES3_ONLY("centroid in", @1, "storage qualifier");
-        if (context->shaderType == SH_VERTEX_SHADER)
+        if (context->shaderType == GL_VERTEX_SHADER)
         {
             context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader");
             context->recover();
         }
-        $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
+        $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
     }
     | CENTROID OUT_QUAL {
         ES3_ONLY("centroid out", @1, "storage qualifier");
-        if (context->shaderType == SH_FRAGMENT_SHADER)
+        if (context->shaderType == GL_FRAGMENT_SHADER)
         {
             context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader");
             context->recover();
         }
-        $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
+        $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
     }
     | UNIFORM {
         if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
@@ -1899,7 +1857,7 @@
                 //
                 // Insert the parameters with name in the symbol table.
                 //
-                if (! context->symbolTable.declare(*variable)) {
+                if (! context->symbolTable.declare(variable)) {
                     context->error(@1, "redefinition", variable->getName().c_str());
                     context->recover();
                     delete variable;
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 63ec8c7..6d483b1 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -84,6 +84,7 @@
 #pragma warning(disable: 4701)
 #endif
 
+#include "angle_gl.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/ParseContext.h"
 #include "GLSLANG/ShaderLang.h"
@@ -362,14 +363,14 @@
   } while (0)
 
 #define VERTEX_ONLY(S, L) {  \
-    if (context->shaderType != SH_VERTEX_SHADER) {  \
+    if (context->shaderType != GL_VERTEX_SHADER) {  \
         context->error(L, " supported in vertex shaders only ", S);  \
         context->recover();  \
     }  \
 }
 
 #define FRAG_ONLY(S, L) {  \
-    if (context->shaderType != SH_FRAGMENT_SHADER) {  \
+    if (context->shaderType != GL_FRAGMENT_SHADER) {  \
         context->error(L, " supported in fragment shaders only ", S);  \
         context->recover();  \
     }  \
@@ -794,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
 
@@ -2546,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)
         {
@@ -2793,7 +2763,7 @@
                     for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
                         qual = fnCandidate->getParam(i).type->getQualifier();
                         if (qual == EvqOut || qual == EvqInOut) {
-                            if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()[i]->getAsTyped())) {
+                            if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (*((yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()))[i]->getAsTyped())) {
                                 context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
                                 context->recover();
                             }
@@ -3343,16 +3313,17 @@
   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;
 
   case 76:
 
     {
-        if (((yyvsp[(2) - (4)].interm.precision) == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
+        if (((yyvsp[(2) - (4)].interm.precision) == EbpHigh) && (context->shaderType == GL_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
             context->error((yylsp[(1) - (4)]), "precision is not supported in fragment shader", "highp");
             context->recover();
         }
@@ -3436,7 +3407,8 @@
         else
         {
             // Insert the unmangled name to detect potential future redefinition as a variable.
-            context->symbolTable.getOuterLevel()->insert((yyvsp[(1) - (2)].interm.function)->getName(), *(yyvsp[(1) - (2)].interm.function));
+            TFunction *function = new TFunction(NewPoolTString((yyvsp[(1) - (2)].interm.function)->getName().c_str()), (yyvsp[(1) - (2)].interm.function)->getReturnType());
+            context->symbolTable.getOuterLevel()->insert(function);
         }
 
         //
@@ -3448,7 +3420,7 @@
 
         // We're at the inner scope level of the function's arguments and body statement.
         // Add the function prototype to the surrounding scope instead.
-        context->symbolTable.getOuterLevel()->insert(*(yyval.interm).function);
+        context->symbolTable.getOuterLevel()->insert((yyval.interm).function);
     }
     break;
 
@@ -3717,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;
 
@@ -3794,7 +3752,7 @@
         ES2_ONLY("varying", (yylsp[(1) - (1)]));
         if (context->globalErrorCheck((yylsp[(1) - (1)]), context->symbolTable.atGlobalLevel(), "varying"))
             context->recover();
-        if (context->shaderType == SH_VERTEX_SHADER)
+        if (context->shaderType == GL_VERTEX_SHADER)
             (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[(1) - (1)]));
         else
             (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[(1) - (1)]));
@@ -3807,7 +3765,7 @@
         ES2_ONLY("varying", (yylsp[(1) - (2)]));
         if (context->globalErrorCheck((yylsp[(1) - (2)]), context->symbolTable.atGlobalLevel(), "invariant varying"))
             context->recover();
-        if (context->shaderType == SH_VERTEX_SHADER)
+        if (context->shaderType == GL_VERTEX_SHADER)
             (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingOut, (yylsp[(1) - (2)]));
         else
             (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingIn, (yylsp[(1) - (2)]));
@@ -3871,7 +3829,7 @@
 
     {
         ES3_ONLY("in", (yylsp[(1) - (1)]), "storage qualifier");
-        (yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
+        (yyval.interm.type).qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
     }
     break;
 
@@ -3879,7 +3837,7 @@
 
     {
         ES3_ONLY("out", (yylsp[(1) - (1)]), "storage qualifier");
-        (yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
+        (yyval.interm.type).qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
     }
     break;
 
@@ -3887,12 +3845,12 @@
 
     {
         ES3_ONLY("centroid in", (yylsp[(1) - (2)]), "storage qualifier");
-        if (context->shaderType == SH_VERTEX_SHADER)
+        if (context->shaderType == GL_VERTEX_SHADER)
         {
             context->error((yylsp[(1) - (2)]), "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader");
             context->recover();
         }
-        (yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
+        (yyval.interm.type).qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
     }
     break;
 
@@ -3900,12 +3858,12 @@
 
     {
         ES3_ONLY("centroid out", (yylsp[(1) - (2)]), "storage qualifier");
-        if (context->shaderType == SH_FRAGMENT_SHADER)
+        if (context->shaderType == GL_FRAGMENT_SHADER)
         {
             context->error((yylsp[(1) - (2)]), "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader");
             context->recover();
         }
-        (yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
+        (yyval.interm.type).qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
     }
     break;
 
@@ -4967,7 +4925,7 @@
                 //
                 // Insert the parameters with name in the symbol table.
                 //
-                if (! context->symbolTable.declare(*variable)) {
+                if (! context->symbolTable.declare(variable)) {
                     context->error((yylsp[(1) - (1)]), "redefinition", variable->getName().c_str());
                     context->recover();
                     delete variable;
diff --git a/src/compiler/translator/intermOut.cpp b/src/compiler/translator/intermOut.cpp
index 7f94ac3..56340c6 100644
--- a/src/compiler/translator/intermOut.cpp
+++ b/src/compiler/translator/intermOut.cpp
@@ -1,12 +1,15 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-#include "compiler/translator/localintermediate.h"
+#include "compiler/translator/Intermediate.h"
 #include "compiler/translator/SymbolTable.h"
 
+namespace
+{
+
 //
 // Two purposes:
 // 1.  Show an example of how to iterate tree.  Functions can
@@ -20,22 +23,40 @@
 // Use this class to carry along data from node to node in
 // the traversal
 //
-class TOutputTraverser : public TIntermTraverser {
-public:
-    TOutputTraverser(TInfoSinkBase& i) : sink(i) { }
+class TOutputTraverser : public TIntermTraverser
+{
+  public:
+    TOutputTraverser(TInfoSinkBase &i)
+        : sink(i) { }
     TInfoSinkBase& sink;
 
-protected:
-    void visitSymbol(TIntermSymbol*);
-    void visitConstantUnion(TIntermConstantUnion*);
-    bool visitBinary(Visit visit, TIntermBinary*);
-    bool visitUnary(Visit visit, TIntermUnary*);
-    bool visitSelection(Visit visit, TIntermSelection*);
-    bool visitAggregate(Visit visit, TIntermAggregate*);
-    bool visitLoop(Visit visit, TIntermLoop*);
-    bool visitBranch(Visit visit, TIntermBranch*);
+  protected:
+    void visitSymbol(TIntermSymbol *);
+    void visitConstantUnion(TIntermConstantUnion *);
+    bool visitBinary(Visit visit, TIntermBinary *);
+    bool visitUnary(Visit visit, TIntermUnary *);
+    bool visitSelection(Visit visit, TIntermSelection *);
+    bool visitAggregate(Visit visit, TIntermAggregate *);
+    bool visitLoop(Visit visit, TIntermLoop *);
+    bool visitBranch(Visit visit, TIntermBranch *);
 };
 
+//
+// Helper functions for printing, not part of traversing.
+//
+void OutputTreeText(TInfoSinkBase &sink, TIntermNode *node, const int depth)
+{
+    int i;
+
+    sink.location(node->getLine());
+
+    for (i = 0; i < depth; ++i)
+        sink << "  ";
+}
+
+}  // namespace anonymous
+
+
 TString TType::getCompleteString() const
 {
     TStringStream stream;
@@ -54,20 +75,6 @@
 }
 
 //
-// Helper functions for printing, not part of traversing.
-//
-
-void OutputTreeText(TInfoSinkBase& sink, TIntermNode* node, const int depth)
-{
-    int i;
-
-    sink.location(node->getLine());
-
-    for (i = 0; i < depth; ++i)
-        sink << "  ";
-}
-
-//
 // The rest of the file are the traversal functions.  The last one
 // is the one that starts the traversal.
 //
@@ -76,58 +83,126 @@
 // return false.
 //
 
-void TOutputTraverser::visitSymbol(TIntermSymbol* node)
+void TOutputTraverser::visitSymbol(TIntermSymbol *node)
 {
-    OutputTreeText(sink, node, depth);
+    OutputTreeText(sink, node, mDepth);
 
     sink << "'" << node->getSymbol() << "' ";
     sink << "(" << node->getCompleteString() << ")\n";
 }
 
-bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node)
+bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
 {
     TInfoSinkBase& out = sink;
 
-    OutputTreeText(out, node, depth);
+    OutputTreeText(out, node, mDepth);
 
-    switch (node->getOp()) {
-        case EOpAssign:                   out << "move second child to first child";           break;
-        case EOpInitialize:               out << "initialize first child with second child";   break;
-        case EOpAddAssign:                out << "add second child into first child";          break;
-        case EOpSubAssign:                out << "subtract second child into first child";     break;
-        case EOpMulAssign:                out << "multiply second child into first child";     break;
-        case EOpVectorTimesMatrixAssign:  out << "matrix mult second child into first child";  break;
-        case EOpVectorTimesScalarAssign:  out << "vector scale second child into first child"; break;
-        case EOpMatrixTimesScalarAssign:  out << "matrix scale second child into first child"; break;
-        case EOpMatrixTimesMatrixAssign:  out << "matrix mult second child into first child"; break;
-        case EOpDivAssign:                out << "divide second child into first child";       break;
-        case EOpIndexDirect:   out << "direct index";   break;
-        case EOpIndexIndirect: out << "indirect index"; break;
-        case EOpIndexDirectStruct:   out << "direct index for structure";   break;
-        case EOpIndexDirectInterfaceBlock: out << "direct index for interface block"; break;
-        case EOpVectorSwizzle: out << "vector swizzle"; break;
+    switch (node->getOp())
+    {
+      case EOpAssign:
+        out << "move second child to first child";
+        break;
+      case EOpInitialize:
+        out << "initialize first child with second child";
+        break;
+      case EOpAddAssign:
+        out << "add second child into first child";
+        break;
+      case EOpSubAssign:
+        out << "subtract second child into first child";
+        break;
+      case EOpMulAssign:
+        out << "multiply second child into first child";
+        break;
+      case EOpVectorTimesMatrixAssign:
+        out << "matrix mult second child into first child";
+        break;
+      case EOpVectorTimesScalarAssign:
+        out << "vector scale second child into first child";
+        break;
+      case EOpMatrixTimesScalarAssign:
+        out << "matrix scale second child into first child";
+        break;
+      case EOpMatrixTimesMatrixAssign:
+        out << "matrix mult second child into first child";
+        break;
+      case EOpDivAssign:
+        out << "divide second child into first child";
+        break;
+      case EOpIndexDirect:
+        out << "direct index";
+        break;
+      case EOpIndexIndirect:
+        out << "indirect index";
+        break;
+      case EOpIndexDirectStruct:
+        out << "direct index for structure";
+        break;
+      case EOpIndexDirectInterfaceBlock:
+        out << "direct index for interface block";
+        break;
+      case EOpVectorSwizzle:
+        out << "vector swizzle";
+        break;
 
-        case EOpAdd:    out << "add";                     break;
-        case EOpSub:    out << "subtract";                break;
-        case EOpMul:    out << "component-wise multiply"; break;
-        case EOpDiv:    out << "divide";                  break;
-        case EOpEqual:            out << "Compare Equal";                 break;
-        case EOpNotEqual:         out << "Compare Not Equal";             break;
-        case EOpLessThan:         out << "Compare Less Than";             break;
-        case EOpGreaterThan:      out << "Compare Greater Than";          break;
-        case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
-        case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
+      case EOpAdd:
+        out << "add";
+        break;
+      case EOpSub:
+        out << "subtract";
+        break;
+      case EOpMul:
+        out << "component-wise multiply";
+        break;
+      case EOpDiv:
+        out << "divide";
+        break;
+      case EOpEqual:
+        out << "Compare Equal";
+        break;
+      case EOpNotEqual:
+        out << "Compare Not Equal";
+        break;
+      case EOpLessThan:
+        out << "Compare Less Than";
+        break;
+      case EOpGreaterThan:
+        out << "Compare Greater Than";
+        break;
+      case EOpLessThanEqual:
+        out << "Compare Less Than or Equal";
+        break;
+      case EOpGreaterThanEqual:
+        out << "Compare Greater Than or Equal";
+        break;
 
-        case EOpVectorTimesScalar: out << "vector-scale";          break;
-        case EOpVectorTimesMatrix: out << "vector-times-matrix";   break;
-        case EOpMatrixTimesVector: out << "matrix-times-vector";   break;
-        case EOpMatrixTimesScalar: out << "matrix-scale";          break;
-        case EOpMatrixTimesMatrix: out << "matrix-multiply";       break;
+      case EOpVectorTimesScalar:
+        out << "vector-scale";
+        break;
+      case EOpVectorTimesMatrix:
+        out << "vector-times-matrix";
+        break;
+      case EOpMatrixTimesVector:
+        out << "matrix-times-vector";
+        break;
+      case EOpMatrixTimesScalar:
+        out << "matrix-scale";
+        break;
+      case EOpMatrixTimesMatrix:
+        out << "matrix-multiply";
+        break;
 
-        case EOpLogicalOr:  out << "logical-or";   break;
-        case EOpLogicalXor: out << "logical-xor"; break;
-        case EOpLogicalAnd: out << "logical-and"; break;
-        default: out << "<unknown op>";
+      case EOpLogicalOr:
+        out << "logical-or";
+        break;
+      case EOpLogicalXor:
+        out << "logical-xor";
+        break;
+      case EOpLogicalAnd:
+        out << "logical-and";
+        break;
+      default:
+        out << "<unknown op>";
     }
 
     out << " (" << node->getCompleteString() << ")";
@@ -137,68 +212,57 @@
     return true;
 }
 
-bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
+bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
 {
     TInfoSinkBase& out = sink;
 
-    OutputTreeText(out, node, depth);
+    OutputTreeText(out, node, mDepth);
 
-    switch (node->getOp()) {
-        case EOpNegative:       out << "Negate value";         break;
-        case EOpVectorLogicalNot:
-        case EOpLogicalNot:     out << "Negate conditional";   break;
+    switch (node->getOp())
+    {
+      case EOpNegative:       out << "Negate value";         break;
+      case EOpVectorLogicalNot:
+      case EOpLogicalNot:     out << "Negate conditional";   break;
 
-        case EOpPostIncrement:  out << "Post-Increment";       break;
-        case EOpPostDecrement:  out << "Post-Decrement";       break;
-        case EOpPreIncrement:   out << "Pre-Increment";        break;
-        case EOpPreDecrement:   out << "Pre-Decrement";        break;
+      case EOpPostIncrement:  out << "Post-Increment";       break;
+      case EOpPostDecrement:  out << "Post-Decrement";       break;
+      case EOpPreIncrement:   out << "Pre-Increment";        break;
+      case EOpPreDecrement:   out << "Pre-Decrement";        break;
 
-        case EOpConvIntToBool:  out << "Convert int to bool";  break;
-        case EOpConvUIntToBool: out << "Convert uint to bool"; break;
-        case EOpConvFloatToBool:out << "Convert float to bool";break;
-        case EOpConvBoolToFloat:out << "Convert bool to float";break;
-        case EOpConvIntToFloat: out << "Convert int to float"; break;
-        case EOpConvUIntToFloat:out << "Convert uint to float";break;
-        case EOpConvFloatToInt: out << "Convert float to int"; break;
-        case EOpConvBoolToInt:  out << "Convert bool to int";  break;
-        case EOpConvIntToUInt:  out << "Convert int to uint";  break;
-        case EOpConvFloatToUInt:out << "Convert float to uint";break;
-        case EOpConvBoolToUInt: out << "Convert bool to uint"; break;
+      case EOpRadians:        out << "radians";              break;
+      case EOpDegrees:        out << "degrees";              break;
+      case EOpSin:            out << "sine";                 break;
+      case EOpCos:            out << "cosine";               break;
+      case EOpTan:            out << "tangent";              break;
+      case EOpAsin:           out << "arc sine";             break;
+      case EOpAcos:           out << "arc cosine";           break;
+      case EOpAtan:           out << "arc tangent";          break;
 
-        case EOpRadians:        out << "radians";              break;
-        case EOpDegrees:        out << "degrees";              break;
-        case EOpSin:            out << "sine";                 break;
-        case EOpCos:            out << "cosine";               break;
-        case EOpTan:            out << "tangent";              break;
-        case EOpAsin:           out << "arc sine";             break;
-        case EOpAcos:           out << "arc cosine";           break;
-        case EOpAtan:           out << "arc tangent";          break;
+      case EOpExp:            out << "exp";                  break;
+      case EOpLog:            out << "log";                  break;
+      case EOpExp2:           out << "exp2";                 break;
+      case EOpLog2:           out << "log2";                 break;
+      case EOpSqrt:           out << "sqrt";                 break;
+      case EOpInverseSqrt:    out << "inverse sqrt";         break;
 
-        case EOpExp:            out << "exp";                  break;
-        case EOpLog:            out << "log";                  break;
-        case EOpExp2:           out << "exp2";                 break;
-        case EOpLog2:           out << "log2";                 break;
-        case EOpSqrt:           out << "sqrt";                 break;
-        case EOpInverseSqrt:    out << "inverse sqrt";         break;
+      case EOpAbs:            out << "Absolute value";       break;
+      case EOpSign:           out << "Sign";                 break;
+      case EOpFloor:          out << "Floor";                break;
+      case EOpCeil:           out << "Ceiling";              break;
+      case EOpFract:          out << "Fraction";             break;
 
-        case EOpAbs:            out << "Absolute value";       break;
-        case EOpSign:           out << "Sign";                 break;
-        case EOpFloor:          out << "Floor";                break;
-        case EOpCeil:           out << "Ceiling";              break;
-        case EOpFract:          out << "Fraction";             break;
+      case EOpLength:         out << "length";               break;
+      case EOpNormalize:      out << "normalize";            break;
+      // case EOpDPdx:           out << "dPdx";                 break;
+      // case EOpDPdy:           out << "dPdy";                 break;
+      // case EOpFwidth:         out << "fwidth";               break;
 
-        case EOpLength:         out << "length";               break;
-        case EOpNormalize:      out << "normalize";            break;
-            //	case EOpDPdx:           out << "dPdx";                 break;               
-            //	case EOpDPdy:           out << "dPdy";                 break;   
-            //	case EOpFwidth:         out << "fwidth";               break;                   
+      case EOpAny:            out << "any";                  break;
+      case EOpAll:            out << "all";                  break;
 
-        case EOpAny:            out << "any";                  break;
-        case EOpAll:            out << "all";                  break;
-
-        default:
-            out.prefix(EPrefixError);
-            out << "Bad unary op";
+      default:
+        out.prefix(EPrefixError);
+        out << "Bad unary op";
     }
 
     out << " (" << node->getCompleteString() << ")";
@@ -208,78 +272,81 @@
     return true;
 }
 
-bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
+bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
 {
-    TInfoSinkBase& out = sink;
+    TInfoSinkBase &out = sink;
 
-    if (node->getOp() == EOpNull) {
+    if (node->getOp() == EOpNull)
+    {
         out.prefix(EPrefixError);
         out << "node is still EOpNull!";
         return true;
     }
 
-    OutputTreeText(out, node, depth);
+    OutputTreeText(out, node, mDepth);
 
-    switch (node->getOp()) {
-        case EOpSequence:      out << "Sequence\n"; return true;
-        case EOpComma:         out << "Comma\n"; return true;
-        case EOpFunction:      out << "Function Definition: " << node->getName(); break;
-        case EOpFunctionCall:  out << "Function Call: " << node->getName(); break;
-        case EOpParameters:    out << "Function Parameters: ";              break;
+    switch (node->getOp())
+    {
+      case EOpSequence:      out << "Sequence\n"; return true;
+      case EOpComma:         out << "Comma\n"; return true;
+      case EOpFunction:      out << "Function Definition: " << node->getName(); break;
+      case EOpFunctionCall:  out << "Function Call: " << node->getName(); break;
+      case EOpParameters:    out << "Function Parameters: ";              break;
 
-        case EOpConstructFloat: out << "Construct float"; break;
-        case EOpConstructVec2:  out << "Construct vec2";  break;
-        case EOpConstructVec3:  out << "Construct vec3";  break;
-        case EOpConstructVec4:  out << "Construct vec4";  break;
-        case EOpConstructBool:  out << "Construct bool";  break;
-        case EOpConstructBVec2: out << "Construct bvec2"; break;
-        case EOpConstructBVec3: out << "Construct bvec3"; break;
-        case EOpConstructBVec4: out << "Construct bvec4"; break;
-        case EOpConstructInt:   out << "Construct int";   break;
-        case EOpConstructIVec2: out << "Construct ivec2"; break;
-        case EOpConstructIVec3: out << "Construct ivec3"; break;
-        case EOpConstructIVec4: out << "Construct ivec4"; break;
-        case EOpConstructUInt:  out << "Construct uint";  break;
-        case EOpConstructUVec2: out << "Construct uvec2"; break;
-        case EOpConstructUVec3: out << "Construct uvec3"; break;
-        case EOpConstructUVec4: out << "Construct uvec4"; break;
-        case EOpConstructMat2:  out << "Construct mat2";  break;
-        case EOpConstructMat3:  out << "Construct mat3";  break;
-        case EOpConstructMat4:  out << "Construct mat4";  break;
-        case EOpConstructStruct:  out << "Construct structure";  break;
+      case EOpConstructFloat: out << "Construct float"; break;
+      case EOpConstructVec2:  out << "Construct vec2";  break;
+      case EOpConstructVec3:  out << "Construct vec3";  break;
+      case EOpConstructVec4:  out << "Construct vec4";  break;
+      case EOpConstructBool:  out << "Construct bool";  break;
+      case EOpConstructBVec2: out << "Construct bvec2"; break;
+      case EOpConstructBVec3: out << "Construct bvec3"; break;
+      case EOpConstructBVec4: out << "Construct bvec4"; break;
+      case EOpConstructInt:   out << "Construct int";   break;
+      case EOpConstructIVec2: out << "Construct ivec2"; break;
+      case EOpConstructIVec3: out << "Construct ivec3"; break;
+      case EOpConstructIVec4: out << "Construct ivec4"; break;
+      case EOpConstructUInt:  out << "Construct uint";  break;
+      case EOpConstructUVec2: out << "Construct uvec2"; break;
+      case EOpConstructUVec3: out << "Construct uvec3"; break;
+      case EOpConstructUVec4: out << "Construct uvec4"; break;
+      case EOpConstructMat2:  out << "Construct mat2";  break;
+      case EOpConstructMat3:  out << "Construct mat3";  break;
+      case EOpConstructMat4:  out << "Construct mat4";  break;
+      case EOpConstructStruct:  out << "Construct structure";  break;
 
-        case EOpLessThan:         out << "Compare Less Than";             break;
-        case EOpGreaterThan:      out << "Compare Greater Than";          break;
-        case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
-        case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
-        case EOpVectorEqual:      out << "Equal";                         break;
-        case EOpVectorNotEqual:   out << "NotEqual";                      break;
+      case EOpLessThan:         out << "Compare Less Than";             break;
+      case EOpGreaterThan:      out << "Compare Greater Than";          break;
+      case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
+      case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
+      case EOpVectorEqual:      out << "Equal";                         break;
+      case EOpVectorNotEqual:   out << "NotEqual";                      break;
 
-        case EOpMod:           out << "mod";         break;
-        case EOpPow:           out << "pow";         break;
+      case EOpMod:           out << "mod";         break;
+      case EOpPow:           out << "pow";         break;
 
-        case EOpAtan:          out << "arc tangent"; break;
+      case EOpAtan:          out << "arc tangent"; break;
 
-        case EOpMin:           out << "min";         break;
-        case EOpMax:           out << "max";         break;
-        case EOpClamp:         out << "clamp";       break;
-        case EOpMix:           out << "mix";         break;
-        case EOpStep:          out << "step";        break;
-        case EOpSmoothStep:    out << "smoothstep";  break;
+      case EOpMin:           out << "min";         break;
+      case EOpMax:           out << "max";         break;
+      case EOpClamp:         out << "clamp";       break;
+      case EOpMix:           out << "mix";         break;
+      case EOpStep:          out << "step";        break;
+      case EOpSmoothStep:    out << "smoothstep";  break;
 
-        case EOpDistance:      out << "distance";                break;
-        case EOpDot:           out << "dot-product";             break;
-        case EOpCross:         out << "cross-product";           break;
-        case EOpFaceForward:   out << "face-forward";            break;
-        case EOpReflect:       out << "reflect";                 break;
-        case EOpRefract:       out << "refract";                 break;
-        case EOpMul:           out << "component-wise multiply"; break;
+      case EOpDistance:      out << "distance";                break;
+      case EOpDot:           out << "dot-product";             break;
+      case EOpCross:         out << "cross-product";           break;
+      case EOpFaceForward:   out << "face-forward";            break;
+      case EOpReflect:       out << "reflect";                 break;
+      case EOpRefract:       out << "refract";                 break;
+      case EOpMul:           out << "component-wise multiply"; break;
 
-        case EOpDeclaration:   out << "Declaration: ";   break;
+      case EOpDeclaration:   out << "Declaration: ";   break;
+      case EOpInvariantDeclaration: out << "Invariant Declaration: "; break;
 
-        default:
-            out.prefix(EPrefixError);
-            out << "Bad aggregation op";
+      default:
+        out.prefix(EPrefixError);
+        out << "Bad aggregation op";
     }
 
     if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
@@ -290,135 +357,156 @@
     return true;
 }
 
-bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
+bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection *node)
 {
-    TInfoSinkBase& out = sink;
+    TInfoSinkBase &out = sink;
 
-    OutputTreeText(out, node, depth);
+    OutputTreeText(out, node, mDepth);
 
     out << "Test condition and select";
     out << " (" << node->getCompleteString() << ")\n";
 
-    ++depth;
+    ++mDepth;
 
-    OutputTreeText(sink, node, depth);
+    OutputTreeText(sink, node, mDepth);
     out << "Condition\n";
     node->getCondition()->traverse(this);
 
-    OutputTreeText(sink, node, depth);
-    if (node->getTrueBlock()) {
+    OutputTreeText(sink, node, mDepth);
+    if (node->getTrueBlock())
+    {
         out << "true case\n";
         node->getTrueBlock()->traverse(this);
-    } else
+    }
+    else
+    {
         out << "true case is null\n";
+    }
 
-    if (node->getFalseBlock()) {
-        OutputTreeText(sink, node, depth);
+    if (node->getFalseBlock())
+    {
+        OutputTreeText(sink, node, mDepth);
         out << "false case\n";
         node->getFalseBlock()->traverse(this);
     }
 
-    --depth;
+    --mDepth;
 
     return false;
 }
 
-void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
+void TOutputTraverser::visitConstantUnion(TIntermConstantUnion *node)
 {
-    TInfoSinkBase& out = sink;
+    TInfoSinkBase &out = sink;
 
     size_t size = node->getType().getObjectSize();
 
-    for (size_t i = 0; i < size; i++) {
-        OutputTreeText(out, node, depth);
-        switch (node->getUnionArrayPointer()[i].getType()) {
-            case EbtBool:
-                if (node->getUnionArrayPointer()[i].getBConst())
-                    out << "true";
-                else
-                    out << "false";
+    for (size_t i = 0; i < size; i++)
+    {
+        OutputTreeText(out, node, mDepth);
+        switch (node->getUnionArrayPointer()[i].getType())
+        {
+          case EbtBool:
+            if (node->getUnionArrayPointer()[i].getBConst())
+                out << "true";
+            else
+                out << "false";
 
-                out << " (" << "const bool" << ")";
-                out << "\n";
-                break;
-            case EbtFloat:
-                out << node->getUnionArrayPointer()[i].getFConst();
-                out << " (const float)\n";
-                break;
-            case EbtInt:
-                out << node->getUnionArrayPointer()[i].getIConst();
-                out << " (const int)\n";
-                break;
-            case EbtUInt:
-                out << node->getUnionArrayPointer()[i].getUConst();
-                out << " (const uint)\n";
-                break;
-            default:
-                out.message(EPrefixInternalError, node->getLine(), "Unknown constant");
-                break;
+            out << " (" << "const bool" << ")";
+            out << "\n";
+            break;
+          case EbtFloat:
+            out << node->getUnionArrayPointer()[i].getFConst();
+            out << " (const float)\n";
+            break;
+          case EbtInt:
+            out << node->getUnionArrayPointer()[i].getIConst();
+            out << " (const int)\n";
+            break;
+          case EbtUInt:
+            out << node->getUnionArrayPointer()[i].getUConst();
+            out << " (const uint)\n";
+            break;
+          default:
+            out.message(EPrefixInternalError, node->getLine(), "Unknown constant");
+            break;
         }
     }
 }
 
-bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
+bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop *node)
 {
-    TInfoSinkBase& out = sink;
+    TInfoSinkBase &out = sink;
 
-    OutputTreeText(out, node, depth);
+    OutputTreeText(out, node, mDepth);
 
     out << "Loop with condition ";
     if (node->getType() == ELoopDoWhile)
         out << "not ";
     out << "tested first\n";
 
-    ++depth;
+    ++mDepth;
 
-    OutputTreeText(sink, node, depth);
-    if (node->getCondition()) {
+    OutputTreeText(sink, node, mDepth);
+    if (node->getCondition())
+    {
         out << "Loop Condition\n";
         node->getCondition()->traverse(this);
-    } else
+    }
+    else
+    {
         out << "No loop condition\n";
+    }
 
-    OutputTreeText(sink, node, depth);
-    if (node->getBody()) {
+    OutputTreeText(sink, node, mDepth);
+    if (node->getBody())
+    {
         out << "Loop Body\n";
         node->getBody()->traverse(this);
-    } else
+    }
+    else
+    {
         out << "No loop body\n";
+    }
 
-    if (node->getExpression()) {
-        OutputTreeText(sink, node, depth);
+    if (node->getExpression())
+    {
+        OutputTreeText(sink, node, mDepth);
         out << "Loop Terminal Expression\n";
         node->getExpression()->traverse(this);
     }
 
-    --depth;
+    --mDepth;
 
     return false;
 }
 
-bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch* node)
+bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch *node)
 {
-    TInfoSinkBase& out = sink;
+    TInfoSinkBase &out = sink;
 
-    OutputTreeText(out, node, depth);
+    OutputTreeText(out, node, mDepth);
 
-    switch (node->getFlowOp()) {
-        case EOpKill:      out << "Branch: Kill";           break;
-        case EOpBreak:     out << "Branch: Break";          break;
-        case EOpContinue:  out << "Branch: Continue";       break;
-        case EOpReturn:    out << "Branch: Return";         break;
-        default:           out << "Branch: Unknown Branch"; break;
+    switch (node->getFlowOp())
+    {
+      case EOpKill:      out << "Branch: Kill";           break;
+      case EOpBreak:     out << "Branch: Break";          break;
+      case EOpContinue:  out << "Branch: Continue";       break;
+      case EOpReturn:    out << "Branch: Return";         break;
+      default:           out << "Branch: Unknown Branch"; break;
     }
 
-    if (node->getExpression()) {
+    if (node->getExpression())
+    {
         out << " with expression\n";
-        ++depth;
+        ++mDepth;
         node->getExpression()->traverse(this);
-        --depth;
-    } else
+        --mDepth;
+    }
+    else
+    {
         out << "\n";
+    }
 
     return false;
 }
@@ -428,12 +516,12 @@
 // Individual functions can be initialized to 0 to skip processing of that
 // type of node.  It's children will still be processed.
 //
-void TIntermediate::outputTree(TIntermNode* root)
+void TIntermediate::outputTree(TIntermNode *root)
 {
-    if (root == 0)
+    if (root == NULL)
         return;
 
-    TOutputTraverser it(infoSink.info);
+    TOutputTraverser it(mInfoSink.info);
 
     root->traverse(&it);
 }
diff --git a/src/compiler/translator/intermediate.h b/src/compiler/translator/intermediate.h
deleted file mode 100644
index 2fdde02..0000000
--- a/src/compiler/translator/intermediate.h
+++ /dev/null
@@ -1,719 +0,0 @@
-//
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-//
-// Definition of the in-memory high-level intermediate representation
-// of shaders.  This is a tree that parser creates.
-//
-// Nodes in the tree are defined as a hierarchy of classes derived from 
-// TIntermNode. Each is a node in a tree.  There is no preset branching factor;
-// each node can have it's own type of list of children.
-//
-
-#ifndef __INTERMEDIATE_H
-#define __INTERMEDIATE_H
-
-#include "GLSLANG/ShaderLang.h"
-
-#include <algorithm>
-#include <queue>
-#include "compiler/translator/Common.h"
-#include "compiler/translator/Types.h"
-#include "compiler/translator/ConstantUnion.h"
-
-//
-// Operators used by the high-level (parse tree) representation.
-//
-enum TOperator {
-    EOpNull,            // if in a node, should only mean a node is still being built
-    EOpSequence,        // denotes a list of statements, or parameters, etc.
-    EOpFunctionCall,    
-    EOpFunction,        // For function definition
-    EOpParameters,      // an aggregate listing the parameters to a function
-
-    EOpDeclaration,
-    EOpPrototype,
-
-    //
-    // Unary operators
-    //
-
-    EOpNegative,
-    EOpLogicalNot,
-    EOpVectorLogicalNot,
-
-    EOpPostIncrement,
-    EOpPostDecrement,
-    EOpPreIncrement,
-    EOpPreDecrement,
-
-    EOpConvIntToBool,
-    EOpConvUIntToBool,
-    EOpConvFloatToBool,
-    EOpConvBoolToFloat,
-    EOpConvIntToFloat,
-    EOpConvUIntToFloat,
-    EOpConvFloatToInt,
-    EOpConvBoolToInt,
-    EOpConvUIntToInt,
-    EOpConvIntToUInt,
-    EOpConvFloatToUInt,
-    EOpConvBoolToUInt,
-
-    //
-    // binary operations
-    //
-
-    EOpAdd,
-    EOpSub,
-    EOpMul,
-    EOpDiv,
-    EOpEqual,
-    EOpNotEqual,
-    EOpVectorEqual,
-    EOpVectorNotEqual,
-    EOpLessThan,
-    EOpGreaterThan,
-    EOpLessThanEqual,
-    EOpGreaterThanEqual,
-    EOpComma,
-
-    EOpVectorTimesScalar,
-    EOpVectorTimesMatrix,
-    EOpMatrixTimesVector,
-    EOpMatrixTimesScalar,
-
-    EOpLogicalOr,
-    EOpLogicalXor,
-    EOpLogicalAnd,
-
-    EOpIndexDirect,
-    EOpIndexIndirect,
-    EOpIndexDirectStruct,
-    EOpIndexDirectInterfaceBlock,
-
-    EOpVectorSwizzle,
-
-    //
-    // Built-in functions potentially mapped to operators
-    //
-
-    EOpRadians,
-    EOpDegrees,
-    EOpSin,
-    EOpCos,
-    EOpTan,
-    EOpAsin,
-    EOpAcos,
-    EOpAtan,
-
-    EOpPow,
-    EOpExp,
-    EOpLog,
-    EOpExp2,
-    EOpLog2,
-    EOpSqrt,
-    EOpInverseSqrt,
-
-    EOpAbs,
-    EOpSign,
-    EOpFloor,
-    EOpCeil,
-    EOpFract,
-    EOpMod,
-    EOpMin,
-    EOpMax,
-    EOpClamp,
-    EOpMix,
-    EOpStep,
-    EOpSmoothStep,
-
-    EOpLength,
-    EOpDistance,
-    EOpDot,
-    EOpCross,
-    EOpNormalize,
-    EOpFaceForward,
-    EOpReflect,
-    EOpRefract,
-
-    EOpDFdx,            // Fragment only, OES_standard_derivatives extension
-    EOpDFdy,            // Fragment only, OES_standard_derivatives extension
-    EOpFwidth,          // Fragment only, OES_standard_derivatives extension
-
-    EOpMatrixTimesMatrix,
-
-    EOpAny,
-    EOpAll,
-
-    //
-    // Branch
-    //
-
-    EOpKill,            // Fragment only
-    EOpReturn,
-    EOpBreak,
-    EOpContinue,
-
-    //
-    // Constructors
-    //
-
-    EOpConstructInt,
-    EOpConstructUInt,
-    EOpConstructBool,
-    EOpConstructFloat,
-    EOpConstructVec2,
-    EOpConstructVec3,
-    EOpConstructVec4,
-    EOpConstructBVec2,
-    EOpConstructBVec3,
-    EOpConstructBVec4,
-    EOpConstructIVec2,
-    EOpConstructIVec3,
-    EOpConstructIVec4,
-    EOpConstructUVec2,
-    EOpConstructUVec3,
-    EOpConstructUVec4,
-    EOpConstructMat2,
-    EOpConstructMat3,
-    EOpConstructMat4,
-    EOpConstructStruct,
-
-    //
-    // moves
-    //
-
-    EOpAssign,
-    EOpInitialize,
-    EOpAddAssign,
-    EOpSubAssign,
-    EOpMulAssign,
-    EOpVectorTimesMatrixAssign,
-    EOpVectorTimesScalarAssign,
-    EOpMatrixTimesScalarAssign,
-    EOpMatrixTimesMatrixAssign,
-    EOpDivAssign
-};
-
-extern const char* getOperatorString(TOperator op);
-
-class TIntermTraverser;
-class TIntermAggregate;
-class TIntermBinary;
-class TIntermUnary;
-class TIntermConstantUnion;
-class TIntermSelection;
-class TIntermTyped;
-class TIntermSymbol;
-class TIntermLoop;
-class TInfoSink;
-class TIntermRaw;
-
-//
-// Base class for the tree nodes
-//
-class TIntermNode {
-public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TIntermNode() {
-        // TODO: Move this to TSourceLoc constructor
-        // after getting rid of TPublicType.
-        line.first_file = line.last_file = 0;
-        line.first_line = line.last_line = 0;
-    }
-    virtual ~TIntermNode() { }
-
-    const TSourceLoc& getLine() const { return line; }
-    void setLine(const TSourceLoc& l) { line = l; }
-
-    virtual void traverse(TIntermTraverser*) = 0;
-    virtual TIntermTyped* getAsTyped() { return 0; }
-    virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
-    virtual TIntermAggregate* getAsAggregate() { return 0; }
-    virtual TIntermBinary* getAsBinaryNode() { return 0; }
-    virtual TIntermUnary* getAsUnaryNode() { return 0; }
-    virtual TIntermSelection* getAsSelectionNode() { return 0; }
-    virtual TIntermSymbol* getAsSymbolNode() { return 0; }
-    virtual TIntermLoop* getAsLoopNode() { return 0; }
-    virtual TIntermRaw* getAsRawNode() { return 0; }
-
-    // Replace a child node. Return true if |original| is a child
-    // node and it is replaced; otherwise, return false.
-    virtual bool replaceChildNode(
-        TIntermNode *original, TIntermNode *replacement) = 0;
-
-    // For traversing a tree in no particular order, but using
-    // heap memory.
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const = 0;
-
-protected:
-    TSourceLoc line;
-};
-
-//
-// This is just to help yacc.
-//
-struct TIntermNodePair {
-    TIntermNode* node1;
-    TIntermNode* node2;
-};
-
-//
-// Intermediate class for nodes that have a type.
-//
-class TIntermTyped : public TIntermNode {
-public:
-    TIntermTyped(const TType& t) : type(t)  { }
-    virtual TIntermTyped* getAsTyped() { return this; }
-
-    virtual bool hasSideEffects() const = 0;
-
-    void setType(const TType& t) { type = t; }
-    const TType& getType() const { return type; }
-    TType* getTypePointer() { return &type; }
-
-    TBasicType getBasicType() const { return type.getBasicType(); }
-    TQualifier getQualifier() const { return type.getQualifier(); }
-    TPrecision getPrecision() const { return type.getPrecision(); }
-    int getCols() const { return type.getCols(); }
-    int getRows() const { return type.getRows(); }
-    int getNominalSize() const { return type.getNominalSize(); }
-    int getSecondarySize() const { return type.getSecondarySize(); }
-    
-    bool isInterfaceBlock() const { return type.isInterfaceBlock(); }
-    bool isMatrix() const { return type.isMatrix(); }
-    bool isArray()  const { return type.isArray(); }
-    bool isVector() const { return type.isVector(); }
-    bool isScalar() const { return type.isScalar(); }
-    bool isScalarInt() const { return type.isScalarInt(); }
-    const char* getBasicString() const { return type.getBasicString(); }
-    const char* getQualifierString() const { return type.getQualifierString(); }
-    TString getCompleteString() const { return type.getCompleteString(); }
-
-    int getArraySize() const { return type.getArraySize(); }
-
-protected:
-    TType type;
-};
-
-//
-// Handle for, do-while, and while loops.
-//
-enum TLoopType {
-    ELoopFor,
-    ELoopWhile,
-    ELoopDoWhile
-};
-
-class TIntermLoop : public TIntermNode {
-public:
-    TIntermLoop(TLoopType aType,
-                TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
-                TIntermNode* aBody) :
-            type(aType),
-            init(aInit),
-            cond(aCond),
-            expr(aExpr),
-            body(aBody),
-            unrollFlag(false) { }
-
-    virtual TIntermLoop* getAsLoopNode() { return this; }
-    virtual void traverse(TIntermTraverser*);
-    virtual bool replaceChildNode(
-        TIntermNode *original, TIntermNode *replacement);
-
-    TLoopType getType() const { return type; }
-    TIntermNode* getInit() { return init; }
-    TIntermTyped* getCondition() { return cond; }
-    TIntermTyped* getExpression() { return expr; }
-    TIntermNode* getBody() { return body; }
-
-    void setUnrollFlag(bool flag) { unrollFlag = flag; }
-    bool getUnrollFlag() { return unrollFlag; }
-
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
-
-protected:
-    TLoopType type;
-    TIntermNode* init;  // for-loop initialization
-    TIntermTyped* cond; // loop exit condition
-    TIntermTyped* expr; // for-loop expression
-    TIntermNode* body;  // loop body
-
-    bool unrollFlag; // Whether the loop should be unrolled or not.
-};
-
-//
-// Handle break, continue, return, and kill.
-//
-class TIntermBranch : public TIntermNode {
-public:
-    TIntermBranch(TOperator op, TIntermTyped* e) :
-            flowOp(op),
-            expression(e) { }
-
-    virtual void traverse(TIntermTraverser*);
-    virtual bool replaceChildNode(
-        TIntermNode *original, TIntermNode *replacement);
-
-    TOperator getFlowOp() { return flowOp; }
-    TIntermTyped* getExpression() { return expression; }
-
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
-
-protected:
-    TOperator flowOp;
-    TIntermTyped* expression;  // non-zero except for "return exp;" statements
-};
-
-//
-// Nodes that correspond to symbols or constants in the source code.
-//
-class TIntermSymbol : public TIntermTyped {
-public:
-    // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
-    // per process globalpoolallocator, then it causes increased memory usage per compile
-    // it is essential to use "symbol = sym" to assign to symbol
-    TIntermSymbol(int i, const TString& sym, const TType& t) : 
-        TIntermTyped(t), id(i)  { symbol = sym; }
-
-    virtual bool hasSideEffects() const { return false; }
-
-    int getId() const { return id; }
-    const TString& getSymbol() const { return symbol; }
-
-    void setId(int newId) { id = newId; }
-
-    virtual void traverse(TIntermTraverser*);
-    virtual TIntermSymbol* getAsSymbolNode() { return this; }
-    virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
-
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {}
-
-protected:
-    int id;
-    TString symbol;
-};
-
-// A Raw node stores raw code, that the translator will insert verbatim
-// into the output stream. Useful for transformation operations that make
-// complex code that might not fit naturally into the GLSL model.
-class TIntermRaw : public TIntermTyped {
-public:
-    TIntermRaw(const TType &t, const TString &rawTextIn)
-        : TIntermTyped(t), rawText(rawTextIn)
-    {}
-
-    virtual bool hasSideEffects() const { return false; }
-
-    TString getRawText() const { return rawText; }
-
-    virtual void traverse(TIntermTraverser*);
-
-    virtual TIntermRaw* getAsRawNode() { return this; }
-    virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {}
-
-protected:
-    TString rawText;
-};
-
-class TIntermConstantUnion : public TIntermTyped {
-public:
-    TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
-
-    virtual bool hasSideEffects() const { return false; }
-
-    ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
-    
-    int getIConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
-    unsigned int getUConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getUConst() : 0; }
-    float getFConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
-    bool getBConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
-
-    virtual TIntermConstantUnion* getAsConstantUnion()  { return this; }
-    virtual void traverse(TIntermTraverser*);
-    virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
-
-    TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
-
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {}
-
-protected:
-    ConstantUnion *unionArrayPointer;
-};
-
-//
-// Intermediate class for node types that hold operators.
-//
-class TIntermOperator : public TIntermTyped {
-public:
-    TOperator getOp() const { return op; }
-    void setOp(TOperator o) { op = o; }
-
-    bool isAssignment() const;
-    bool isConstructor() const;
-
-    virtual bool hasSideEffects() const { return isAssignment(); }
-
-protected:
-    TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
-    TIntermOperator(TOperator o, const TType& t) : TIntermTyped(t), op(o) {}
-    TOperator op;
-};
-
-//
-// Nodes for all the basic binary math operators.
-//
-class TIntermBinary : public TIntermOperator {
-public:
-    TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
-
-    virtual TIntermBinary* getAsBinaryNode() { return this; }
-    virtual void traverse(TIntermTraverser*);
-    virtual bool replaceChildNode(
-        TIntermNode *original, TIntermNode *replacement);
-
-    virtual bool hasSideEffects() const { return (isAssignment() || left->hasSideEffects() || right->hasSideEffects()); }
-
-    void setLeft(TIntermTyped* n) { left = n; }
-    void setRight(TIntermTyped* n) { right = n; }
-    TIntermTyped* getLeft() const { return left; }
-    TIntermTyped* getRight() const { return right; }
-    bool promote(TInfoSink&);
-
-    void setAddIndexClamp() { addIndexClamp = true; }
-    bool getAddIndexClamp() { return addIndexClamp; }
-
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
-
-protected:
-    TIntermTyped* left;
-    TIntermTyped* right;
-
-    // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
-    bool addIndexClamp;
-};
-
-//
-// Nodes for unary math operators.
-//
-class TIntermUnary : public TIntermOperator {
-public:
-    TIntermUnary(TOperator o, const TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
-    TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
-
-    virtual void traverse(TIntermTraverser*);
-    virtual TIntermUnary* getAsUnaryNode() { return this; }
-    virtual bool replaceChildNode(
-        TIntermNode *original, TIntermNode *replacement);
-
-    virtual bool hasSideEffects() const { return (isAssignment() || operand->hasSideEffects()); }
-
-    void setOperand(TIntermTyped* o) { operand = o; }
-    TIntermTyped* getOperand() { return operand; }    
-    bool promote(TInfoSink&);
-
-    void setUseEmulatedFunction() { useEmulatedFunction = true; }
-    bool getUseEmulatedFunction() { return useEmulatedFunction; }
-
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
-
-protected:
-    TIntermTyped* operand;
-
-    // If set to true, replace the built-in function call with an emulated one
-    // to work around driver bugs.
-    bool useEmulatedFunction;
-};
-
-typedef TVector<TIntermNode*> TIntermSequence;
-typedef TVector<int> TQualifierList;
-
-//
-// Nodes that operate on an arbitrary sized set of children.
-//
-class TIntermAggregate : public TIntermOperator {
-public:
-    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), useEmulatedFunction(false) { }
-    TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
-    ~TIntermAggregate() { }
-
-    virtual TIntermAggregate* getAsAggregate() { return this; }
-    virtual void traverse(TIntermTraverser*);
-    virtual bool replaceChildNode(
-        TIntermNode *original, TIntermNode *replacement);
-
-    // Conservatively assume function calls and other aggregate operators have side-effects
-    virtual bool hasSideEffects() const { return true; }
-
-    TIntermSequence& getSequence() { return sequence; }
-
-    void setName(const TString& n) { name = n; }
-    const TString& getName() const { return name; }
-
-    void setUserDefined() { userDefined = true; }
-    bool isUserDefined() const { return userDefined; }
-
-    void setOptimize(bool o) { optimize = o; }
-    bool getOptimize() { return optimize; }
-    void setDebug(bool d) { debug = d; }
-    bool getDebug() { return debug; }
-
-    void setUseEmulatedFunction() { useEmulatedFunction = true; }
-    bool getUseEmulatedFunction() { return useEmulatedFunction; }
-
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
-
-protected:
-    TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
-    TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
-    TIntermSequence sequence;
-    TString name;
-    bool userDefined; // used for user defined function names
-
-    bool optimize;
-    bool debug;
-
-    // If set to true, replace the built-in function call with an emulated one
-    // to work around driver bugs.
-    bool useEmulatedFunction;
-};
-
-//
-// For if tests.  Simplified since there is no switch statement.
-//
-class TIntermSelection : public TIntermTyped {
-public:
-    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
-            TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
-    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
-            TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
-
-    virtual void traverse(TIntermTraverser*);
-    virtual bool replaceChildNode(
-        TIntermNode *original, TIntermNode *replacement);
-
-    // Conservatively assume selections have side-effects
-    virtual bool hasSideEffects() const { return true; }
-
-    bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
-    TIntermNode* getCondition() const { return condition; }
-    TIntermNode* getTrueBlock() const { return trueBlock; }
-    TIntermNode* getFalseBlock() const { return falseBlock; }
-    TIntermSelection* getAsSelectionNode() { return this; }
-
-    virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
-
-protected:
-    TIntermTyped* condition;
-    TIntermNode* trueBlock;
-    TIntermNode* falseBlock;
-};
-
-enum Visit
-{
-    PreVisit,
-    InVisit,
-    PostVisit
-};
-
-//
-// For traversing the tree.  User should derive from this, 
-// put their traversal specific data in it, and then pass
-// it to a Traverse method.
-//
-// When using this, just fill in the methods for nodes you want visited.
-// Return false from a pre-visit to skip visiting that node's subtree.
-//
-class TIntermTraverser
-{
-public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) : 
-            preVisit(preVisit),
-            inVisit(inVisit),
-            postVisit(postVisit),
-            rightToLeft(rightToLeft),
-            depth(0),
-            maxDepth(0) {}
-    virtual ~TIntermTraverser() {}
-
-    virtual void visitSymbol(TIntermSymbol*) {}
-    virtual void visitRaw(TIntermRaw*) {}
-    virtual void visitConstantUnion(TIntermConstantUnion*) {}
-    virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
-    virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
-    virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
-    virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
-    virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
-    virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
-
-    int getMaxDepth() const {return maxDepth;}
-
-    void incrementDepth(TIntermNode *current)
-    {
-        depth++;
-        maxDepth = std::max(maxDepth, depth);
-        path.push_back(current);
-    }
-
-    void decrementDepth()
-    {
-        depth--;
-        path.pop_back();
-    }
-
-    TIntermNode *getParentNode()
-    {
-        return path.size() == 0 ? NULL : path.back();
-    }
-
-    // Return the original name if hash function pointer is NULL;
-    // otherwise return the hashed name.
-    static TString hash(const TString& name, ShHashFunction64 hashFunction);
-
-    const bool preVisit;
-    const bool inVisit;
-    const bool postVisit;
-    const bool rightToLeft;
-
-protected:
-    int depth;
-    int maxDepth;
-
-    // All the nodes from root to the current node's parent during traversing.
-    TVector<TIntermNode *> path;
-};
-
-//
-// For traversing the tree, and computing max depth.
-// Takes a maximum depth limit to prevent stack overflow.
-//
-class TMaxDepthTraverser : public TIntermTraverser
-{
-public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TMaxDepthTraverser(int depthLimit)
-      : TIntermTraverser(true, true, false, false),
-        depthLimit(depthLimit)
-    {}
-
-    virtual bool visitBinary(Visit visit, TIntermBinary*) { return depthCheck(); }
-    virtual bool visitUnary(Visit visit, TIntermUnary*) { return depthCheck(); }
-    virtual bool visitSelection(Visit visit, TIntermSelection*) { return depthCheck(); }
-    virtual bool visitAggregate(Visit visit, TIntermAggregate*) { return depthCheck(); }
-    virtual bool visitLoop(Visit visit, TIntermLoop*) { return depthCheck(); }
-    virtual bool visitBranch(Visit visit, TIntermBranch*) { return depthCheck(); }
-
-protected:
-    int depthLimit;
-
-    bool depthCheck() const { return maxDepth < depthLimit; }
-};
-
-#endif // __INTERMEDIATE_H
diff --git a/src/compiler/translator/localintermediate.h b/src/compiler/translator/localintermediate.h
deleted file mode 100644
index 125dcd9..0000000
--- a/src/compiler/translator/localintermediate.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef _LOCAL_INTERMEDIATE_INCLUDED_
-#define _LOCAL_INTERMEDIATE_INCLUDED_
-
-#include "compiler/translator/intermediate.h"
-
-struct TVectorFields {
-    int offsets[4];
-    int num;
-};
-
-//
-// Set of helper functions to help parse and build the tree.
-//
-class TInfoSink;
-class TIntermediate {
-public:    
-    POOL_ALLOCATOR_NEW_DELETE();
-    TIntermediate(TInfoSink& i) : infoSink(i) { }
-
-    TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&);
-    TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
-    TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
-    TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
-    TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&);
-    TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, const TSourceLoc&);
-    TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
-    TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
-    TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, const TSourceLoc&);
-    TIntermNode*  addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
-    TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
-    TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
-    TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, const TSourceLoc&);
-    TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
-    bool parseConstTree(const TSourceLoc&, TIntermNode*, ConstantUnion*, TOperator, TType, bool singleConstantParam = false);        
-    TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, const TSourceLoc&);
-    TIntermBranch* addBranch(TOperator, const TSourceLoc&);
-    TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
-    TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
-    bool postProcess(TIntermNode*);
-	void remove(TIntermNode*);
-    void outputTree(TIntermNode*);
-
-private:
-    void operator=(TIntermediate&); // prevent assignments
-
-    TInfoSink& infoSink;
-};
-
-#endif // _LOCAL_INTERMEDIATE_INCLUDED_
diff --git a/src/compiler/translator/osinclude.h b/src/compiler/translator/osinclude.h
deleted file mode 100644
index c3063d6..0000000
--- a/src/compiler/translator/osinclude.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef __OSINCLUDE_H
-#define __OSINCLUDE_H
-
-//
-// This file contains contains os-specific datatypes and
-// declares any os-specific functions.
-//
-
-#if defined(_WIN32) || defined(_WIN64)
-#define ANGLE_OS_WIN
-#elif defined(__APPLE__) || defined(__linux__) || \
-      defined(__FreeBSD__) || defined(__OpenBSD__) || \
-      defined(__NetBSD__) || defined(__DragonFly__) || \
-      defined(__sun) || defined(ANDROID) || \
-      defined(__GLIBC__) || defined(__GNU__) || \
-      defined(__QNX__)
-#define ANGLE_OS_POSIX
-#else
-#error Unsupported platform.
-#endif
-
-#if defined(ANGLE_OS_WIN)
-#define STRICT
-#define VC_EXTRALEAN 1
-#include <windows.h>
-#elif defined(ANGLE_OS_POSIX)
-#include <pthread.h>
-#include <semaphore.h>
-#include <errno.h>
-#endif  // ANGLE_OS_WIN
-
-
-#include "compiler/translator/compilerdebug.h"
-
-//
-// Thread Local Storage Operations
-//
-#if defined(ANGLE_OS_WIN)
-typedef DWORD OS_TLSIndex;
-#define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
-#elif defined(ANGLE_OS_POSIX)
-typedef pthread_key_t OS_TLSIndex;
-#define OS_INVALID_TLS_INDEX (static_cast<OS_TLSIndex>(-1))
-#endif  // ANGLE_OS_WIN
-
-OS_TLSIndex OS_AllocTLSIndex();
-bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
-bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
-
-inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
-{
-    ASSERT(nIndex != OS_INVALID_TLS_INDEX);
-#if defined(ANGLE_OS_WIN)
-    return TlsGetValue(nIndex);
-#elif defined(ANGLE_OS_POSIX)
-    return pthread_getspecific(nIndex);
-#endif  // ANGLE_OS_WIN
-}
-
-#endif // __OSINCLUDE_H
diff --git a/src/compiler/translator/ossource_posix.cpp b/src/compiler/translator/ossource_posix.cpp
deleted file mode 100644
index 90a3757..0000000
--- a/src/compiler/translator/ossource_posix.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-//
-// This file contains the posix specific functions
-//
-#include "compiler/translator/osinclude.h"
-
-#if !defined(ANGLE_OS_POSIX)
-#error Trying to build a posix specific file in a non-posix build.
-#endif
-
-//
-// Thread Local Storage Operations
-//
-OS_TLSIndex OS_AllocTLSIndex()
-{
-    pthread_key_t pPoolIndex;
-
-    //
-    // Create global pool key.
-    //
-    if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
-        assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
-        return false;
-    }
-    else {
-        return pPoolIndex;
-    }
-}
-
-
-bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
-{
-    if (nIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
-        return false;
-    }
-
-    if (pthread_setspecific(nIndex, lpvValue) == 0)
-        return true;
-    else
-        return false;
-}
-
-
-bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
-{
-    if (nIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
-        return false;
-    }
-
-    //
-    // Delete the global pool key.
-    //
-    if (pthread_key_delete(nIndex) == 0)
-        return true;
-    else
-        return false;
-}
diff --git a/src/compiler/translator/ossource_win.cpp b/src/compiler/translator/ossource_win.cpp
deleted file mode 100644
index 2cc5871..0000000
--- a/src/compiler/translator/ossource_win.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/translator/osinclude.h"
-//
-// This file contains contains the window's specific functions
-//
-
-#if !defined(ANGLE_OS_WIN)
-#error Trying to build a windows specific file in a non windows build.
-#endif
-
-
-//
-// Thread Local Storage Operations
-//
-OS_TLSIndex OS_AllocTLSIndex()
-{
-	DWORD dwIndex = TlsAlloc();
-	if (dwIndex == TLS_OUT_OF_INDEXES) {
-		assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
-		return OS_INVALID_TLS_INDEX;
-	}
-
-	return dwIndex;
-}
-
-
-bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
-{
-	if (nIndex == OS_INVALID_TLS_INDEX) {
-		assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
-		return false;
-	}
-
-	if (TlsSetValue(nIndex, lpvValue))
-		return true;
-	else
-		return false;
-}
-
-
-bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
-{
-	if (nIndex == OS_INVALID_TLS_INDEX) {
-		assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
-		return false;
-	}
-
-	if (TlsFree(nIndex))
-		return true;
-	else
-		return false;
-}
diff --git a/src/compiler/translator/parseConst.cpp b/src/compiler/translator/parseConst.cpp
index 33617e5..1897ed1 100644
--- a/src/compiler/translator/parseConst.cpp
+++ b/src/compiler/translator/parseConst.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -7,47 +7,50 @@
 #include "compiler/translator/ParseContext.h"
 
 //
-// Use this class to carry along data from node to node in 
+// Use this class to carry along data from node to node in
 // the traversal
 //
-class TConstTraverser : public TIntermTraverser {
-public:
-    TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TType& t)
+class TConstTraverser : public TIntermTraverser
+{
+  public:
+    TConstTraverser(ConstantUnion *cUnion, bool singleConstParam,
+                    TOperator constructType, TInfoSink &sink, TType &t)
         : error(false),
-          index(0),
-          unionArray(cUnion),
-          type(t),
-          constructorType(constructType),
-          singleConstantParam(singleConstParam),
-          infoSink(sink),
-          size(0),
-          isDiagonalMatrixInit(false),
-          matrixCols(0),
-          matrixRows(0) {
+          mIndex(0),
+          mUnionArray(cUnion),
+          mType(t),
+          mConstructorType(constructType),
+          mSingleConstantParam(singleConstParam),
+          mInfoSink(sink),
+          mSize(0),
+          mIsDiagonalMatrixInit(false),
+          mMatrixCols(0),
+          mMatrixRows(0)
+    {
     }
 
     bool error;
 
-protected:
-    void visitSymbol(TIntermSymbol*);
-    void visitConstantUnion(TIntermConstantUnion*);
-    bool visitBinary(Visit visit, TIntermBinary*);
-    bool visitUnary(Visit visit, TIntermUnary*);
-    bool visitSelection(Visit visit, TIntermSelection*);
-    bool visitAggregate(Visit visit, TIntermAggregate*);
-    bool visitLoop(Visit visit, TIntermLoop*);
-    bool visitBranch(Visit visit, TIntermBranch*);
+  protected:
+    void visitSymbol(TIntermSymbol *);
+    void visitConstantUnion(TIntermConstantUnion *);
+    bool visitBinary(Visit visit, TIntermBinary *);
+    bool visitUnary(Visit visit, TIntermUnary *);
+    bool visitSelection(Visit visit, TIntermSelection *);
+    bool visitAggregate(Visit visit, TIntermAggregate *);
+    bool visitLoop(Visit visit, TIntermLoop *);
+    bool visitBranch(Visit visit, TIntermBranch *);
 
-    size_t index;
-    ConstantUnion *unionArray;
-    TType type;
-    TOperator constructorType;
-    bool singleConstantParam;
-    TInfoSink& infoSink;
-    size_t size; // size of the constructor ( 4 for vec4)
-    bool isDiagonalMatrixInit;
-    int matrixCols; // columns of the matrix
-    int matrixRows; // rows of the matrix
+    size_t mIndex;
+    ConstantUnion *mUnionArray;
+    TType mType;
+    TOperator mConstructorType;
+    bool mSingleConstantParam;
+    TInfoSink &mInfoSink;
+    size_t mSize; // size of the constructor ( 4 for vec4)
+    bool mIsDiagonalMatrixInit;
+    int mMatrixCols; // columns of the matrix
+    int mMatrixRows; // rows of the matrix
 };
 
 //
@@ -58,138 +61,144 @@
 // continue on to children.  If you process children yourself,
 // return false.
 //
-
-void TConstTraverser::visitSymbol(TIntermSymbol* node)
+void TConstTraverser::visitSymbol(TIntermSymbol *node)
 {
-    infoSink.info.message(EPrefixInternalError, node->getLine(), "Symbol Node found in constant constructor");
+    mInfoSink.info.message(EPrefixInternalError, node->getLine(),
+                           "Symbol Node found in constant constructor");
     return;
-
 }
 
-bool TConstTraverser::visitBinary(Visit visit, TIntermBinary* node)
+bool TConstTraverser::visitBinary(Visit visit, TIntermBinary *node)
 {
     TQualifier qualifier = node->getType().getQualifier();
-    
-    if (qualifier != EvqConst) {
+
+    if (qualifier != EvqConst)
+    {
         TString buf;
         buf.append("'constructor' : assigning non-constant to ");
-        buf.append(type.getCompleteString());
-        infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
-        error = true;
-        return false;  
-    }
-
-   infoSink.info.message(EPrefixInternalError, node->getLine(), "Binary Node found in constant constructor");
-    
-    return false;
-}
-
-bool TConstTraverser::visitUnary(Visit visit, TIntermUnary* node)
-{
-    TString buf;
-    buf.append("'constructor' : assigning non-constant to ");
-    buf.append(type.getCompleteString());
-    infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
-    error = true;
-    return false;  
-}
-
-bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
-{
-    if (!node->isConstructor() && node->getOp() != EOpComma) {
-        TString buf;
-        buf.append("'constructor' : assigning non-constant to ");
-        buf.append(type.getCompleteString());
-        infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
-        error = true;
-        return false;  
-    }
-
-    if (node->getSequence().size() == 0) {
+        buf.append(mType.getCompleteString());
+        mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
         error = true;
         return false;
     }
 
-    bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
-    if (flag) 
-    {
-        singleConstantParam = true; 
-        constructorType = node->getOp();
-        size = node->getType().getObjectSize();
-
-        if (node->getType().isMatrix()) {
-            isDiagonalMatrixInit = true;
-            matrixCols = node->getType().getCols();
-            matrixRows = node->getType().getRows();
-        }
-    }       
-
-    for (TIntermSequence::iterator p = node->getSequence().begin(); 
-                                   p != node->getSequence().end(); p++) {
-
-        if (node->getOp() == EOpComma)
-            index = 0;           
-
-        (*p)->traverse(this);
-    }   
-    if (flag) 
-    {
-        singleConstantParam = false;   
-        constructorType = EOpNull;
-        size = 0;
-        isDiagonalMatrixInit = false;
-        matrixCols = 0;
-        matrixRows = 0;
-    }
+    mInfoSink.info.message(EPrefixInternalError, node->getLine(),
+                           "Binary Node found in constant constructor");
     return false;
 }
 
-bool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node)
+bool TConstTraverser::visitUnary(Visit visit, TIntermUnary *node)
 {
-    infoSink.info.message(EPrefixInternalError, node->getLine(), "Selection Node found in constant constructor");
+    TString buf;
+    buf.append("'constructor' : assigning non-constant to ");
+    buf.append(mType.getCompleteString());
+    mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
     error = true;
     return false;
 }
 
-void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
+bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+    if (!node->isConstructor() && node->getOp() != EOpComma)
+    {
+        TString buf;
+        buf.append("'constructor' : assigning non-constant to ");
+        buf.append(mType.getCompleteString());
+        mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
+        error = true;
+        return false;
+    }
+
+    if (node->getSequence()->size() == 0)
+    {
+        error = true;
+        return false;
+    }
+
+    bool flag = node->getSequence()->size() == 1 &&
+                (*node->getSequence())[0]->getAsTyped()->getAsConstantUnion();
+    if (flag)
+    {
+        mSingleConstantParam = true;
+        mConstructorType = node->getOp();
+        mSize = node->getType().getObjectSize();
+
+        if (node->getType().isMatrix())
+        {
+            mIsDiagonalMatrixInit = true;
+            mMatrixCols = node->getType().getCols();
+            mMatrixRows = node->getType().getRows();
+        }
+    }
+
+    for (TIntermSequence::iterator p = node->getSequence()->begin();
+         p != node->getSequence()->end(); p++)
+    {
+        if (node->getOp() == EOpComma)
+            mIndex = 0;
+        (*p)->traverse(this);
+    }
+    if (flag)
+    {
+        mSingleConstantParam = false;
+        mConstructorType = EOpNull;
+        mSize = 0;
+        mIsDiagonalMatrixInit = false;
+        mMatrixCols = 0;
+        mMatrixRows = 0;
+    }
+    return false;
+}
+
+bool TConstTraverser::visitSelection(Visit visit, TIntermSelection *node)
+{
+    mInfoSink.info.message(EPrefixInternalError, node->getLine(),
+                           "Selection Node found in constant constructor");
+    error = true;
+    return false;
+}
+
+void TConstTraverser::visitConstantUnion(TIntermConstantUnion *node)
 {
     if (!node->getUnionArrayPointer())
     {
         // The constant was not initialized, this should already have been logged
-        assert(infoSink.info.size() != 0);
+        ASSERT(mInfoSink.info.size() != 0);
         return;
     }
 
-    ConstantUnion* leftUnionArray = unionArray;
-    size_t instanceSize = type.getObjectSize();
+    ConstantUnion *leftUnionArray = mUnionArray;
+    size_t instanceSize = mType.getObjectSize();
+    TBasicType basicType = mType.getBasicType();
 
-    if (index >= instanceSize)
+    if (mIndex >= instanceSize)
         return;
 
-    if (!singleConstantParam) {
+    if (!mSingleConstantParam)
+    {
         size_t objectSize = node->getType().getObjectSize();
-    
         ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
-        for (size_t i=0; i < objectSize; i++) {
-            if (index >= instanceSize)
+        for (size_t i=0; i < objectSize; i++)
+        {
+            if (mIndex >= instanceSize)
                 return;
-            leftUnionArray[index] = rightUnionArray[i];
-
-            (index)++;
+            leftUnionArray[mIndex].cast(basicType, rightUnionArray[i]);
+            mIndex++;
         }
-    } else {
-        size_t totalSize = index + size;
+    }
+    else
+    {
+        size_t totalSize = mIndex + mSize;
         ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
-        if (!isDiagonalMatrixInit) {
+        if (!mIsDiagonalMatrixInit)
+        {
             int count = 0;
-            for (size_t i = index; i < totalSize; i++) {
+            for (size_t i = mIndex; i < totalSize; i++)
+            {
                 if (i >= instanceSize)
                     return;
-
-                leftUnionArray[i] = rightUnionArray[count];
-
-                (index)++;
-                
+                leftUnionArray[i].cast(basicType, rightUnionArray[count]);
+                mIndex++;
                 if (node->getType().getObjectSize() > 1)
                     count++;
             }
@@ -197,36 +206,37 @@
         else
         {
             // for matrix diagonal constructors from a single scalar
-            for (int i = 0, col = 0; col < matrixCols; col++)
+            for (int i = 0, col = 0; col < mMatrixCols; col++)
             {
-                for (int row = 0; row < matrixRows; row++, i++)
+                for (int row = 0; row < mMatrixRows; row++, i++)
                 {
                     if (col == row)
                     {
-                        leftUnionArray[i] = rightUnionArray[0];
+                        leftUnionArray[i].cast(basicType, rightUnionArray[0]);
                     }
                     else
                     {
                         leftUnionArray[i].setFConst(0.0f);
                     }
-
-                    (index)++;
+                    mIndex++;
                 }
             }
         }
     }
 }
 
-bool TConstTraverser::visitLoop(Visit visit, TIntermLoop* node)
+bool TConstTraverser::visitLoop(Visit visit, TIntermLoop *node)
 {
-    infoSink.info.message(EPrefixInternalError, node->getLine(), "Loop Node found in constant constructor");
+    mInfoSink.info.message(EPrefixInternalError, node->getLine(),
+                           "Loop Node found in constant constructor");
     error = true;
     return false;
 }
 
-bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node)
+bool TConstTraverser::visitBranch(Visit visit, TIntermBranch *node)
 {
-    infoSink.info.message(EPrefixInternalError, node->getLine(), "Branch Node found in constant constructor");
+    mInfoSink.info.message(EPrefixInternalError, node->getLine(),
+                           "Branch Node found in constant constructor");
     error = true;
     return false;
 }
@@ -236,12 +246,15 @@
 // Individual functions can be initialized to 0 to skip processing of that
 // type of node.  It's children will still be processed.
 //
-bool TIntermediate::parseConstTree(const TSourceLoc& line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TType t, bool singleConstantParam)
+bool TIntermediate::parseConstTree(
+    const TSourceLoc &line, TIntermNode *root, ConstantUnion *unionArray,
+    TOperator constructorType, TType t, bool singleConstantParam)
 {
     if (root == 0)
         return false;
 
-    TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, t);
+    TConstTraverser it(unionArray, singleConstantParam, constructorType,
+                       mInfoSink, t);
 
     root->traverse(&it);
     if (it.error)
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 077bdcc..f74c7d1 100644
--- a/src/compiler/translator/util.cpp
+++ b/src/compiler/translator/util.cpp
@@ -9,6 +9,7 @@
 #include <limits>
 
 #include "compiler/preprocessor/numeric_lex.h"
+#include "common/utilities.h"
 
 bool atof_clamp(const char *str, float *value)
 {
@@ -26,3 +27,297 @@
     return success;
 }
 
+namespace sh
+{
+
+GLenum GLVariableType(const TType &type)
+{
+    if (type.getBasicType() == EbtFloat)
+    {
+        if (type.isScalar())
+        {
+            return GL_FLOAT;
+        }
+        else if (type.isVector())
+        {
+            switch (type.getNominalSize())
+            {
+              case 2: return GL_FLOAT_VEC2;
+              case 3: return GL_FLOAT_VEC3;
+              case 4: return GL_FLOAT_VEC4;
+              default: UNREACHABLE();
+            }
+        }
+        else if (type.isMatrix())
+        {
+            switch (type.getCols())
+            {
+              case 2:
+                switch (type.getRows())
+                {
+                  case 2: return GL_FLOAT_MAT2;
+                  case 3: return GL_FLOAT_MAT2x3;
+                  case 4: return GL_FLOAT_MAT2x4;
+                  default: UNREACHABLE();
+                }
+
+              case 3:
+                switch (type.getRows())
+                {
+                  case 2: return GL_FLOAT_MAT3x2;
+                  case 3: return GL_FLOAT_MAT3;
+                  case 4: return GL_FLOAT_MAT3x4;
+                  default: UNREACHABLE();
+                }
+
+              case 4:
+                switch (type.getRows())
+                {
+                  case 2: return GL_FLOAT_MAT4x2;
+                  case 3: return GL_FLOAT_MAT4x3;
+                  case 4: return GL_FLOAT_MAT4;
+                  default: UNREACHABLE();
+                }
+
+              default: UNREACHABLE();
+            }
+        }
+        else UNREACHABLE();
+    }
+    else if (type.getBasicType() == EbtInt)
+    {
+        if (type.isScalar())
+        {
+            return GL_INT;
+        }
+        else if (type.isVector())
+        {
+            switch (type.getNominalSize())
+            {
+              case 2: return GL_INT_VEC2;
+              case 3: return GL_INT_VEC3;
+              case 4: return GL_INT_VEC4;
+              default: UNREACHABLE();
+            }
+        }
+        else UNREACHABLE();
+    }
+    else if (type.getBasicType() == EbtUInt)
+    {
+        if (type.isScalar())
+        {
+            return GL_UNSIGNED_INT;
+        }
+        else if (type.isVector())
+        {
+            switch (type.getNominalSize())
+            {
+              case 2: return GL_UNSIGNED_INT_VEC2;
+              case 3: return GL_UNSIGNED_INT_VEC3;
+              case 4: return GL_UNSIGNED_INT_VEC4;
+              default: UNREACHABLE();
+            }
+        }
+        else UNREACHABLE();
+    }
+    else if (type.getBasicType() == EbtBool)
+    {
+        if (type.isScalar())
+        {
+            return GL_BOOL;
+        }
+        else if (type.isVector())
+        {
+            switch (type.getNominalSize())
+            {
+              case 2: return GL_BOOL_VEC2;
+              case 3: return GL_BOOL_VEC3;
+              case 4: return GL_BOOL_VEC4;
+              default: UNREACHABLE();
+            }
+        }
+        else UNREACHABLE();
+    }
+
+    switch (type.getBasicType())
+    {
+      case EbtSampler2D:            return GL_SAMPLER_2D;
+      case EbtSampler3D:            return GL_SAMPLER_3D;
+      case EbtSamplerCube:          return GL_SAMPLER_CUBE;
+      case EbtSamplerExternalOES:   return GL_SAMPLER_EXTERNAL_OES;
+      case EbtSampler2DRect:        return GL_SAMPLER_2D_RECT_ARB;
+      case EbtSampler2DArray:       return GL_SAMPLER_2D_ARRAY;
+      case EbtISampler2D:           return GL_INT_SAMPLER_2D;
+      case EbtISampler3D:           return GL_INT_SAMPLER_3D;
+      case EbtISamplerCube:         return GL_INT_SAMPLER_CUBE;
+      case EbtISampler2DArray:      return GL_INT_SAMPLER_2D_ARRAY;
+      case EbtUSampler2D:           return GL_UNSIGNED_INT_SAMPLER_2D;
+      case EbtUSampler3D:           return GL_UNSIGNED_INT_SAMPLER_3D;
+      case EbtUSamplerCube:         return GL_UNSIGNED_INT_SAMPLER_CUBE;
+      case EbtUSampler2DArray:      return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
+      case EbtSampler2DShadow:      return GL_SAMPLER_2D_SHADOW;
+      case EbtSamplerCubeShadow:    return GL_SAMPLER_CUBE_SHADOW;
+      case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW;
+      default: UNREACHABLE();
+    }
+
+    return GL_NONE;
+}
+
+GLenum GLVariablePrecision(const TType &type)
+{
+    if (type.getBasicType() == EbtFloat)
+    {
+        switch (type.getPrecision())
+        {
+          case EbpHigh:
+            return GL_HIGH_FLOAT;
+          case EbpMedium:
+            return GL_MEDIUM_FLOAT;
+          case EbpLow:
+            return GL_LOW_FLOAT;
+          case EbpUndefined:
+          // Should be defined as the default precision by the parser
+          default:
+            UNREACHABLE();
+        }
+    }
+    else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
+    {
+        switch (type.getPrecision())
+        {
+          case EbpHigh:
+            return GL_HIGH_INT;
+          case EbpMedium:
+            return GL_MEDIUM_INT;
+          case EbpLow:
+            return GL_LOW_INT;
+          case EbpUndefined:
+          // Should be defined as the default precision by the parser
+          default:
+            UNREACHABLE();
+        }
+    }
+
+    // Other types (boolean, sampler) don't have a precision
+    return GL_NONE;
+}
+
+TString ArrayString(const TType &type)
+{
+    if (!type.isArray())
+    {
+        return "";
+    }
+
+    return "[" + str(type.getArraySize()) + "]";
+}
+
+bool IsVaryingOut(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+      case EvqVaryingOut:
+      case EvqInvariantVaryingOut:
+      case EvqSmoothOut:
+      case EvqFlatOut:
+      case EvqCentroidOut:
+      case EvqVertexOut:
+        return true;
+
+      default: break;
+    }
+
+    return false;
+}
+
+bool IsVaryingIn(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+      case EvqVaryingIn:
+      case EvqInvariantVaryingIn:
+      case EvqSmoothIn:
+      case EvqFlatIn:
+      case EvqCentroidIn:
+      case EvqFragmentIn:
+        return true;
+
+      default: break;
+    }
+
+    return false;
+}
+
+bool IsVarying(TQualifier qualifier)
+{
+    return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
+}
+
+InterpolationType GetInterpolationType(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+      case EvqFlatIn:
+      case EvqFlatOut:
+        return INTERPOLATION_FLAT;
+
+      case EvqSmoothIn:
+      case EvqSmoothOut:
+      case EvqVertexOut:
+      case EvqFragmentIn:
+      case EvqVaryingIn:
+      case EvqVaryingOut:
+      case EvqInvariantVaryingIn:
+      case EvqInvariantVaryingOut:
+        return INTERPOLATION_SMOOTH;
+
+      case EvqCentroidIn:
+      case EvqCentroidOut:
+        return INTERPOLATION_CENTROID;
+
+      default: UNREACHABLE();
+        return INTERPOLATION_SMOOTH;
+    }
+}
+
+template <typename VarT>
+void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
+{
+    const TStructure *structure = type.getStruct();
+
+    VarT variable;
+    variable.name = name.c_str();
+    variable.arraySize = static_cast<unsigned int>(type.getArraySize());
+
+    if (!structure)
+    {
+        variable.type = GLVariableType(type);
+        variable.precision = GLVariablePrecision(type);
+    }
+    else
+    {
+        // Note: this enum value is not exposed outside ANGLE
+        variable.type = GL_STRUCT_ANGLEX;
+        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(), &variable.fields);
+        }
+    }
+
+    visitVariable(&variable);
+
+    ASSERT(output);
+    output->push_back(variable);
+}
+
+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 dc69f39..241e2cc 100644
--- a/src/compiler/translator/util.h
+++ b/src/compiler/translator/util.h
@@ -7,6 +7,13 @@
 #ifndef COMPILER_UTIL_H
 #define COMPILER_UTIL_H
 
+#include <stack>
+
+#include "angle_gl.h"
+#include <GLSLANG/ShaderLang.h>
+
+#include "compiler/translator/Types.h"
+
 // atof_clamp is like atof but
 //   1. it forces C locale, i.e. forcing '.' as decimal point.
 //   2. it clamps the value to -FLT_MAX or FLT_MAX if overflow happens.
@@ -17,4 +24,33 @@
 // Return false if overflow happens.
 extern bool atoi_clamp(const char *str, int *value);
 
+namespace sh
+{
+
+GLenum GLVariableType(const TType &type);
+GLenum GLVariablePrecision(const TType &type);
+bool IsVaryingIn(TQualifier qualifier);
+bool IsVaryingOut(TQualifier qualifier);
+bool IsVarying(TQualifier qualifier);
+InterpolationType GetInterpolationType(TQualifier qualifier);
+TString ArrayString(const TType &type);
+
+class GetVariableTraverser
+{
+  public:
+    GetVariableTraverser() {}
+
+    template <typename VarT>
+    void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
+
+  protected:
+    // May be overloaded
+    virtual void visitVariable(ShaderVariable *newVar) {}
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
+};
+
+}
+
 #endif // COMPILER_UTIL_H
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-mips64.mk b/src/copy_scripts.target.darwin-mips64.mk
new file mode 100644
index 0000000..a406fcb
--- /dev/null
+++ b/src/copy_scripts.target.darwin-mips64.mk
@@ -0,0 +1,55 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
+LOCAL_MODULE_STEM := copy_scripts
+LOCAL_MODULE_SUFFIX := .stamp
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+### Generated for copy rule.
+$(gyp_shared_intermediate_dir)/angle/copy_compiler_dll.bat: $(LOCAL_PATH)/third_party/angle/src/copy_compiler_dll.bat $(GYP_TARGET_DEPENDENCIES) | $(ACP)
+	@echo Copying: $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(ACP) -rpf $< $@
+
+$(gyp_shared_intermediate_dir)/angle/commit_id.py: $(LOCAL_PATH)/third_party/angle/src/commit_id.py $(GYP_TARGET_DEPENDENCIES) | $(ACP)
+	@echo Copying: $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(ACP) -rpf $< $@
+
+third_party_angle_src_build_angle_gyp_copy_scripts_target_copies = $(gyp_shared_intermediate_dir)/angle/copy_compiler_dll.bat $(gyp_shared_intermediate_dir)/angle/commit_id.py
+
+GYP_GENERATED_OUTPUTS := \
+	$(third_party_angle_src_build_angle_gyp_copy_scripts_target_copies)
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_copy_scripts_gyp
+
+# Alias gyp target name.
+.PHONY: copy_scripts
+copy_scripts: third_party_angle_src_copy_scripts_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+	$(hide) echo "Gyp timestamp: $@"
+	$(hide) mkdir -p $(dir $@)
+	$(hide) touch $@
+
+LOCAL_2ND_ARCH_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-mips64.mk b/src/copy_scripts.target.linux-mips64.mk
new file mode 100644
index 0000000..a406fcb
--- /dev/null
+++ b/src/copy_scripts.target.linux-mips64.mk
@@ -0,0 +1,55 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := third_party_angle_src_copy_scripts_gyp
+LOCAL_MODULE_STEM := copy_scripts
+LOCAL_MODULE_SUFFIX := .stamp
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+### Generated for copy rule.
+$(gyp_shared_intermediate_dir)/angle/copy_compiler_dll.bat: $(LOCAL_PATH)/third_party/angle/src/copy_compiler_dll.bat $(GYP_TARGET_DEPENDENCIES) | $(ACP)
+	@echo Copying: $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(ACP) -rpf $< $@
+
+$(gyp_shared_intermediate_dir)/angle/commit_id.py: $(LOCAL_PATH)/third_party/angle/src/commit_id.py $(GYP_TARGET_DEPENDENCIES) | $(ACP)
+	@echo Copying: $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(ACP) -rpf $< $@
+
+third_party_angle_src_build_angle_gyp_copy_scripts_target_copies = $(gyp_shared_intermediate_dir)/angle/copy_compiler_dll.bat $(gyp_shared_intermediate_dir)/angle/commit_id.py
+
+GYP_GENERATED_OUTPUTS := \
+	$(third_party_angle_src_build_angle_gyp_copy_scripts_target_copies)
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_copy_scripts_gyp
+
+# Alias gyp target name.
+.PHONY: copy_scripts
+copy_scripts: third_party_angle_src_copy_scripts_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+	$(hide) echo "Gyp timestamp: $@"
+	$(hide) mkdir -p $(dir $@)
+	$(hide) touch $@
+
+LOCAL_2ND_ARCH_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 f5def3f..85ac315 100644
--- a/src/libEGL.gypi
+++ b/src/libEGL.gypi
@@ -3,6 +3,58 @@
 # found in the LICENSE file.
 
 {
+    'variables':
+    {
+        'angle_enable_d3d9%': 1,
+        'angle_enable_d3d11%': 1,
+        # This file list is shared with the GN build.
+        'angle_libegl_sources':
+        [
+            '../include/EGL/egl.h',
+            '../include/EGL/eglext.h',
+            '../include/EGL/eglplatform.h',
+            '../include/GLES2/gl2.h',
+            '../include/GLES2/gl2ext.h',
+            '../include/GLES2/gl2platform.h',
+            '../include/GLES3/gl3.h',
+            '../include/GLES3/gl3ext.h',
+            '../include/GLES3/gl3platform.h',
+            '../include/GLSLANG/ShaderLang.h',
+            '../include/GLSLANG/ShaderVars.h',
+            '../include/KHR/khrplatform.h',
+            '../include/angle_gl.h',
+            'common/RefCountObject.cpp',
+            'common/RefCountObject.h',
+            'common/angleutils.cpp',
+            'common/angleutils.h',
+            'common/debug.cpp',
+            'common/debug.h',
+            'common/event_tracer.cpp',
+            'common/event_tracer.h',
+            'common/mathutil.cpp',
+            'common/mathutil.h',
+            'common/platform.h',
+            'common/tls.cpp',
+            'common/tls.h',
+            'common/utilities.cpp',
+            'common/utilities.h',
+            'common/version.h',
+            'libEGL/Config.cpp',
+            'libEGL/Config.h',
+            'libEGL/Display.cpp',
+            'libEGL/Display.h',
+            'libEGL/Surface.cpp',
+            'libEGL/Surface.h',
+            'libEGL/libEGL.cpp',
+            'libEGL/libEGL.def',
+            'libEGL/libEGL.rc',
+            'libEGL/main.cpp',
+            'libEGL/main.h',
+            'libEGL/resource.h',
+        ],
+    },
+    # Everything below this is duplicated in the GN build. If you change
+    # anything also change angle/BUILD.gn
     'conditions':
     [
         ['OS=="win"',
@@ -21,9 +73,7 @@
                     ],
                     'sources':
                     [
-                        '<!@(python <(angle_path)/enumerate_files.py \
-                             -dirs common libEGL ../include \
-                             -types *.cpp *.h *.def *.rc)',
+                        '<@(angle_libegl_sources)',
                     ],
                     'defines':
                     [
@@ -31,6 +81,23 @@
                         'GL_GLEXT_PROTOTYPES=',
                         'EGLAPI=',
                     ],
+                    'conditions':
+                    [
+                        ['angle_enable_d3d9==1',
+                        {
+                            'defines':
+                            [
+                                'ANGLE_ENABLE_D3D9',
+                            ],
+                        }],
+                        ['angle_enable_d3d11==1',
+                        {
+                            'defines':
+                            [
+                                'ANGLE_ENABLE_D3D11',
+                            ],
+                        }],
+                    ],
                     'includes': [ '../build/common_defines.gypi', ],
                     'msvs_settings':
                     {
diff --git a/src/libEGL/Config.cpp b/src/libEGL/Config.cpp
index 0b47d55..fdc41a9 100644
--- a/src/libEGL/Config.cpp
+++ b/src/libEGL/Config.cpp
@@ -13,10 +13,7 @@
 #include <algorithm>
 #include <vector>
 
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
+#include "angle_gl.h"
 #include <EGL/eglext.h>
 
 #include "common/debug.h"
diff --git a/src/libEGL/Config.h b/src/libEGL/Config.h
index 680337b..9844114 100644
--- a/src/libEGL/Config.h
+++ b/src/libEGL/Config.h
@@ -11,7 +11,6 @@
 #ifndef INCLUDE_CONFIG_H_
 #define INCLUDE_CONFIG_H_
 
-#define EGLAPI
 #include <EGL/egl.h>
 
 #include <set>
diff --git a/src/libEGL/Display.cpp b/src/libEGL/Display.cpp
index 07b2dac..43d9b26 100644
--- a/src/libEGL/Display.cpp
+++ b/src/libEGL/Display.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -13,6 +13,7 @@
 #include <algorithm>
 #include <map>
 #include <vector>
+#include <sstream>
 
 #include "common/debug.h"
 #include "common/mathutil.h"
@@ -25,42 +26,47 @@
 
 namespace egl
 {
-namespace
+
+typedef std::map<EGLNativeDisplayType, Display*> DisplayMap;
+static DisplayMap *GetDisplayMap()
 {
-    typedef std::map<EGLNativeDisplayType, Display*> DisplayMap; 
-    DisplayMap displays;
+    static DisplayMap displays;
+    return &displays;
 }
 
-egl::Display *Display::getDisplay(EGLNativeDisplayType displayId)
+egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, EGLint displayType)
 {
-    if (displays.find(displayId) != displays.end())
+    DisplayMap *displays = GetDisplayMap();
+    DisplayMap::const_iterator iter = displays->find(displayId);
+    if (iter != displays->end())
     {
-        return displays[displayId];
+        return iter->second;
     }
     
     // FIXME: Check if displayId is a valid display device context
 
-    egl::Display *display = new egl::Display(displayId, (HDC)displayId);
+    egl::Display *display = new egl::Display(displayId, displayType);
+    displays->insert(std::make_pair(displayId, display));
 
-    displays[displayId] = display;
     return display;
 }
 
-Display::Display(EGLNativeDisplayType displayId, HDC deviceContext) : mDc(deviceContext)
+Display::Display(EGLNativeDisplayType displayId, EGLint displayType)
+    : mDisplayId(displayId),
+      mRequestedDisplayType(displayType),
+      mRenderer(NULL)
 {
-    mDisplayId = displayId;
-    mRenderer = NULL;
 }
 
 Display::~Display()
 {
     terminate();
 
-    DisplayMap::iterator thisDisplay = displays.find(mDisplayId);
-
-    if (thisDisplay != displays.end())
+    DisplayMap *displays = GetDisplayMap();
+    DisplayMap::iterator iter = displays->find(mDisplayId);
+    if (iter != displays->end())
     {
-        displays.erase(thisDisplay);
+        displays->erase(iter);
     }
 }
 
@@ -71,8 +77,8 @@
         return true;
     }
 
-    mRenderer = glCreateRenderer(this, mDc, mDisplayId);
-    
+    mRenderer = glCreateRenderer(this, mDisplayId, mRequestedDisplayType);
+
     if (!mRenderer)
     {
         terminate();
@@ -81,16 +87,16 @@
 
     EGLint minSwapInterval = mRenderer->getMinSwapInterval();
     EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
-    EGLint maxTextureWidth = mRenderer->getMaxTextureWidth();
-    EGLint maxTextureHeight = mRenderer->getMaxTextureHeight();
+    EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize;
 
     rx::ConfigDesc *descList;
     int numConfigs = mRenderer->generateConfigs(&descList);
     ConfigSet configSet;
 
     for (int i = 0; i < numConfigs; ++i)
-        configSet.add(descList[i], minSwapInterval, maxSwapInterval,
-                      maxTextureWidth, maxTextureHeight);
+    {
+        configSet.add(descList[i], minSwapInterval, maxSwapInterval, maxTextureSize, maxTextureSize);
+    }
 
     // Give the sorted configs a unique ID and store them internally
     EGLint index = 1;
@@ -112,7 +118,7 @@
         return false;
     }
 
-    initExtensionString();
+    initDisplayExtensionString();
     initVendorString();
 
     return true;
@@ -343,7 +349,7 @@
         return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
     }
 
-    if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getNonPower2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
+    if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
     {
         return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
     }
@@ -500,48 +506,84 @@
     return false;
 }
 
-void Display::initExtensionString()
+std::string Display::generateClientExtensionString()
 {
-    bool shareHandleSupported = mRenderer->getShareHandleSupport();
+    std::vector<std::string> extensions;
 
-    mExtensionString = "";
+    extensions.push_back("EGL_EXT_client_extensions");
+
+    extensions.push_back("ANGLE_platform_angle");
+
+    if (supportsPlatformD3D())
+    {
+        extensions.push_back("ANGLE_platform_angle_d3d");
+    }
+
+    if (supportsPlatformOpenGL())
+    {
+        extensions.push_back("ANGLE_platform_angle_opengl");
+    }
+
+    std::ostringstream stream;
+    std::copy(extensions.begin(), extensions.end(), std::ostream_iterator<std::string>(stream, " "));
+    return stream.str();
+}
+
+void Display::initDisplayExtensionString()
+{
+    std::vector<std::string> extensions;
 
     // Multi-vendor (EXT) extensions
-    mExtensionString += "EGL_EXT_create_context_robustness ";
+    extensions.push_back("EGL_EXT_create_context_robustness");
 
     // ANGLE-specific extensions
-    if (shareHandleSupported)
+    if (mRenderer->getShareHandleSupport())
     {
-        mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
+        extensions.push_back("EGL_ANGLE_d3d_share_handle_client_buffer");
+        extensions.push_back("EGL_ANGLE_surface_d3d_texture_2d_share_handle");
     }
 
-    mExtensionString += "EGL_ANGLE_query_surface_pointer ";
-
-    mExtensionString += "EGL_ANGLE_window_fixed_size ";
-
-    if (shareHandleSupported)
-    {
-        mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
-    }
+    extensions.push_back("EGL_ANGLE_query_surface_pointer");
+    extensions.push_back("EGL_ANGLE_window_fixed_size");
 
     if (mRenderer->getPostSubBufferSupport())
     {
-        mExtensionString += "EGL_NV_post_sub_buffer ";
+        extensions.push_back("EGL_NV_post_sub_buffer");
     }
 
     // TODO: complete support for the EGL_KHR_create_context extension
-    mExtensionString += "EGL_KHR_create_context ";
+    extensions.push_back("EGL_KHR_create_context");
 
-    std::string::size_type end = mExtensionString.find_last_not_of(' ');
-    if (end != std::string::npos)
+    std::ostringstream stream;
+    std::copy(extensions.begin(), extensions.end(), std::ostream_iterator<std::string>(stream, " "));
+    mDisplayExtensionString = stream.str();
+}
+
+const char *Display::getExtensionString(egl::Display *display)
+{
+    if (display != EGL_NO_DISPLAY)
     {
-        mExtensionString.resize(end+1);
+        return display->mDisplayExtensionString.c_str();
+    }
+    else
+    {
+        static std::string clientExtensions = generateClientExtensionString();
+        return clientExtensions.c_str();
     }
 }
 
-const char *Display::getExtensionString() const
+bool Display::supportsPlatformD3D()
 {
-    return mExtensionString.c_str();
+#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool Display::supportsPlatformOpenGL()
+{
+    return false;
 }
 
 void Display::initVendorString()
diff --git a/src/libEGL/Display.h b/src/libEGL/Display.h
index e394260..250878f 100644
--- a/src/libEGL/Display.h
+++ b/src/libEGL/Display.h
@@ -33,7 +33,12 @@
     bool initialize();
     void terminate();
 
-    static egl::Display *getDisplay(EGLNativeDisplayType displayId);
+    static egl::Display *getDisplay(EGLNativeDisplayType displayId, EGLint displayType);
+
+    static const char *getExtensionString(egl::Display *display);
+
+    static bool supportsPlatformD3D();
+    static bool supportsPlatformOpenGL();
 
     bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
     bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
@@ -63,15 +68,13 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Display);
 
-    Display(EGLNativeDisplayType displayId, HDC deviceContext);
+    Display(EGLNativeDisplayType displayId, EGLint displayType);
 
     bool restoreLostDevice();
 
     EGLNativeDisplayType mDisplayId;
-    const HDC mDc;
+    EGLint mRequestedDisplayType;
 
-    bool mSoftwareDevice;
-    
     typedef std::set<Surface*> SurfaceSet;
     SurfaceSet mSurfaceSet;
 
@@ -82,9 +85,12 @@
 
     rx::Renderer *mRenderer;
 
-    void initExtensionString();
+    static std::string generateClientExtensionString();
+
+    void initDisplayExtensionString();
+    std::string mDisplayExtensionString;
+
     void initVendorString();
-    std::string mExtensionString;
     std::string mVendorString;
 };
 }
diff --git a/src/libEGL/Surface.h b/src/libEGL/Surface.h
index 2361fcd..24c66b7 100644
--- a/src/libEGL/Surface.h
+++ b/src/libEGL/Surface.h
@@ -11,7 +11,6 @@
 #ifndef LIBEGL_SURFACE_H_
 #define LIBEGL_SURFACE_H_
 
-#define EGLAPI
 #include <EGL/egl.h>
 
 #include "common/angleutils.h"
@@ -105,7 +104,7 @@
     EGLint mSwapInterval;
     EGLint mPostSubBufferSupported;
     EGLint mFixedSize;
-    
+
     bool mSwapIntervalDirty;
     gl::Texture2D *mTexture;
 };
diff --git a/src/libEGL/libEGL.cpp b/src/libEGL/libEGL.cpp
index 09e1452..f9a4780 100644
--- a/src/libEGL/libEGL.cpp
+++ b/src/libEGL/libEGL.cpp
@@ -99,14 +99,75 @@
 {
     EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
 
-    try
+    return egl::Display::getDisplay(display_id, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+}
+
+EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
+{
+    EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
+          platform, native_display, attrib_list);
+
+    switch (platform)
     {
-        return egl::Display::getDisplay(display_id);
+      case EGL_PLATFORM_ANGLE_ANGLE:
+        break;
+
+      default:
+        return egl::error(EGL_BAD_CONFIG, EGL_NO_DISPLAY);
     }
-    catch (...)
+
+    EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
+
+    // Validate the display device context
+    if (WindowFromDC(displayId) == NULL)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
+        return egl::success(EGL_NO_DISPLAY);
     }
+
+    EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
+    if (attrib_list)
+    {
+        for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
+        {
+            switch (curAttrib[0])
+            {
+              case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
+                requestedDisplayType = curAttrib[1];
+                break;
+
+              default:
+                break;
+            }
+        }
+    }
+
+    switch (requestedDisplayType)
+    {
+      case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
+        break;
+
+      case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
+      case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
+      case EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE:
+        if (!egl::Display::supportsPlatformD3D())
+        {
+            return egl::success(EGL_NO_DISPLAY);
+        }
+        break;
+
+      case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
+      case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
+        if (!egl::Display::supportsPlatformOpenGL())
+        {
+            return egl::success(EGL_NO_DISPLAY);
+        }
+        break;
+
+      default:
+        return egl::success(EGL_NO_DISPLAY);
+    }
+
+    return egl::Display::getDisplay(displayId, requestedDisplayType);
 }
 
 EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
@@ -114,84 +175,62 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
           dpy, major, minor);
 
-    try
+    if (dpy == EGL_NO_DISPLAY)
     {
-        if (dpy == EGL_NO_DISPLAY)
-        {
-            return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
-        }
-
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!display->initialize())
-        {
-            return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE);
-        }
-
-        if (major) *major = 1;
-        if (minor) *minor = 4;
-
-        return egl::success(EGL_TRUE);
+        return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
     }
-    catch (...)
+
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (!display->initialize())
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE);
     }
+
+    if (major) *major = 1;
+    if (minor) *minor = 4;
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
 
-    try
+    if (dpy == EGL_NO_DISPLAY)
     {
-        if (dpy == EGL_NO_DISPLAY)
-        {
-            return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
-        }
-
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        display->terminate();
-
-        return egl::success(EGL_TRUE);
+        return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
     }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    display->terminate();
+
+    return egl::success(EGL_TRUE);
 }
 
 const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) && !validateDisplay(display))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!validateDisplay(display))
-        {
-            return NULL;
-        }
-
-        switch (name)
-        {
-          case EGL_CLIENT_APIS:
-            return egl::success("OpenGL_ES");
-          case EGL_EXTENSIONS:
-            return egl::success(display->getExtensionString());
-          case EGL_VENDOR:
-            return egl::success(display->getVendorString());
-          case EGL_VERSION:
-            return egl::success("1.4 (ANGLE " ANGLE_VERSION_STRING ")");
-        }
-
-        return egl::error(EGL_BAD_PARAMETER, (const char*)NULL);
+        return NULL;
     }
-    catch (...)
+
+    switch (name)
     {
-        return egl::error(EGL_BAD_ALLOC, (const char*)NULL);
+      case EGL_CLIENT_APIS:
+        return egl::success("OpenGL_ES");
+      case EGL_EXTENSIONS:
+        return egl::success(egl::Display::getExtensionString(display));
+      case EGL_VENDOR:
+        return egl::success(display->getVendorString());
+      case EGL_VERSION:
+        return egl::success("1.4 (ANGLE " ANGLE_VERSION_STRING ")");
+      default:
+        return egl::error(EGL_BAD_PARAMETER, (const char*)NULL);
     }
 }
 
@@ -201,33 +240,26 @@
           "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
           dpy, configs, config_size, num_config);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (!validateDisplay(display))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!validateDisplay(display))
-        {
-            return EGL_FALSE;
-        }
-
-        if (!num_config)
-        {
-            return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
-        }
-
-        const EGLint attribList[] =    {EGL_NONE};
-
-        if (!display->getConfigs(configs, attribList, config_size, num_config))
-        {
-            return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-        }
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (!num_config)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
     }
+
+    const EGLint attribList[] =    {EGL_NONE};
+
+    if (!display->getConfigs(configs, attribList, config_size, num_config))
+    {
+        return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+    }
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
@@ -236,35 +268,28 @@
           "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
           dpy, attrib_list, configs, config_size, num_config);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (!validateDisplay(display))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!validateDisplay(display))
-        {
-            return EGL_FALSE;
-        }
-
-        if (!num_config)
-        {
-            return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
-        }
-
-        const EGLint attribList[] =    {EGL_NONE};
-
-        if (!attrib_list)
-        {
-            attrib_list = attribList;
-        }
-
-        display->getConfigs(configs, attrib_list, config_size, num_config);
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (!num_config)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
     }
+
+    const EGLint attribList[] =    {EGL_NONE};
+
+    if (!attrib_list)
+    {
+        attrib_list = attribList;
+    }
+
+    display->getConfigs(configs, attrib_list, config_size, num_config);
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
@@ -272,26 +297,19 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
           dpy, config, attribute, value);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (!validateConfig(display, config))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!validateConfig(display, config))
-        {
-            return EGL_FALSE;
-        }
-
-        if (!display->getConfigAttrib(config, attribute, value))
-        {
-            return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-        }
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (!display->getConfigAttrib(config, attribute, value))
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
     }
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
@@ -299,28 +317,21 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (!validateConfig(display, config))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!validateConfig(display, config))
-        {
-            return EGL_NO_SURFACE;
-        }
-
-        HWND window = (HWND)win;
-
-        if (!IsWindow(window))
-        {
-            return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
-        }
-
-        return display->createWindowSurface(window, config, attrib_list);
+        return EGL_NO_SURFACE;
     }
-    catch (...)
+
+    HWND window = (HWND)win;
+
+    if (!IsWindow(window))
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+        return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
     }
+
+    return display->createWindowSurface(window, config, attrib_list);
 }
 
 EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
@@ -328,21 +339,14 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
           dpy, config, attrib_list);
 
-    try
-    {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validateConfig(display, config))
-        {
-            return EGL_NO_SURFACE;
-        }
-
-        return display->createOffscreenSurface(config, NULL, attrib_list);
-    }
-    catch (...)
+    if (!validateConfig(display, config))
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+        return EGL_NO_SURFACE;
     }
+
+    return display->createOffscreenSurface(config, NULL, attrib_list);
 }
 
 EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
@@ -350,52 +354,38 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (!validateConfig(display, config))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!validateConfig(display, config))
-        {
-            return EGL_NO_SURFACE;
-        }
-
-        UNIMPLEMENTED();   // FIXME
-
-        return egl::success(EGL_NO_SURFACE);
+        return EGL_NO_SURFACE;
     }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
-    }
+
+    UNIMPLEMENTED();   // FIXME
+
+    return egl::success(EGL_NO_SURFACE);
 }
 
 EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+    if (!validateSurface(display, eglSurface))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        if (surface == EGL_NO_SURFACE)
-        {
-            return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
-        }
-
-        display->destroySurface((egl::Surface*)surface);
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (surface == EGL_NO_SURFACE)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
     }
+
+    display->destroySurface((egl::Surface*)surface);
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
@@ -403,87 +393,80 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
           dpy, surface, attribute, value);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = (egl::Surface*)surface;
+
+    if (!validateSurface(display, eglSurface))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = (egl::Surface*)surface;
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        if (surface == EGL_NO_SURFACE)
-        {
-            return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
-        }
-
-        switch (attribute)
-        {
-          case EGL_VG_ALPHA_FORMAT:
-            UNIMPLEMENTED();   // FIXME
-            break;
-          case EGL_VG_COLORSPACE:
-            UNIMPLEMENTED();   // FIXME
-            break;
-          case EGL_CONFIG_ID:
-            *value = eglSurface->getConfigID();
-            break;
-          case EGL_HEIGHT:
-            *value = eglSurface->getHeight();
-            break;
-          case EGL_HORIZONTAL_RESOLUTION:
-            UNIMPLEMENTED();   // FIXME
-            break;
-          case EGL_LARGEST_PBUFFER:
-            UNIMPLEMENTED();   // FIXME
-            break;
-          case EGL_MIPMAP_TEXTURE:
-            UNIMPLEMENTED();   // FIXME
-            break;
-          case EGL_MIPMAP_LEVEL:
-            UNIMPLEMENTED();   // FIXME
-            break;
-          case EGL_MULTISAMPLE_RESOLVE:
-            UNIMPLEMENTED();   // FIXME
-            break;
-          case EGL_PIXEL_ASPECT_RATIO:
-            *value = eglSurface->getPixelAspectRatio();
-            break;
-          case EGL_RENDER_BUFFER:
-            *value = eglSurface->getRenderBuffer();
-            break;
-          case EGL_SWAP_BEHAVIOR:
-            *value = eglSurface->getSwapBehavior();
-            break;
-          case EGL_TEXTURE_FORMAT:
-            *value = eglSurface->getTextureFormat();
-            break;
-          case EGL_TEXTURE_TARGET:
-            *value = eglSurface->getTextureTarget();
-            break;
-          case EGL_VERTICAL_RESOLUTION:
-            UNIMPLEMENTED();   // FIXME
-            break;
-          case EGL_WIDTH:
-            *value = eglSurface->getWidth();
-            break;
-          case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
-            *value = eglSurface->isPostSubBufferSupported();
-            break;
-          case EGL_FIXED_SIZE_ANGLE:
-            *value = eglSurface->isFixedSize();
-            break;
-          default:
-            return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-        }
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (surface == EGL_NO_SURFACE)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
     }
+
+    switch (attribute)
+    {
+      case EGL_VG_ALPHA_FORMAT:
+        UNIMPLEMENTED();   // FIXME
+        break;
+      case EGL_VG_COLORSPACE:
+        UNIMPLEMENTED();   // FIXME
+        break;
+      case EGL_CONFIG_ID:
+        *value = eglSurface->getConfigID();
+        break;
+      case EGL_HEIGHT:
+        *value = eglSurface->getHeight();
+        break;
+      case EGL_HORIZONTAL_RESOLUTION:
+        UNIMPLEMENTED();   // FIXME
+        break;
+      case EGL_LARGEST_PBUFFER:
+        UNIMPLEMENTED();   // FIXME
+        break;
+      case EGL_MIPMAP_TEXTURE:
+        UNIMPLEMENTED();   // FIXME
+        break;
+      case EGL_MIPMAP_LEVEL:
+        UNIMPLEMENTED();   // FIXME
+        break;
+      case EGL_MULTISAMPLE_RESOLVE:
+        UNIMPLEMENTED();   // FIXME
+        break;
+      case EGL_PIXEL_ASPECT_RATIO:
+        *value = eglSurface->getPixelAspectRatio();
+        break;
+      case EGL_RENDER_BUFFER:
+        *value = eglSurface->getRenderBuffer();
+        break;
+      case EGL_SWAP_BEHAVIOR:
+        *value = eglSurface->getSwapBehavior();
+        break;
+      case EGL_TEXTURE_FORMAT:
+        *value = eglSurface->getTextureFormat();
+        break;
+      case EGL_TEXTURE_TARGET:
+        *value = eglSurface->getTextureTarget();
+        break;
+      case EGL_VERTICAL_RESOLUTION:
+        UNIMPLEMENTED();   // FIXME
+        break;
+      case EGL_WIDTH:
+        *value = eglSurface->getWidth();
+        break;
+      case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
+        *value = eglSurface->isPostSubBufferSupported();
+        break;
+      case EGL_FIXED_SIZE_ANGLE:
+        *value = eglSurface->isFixedSize();
+        break;
+      default:
+        return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+    }
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
@@ -491,114 +474,79 @@
     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)",
           dpy, surface, attribute, value);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = (egl::Surface*)surface;
+
+    if (!validateSurface(display, eglSurface))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = (egl::Surface*)surface;
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        if (surface == EGL_NO_SURFACE)
-        {
-            return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
-        }
-
-        switch (attribute)
-        {
-          case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
-            {
-                rx::SwapChain *swapchain = eglSurface->getSwapChain();
-                *value = (void*) (swapchain ? swapchain->getShareHandle() : NULL);
-            }
-            break;
-          default:
-            return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-        }
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (surface == EGL_NO_SURFACE)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
     }
+
+    switch (attribute)
+    {
+      case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+        {
+            rx::SwapChain *swapchain = eglSurface->getSwapChain();
+            *value = (void*) (swapchain ? swapchain->getShareHandle() : NULL);
+        }
+        break;
+      default:
+        return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+    }
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglBindAPI(EGLenum api)
 {
     EVENT("(EGLenum api = 0x%X)", api);
 
-    try
+    switch (api)
     {
-        switch (api)
-        {
-          case EGL_OPENGL_API:
-          case EGL_OPENVG_API:
-            return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation
-          case EGL_OPENGL_ES_API:
-            break;
-          default:
-            return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
-        }
-
-        egl::setCurrentAPI(api);
-
-        return egl::success(EGL_TRUE);
+      case EGL_OPENGL_API:
+      case EGL_OPENVG_API:
+        return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation
+      case EGL_OPENGL_ES_API:
+        break;
+      default:
+        return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
     }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+
+    egl::setCurrentAPI(api);
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLenum __stdcall eglQueryAPI(void)
 {
     EVENT("()");
 
-    try
-    {
-        EGLenum API = egl::getCurrentAPI();
+    EGLenum API = egl::getCurrentAPI();
 
-        return egl::success(API);
-    }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+    return egl::success(API);
 }
 
 EGLBoolean __stdcall eglWaitClient(void)
 {
     EVENT("()");
 
-    try
-    {
-        UNIMPLEMENTED();   // FIXME
+    UNIMPLEMENTED();   // FIXME
 
-        return egl::success(0);
-    }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+    return egl::success(0);
 }
 
 EGLBoolean __stdcall eglReleaseThread(void)
 {
     EVENT("()");
 
-    try
-    {
-        eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+    eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
 
-        return egl::success(EGL_TRUE);
-    }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+    return egl::success(EGL_TRUE);
 }
 
 EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
@@ -607,26 +555,19 @@
           "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
           dpy, buftype, buffer, config, attrib_list);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (!validateConfig(display, config))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!validateConfig(display, config))
-        {
-            return EGL_NO_SURFACE;
-        }
-
-        if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
-        {
-            return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
-        }
-
-        return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
+        return EGL_NO_SURFACE;
     }
-    catch (...)
+
+    if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+        return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
     }
+
+    return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
 }
 
 EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
@@ -634,145 +575,117 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
           dpy, surface, attribute, value);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+    if (!validateSurface(display, eglSurface))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        UNIMPLEMENTED();   // FIXME
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+
+    UNIMPLEMENTED();   // FIXME
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+    if (!validateSurface(display, eglSurface))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        if (buffer != EGL_BACK_BUFFER)
-        {
-            return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
-        }
-
-        if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
-        {
-            return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
-        }
-
-        if (eglSurface->getBoundTexture())
-        {
-            return egl::error(EGL_BAD_ACCESS, EGL_FALSE);
-        }
-
-        if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
-        {
-            return egl::error(EGL_BAD_MATCH, EGL_FALSE);
-        }
-
-        if (!glBindTexImage(eglSurface))
-        {
-            return egl::error(EGL_BAD_MATCH, EGL_FALSE);
-        }
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (buffer != EGL_BACK_BUFFER)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
     }
+
+    if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
+    {
+        return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    if (eglSurface->getBoundTexture())
+    {
+        return egl::error(EGL_BAD_ACCESS, EGL_FALSE);
+    }
+
+    if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+    {
+        return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+    }
+
+    if (!glBindTexImage(eglSurface))
+    {
+        return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+    }
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+    if (!validateSurface(display, eglSurface))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        if (buffer != EGL_BACK_BUFFER)
-        {
-            return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
-        }
-
-        if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
-        {
-            return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
-        }
-
-        if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
-        {
-            return egl::error(EGL_BAD_MATCH, EGL_FALSE);
-        }
-
-        gl::Texture2D *texture = eglSurface->getBoundTexture();
-
-        if (texture)
-        {
-            texture->releaseTexImage();
-        }
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (buffer != EGL_BACK_BUFFER)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
     }
+
+    if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
+    {
+        return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+    {
+        return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+    }
+
+    gl::Texture2D *texture = eglSurface->getBoundTexture();
+
+    if (texture)
+    {
+        texture->releaseTexImage();
+    }
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (!validateDisplay(display))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (!validateDisplay(display))
-        {
-            return EGL_FALSE;
-        }
-
-        egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
-
-        if (draw_surface == NULL)
-        {
-            return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
-        }
-        
-        draw_surface->setSwapInterval(interval);
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
+
+    if (draw_surface == NULL)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
     }
+
+    draw_surface->setSwapInterval(interval);
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
@@ -780,111 +693,97 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
 
-    try
-    {
-        // Get the requested client version (default is 1) and check it is 2 or 3.
-        EGLint client_version = 1;
-        bool reset_notification = false;
-        bool robust_access = false;
+    // Get the requested client version (default is 1) and check it is 2 or 3.
+    EGLint client_version = 1;
+    bool reset_notification = false;
+    bool robust_access = false;
 
-        if (attrib_list)
+    if (attrib_list)
+    {
+        for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
         {
-            for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
+            switch (attribute[0])
             {
-                switch (attribute[0])
+              case EGL_CONTEXT_CLIENT_VERSION:
+                client_version = attribute[1];
+                break;
+              case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
+                if (attribute[1] == EGL_TRUE)
                 {
-                  case EGL_CONTEXT_CLIENT_VERSION:
-                    client_version = attribute[1];
-                    break;
-                  case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
-                    if (attribute[1] == EGL_TRUE)
-                    {
-                        return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);   // Unimplemented
-                        // robust_access = true;
-                    }
-                    else if (attribute[1] != EGL_FALSE)
-                        return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
-                    break;
-                  case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
-                    if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
-                        reset_notification = true;
-                    else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
-                        return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
-                    break;
-                  default:
-                    return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+                    return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);   // Unimplemented
+                    // robust_access = true;
                 }
+                else if (attribute[1] != EGL_FALSE)
+                    return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+                break;
+              case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
+                if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
+                    reset_notification = true;
+                else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
+                    return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+                break;
+              default:
+                return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
             }
         }
-
-        if (client_version != 2 && client_version != 3)
-        {
-            return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
-        }
-
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-
-        if (share_context)
-        {
-            gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context);
-
-            if (sharedGLContext->isResetNotificationEnabled() != reset_notification)
-            {
-                return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
-            }
-
-            if (sharedGLContext->getClientVersion() != client_version)
-            {
-                return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
-            }
-
-            // Can not share contexts between displays
-            if (sharedGLContext->getRenderer() != display->getRenderer())
-            {
-                return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
-            }
-        }
-
-        if (!validateConfig(display, config))
-        {
-            return EGL_NO_CONTEXT;
-        }
-
-        return display->createContext(config, client_version, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
     }
-    catch (...)
+
+    if (client_version != 2 && client_version != 3)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+        return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
     }
+
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+
+    if (share_context)
+    {
+        gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context);
+
+        if (sharedGLContext->isResetNotificationEnabled() != reset_notification)
+        {
+            return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+        }
+
+        if (sharedGLContext->getClientVersion() != client_version)
+        {
+            return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
+        }
+
+        // Can not share contexts between displays
+        if (sharedGLContext->getRenderer() != display->getRenderer())
+        {
+            return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+        }
+    }
+
+    if (!validateConfig(display, config))
+    {
+        return EGL_NO_CONTEXT;
+    }
+
+    return display->createContext(config, client_version, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
 }
 
 EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    gl::Context *context = static_cast<gl::Context*>(ctx);
+
+    if (!validateContext(display, context))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        gl::Context *context = static_cast<gl::Context*>(ctx);
-
-        if (!validateContext(display, context))
-        {
-            return EGL_FALSE;
-        }
-
-        if (ctx == EGL_NO_CONTEXT)
-        {
-            return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
-        }
-
-        display->destroyContext(context);
-
-        return egl::success(EGL_TRUE);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (ctx == EGL_NO_CONTEXT)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
     }
+
+    display->destroyContext(context);
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
@@ -892,95 +791,81 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
           dpy, draw, read, ctx);
 
-    try
-    {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        gl::Context *context = static_cast<gl::Context*>(ctx);
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    gl::Context *context = static_cast<gl::Context*>(ctx);
 
-        if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
+    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 && display->isInitialized())
+    {
+        rx::Renderer *renderer = display->getRenderer();
+        if (renderer->testDeviceLost(true))
         {
             return EGL_FALSE;
         }
 
-        if (dpy != EGL_NO_DISPLAY)
+        if (renderer->isDeviceLost())
         {
-            rx::Renderer *renderer = display->getRenderer();
-            if (renderer->testDeviceLost(true))
-            {
-                return EGL_FALSE;
-            }
-
-            if (renderer->isDeviceLost())
-            {
-                return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
-            }
+            return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
         }
-
-        if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) ||
-            (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read))))
-        {
-            return EGL_FALSE;
-        }
-
-        if (draw != read)
-        {
-            UNIMPLEMENTED();   // FIXME
-        }
-
-        egl::setCurrentDisplay(dpy);
-        egl::setCurrentDrawSurface(draw);
-        egl::setCurrentReadSurface(read);
-
-        glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
-
-        return egl::success(EGL_TRUE);
     }
-    catch (...)
+
+    if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) ||
+        (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read))))
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return EGL_FALSE;
     }
+
+    if (draw != read)
+    {
+        UNIMPLEMENTED();   // FIXME
+    }
+
+    egl::setCurrentDisplay(dpy);
+    egl::setCurrentDrawSurface(draw);
+    egl::setCurrentReadSurface(read);
+
+    glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
+
+    return egl::success(EGL_TRUE);
 }
 
 EGLContext __stdcall eglGetCurrentContext(void)
 {
     EVENT("()");
 
-    try
-    {
-        EGLContext context = glGetCurrentContext();
+    EGLContext context = glGetCurrentContext();
 
-        return egl::success(context);
-    }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
-    }
+    return egl::success(context);
 }
 
 EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
 {
     EVENT("(EGLint readdraw = %d)", readdraw);
 
-    try
+    if (readdraw == EGL_READ)
     {
-        if (readdraw == EGL_READ)
-        {
-            EGLSurface read = egl::getCurrentReadSurface();
-            return egl::success(read);
-        }
-        else if (readdraw == EGL_DRAW)
-        {
-            EGLSurface draw = egl::getCurrentDrawSurface();
-            return egl::success(draw);
-        }
-        else
-        {
-            return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
-        }
+        EGLSurface read = egl::getCurrentReadSurface();
+        return egl::success(read);
     }
-    catch (...)
+    else if (readdraw == EGL_DRAW)
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+        EGLSurface draw = egl::getCurrentDrawSurface();
+        return egl::success(draw);
+    }
+    else
+    {
+        return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
     }
 }
 
@@ -988,16 +873,9 @@
 {
     EVENT("()");
 
-    try
-    {
-        EGLDisplay dpy = egl::getCurrentDisplay();
+    EGLDisplay dpy = egl::getCurrentDisplay();
 
-        return egl::success(dpy);
-    }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
-    }
+    return egl::success(dpy);
 }
 
 EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
@@ -1005,90 +883,62 @@
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
           dpy, ctx, attribute, value);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    gl::Context *context = static_cast<gl::Context*>(ctx);
+
+    if (!validateContext(display, context))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        gl::Context *context = static_cast<gl::Context*>(ctx);
-
-        if (!validateContext(display, context))
-        {
-            return EGL_FALSE;
-        }
-
-        UNIMPLEMENTED();   // FIXME
-
-        return egl::success(0);
+        return EGL_FALSE;
     }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+
+    UNIMPLEMENTED();   // FIXME
+
+    return egl::success(0);
 }
 
 EGLBoolean __stdcall eglWaitGL(void)
 {
     EVENT("()");
 
-    try
-    {
-        UNIMPLEMENTED();   // FIXME
+    UNIMPLEMENTED();   // FIXME
 
-        return egl::success(0);
-    }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+    return egl::success(0);
 }
 
 EGLBoolean __stdcall eglWaitNative(EGLint engine)
 {
     EVENT("(EGLint engine = %d)", engine);
 
-    try
-    {
-        UNIMPLEMENTED();   // FIXME
+    UNIMPLEMENTED();   // FIXME
 
-        return egl::success(0);
-    }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
-    }
+    return egl::success(0);
 }
 
 EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = (egl::Surface*)surface;
+
+    if (!validateSurface(display, eglSurface))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = (egl::Surface*)surface;
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        if (display->getRenderer()->isDeviceLost())
-        {
-            return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
-        }
-
-        if (surface == EGL_NO_SURFACE)
-        {
-            return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
-        }
-
-        if (eglSurface->swap())
-        {
-            return egl::success(EGL_TRUE);
-        }
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (display->getRenderer()->isDeviceLost())
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+    }
+
+    if (surface == EGL_NO_SURFACE)
+    {
+        return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    if (eglSurface->swap())
+    {
+        return egl::success(EGL_TRUE);
     }
 
     return EGL_FALSE;
@@ -1098,68 +948,54 @@
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
 
-    try
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+    if (!validateSurface(display, eglSurface))
     {
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        if (display->getRenderer()->isDeviceLost())
-        {
-            return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
-        }
-
-        UNIMPLEMENTED();   // FIXME
-
-        return egl::success(0);
+        return EGL_FALSE;
     }
-    catch (...)
+
+    if (display->getRenderer()->isDeviceLost())
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
     }
+
+    UNIMPLEMENTED();   // FIXME
+
+    return egl::success(0);
 }
 
 EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height);
 
-    try
+    if (x < 0 || y < 0 || width < 0 || height < 0)
     {
-        if (x < 0 || y < 0 || width < 0 || height < 0)
-        {
-            return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
-        }
-
-        egl::Display *display = static_cast<egl::Display*>(dpy);
-        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-        if (!validateSurface(display, eglSurface))
-        {
-            return EGL_FALSE;
-        }
-
-        if (display->getRenderer()->isDeviceLost())
-        {
-            return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
-        }
-
-        if (surface == EGL_NO_SURFACE)
-        {
-            return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
-        }
-
-        if (eglSurface->postSubBuffer(x, y, width, height))
-        {
-            return egl::success(EGL_TRUE);
-        }
+        return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
     }
-    catch (...)
+
+    egl::Display *display = static_cast<egl::Display*>(dpy);
+    egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+    if (!validateSurface(display, eglSurface))
     {
-        return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
+        return EGL_FALSE;
+    }
+
+    if (display->getRenderer()->isDeviceLost())
+    {
+        return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+    }
+
+    if (surface == EGL_NO_SURFACE)
+    {
+        return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    if (eglSurface->postSubBuffer(x, y, width, height))
+    {
+        return egl::success(EGL_TRUE);
     }
 
     return EGL_FALSE;
@@ -1169,34 +1005,28 @@
 {
     EVENT("(const char *procname = \"%s\")", procname);
 
-    try
+    struct Extension
     {
-        struct Extension
-        {
-            const char *name;
-            __eglMustCastToProperFunctionPointerType address;
-        };
+        const char *name;
+        __eglMustCastToProperFunctionPointerType address;
+    };
 
-        static const Extension eglExtensions[] =
-        {
-            {"eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE},
-            {"eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV},
-            {"", NULL},
-        };
+    static const Extension eglExtensions[] =
+    {
+        { "eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE },
+        { "eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV },
+        { "eglGetPlatformDisplayEXT", (__eglMustCastToProperFunctionPointerType)eglGetPlatformDisplayEXT },
+        { "", NULL },
+    };
 
-        for (unsigned int ext = 0; ext < ArraySize(eglExtensions); ext++)
+    for (unsigned int ext = 0; ext < ArraySize(eglExtensions); ext++)
+    {
+        if (strcmp(procname, eglExtensions[ext].name) == 0)
         {
-            if (strcmp(procname, eglExtensions[ext].name) == 0)
-            {
-                return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
-            }
+            return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
         }
+    }
 
-        return glGetProcAddress(procname);
-    }
-    catch (...)
-    {
-        return egl::error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
-    }
+    return glGetProcAddress(procname);
 }
 }
diff --git a/src/libEGL/libEGL.def b/src/libEGL/libEGL.def
index 71a5e67..d7949d0 100644
--- a/src/libEGL/libEGL.def
+++ b/src/libEGL/libEGL.def
@@ -1,36 +1,41 @@
-LIBRARY	libEGL
+LIBRARY libEGL
 EXPORTS
-	eglBindAPI                      @14
-	eglBindTexImage                 @20
-	eglChooseConfig                 @7
-	eglCopyBuffers                  @33
-	eglCreateContext                @23
-	eglCreatePbufferFromClientBuffer        @18
-	eglCreatePbufferSurface         @10
-	eglCreatePixmapSurface          @11
-	eglCreateWindowSurface          @9
-	eglDestroyContext               @24
-	eglDestroySurface               @12
-	eglGetConfigAttrib              @8
-	eglGetConfigs                   @6
-	eglGetCurrentContext            @26
-	eglGetCurrentDisplay            @28
-	eglGetCurrentSurface            @27
-	eglGetDisplay                   @2
-	eglGetError                     @1
-	eglGetProcAddress               @34
-	eglInitialize                   @3
-	eglMakeCurrent                  @25
-	eglQueryAPI                     @15
-	eglQueryContext                 @29
-	eglQueryString                  @5
-	eglQuerySurface                 @13
-	eglReleaseTexImage              @21
-	eglReleaseThread                @17
-	eglSurfaceAttrib                @19
-	eglSwapBuffers                  @32
-	eglSwapInterval                 @22
-	eglTerminate                    @4
-	eglWaitClient                   @16
-	eglWaitGL                       @30
-	eglWaitNative                   @31
\ No newline at end of file
+    eglBindAPI                       @14
+    eglBindTexImage                  @20
+    eglChooseConfig                  @7
+    eglCopyBuffers                   @33
+    eglCreateContext                 @23
+    eglCreatePbufferFromClientBuffer @18
+    eglCreatePbufferSurface          @10
+    eglCreatePixmapSurface           @11
+    eglCreateWindowSurface           @9
+    eglDestroyContext                @24
+    eglDestroySurface                @12
+    eglGetConfigAttrib               @8
+    eglGetConfigs                    @6
+    eglGetCurrentContext             @26
+    eglGetCurrentDisplay             @28
+    eglGetCurrentSurface             @27
+    eglGetDisplay                    @2
+    eglGetError                      @1
+    eglGetProcAddress                @34
+    eglInitialize                    @3
+    eglMakeCurrent                   @25
+    eglQueryAPI                      @15
+    eglQueryContext                  @29
+    eglQueryString                   @5
+    eglQuerySurface                  @13
+    eglReleaseTexImage               @21
+    eglReleaseThread                 @17
+    eglSurfaceAttrib                 @19
+    eglSwapBuffers                   @32
+    eglSwapInterval                  @22
+    eglTerminate                     @4
+    eglWaitClient                    @16
+    eglWaitGL                        @30
+    eglWaitNative                    @31
+
+    ; Extensions
+    eglGetPlatformDisplayEXT         @35
+    eglQuerySurfacePointerANGLE      @36
+    eglPostSubBufferNV               @37
diff --git a/src/libEGL/main.cpp b/src/libEGL/main.cpp
index 80dcc34..0f8439c 100644
--- a/src/libEGL/main.cpp
+++ b/src/libEGL/main.cpp
@@ -9,42 +9,42 @@
 #include "libEGL/main.h"
 
 #include "common/debug.h"
+#include "common/tls.h"
 
-static DWORD currentTLS = TLS_OUT_OF_INDEXES;
+static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
 
 namespace egl
 {
 
 Current *AllocateCurrent()
 {
-    Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
-
-    if (!current)
+    ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
+    if (currentTLS == TLS_OUT_OF_INDEXES)
     {
-        ERR("Could not allocate thread local storage.");
         return NULL;
     }
 
-    ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
-    TlsSetValue(currentTLS, current);
-
+    Current *current = new Current();
     current->error = EGL_SUCCESS;
     current->API = EGL_OPENGL_ES_API;
     current->display = EGL_NO_DISPLAY;
     current->drawSurface = EGL_NO_SURFACE;
     current->readSurface = EGL_NO_SURFACE;
 
+    if (!SetTLSValue(currentTLS, current))
+    {
+        ERR("Could not set thread local storage.");
+        return NULL;
+    }
+
     return current;
 }
 
 void DeallocateCurrent()
 {
-    void *current = TlsGetValue(currentTLS);
-
-    if (current)
-    {
-        LocalFree((HLOCAL)current);
-    }
+    Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
+    SafeDelete(current);
+    SetTLSValue(currentTLS, NULL);
 }
 
 }
@@ -70,14 +70,13 @@
             }
 #endif
 
-            currentTLS = TlsAlloc();
-
+            currentTLS = CreateTLSIndex();
             if (currentTLS == TLS_OUT_OF_INDEXES)
             {
                 return FALSE;
             }
         }
-        // Fall throught to initialize index
+        // Fall through to initialize index
       case DLL_THREAD_ATTACH:
         {
             egl::AllocateCurrent();
@@ -91,7 +90,7 @@
       case DLL_PROCESS_DETACH:
         {
             egl::DeallocateCurrent();
-            TlsFree(currentTLS);
+            DestroyTLSIndex(currentTLS);
         }
         break;
       default:
@@ -106,7 +105,7 @@
 
 Current *GetCurrentData()
 {
-    Current *current = (Current*)TlsGetValue(currentTLS);
+    Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
 
     // ANGLE issue 488: when the dll is loaded after thread initialization,
     // thread local storage (current) might not exist yet.
diff --git a/src/libEGL/main.h b/src/libEGL/main.h
index 77da8f0..07f5b9e 100644
--- a/src/libEGL/main.h
+++ b/src/libEGL/main.h
@@ -9,7 +9,6 @@
 #ifndef LIBEGL_MAIN_H_
 #define LIBEGL_MAIN_H_
 
-#define EGLAPI
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index b2dce12..7f238af 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -7,15 +7,302 @@
     {
         'angle_enable_d3d9%': 1,
         'angle_enable_d3d11%': 1,
-    },
-    'target_defaults':
-    {
-        'defines':
+        # These file lists are shared with the GN build.
+        'angle_libangle_sources':
         [
-            'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }',
+            '../include/EGL/egl.h',
+            '../include/EGL/eglext.h',
+            '../include/EGL/eglplatform.h',
+            '../include/GLES2/gl2.h',
+            '../include/GLES2/gl2ext.h',
+            '../include/GLES2/gl2platform.h',
+            '../include/GLES3/gl3.h',
+            '../include/GLES3/gl3ext.h',
+            '../include/GLES3/gl3platform.h',
+            '../include/GLSLANG/ShaderLang.h',
+            '../include/GLSLANG/ShaderVars.h',
+            '../include/KHR/khrplatform.h',
+            '../include/angle_gl.h',
+            'common/RefCountObject.cpp',
+            'common/RefCountObject.h',
+            'common/angleutils.cpp',
+            'common/angleutils.h',
+            'common/blocklayout.cpp',
+            'common/blocklayout.h',
+            'common/debug.cpp',
+            'common/debug.h',
+            'common/event_tracer.cpp',
+            'common/event_tracer.h',
+            'common/mathutil.cpp',
+            'common/mathutil.h',
+            'common/platform.h',
+            'common/tls.cpp',
+            'common/tls.h',
+            'common/utilities.cpp',
+            'common/utilities.h',
+            'common/version.h',
+            'libGLESv2/BinaryStream.h',
+            'libGLESv2/Buffer.cpp',
+            'libGLESv2/Buffer.h',
+            'libGLESv2/Caps.cpp',
+            'libGLESv2/Caps.h',
+            'libGLESv2/Context.cpp',
+            'libGLESv2/Context.h',
+            'libGLESv2/Error.cpp',
+            'libGLESv2/Error.h',
+            'libGLESv2/Fence.cpp',
+            'libGLESv2/Fence.h',
+            'libGLESv2/Float16ToFloat32.cpp',
+            'libGLESv2/Framebuffer.cpp',
+            'libGLESv2/Framebuffer.h',
+            'libGLESv2/FramebufferAttachment.cpp',
+            'libGLESv2/FramebufferAttachment.h',
+            'libGLESv2/HandleAllocator.cpp',
+            'libGLESv2/HandleAllocator.h',
+            'libGLESv2/ImageIndex.h',
+            'libGLESv2/ImageIndex.cpp',
+            'libGLESv2/Program.cpp',
+            'libGLESv2/Program.h',
+            'libGLESv2/ProgramBinary.cpp',
+            'libGLESv2/ProgramBinary.h',
+            'libGLESv2/Query.cpp',
+            'libGLESv2/Query.h',
+            'libGLESv2/Renderbuffer.cpp',
+            'libGLESv2/Renderbuffer.h',
+            'libGLESv2/ResourceManager.cpp',
+            'libGLESv2/ResourceManager.h',
+            'libGLESv2/Sampler.cpp',
+            'libGLESv2/Sampler.h',
+            'libGLESv2/Shader.cpp',
+            'libGLESv2/Shader.h',
+            'libGLESv2/State.cpp',
+            'libGLESv2/State.h',
+            'libGLESv2/Texture.cpp',
+            'libGLESv2/Texture.h',
+            'libGLESv2/TransformFeedback.cpp',
+            'libGLESv2/TransformFeedback.h',
+            'libGLESv2/Uniform.cpp',
+            'libGLESv2/Uniform.h',
+            'libGLESv2/VertexArray.cpp',
+            'libGLESv2/VertexArray.h',
+            'libGLESv2/VertexAttribute.cpp',
+            'libGLESv2/VertexAttribute.h',
+            'libGLESv2/angletypes.cpp',
+            'libGLESv2/angletypes.h',
+            'libGLESv2/constants.h',
+            'libGLESv2/formatutils.cpp',
+            'libGLESv2/formatutils.h',
+            'libGLESv2/main.cpp',
+            'libGLESv2/main.h',
+            'libGLESv2/queryconversions.cpp',
+            'libGLESv2/queryconversions.h',
+            'libGLESv2/renderer/BufferImpl.h',
+            'libGLESv2/renderer/FenceImpl.h',
+            'libGLESv2/renderer/Image.cpp',
+            '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',
+            'libGLESv2/renderer/loadimage.cpp',
+            'libGLESv2/renderer/loadimage.h',
+            'libGLESv2/renderer/loadimage.inl',
+            'libGLESv2/renderer/loadimageSSE2.cpp',
+            'libGLESv2/renderer/vertexconversion.h',
+            'libGLESv2/resource.h',
+            'libGLESv2/validationES.cpp',
+            'libGLESv2/validationES.h',
+            'libGLESv2/validationES2.cpp',
+            'libGLESv2/validationES2.h',
+            'libGLESv2/validationES3.cpp',
+            'libGLESv2/validationES3.h',
+            'third_party/murmurhash/MurmurHash3.cpp',
+            'third_party/murmurhash/MurmurHash3.h',
+            'third_party/systeminfo/SystemInfo.cpp',
+            'third_party/systeminfo/SystemInfo.h',
         ],
+        'angle_d3d_shared_sources':
+        [
+            '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',
+            'libGLESv2/renderer/d3d/ImageD3D.h',
+            'libGLESv2/renderer/d3d/IndexBuffer.cpp',
+            'libGLESv2/renderer/d3d/IndexBuffer.h',
+            'libGLESv2/renderer/d3d/IndexDataManager.cpp',
+            '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',
+            'libGLESv2/renderer/d3d/VertexDataManager.h',
+        ],
+        'angle_d3d9_sources':
+        [
+            'libGLESv2/renderer/d3d/d3d9/Blit9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/Blit9.h',
+            'libGLESv2/renderer/d3d/d3d9/Buffer9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/Buffer9.h',
+            'libGLESv2/renderer/d3d/d3d9/Fence9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/Fence9.h',
+            'libGLESv2/renderer/d3d/d3d9/formatutils9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/formatutils9.h',
+            'libGLESv2/renderer/d3d/d3d9/Image9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/Image9.h',
+            'libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h',
+            'libGLESv2/renderer/d3d/d3d9/Query9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/Query9.h',
+            'libGLESv2/renderer/d3d/d3d9/Renderer9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/Renderer9.h',
+            'libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp',
+            'libGLESv2/renderer/d3d/d3d9/renderer9_utils.h',
+            'libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/RenderTarget9.h',
+            'libGLESv2/renderer/d3d/d3d9/ShaderCache.h',
+            'libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h',
+            'libGLESv2/renderer/d3d/d3d9/shaders/compiled/flipyvs.h',
+            'libGLESv2/renderer/d3d/d3d9/shaders/compiled/luminanceps.h',
+            'libGLESv2/renderer/d3d/d3d9/shaders/compiled/passthroughps.h',
+            'libGLESv2/renderer/d3d/d3d9/shaders/compiled/standardvs.h',
+            'libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/SwapChain9.h',
+            'libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/TextureStorage9.h',
+            'libGLESv2/renderer/d3d/d3d9/VertexArray9.h',
+            'libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp',
+            'libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h',
+            'libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp',
+            'libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h',
+        ],
+        'angle_d3d11_sources':
+        [
+            'libGLESv2/renderer/d3d/d3d11/Blit11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/Blit11.h',
+            'libGLESv2/renderer/d3d/d3d11/Buffer11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/Buffer11.h',
+            'libGLESv2/renderer/d3d/d3d11/Clear11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/Clear11.h',
+            'libGLESv2/renderer/d3d/d3d11/Fence11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/Fence11.h',
+            'libGLESv2/renderer/d3d/d3d11/formatutils11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/formatutils11.h',
+            'libGLESv2/renderer/d3d/d3d11/Image11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/Image11.h',
+            'libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h',
+            'libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp',
+            'libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h',
+            'libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h',
+            'libGLESv2/renderer/d3d/d3d11/Query11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/Query11.h',
+            'libGLESv2/renderer/d3d/d3d11/Renderer11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/Renderer11.h',
+            'libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp',
+            'libGLESv2/renderer/d3d/d3d11/renderer11_utils.h',
+            'libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp',
+            'libGLESv2/renderer/d3d/d3d11/RenderStateCache.h',
+            'libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/RenderTarget11.h',
+            'libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h',
+            'libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h',
+            'libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/SwapChain11.h',
+            'libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/TextureStorage11.h',
+            'libGLESv2/renderer/d3d/d3d11/VertexArray11.h',
+            'libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp',
+            'libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h',
+        ]
     },
-
+    # Everything below this is duplicated in the GN build. If you change
+    # anything also change angle/BUILD.gn
     'conditions':
     [
         ['OS=="win"',
@@ -23,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':
@@ -35,62 +323,85 @@
                     ],
                     'sources':
                     [
-                        '<!@(python <(angle_path)/enumerate_files.py \
-                             -dirs common libGLESv2 third_party/murmurhash ../include third_party/systeminfo \
-                             -types *.cpp *.h *.hlsl *.vs *.ps *.bat *.def *.rc \
-                             -excludes */d3d/* */d3d9/* */d3d11/*)',
+                        '<@(angle_libangle_sources)',
                     ],
                     'defines':
                     [
                         'GL_APICALL=',
                         'GL_GLEXT_PROTOTYPES=',
                         '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',
+                        {
+                            'sources':
+                            [
+                                '<@(angle_d3d_shared_sources)',
+                            ],
+                        }],
                         ['angle_enable_d3d9==1',
                         {
                             'sources':
                             [
-                                '<!@(python <(angle_path)/enumerate_files.py \
-                                     -dirs libGLESv2/renderer/d3d libGLESv2/renderer/d3d9 \
-                                     -types *.cpp *.h *.vs *.ps *.bat)',
+                                '<@(angle_d3d9_sources)',
                             ],
                             'defines':
                             [
                                 'ANGLE_ENABLE_D3D9',
                             ],
-                            'msvs_settings':
+                            'link_settings':
                             {
-                                'VCLinkerTool':
+                                'msvs_settings':
                                 {
-                                    'AdditionalDependencies':
-                                    [
-                                        'd3d9.lib',
-                                    ]
-                                }
+                                    'VCLinkerTool':
+                                    {
+                                        'AdditionalDependencies':
+                                        [
+                                            'd3d9.lib',
+                                        ]
+                                    }
+                                },
                             },
                         }],
                         ['angle_enable_d3d11==1',
                         {
                             'sources':
                             [
-                                '<!@(python <(angle_path)/enumerate_files.py \
-                                     -dirs libGLESv2/renderer/d3d libGLESv2/renderer/d3d11 \
-                                     -types *.cpp *.h *.hlsl *.bat)',
+                                '<@(angle_d3d11_sources)',
                             ],
                             'defines':
                             [
                                 'ANGLE_ENABLE_D3D11',
                             ],
-                            'msvs_settings':
+                            'link_settings':
                             {
-                                'VCLinkerTool':
+                                'msvs_settings':
                                 {
-                                    'AdditionalDependencies':
-                                    [
-                                        'dxguid.lib',
-                                    ],
+                                    'VCLinkerTool':
+                                    {
+                                        'AdditionalDependencies':
+                                        [
+                                            'dxguid.lib',
+                                        ]
+                                    }
                                 },
                             },
                         }],
@@ -117,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 253c1eb..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
 {
 
@@ -165,7 +169,7 @@
         write(v.c_str(), v.length());
     }
 
-    void writeBytes(unsigned char *bytes, size_t count)
+    void writeBytes(const unsigned char *bytes, size_t count)
     {
         write(bytes, count);
     }
diff --git a/src/libGLESv2/Buffer.cpp b/src/libGLESv2/Buffer.cpp
index e7d2c00..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
@@ -10,185 +9,120 @@
 // [OpenGL ES 2.0.24] section 2.9 page 21.
 
 #include "libGLESv2/Buffer.h"
-
-#include "libGLESv2/renderer/VertexBuffer.h"
-#include "libGLESv2/renderer/IndexBuffer.h"
-#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/BufferImpl.h"
 #include "libGLESv2/renderer/Renderer.h"
 
 namespace gl
 {
 
-Buffer::Buffer(rx::Renderer *renderer, GLuint id)
+Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
     : RefCountObject(id),
-      mRenderer(renderer),
+      mBuffer(impl),
       mUsage(GL_DYNAMIC_DRAW),
+      mSize(0),
       mAccessFlags(0),
       mMapped(GL_FALSE),
       mMapPointer(NULL),
       mMapOffset(0),
-      mMapLength(0),
-      mBufferStorage(NULL),
-      mStaticVertexBuffer(NULL),
-      mStaticIndexBuffer(NULL),
-      mUnmodifiedDataUse(0)
+      mMapLength(0)
 {
-    mBufferStorage = renderer->createBufferStorage();
 }
 
 Buffer::~Buffer()
 {
-    delete mBufferStorage;
-    delete mStaticVertexBuffer;
-    delete mStaticIndexBuffer;
+    SafeDelete(mBuffer);
 }
 
-void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
+Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
 {
-    mBufferStorage->clear();
-    mIndexRangeCache.clear();
-    mBufferStorage->setData(data, size, 0);
-
-    mUsage = usage;
-
-    invalidateStaticData();
-
-    if (usage == GL_STATIC_DRAW)
+    gl::Error error = mBuffer->setData(data, size, usage);
+    if (error.isError())
     {
-        mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer);
-        mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer);
+        return error;
     }
+
+    mIndexRangeCache.clear();
+    mUsage = usage;
+    mSize = size;
+
+    return error;
 }
 
-void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
+Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
 {
-    mBufferStorage->setData(data, size, offset);
+    gl::Error error = mBuffer->setSubData(data, size, offset);
+    if (error.isError())
+    {
+        return error;
+    }
+
     mIndexRangeCache.invalidateRange(offset, size);
-    invalidateStaticData();
+
+    return error;
 }
 
-void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
 {
-    mBufferStorage->copyData(source->mBufferStorage, size, sourceOffset, destOffset);
-    invalidateStaticData();
+    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 = mBufferStorage->map(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) + offset);
     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);
 
-    mBufferStorage->unmap();
+    Error error = mBuffer->unmap();
+    if (error.isError())
+    {
+        return error;
+    }
 
     mMapped = GL_FALSE;
     mMapPointer = NULL;
     mMapOffset = 0;
     mMapLength = 0;
     mAccessFlags = 0;
-}
 
-rx::BufferStorage *Buffer::getStorage() const
-{
-    return mBufferStorage;
-}
-
-GLint64 Buffer::size() const
-{
-    return static_cast<GLint64>(mBufferStorage->getSize());
-}
-
-GLenum Buffer::usage() const
-{
-    return mUsage;
-}
-
-GLint Buffer::accessFlags() const
-{
-    return mAccessFlags;
-}
-
-GLboolean Buffer::mapped() const
-{
-    return mMapped;
-}
-
-GLvoid *Buffer::mapPointer() const
-{
-    return mMapPointer;
-}
-
-GLint64 Buffer::mapOffset() const
-{
-    return mMapOffset;
-}
-
-GLint64 Buffer::mapLength() const
-{
-    return mMapLength;
+    return error;
 }
 
 void Buffer::markTransformFeedbackUsage()
 {
-    mBufferStorage->markTransformFeedbackUsage();
-    invalidateStaticData();
-}
-
-rx::StaticVertexBufferInterface *Buffer::getStaticVertexBuffer()
-{
-    return mStaticVertexBuffer;
-}
-
-rx::StaticIndexBufferInterface *Buffer::getStaticIndexBuffer()
-{
-    return mStaticIndexBuffer;
-}
-
-void Buffer::invalidateStaticData()
-{
-    if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
-    {
-        delete mStaticVertexBuffer;
-        mStaticVertexBuffer = NULL;
-
-        delete mStaticIndexBuffer;
-        mStaticIndexBuffer = NULL;
-    }
-
-    mUnmodifiedDataUse = 0;
-}
-
-// Creates static buffers if sufficient used data has been left unmodified
-void Buffer::promoteStaticUsage(int dataSize)
-{
-    if (!mStaticVertexBuffer && !mStaticIndexBuffer)
-    {
-        mUnmodifiedDataUse += dataSize;
-
-        if (mUnmodifiedDataUse > 3 * mBufferStorage->getSize())
-        {
-            mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer);
-            mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer);
-        }
-    }
-}
-
-rx::IndexRangeCache *Buffer::getIndexRangeCache()
-{
-    return &mIndexRangeCache;
+    // 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 55fbdeb..35a6767 100644
--- a/src/libGLESv2/Buffer.h
+++ b/src/libGLESv2/Buffer.h
@@ -11,6 +11,8 @@
 #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"
@@ -18,9 +20,7 @@
 namespace rx
 {
 class Renderer;
-class BufferStorage;
-class StaticIndexBufferInterface;
-class StaticVertexBufferInterface;
+class BufferImpl;
 };
 
 namespace gl
@@ -29,53 +29,45 @@
 class Buffer : public RefCountObject
 {
   public:
-    Buffer(rx::Renderer *renderer, GLuint id);
+    Buffer(rx::BufferImpl *impl, GLuint id);
 
     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 usage() const;
-    GLint accessFlags() const;
-    GLboolean mapped() const;
-    GLvoid *mapPointer() const;
-    GLint64 mapOffset() const;
-    GLint64 mapLength() const;
+    GLenum getUsage() const { return mUsage; }
+    GLint getAccessFlags() const {  return mAccessFlags; }
+    GLboolean isMapped() const { return mMapped; }
+    GLvoid *getMapPointer() const { return mMapPointer; }
+    GLint64 getMapOffset() const { return mMapOffset; }
+    GLint64 getMapLength() const { return mMapLength; }
+    GLint64 getSize() const { return mSize; }
 
-    rx::BufferStorage *getStorage() const;
-    GLint64 size() const;
+    rx::BufferImpl *getImplementation() const { return mBuffer; }
 
     void markTransformFeedbackUsage();
 
-    rx::StaticVertexBufferInterface *getStaticVertexBuffer();
-    rx::StaticIndexBufferInterface *getStaticIndexBuffer();
-    void invalidateStaticData();
-    void promoteStaticUsage(int dataSize);
-
-    rx::IndexRangeCache *getIndexRangeCache();
+    rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; }
+    const rx::IndexRangeCache *getIndexRangeCache() const { return &mIndexRangeCache; }
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Buffer);
 
-    rx::Renderer *mRenderer;
+    rx::BufferImpl *mBuffer;
+
     GLenum mUsage;
+    GLint64 mSize;
     GLint mAccessFlags;
     GLboolean mMapped;
     GLvoid *mMapPointer;
     GLint64 mMapOffset;
     GLint64 mMapLength;
 
-    rx::BufferStorage *mBufferStorage;
-
     rx::IndexRangeCache mIndexRangeCache;
-
-    rx::StaticVertexBufferInterface *mStaticVertexBuffer;
-    rx::StaticIndexBufferInterface *mStaticIndexBuffer;
-    unsigned int mUnmodifiedDataUse;
 };
 
 }
diff --git a/src/libGLESv2/Caps.cpp b/src/libGLESv2/Caps.cpp
new file mode 100644
index 0000000..0c2b821
--- /dev/null
+++ b/src/libGLESv2/Caps.cpp
@@ -0,0 +1,420 @@
+//
+// 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 "libGLESv2/Caps.h"
+#include "common/debug.h"
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+#include <algorithm>
+#include <sstream>
+
+namespace gl
+{
+
+TextureCaps::TextureCaps()
+    : texturable(false),
+      filterable(false),
+      renderable(false),
+      sampleCounts()
+{
+}
+
+GLuint TextureCaps::getMaxSamples() const
+{
+    return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
+}
+
+GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
+{
+    if (requestedSamples == 0)
+    {
+        return 0;
+    }
+
+    for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++)
+    {
+        GLuint samples = *i;
+        if (samples >= requestedSamples)
+        {
+            return samples;
+        }
+    }
+
+    return 0;
+}
+
+void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
+{
+    mCapsMap.insert(std::make_pair(internalFormat, caps));
+}
+
+void TextureCapsMap::remove(GLenum internalFormat)
+{
+    InternalFormatToCapsMap::iterator i = mCapsMap.find(internalFormat);
+    if (i != mCapsMap.end())
+    {
+        mCapsMap.erase(i);
+    }
+}
+
+const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const
+{
+    static TextureCaps defaultUnsupportedTexture;
+    InternalFormatToCapsMap::const_iterator iter = mCapsMap.find(internalFormat);
+    return (iter != mCapsMap.end()) ? iter->second : defaultUnsupportedTexture;
+}
+
+TextureCapsMap::const_iterator TextureCapsMap::begin() const
+{
+    return mCapsMap.begin();
+}
+
+TextureCapsMap::const_iterator TextureCapsMap::end() const
+{
+    return mCapsMap.end();
+}
+
+size_t TextureCapsMap::size() const
+{
+    return mCapsMap.size();
+}
+
+Extensions::Extensions()
+    : elementIndexUint(false),
+      packedDepthStencil(false),
+      getProgramBinary(false),
+      rgb8rgba8(false),
+      textureFormatBGRA8888(false),
+      readFormatBGRA(false),
+      pixelBufferObject(false),
+      mapBuffer(false),
+      mapBufferRange(false),
+      textureHalfFloat(false),
+      textureHalfFloatLinear(false),
+      textureFloat(false),
+      textureFloatLinear(false),
+      textureRG(false),
+      textureCompressionDXT1(false),
+      textureCompressionDXT3(false),
+      textureCompressionDXT5(false),
+      depthTextures(false),
+      textureNPOT(false),
+      drawBuffers(false),
+      textureStorage(false),
+      textureFilterAnisotropic(false),
+      maxTextureAnisotropy(false),
+      occlusionQueryBoolean(false),
+      fence(false),
+      timerQuery(false),
+      robustness(false),
+      blendMinMax(false),
+      framebufferBlit(false),
+      framebufferMultisample(false),
+      instancedArrays(false),
+      packReverseRowOrder(false),
+      standardDerivatives(false),
+      shaderTextureLOD(false),
+      fragDepth(false),
+      textureUsage(false),
+      translatedShaderSource(false),
+      colorBufferFloat(false)
+{
+}
+
+static void InsertExtensionString(const std::string &extension, bool supported, std::vector<std::string> *extensionVector)
+{
+    if (supported)
+    {
+        extensionVector->push_back(extension);
+    }
+}
+
+std::vector<std::string> Extensions::getStrings() const
+{
+    std::vector<std::string> extensionStrings;
+
+    //                   | Extension name                     | Supported flag          | Output vector   |
+    InsertExtensionString("GL_OES_element_index_uint",         elementIndexUint,         &extensionStrings);
+    InsertExtensionString("GL_OES_packed_depth_stencil",       packedDepthStencil,       &extensionStrings);
+    InsertExtensionString("GL_OES_get_program_binary",         getProgramBinary,         &extensionStrings);
+    InsertExtensionString("GL_OES_rgb8_rgba8",                 rgb8rgba8,                &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_format_BGRA8888",    textureFormatBGRA8888,    &extensionStrings);
+    InsertExtensionString("GL_EXT_read_format_bgra",           readFormatBGRA,           &extensionStrings);
+    InsertExtensionString("GL_NV_pixel_buffer_object",         pixelBufferObject,        &extensionStrings);
+    InsertExtensionString("GL_OES_mapbuffer",                  mapBuffer,                &extensionStrings);
+    InsertExtensionString("GL_EXT_map_buffer_range",           mapBufferRange,           &extensionStrings);
+    InsertExtensionString("GL_OES_texture_half_float",         textureHalfFloat,         &extensionStrings);
+    InsertExtensionString("GL_OES_texture_half_float_linear",  textureHalfFloatLinear,   &extensionStrings);
+    InsertExtensionString("GL_OES_texture_float",              textureFloat,             &extensionStrings);
+    InsertExtensionString("GL_OES_texture_float_linear",       textureFloatLinear,       &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_rg",                 textureRG,                &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_compression_dxt1",   textureCompressionDXT1,   &extensionStrings);
+    InsertExtensionString("GL_ANGLE_texture_compression_dxt3", textureCompressionDXT3,   &extensionStrings);
+    InsertExtensionString("GL_ANGLE_texture_compression_dxt5", textureCompressionDXT5,   &extensionStrings);
+    InsertExtensionString("GL_EXT_sRGB",                       sRGB,                     &extensionStrings);
+    InsertExtensionString("GL_ANGLE_depth_texture",            depthTextures,            &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_storage",            textureStorage,           &extensionStrings);
+    InsertExtensionString("GL_OES_texture_npot",               textureNPOT,              &extensionStrings);
+    InsertExtensionString("GL_EXT_draw_buffers",               drawBuffers,              &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_filter_anisotropic", textureFilterAnisotropic, &extensionStrings);
+    InsertExtensionString("GL_EXT_occlusion_query_boolean",    occlusionQueryBoolean,    &extensionStrings);
+    InsertExtensionString("GL_NV_fence",                       fence,                    &extensionStrings);
+    InsertExtensionString("GL_ANGLE_timer_query",              timerQuery,               &extensionStrings);
+    InsertExtensionString("GL_EXT_robustness",                 robustness,               &extensionStrings);
+    InsertExtensionString("GL_EXT_blend_minmax",               blendMinMax,              &extensionStrings);
+    InsertExtensionString("GL_ANGLE_framebuffer_blit",         framebufferBlit,          &extensionStrings);
+    InsertExtensionString("GL_ANGLE_framebuffer_multisample",  framebufferMultisample,   &extensionStrings);
+    InsertExtensionString("GL_ANGLE_instanced_arrays",         instancedArrays,          &extensionStrings);
+    InsertExtensionString("GL_ANGLE_pack_reverse_row_order",   packReverseRowOrder,      &extensionStrings);
+    InsertExtensionString("GL_OES_standard_derivatives",       standardDerivatives,      &extensionStrings);
+    InsertExtensionString("GL_EXT_shader_texture_lod",         shaderTextureLOD,         &extensionStrings);
+    InsertExtensionString("GL_EXT_frag_depth",                 fragDepth,                &extensionStrings);
+    InsertExtensionString("GL_ANGLE_texture_usage",            textureUsage,             &extensionStrings);
+    InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource,   &extensionStrings);
+    InsertExtensionString("GL_EXT_color_buffer_float",         colorBufferFloat,         &extensionStrings);
+
+    return extensionStrings;
+}
+
+static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vector<GLenum> &requiredFormats,
+                             bool requiresFiltering, bool requiresRendering)
+{
+    for (size_t i = 0; i < requiredFormats.size(); i++)
+    {
+        const TextureCaps &cap = textureCaps.get(requiredFormats[i]);
+
+        if (requiresFiltering && !cap.filterable)
+        {
+            return false;
+        }
+
+        if (requiresRendering && !cap.renderable)
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// Checks for GL_OES_rgb8_rgba8 support
+static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_RGB8);
+    requiredFormats.push_back(GL_RGBA8);
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, true);
+}
+
+// Checks for GL_EXT_texture_format_BGRA8888 support
+static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_BGRA8_EXT);
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, true);
+}
+
+// Checks for GL_OES_texture_half_float support
+static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_RGB16F);
+    requiredFormats.push_back(GL_RGBA16F);
+
+    return GetFormatSupport(textureCaps, requiredFormats, false, true);
+}
+
+// Checks for GL_OES_texture_half_float_linear support
+static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_RGB16F);
+    requiredFormats.push_back(GL_RGBA16F);
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, false);
+}
+
+// Checks for GL_OES_texture_float support
+static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_RGB32F);
+    requiredFormats.push_back(GL_RGBA32F);
+
+    return GetFormatSupport(textureCaps, requiredFormats, false, true);
+}
+
+// Checks for GL_OES_texture_float_linear support
+static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_RGB32F);
+    requiredFormats.push_back(GL_RGBA32F);
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, false);
+}
+
+// Checks for GL_EXT_texture_rg support
+static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, bool checkHalfFloatFormats, bool checkFloatFormats)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_R8);
+    requiredFormats.push_back(GL_RG8);
+    if (checkHalfFloatFormats)
+    {
+        requiredFormats.push_back(GL_R16F);
+        requiredFormats.push_back(GL_RG16F);
+    }
+    if (checkFloatFormats)
+    {
+        requiredFormats.push_back(GL_R32F);
+        requiredFormats.push_back(GL_RG32F);
+    }
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, false);
+}
+
+// Check for GL_EXT_texture_compression_dxt1
+static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+    requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, false);
+}
+
+// Check for GL_ANGLE_texture_compression_dxt3
+static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, false);
+}
+
+// Check for GL_ANGLE_texture_compression_dxt5
+static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, false);
+}
+
+// Check for GL_ANGLE_texture_compression_dxt5
+static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFilterFormats;
+    requiredFilterFormats.push_back(GL_SRGB8);
+    requiredFilterFormats.push_back(GL_SRGB8_ALPHA8);
+
+    std::vector<GLenum> requiredRenderFormats;
+    requiredRenderFormats.push_back(GL_SRGB8_ALPHA8);
+
+    return GetFormatSupport(textureCaps, requiredFilterFormats, true, false) &&
+           GetFormatSupport(textureCaps, requiredRenderFormats, false, true);
+}
+
+// Check for GL_ANGLE_depth_texture
+static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_DEPTH_COMPONENT16);
+    requiredFormats.push_back(GL_DEPTH_COMPONENT32_OES);
+    requiredFormats.push_back(GL_DEPTH24_STENCIL8_OES);
+
+    return GetFormatSupport(textureCaps, requiredFormats, true, true);
+}
+
+// Check for GL_EXT_color_buffer_float
+static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps)
+{
+    std::vector<GLenum> requiredFormats;
+    requiredFormats.push_back(GL_R16F);
+    requiredFormats.push_back(GL_RG16F);
+    requiredFormats.push_back(GL_RGBA16F);
+    requiredFormats.push_back(GL_R32F);
+    requiredFormats.push_back(GL_RG32F);
+    requiredFormats.push_back(GL_RGBA32F);
+    requiredFormats.push_back(GL_R11F_G11F_B10F);
+
+    return GetFormatSupport(textureCaps, requiredFormats, false, true);
+}
+
+void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
+{
+    rgb8rgba8 = DetermineRGB8AndRGBA8TextureSupport(textureCaps);
+    textureFormatBGRA8888 = DetermineBGRA8TextureSupport(textureCaps);
+    textureHalfFloat = DetermineHalfFloatTextureSupport(textureCaps);
+    textureHalfFloatLinear = DetermineHalfFloatTextureFilteringSupport(textureCaps);
+    textureFloat = DetermineFloatTextureSupport(textureCaps);
+    textureFloatLinear = DetermineFloatTextureFilteringSupport(textureCaps);
+    textureRG = DetermineRGTextureSupport(textureCaps, textureHalfFloat, textureFloat);
+    textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps);
+    textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps);
+    textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps);
+    sRGB = DetermineSRGBTextureSupport(textureCaps);
+    depthTextures = DetermineDepthTextureSupport(textureCaps);
+    colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps);
+}
+
+Caps::Caps()
+    : maxElementIndex(0),
+      max3DTextureSize(0),
+      max2DTextureSize(0),
+      maxArrayTextureLayers(0),
+      maxLODBias(0),
+      maxCubeMapTextureSize(0),
+      maxRenderbufferSize(0),
+      maxDrawBuffers(0),
+      maxColorAttachments(0),
+      maxViewportWidth(0),
+      maxViewportHeight(0),
+      minAliasedPointSize(0),
+      maxAliasedPointSize(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
new file mode 100644
index 0000000..a00e554
--- /dev/null
+++ b/src/libGLESv2/Caps.h
@@ -0,0 +1,273 @@
+#ifndef LIBGLESV2_CAPS_H
+#define LIBGLESV2_CAPS_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
+// found in the LICENSE file.
+//
+
+#include "angle_gl.h"
+
+#include <set>
+#include <unordered_map>
+#include <vector>
+#include <string>
+
+namespace gl
+{
+
+typedef std::set<GLuint> SupportedSampleSet;
+
+struct TextureCaps
+{
+    TextureCaps();
+
+    // Supports for basic texturing: glTexImage, glTexSubImage, etc
+    bool texturable;
+
+    // Support for linear or anisotropic filtering
+    bool filterable;
+
+    // Support for being used as a framebuffer attachment or renderbuffer format
+    bool renderable;
+
+    SupportedSampleSet sampleCounts;
+
+    // Get the maximum number of samples supported
+    GLuint getMaxSamples() const;
+
+    // Get the number of supported samples that is at least as many as requested.  Returns 0 if
+    // there are no sample counts available
+    GLuint getNearestSamples(GLuint requestedSamples) const;
+};
+
+class TextureCapsMap
+{
+  public:
+    typedef std::unordered_map<GLenum, TextureCaps>::const_iterator const_iterator;
+
+    void insert(GLenum internalFormat, const TextureCaps &caps);
+    void remove(GLenum internalFormat);
+
+    const TextureCaps &get(GLenum internalFormat) const;
+
+    const_iterator begin() const;
+    const_iterator end() const;
+
+    size_t size() const;
+
+  private:
+    typedef std::unordered_map<GLenum, TextureCaps> InternalFormatToCapsMap;
+    InternalFormatToCapsMap mCapsMap;
+};
+
+struct Extensions
+{
+    Extensions();
+
+    // Generate a vector of supported extension strings
+    std::vector<std::string> getStrings() const;
+
+    // Set all texture related extension support based on the supported textures.
+    // Determines support for:
+    // GL_OES_rgb8_rgba8
+    // GL_EXT_texture_format_BGRA8888
+    // GL_OES_texture_half_float, GL_OES_texture_half_float_linear
+    // GL_OES_texture_float, GL_OES_texture_float_linear
+    // GL_EXT_texture_rg
+    // GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5
+    // GL_EXT_sRGB
+    // GL_ANGLE_depth_texture
+    // GL_EXT_color_buffer_float
+    void setTextureExtensionSupport(const TextureCapsMap &textureCaps);
+
+    // ES2 Extension support
+
+    // GL_OES_element_index_uint
+    bool elementIndexUint;
+
+    // GL_OES_packed_depth_stencil
+    bool packedDepthStencil;
+
+    // GL_OES_get_program_binary
+    bool getProgramBinary;
+
+    // GL_OES_rgb8_rgba8
+    // Implies that TextureCaps for GL_RGB8 and GL_RGBA8 exist
+    bool rgb8rgba8;
+
+    // GL_EXT_texture_format_BGRA8888
+    // Implies that TextureCaps for GL_BGRA8 exist
+    bool textureFormatBGRA8888;
+
+    // GL_EXT_read_format_bgra
+    bool readFormatBGRA;
+
+    // GL_NV_pixel_buffer_object
+    bool pixelBufferObject;
+
+    // GL_OES_mapbuffer and GL_EXT_map_buffer_range
+    bool mapBuffer;
+    bool mapBufferRange;
+
+    // GL_OES_texture_half_float and GL_OES_texture_half_float_linear
+    // Implies that TextureCaps for GL_RGB16F, GL_RGBA16F, GL_ALPHA32F_EXT, GL_LUMINANCE32F_EXT and
+    // GL_LUMINANCE_ALPHA32F_EXT exist
+    bool textureHalfFloat;
+    bool textureHalfFloatLinear;
+
+    // GL_OES_texture_float and GL_OES_texture_float_linear
+    // Implies that TextureCaps for GL_RGB32F, GL_RGBA32F, GL_ALPHA16F_EXT, GL_LUMINANCE16F_EXT and
+    // GL_LUMINANCE_ALPHA16F_EXT exist
+    bool textureFloat;
+    bool textureFloatLinear;
+
+    // GL_EXT_texture_rg
+    // Implies that TextureCaps for GL_R8, GL_RG8 (and floating point R/RG texture formats if floating point extensions
+    // are also present) exist
+    bool textureRG;
+
+    // GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3 and GL_ANGLE_texture_compression_dxt5
+    // Implies that TextureCaps for GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+    // GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE and GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE
+    bool textureCompressionDXT1;
+    bool textureCompressionDXT3;
+    bool textureCompressionDXT5;
+
+    // GL_EXT_sRGB
+    // Implies that TextureCaps for GL_SRGB8_ALPHA8 and GL_SRGB8 exist
+    // TODO: Don't advertise this extension in ES3
+    bool sRGB;
+
+    // GL_ANGLE_depth_texture
+    bool depthTextures;
+
+    // GL_EXT_texture_storage
+    bool textureStorage;
+
+    // GL_OES_texture_npot
+    bool textureNPOT;
+
+    // GL_EXT_draw_buffers
+    bool drawBuffers;
+
+    // GL_EXT_texture_filter_anisotropic
+    bool textureFilterAnisotropic;
+    GLfloat maxTextureAnisotropy;
+
+    // GL_EXT_occlusion_query_boolean
+    bool occlusionQueryBoolean;
+
+    // GL_NV_fence
+    bool fence;
+
+    // GL_ANGLE_timer_query
+    bool timerQuery;
+
+    // GL_EXT_robustness
+    bool robustness;
+
+    // GL_EXT_blend_minmax
+    bool blendMinMax;
+
+    // GL_ANGLE_framebuffer_blit
+    bool framebufferBlit;
+
+    // GL_ANGLE_framebuffer_multisample
+    bool framebufferMultisample;
+    GLuint maxSamples;
+
+    // GL_ANGLE_instanced_arrays
+    bool instancedArrays;
+
+    // GL_ANGLE_pack_reverse_row_order
+    bool packReverseRowOrder;
+
+    // GL_OES_standard_derivatives
+    bool standardDerivatives;
+
+    // GL_EXT_shader_texture_lod
+    bool shaderTextureLOD;
+
+    // GL_EXT_frag_depth
+    bool fragDepth;
+
+    // GL_ANGLE_texture_usage
+    bool textureUsage;
+
+    // GL_ANGLE_translated_shader_source
+    bool translatedShaderSource;
+
+    // ES3 Extension support
+
+    // GL_EXT_color_buffer_float
+    bool colorBufferFloat;
+};
+
+struct Caps
+{
+    Caps();
+
+    // Table 6.28, implementation dependent values
+    GLuint64 maxElementIndex;
+    GLuint max3DTextureSize;
+    GLuint max2DTextureSize;
+    GLuint maxArrayTextureLayers;
+    GLfloat maxLODBias;
+    GLuint maxCubeMapTextureSize;
+    GLuint maxRenderbufferSize;
+    GLuint maxDrawBuffers;
+    GLuint maxColorAttachments;
+    GLuint maxViewportWidth;
+    GLuint maxViewportHeight;
+    GLfloat minAliasedPointSize;
+    GLfloat maxAliasedPointSize;
+    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;
+};
+
+}
+
+#endif // LIBGLESV2_CAPS_H
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 879a560..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,18 +11,19 @@
 
 #include "libGLESv2/main.h"
 #include "common/utilities.h"
+#include "common/platform.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Fence.h"
 #include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/Query.h"
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/ResourceManager.h"
-#include "libGLESv2/renderer/IndexDataManager.h"
-#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/d3d/IndexDataManager.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/VertexArray.h"
 #include "libGLESv2/Sampler.h"
@@ -32,109 +32,22 @@
 
 #include "libEGL/Surface.h"
 
-#undef near
-#undef far
+#include <sstream>
 
 namespace gl
 {
-static const char* makeStaticString(const std::string& str)
-{
-    static std::set<std::string> strings;
-    std::set<std::string>::iterator it = strings.find(str);
-    if (it != strings.end())
-      return it->c_str();
 
-    return strings.insert(str).first->c_str();
-}
-
-Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
+Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
+    : mRenderer(renderer)
 {
     ASSERT(robustAccess == false);   // Unimplemented
 
-    mFenceNVHandleAllocator.setBaseHandle(0);
-
-    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    initCaps(clientVersion);
+    mState.initialize(mCaps, clientVersion);
 
     mClientVersion = clientVersion;
 
-    mState.depthClearValue = 1.0f;
-    mState.stencilClearValue = 0;
-
-    mState.rasterizer.rasterizerDiscard = false;
-    mState.rasterizer.cullFace = false;
-    mState.rasterizer.cullMode = GL_BACK;
-    mState.rasterizer.frontFace = GL_CCW;
-    mState.rasterizer.polygonOffsetFill = false;
-    mState.rasterizer.polygonOffsetFactor = 0.0f;
-    mState.rasterizer.polygonOffsetUnits = 0.0f;
-    mState.rasterizer.pointDrawMode = false;
-    mState.rasterizer.multiSample = false;
-    mState.scissorTest = false;
-    mState.scissor.x = 0;
-    mState.scissor.y = 0;
-    mState.scissor.width = 0;
-    mState.scissor.height = 0;
-
-    mState.blend.blend = false;
-    mState.blend.sourceBlendRGB = GL_ONE;
-    mState.blend.sourceBlendAlpha = GL_ONE;
-    mState.blend.destBlendRGB = GL_ZERO;
-    mState.blend.destBlendAlpha = GL_ZERO;
-    mState.blend.blendEquationRGB = GL_FUNC_ADD;
-    mState.blend.blendEquationAlpha = GL_FUNC_ADD;
-    mState.blend.sampleAlphaToCoverage = false;
-    mState.blend.dither = true;
-
-    mState.blendColor.red = 0;
-    mState.blendColor.green = 0;
-    mState.blendColor.blue = 0;
-    mState.blendColor.alpha = 0;
-
-    mState.depthStencil.depthTest = false;
-    mState.depthStencil.depthFunc = GL_LESS;
-    mState.depthStencil.depthMask = true;
-    mState.depthStencil.stencilTest = false;
-    mState.depthStencil.stencilFunc = GL_ALWAYS;
-    mState.depthStencil.stencilMask = -1;
-    mState.depthStencil.stencilWritemask = -1;
-    mState.depthStencil.stencilBackFunc = GL_ALWAYS;
-    mState.depthStencil.stencilBackMask = - 1;
-    mState.depthStencil.stencilBackWritemask = -1;
-    mState.depthStencil.stencilFail = GL_KEEP;
-    mState.depthStencil.stencilPassDepthFail = GL_KEEP;
-    mState.depthStencil.stencilPassDepthPass = GL_KEEP;
-    mState.depthStencil.stencilBackFail = GL_KEEP;
-    mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
-    mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
-
-    mState.stencilRef = 0;
-    mState.stencilBackRef = 0;
-
-    mState.sampleCoverage = false;
-    mState.sampleCoverageValue = 1.0f;
-    mState.sampleCoverageInvert = false;
-    mState.generateMipmapHint = GL_DONT_CARE;
-    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
-
-    mState.lineWidth = 1.0f;
-
-    mState.viewport.x = 0;
-    mState.viewport.y = 0;
-    mState.viewport.width = 0;
-    mState.viewport.height = 0;
-    mState.zNear = 0.0f;
-    mState.zFar = 1.0f;
-
-    mState.blend.colorMaskRed = true;
-    mState.blend.colorMaskGreen = true;
-    mState.blend.colorMaskBlue = true;
-    mState.blend.colorMaskAlpha = true;
-
-    const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
-    for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
-    {
-        mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
-    }
+    mFenceNVHandleAllocator.setBaseHandle(0);
 
     if (shareContext != NULL)
     {
@@ -152,30 +65,30 @@
     // 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, 0));
-    mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
-    mTexture3DZero.set(new Texture3D(mRenderer, 0));
-    mTexture2DArrayZero.set(new Texture2DArray(mRenderer, 0));
+    mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
+    bindTexture(GL_TEXTURE_2D, 0);
 
-    for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
+    mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
+    bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+
+    if (mClientVersion >= 3)
     {
-        mState.samplers[textureUnit] = 0;
+        // 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);
     }
 
-    mState.activeSampler = 0;
     bindVertexArray(0);
     bindArrayBuffer(0);
     bindElementArrayBuffer(0);
-    bindTextureCubeMap(0);
-    bindTexture2D(0);
+
     bindReadFramebuffer(0);
     bindDrawFramebuffer(0);
     bindRenderbuffer(0);
 
-    mState.activeQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
-    mState.activeQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
-    mState.activeQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
-
     bindGenericUniformBuffer(0);
     for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
     {
@@ -197,48 +110,31 @@
     // 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);
 
-    mState.currentProgram = 0;
-    mCurrentProgramBinary.set(NULL);
-
-    mCombinedExtensionsString = NULL;
-    mRendererString = NULL;
-
-    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;
 
-    mSupportsBGRATextures = false;
-    mSupportsDXT1Textures = false;
-    mSupportsDXT3Textures = false;
-    mSupportsDXT5Textures = false;
-    mSupportsEventQueries = false;
-    mSupportsOcclusionQueries = false;
-    mNumCompressedTextureFormats = 0;
+    mState.setContext(this);
 }
 
 Context::~Context()
 {
-    if (mState.currentProgram != 0)
+    GLuint currentProgram = mState.getCurrentProgramId();
+    if (currentProgram != 0)
     {
-        Program *programObject = mResourceManager->getProgram(mState.currentProgram);
+        Program *programObject = mResourceManager->getProgram(currentProgram);
         if (programObject)
         {
             programObject->release();
         }
-        mState.currentProgram = 0;
+        currentProgram = 0;
     }
-    mCurrentProgramBinary.set(NULL);
+    mState.setCurrentProgram(0, NULL);
 
     while (!mFramebufferMap.empty())
     {
@@ -266,57 +162,17 @@
         deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
     }
 
-    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
-    {
-        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
-        {
-            mState.samplerTexture[type][sampler].set(NULL);
-        }
-    }
-
-    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
-    {
-        mIncompleteTextures[type].set(NULL);
-    }
-
-    const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
-    for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
-    {
-        mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
-    }
-
-    mState.arrayBuffer.set(NULL);
-    mState.renderbuffer.set(NULL);
-
-    mState.transformFeedback.set(NULL);
-
-    mTexture2DZero.set(NULL);
-    mTextureCubeMapZero.set(NULL);
-    mTexture3DZero.set(NULL);
-    mTexture2DArrayZero.set(NULL);
-
-    for (State::ActiveQueryMap::iterator i = mState.activeQueries.begin(); i != mState.activeQueries.end(); i++)
+    for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
     {
         i->second.set(NULL);
     }
+    mIncompleteTextures.clear();
 
-    mState.genericUniformBuffer.set(NULL);
-    for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
+    for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
     {
-        mState.uniformBuffers[i].set(NULL);
+        i->second.set(NULL);
     }
-
-    mState.genericTransformFeedbackBuffer.set(NULL);
-    for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
-    {
-        mState.transformFeedbackBuffers[i].set(NULL);
-    }
-
-    mState.copyReadBuffer.set(NULL);
-    mState.copyWriteBuffer.set(NULL);
-
-    mState.pack.pixelBuffer.set(NULL);
-    mState.unpack.pixelBuffer.set(NULL);
+    mZeroTextures.clear();
 
     mResourceManager->release();
 }
@@ -325,78 +181,11 @@
 {
     if (!mHasBeenCurrent)
     {
-        mMajorShaderModel = mRenderer->getMajorShaderModel();
-        mMaximumPointSize = mRenderer->getMaxPointSize();
-        mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
-        mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
-        mSupportsInstancing = mRenderer->getInstancingSupport();
-
-        mMaxViewportDimension = mRenderer->getMaxViewportDimension();
-        mMax2DTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
-                                          (int)gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
-        mMaxCubeTextureDimension = std::min(mMax2DTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
-        mMax3DTextureDimension = std::min(std::min(mMax2DTextureDimension, mRenderer->getMaxTextureDepth()),
-                                          (int)gl::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
-        mMax2DArrayTextureLayers = mRenderer->getMaxTextureArrayLayers();
-        mMaxRenderbufferDimension = mMax2DTextureDimension;
-        mMax2DTextureLevel = log2(mMax2DTextureDimension) + 1;
-        mMaxCubeTextureLevel = log2(mMaxCubeTextureDimension) + 1;
-        mMax3DTextureLevel = log2(mMax3DTextureDimension) + 1;
-        mMax2DArrayTextureLevel = log2(mMax2DTextureDimension) + 1;
-        mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
-        TRACE("Max2DTextureDimension=%d, MaxCubeTextureDimension=%d, Max3DTextureDimension=%d, Max2DArrayTextureLayers = %d, "
-              "Max2DTextureLevel=%d, MaxCubeTextureLevel=%d, Max3DTextureLevel=%d, Max2DArrayTextureLevel=%d, "
-              "MaxRenderbufferDimension=%d, MaxTextureAnisotropy=%f",
-              mMax2DTextureDimension, mMaxCubeTextureDimension, mMax3DTextureDimension, mMax2DArrayTextureLayers,
-              mMax2DTextureLevel, mMaxCubeTextureLevel, mMax3DTextureLevel, mMax2DArrayTextureLevel,
-              mMaxRenderbufferDimension, mMaxTextureAnisotropy);
-
-        mSupportsEventQueries = mRenderer->getEventQuerySupport();
-        mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
-        mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
-        mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
-        mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
-        mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
-        mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport();
-        mSupportsFloat32LinearFilter = mRenderer->getFloat32TextureFilteringSupport();
-        mSupportsFloat32RenderableTextures = mRenderer->getFloat32TextureRenderingSupport();
-        mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport();
-        mSupportsFloat16LinearFilter = mRenderer->getFloat16TextureFilteringSupport();
-        mSupportsFloat16RenderableTextures = mRenderer->getFloat16TextureRenderingSupport();
-        mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
-        mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
-        mSupportsRGTextures = mRenderer->getRGTextureSupport();
-        mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
-        mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
-        mSupports32bitIndices = mRenderer->get32BitIndexSupport();
-        mSupportsPBOs = mRenderer->getPBOSupport();
-
-        mNumCompressedTextureFormats = 0;
-        if (supportsDXT1Textures())
-        {
-            mNumCompressedTextureFormats += 2;
-        }
-        if (supportsDXT3Textures())
-        {
-            mNumCompressedTextureFormats += 1;
-        }
-        if (supportsDXT5Textures())
-        {
-            mNumCompressedTextureFormats += 1;
-        }
-
-        initExtensionString();
         initRendererString();
+        initExtensionStrings();
 
-        mState.viewport.x = 0;
-        mState.viewport.y = 0;
-        mState.viewport.width = surface->getWidth();
-        mState.viewport.height = surface->getHeight();
-
-        mState.scissor.x = 0;
-        mState.scissor.y = 0;
-        mState.scissor.width = surface->getWidth();
-        mState.scissor.height = surface->getHeight();
+        mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
+        mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
 
         mHasBeenCurrent = true;
     }
@@ -427,447 +216,6 @@
     return mContextLost;
 }
 
-void Context::setCap(GLenum cap, bool enabled)
-{
-    switch (cap)
-    {
-      case GL_CULL_FACE:                     setCullFace(enabled);              break;
-      case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
-      case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
-      case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
-      case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
-      case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
-      case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
-      case GL_BLEND:                         setBlend(enabled);                 break;
-      case GL_DITHER:                        setDither(enabled);                break;
-      case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED();                   break;
-      case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
-      default:                               UNREACHABLE();
-    }
-}
-
-bool Context::getCap(GLenum cap)
-{
-    switch (cap)
-    {
-      case GL_CULL_FACE:                     return isCullFaceEnabled();
-      case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
-      case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
-      case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
-      case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
-      case GL_STENCIL_TEST:                  return isStencilTestEnabled();
-      case GL_DEPTH_TEST:                    return isDepthTestEnabled();
-      case GL_BLEND:                         return isBlendEnabled();
-      case GL_DITHER:                        return isDitherEnabled();
-      case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
-      case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
-      default:                               UNREACHABLE(); return false;
-    }
-}
-
-void Context::setClearColor(float red, float green, float blue, float alpha)
-{
-    mState.colorClearValue.red = red;
-    mState.colorClearValue.green = green;
-    mState.colorClearValue.blue = blue;
-    mState.colorClearValue.alpha = alpha;
-}
-
-void Context::setClearDepth(float depth)
-{
-    mState.depthClearValue = depth;
-}
-
-void Context::setClearStencil(int stencil)
-{
-    mState.stencilClearValue = stencil;
-}
-
-void Context::setRasterizerDiscard(bool enabled)
-{
-    mState.rasterizer.rasterizerDiscard = enabled;
-}
-
-bool Context::isRasterizerDiscardEnabled() const
-{
-    return mState.rasterizer.rasterizerDiscard;
-}
-
-void Context::setCullFace(bool enabled)
-{
-    mState.rasterizer.cullFace = enabled;
-}
-
-bool Context::isCullFaceEnabled() const
-{
-    return mState.rasterizer.cullFace;
-}
-
-void Context::setCullMode(GLenum mode)
-{
-    mState.rasterizer.cullMode = mode;
-}
-
-void Context::setFrontFace(GLenum front)
-{
-    mState.rasterizer.frontFace = front;
-}
-
-void Context::setDepthTest(bool enabled)
-{
-    mState.depthStencil.depthTest = enabled;
-}
-
-bool Context::isDepthTestEnabled() const
-{
-    return mState.depthStencil.depthTest;
-}
-
-void Context::setDepthFunc(GLenum depthFunc)
-{
-     mState.depthStencil.depthFunc = depthFunc;
-}
-
-void Context::setDepthRange(float zNear, float zFar)
-{
-    mState.zNear = zNear;
-    mState.zFar = zFar;
-}
-
-void Context::setBlend(bool enabled)
-{
-    mState.blend.blend = enabled;
-}
-
-bool Context::isBlendEnabled() const
-{
-    return mState.blend.blend;
-}
-
-void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
-{
-    mState.blend.sourceBlendRGB = sourceRGB;
-    mState.blend.destBlendRGB = destRGB;
-    mState.blend.sourceBlendAlpha = sourceAlpha;
-    mState.blend.destBlendAlpha = destAlpha;
-}
-
-void Context::setBlendColor(float red, float green, float blue, float alpha)
-{
-    mState.blendColor.red = red;
-    mState.blendColor.green = green;
-    mState.blendColor.blue = blue;
-    mState.blendColor.alpha = alpha;
-}
-
-void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
-{
-    mState.blend.blendEquationRGB = rgbEquation;
-    mState.blend.blendEquationAlpha = alphaEquation;
-}
-
-void Context::setStencilTest(bool enabled)
-{
-    mState.depthStencil.stencilTest = enabled;
-}
-
-bool Context::isStencilTestEnabled() const
-{
-    return mState.depthStencil.stencilTest;
-}
-
-void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
-{
-    mState.depthStencil.stencilFunc = stencilFunc;
-    mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
-    mState.depthStencil.stencilMask = stencilMask;
-}
-
-void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
-{
-    mState.depthStencil.stencilBackFunc = stencilBackFunc;
-    mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
-    mState.depthStencil.stencilBackMask = stencilBackMask;
-}
-
-void Context::setStencilWritemask(GLuint stencilWritemask)
-{
-    mState.depthStencil.stencilWritemask = stencilWritemask;
-}
-
-void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
-{
-    mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
-}
-
-void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
-{
-    mState.depthStencil.stencilFail = stencilFail;
-    mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
-    mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
-}
-
-void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
-{
-    mState.depthStencil.stencilBackFail = stencilBackFail;
-    mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
-    mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
-}
-
-void Context::setPolygonOffsetFill(bool enabled)
-{
-     mState.rasterizer.polygonOffsetFill = enabled;
-}
-
-bool Context::isPolygonOffsetFillEnabled() const
-{
-    return mState.rasterizer.polygonOffsetFill;
-}
-
-void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
-{
-    // An application can pass NaN values here, so handle this gracefully
-    mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
-    mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
-}
-
-void Context::setSampleAlphaToCoverage(bool enabled)
-{
-    mState.blend.sampleAlphaToCoverage = enabled;
-}
-
-bool Context::isSampleAlphaToCoverageEnabled() const
-{
-    return mState.blend.sampleAlphaToCoverage;
-}
-
-void Context::setSampleCoverage(bool enabled)
-{
-    mState.sampleCoverage = enabled;
-}
-
-bool Context::isSampleCoverageEnabled() const
-{
-    return mState.sampleCoverage;
-}
-
-void Context::setSampleCoverageParams(GLclampf value, bool invert)
-{
-    mState.sampleCoverageValue = value;
-    mState.sampleCoverageInvert = invert;
-}
-
-void Context::setScissorTest(bool enabled)
-{
-    mState.scissorTest = enabled;
-}
-
-bool Context::isScissorTestEnabled() const
-{
-    return mState.scissorTest;
-}
-
-void Context::setDither(bool enabled)
-{
-    mState.blend.dither = enabled;
-}
-
-bool Context::isDitherEnabled() const
-{
-    return mState.blend.dither;
-}
-
-void Context::setLineWidth(GLfloat width)
-{
-    mState.lineWidth = width;
-}
-
-void Context::setGenerateMipmapHint(GLenum hint)
-{
-    mState.generateMipmapHint = hint;
-}
-
-void Context::setFragmentShaderDerivativeHint(GLenum hint)
-{
-    mState.fragmentShaderDerivativeHint = hint;
-    // TODO: Propagate the hint to shader translator so we can write
-    // ddx, ddx_coarse, or ddx_fine depending on the hint.
-    // Ignore for now. It is valid for implementations to ignore hint.
-}
-
-void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-    mState.viewport.x = x;
-    mState.viewport.y = y;
-    mState.viewport.width = width;
-    mState.viewport.height = height;
-}
-
-void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-    mState.scissor.x = x;
-    mState.scissor.y = y;
-    mState.scissor.width = width;
-    mState.scissor.height = height;
-}
-
-void Context::getScissorParams(GLint *x, GLint *y, GLsizei *width, GLsizei *height)
-{
-    *x = mState.scissor.x;
-    *y = mState.scissor.y;
-    *width = mState.scissor.width;
-    *height = mState.scissor.height;
-}
-
-void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
-{
-    mState.blend.colorMaskRed = red;
-    mState.blend.colorMaskGreen = green;
-    mState.blend.colorMaskBlue = blue;
-    mState.blend.colorMaskAlpha = alpha;
-}
-
-void Context::setDepthMask(bool mask)
-{
-    mState.depthStencil.depthMask = mask;
-}
-
-void Context::setActiveSampler(unsigned int active)
-{
-    mState.activeSampler = active;
-}
-
-GLuint Context::getReadFramebufferHandle() const
-{
-    return mState.readFramebuffer;
-}
-
-GLuint Context::getDrawFramebufferHandle() const
-{
-    return mState.drawFramebuffer;
-}
-
-GLuint Context::getRenderbufferHandle() const
-{
-    return mState.renderbuffer.id();
-}
-
-GLuint Context::getVertexArrayHandle() const
-{
-    return mState.vertexArray;
-}
-
-GLuint Context::getSamplerHandle(GLuint textureUnit) const
-{
-    ASSERT(textureUnit < ArraySize(mState.samplers));
-    return mState.samplers[textureUnit];
-}
-
-unsigned int Context::getActiveSampler() const
-{
-    return mState.activeSampler;
-}
-
-GLuint Context::getArrayBufferHandle() const
-{
-    return mState.arrayBuffer.id();
-}
-
-bool Context::isQueryActive() const
-{
-    for (State::ActiveQueryMap::const_iterator i = mState.activeQueries.begin();
-         i != mState.activeQueries.end(); i++)
-    {
-        if (i->second.get() != NULL)
-        {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-const Query *Context::getActiveQuery(GLenum target) const
-{
-    // All query types should already exist in the activeQueries map
-    ASSERT(mState.activeQueries.find(target) != mState.activeQueries.end());
-
-    return mState.activeQueries.at(target).get();
-}
-
-GLuint Context::getActiveQueryId(GLenum target) const
-{
-    const Query *query = getActiveQuery(target);
-    return (query ? query->id() : 0u);
-}
-
-void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
-{
-    getCurrentVertexArray()->enableAttribute(attribNum, enabled);
-}
-
-const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
-{
-    return getCurrentVertexArray()->getVertexAttribute(attribNum);
-}
-
-const VertexAttribCurrentValueData &Context::getVertexAttribCurrentValue(unsigned int attribNum) const
-{
-    ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
-    return mState.vertexAttribCurrentValues[attribNum];
-}
-
-void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
-                                   bool pureInteger, GLsizei stride, const void *pointer)
-{
-    getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
-}
-
-const void *Context::getVertexAttribPointer(unsigned int attribNum) const
-{
-    return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
-}
-
-void Context::setPackAlignment(GLint alignment)
-{
-    mState.pack.alignment = alignment;
-}
-
-GLint Context::getPackAlignment() const
-{
-    return mState.pack.alignment;
-}
-
-void Context::setUnpackAlignment(GLint alignment)
-{
-    mState.unpack.alignment = alignment;
-}
-
-GLint Context::getUnpackAlignment() const
-{
-    return mState.unpack.alignment;
-}
-
-void Context::setPackReverseRowOrder(bool reverseRowOrder)
-{
-    mState.pack.reverseRowOrder = reverseRowOrder;
-}
-
-bool Context::getPackReverseRowOrder() const
-{
-    return mState.pack.reverseRowOrder;
-}
-
-const PixelUnpackState &Context::getUnpackState() const
-{
-    return mState.unpack;
-}
-
-const PixelPackState &Context::getPackState() const
-{
-    return mState.pack;
-}
-
 GLuint Context::createBuffer()
 {
     return mResourceManager->createBuffer();
@@ -912,8 +260,8 @@
     // Although the spec states VAO state is not initialized until the object is bound,
     // we create it immediately. The resulting behaviour is transparent to the application,
     // since it's not currently possible to access the state until the object is bound.
-    mVertexArrayMap[handle] = new VertexArray(mRenderer, handle);
-
+    VertexArray *vertexArray = new VertexArray(mRenderer->createVertexArray(), handle, MAX_VERTEX_ATTRIBS);
+    mVertexArrayMap[handle] = vertexArray;
     return handle;
 }
 
@@ -925,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;
@@ -1100,12 +448,12 @@
     return mResourceManager->getProgram(handle);
 }
 
-Texture *Context::getTexture(GLuint handle)
+Texture *Context::getTexture(GLuint handle) const
 {
     return mResourceManager->getTexture(handle);
 }
 
-FramebufferAttachment *Context::getRenderbuffer(GLuint handle)
+Renderbuffer *Context::getRenderbuffer(GLuint handle)
 {
     return mResourceManager->getRenderbuffer(handle);
 }
@@ -1147,28 +495,6 @@
     }
 }
 
-Framebuffer *Context::getReadFramebuffer()
-{
-    return getFramebuffer(mState.readFramebuffer);
-}
-
-Framebuffer *Context::getDrawFramebuffer()
-{
-    return mBoundDrawFramebuffer;
-}
-
-VertexArray *Context::getCurrentVertexArray() const
-{
-    VertexArray *vao = getVertexArray(mState.vertexArray);
-    ASSERT(vao != NULL);
-    return vao;
-}
-
-TransformFeedback *Context::getCurrentTransformFeedback() const
-{
-    return mState.transformFeedback.get();
-}
-
 bool Context::isSampler(GLuint samplerName) const
 {
     return mResourceManager->isSampler(samplerName);
@@ -1178,167 +504,137 @@
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.arrayBuffer.set(getBuffer(buffer));
+    mState.setArrayBufferBinding(getBuffer(buffer));
 }
 
 void Context::bindElementArrayBuffer(unsigned int buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
+    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.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
-}
-
-void Context::bindTextureCubeMap(GLuint texture)
-{
-    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
-
-    mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
-}
-
-void Context::bindTexture3D(GLuint texture)
-{
-    mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
-
-    mState.samplerTexture[TEXTURE_3D][mState.activeSampler].set(getTexture(texture));
-}
-
-void Context::bindTexture2DArray(GLuint texture)
-{
-    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
-
-    mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].set(getTexture(texture));
+    mState.setSamplerTexture(target, getTexture(texture));
 }
 
 void Context::bindReadFramebuffer(GLuint framebuffer)
 {
     if (!getFramebuffer(framebuffer))
     {
-        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
+        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
     }
 
-    mState.readFramebuffer = framebuffer;
+    mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
 }
 
 void Context::bindDrawFramebuffer(GLuint framebuffer)
 {
     if (!getFramebuffer(framebuffer))
     {
-        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
+        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
     }
 
-    mState.drawFramebuffer = framebuffer;
-
-    mBoundDrawFramebuffer = getFramebuffer(framebuffer);
+    mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
 }
 
 void Context::bindRenderbuffer(GLuint renderbuffer)
 {
     mResourceManager->checkRenderbufferAllocation(renderbuffer);
 
-    mState.renderbuffer.set(getRenderbuffer(renderbuffer));
+    mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
 }
 
 void Context::bindVertexArray(GLuint vertexArray)
 {
     if (!getVertexArray(vertexArray))
     {
-        mVertexArrayMap[vertexArray] = new VertexArray(mRenderer, vertexArray);
+        VertexArray *vertexArrayObject = new VertexArray(mRenderer->createVertexArray(), vertexArray, MAX_VERTEX_ATTRIBS);
+        mVertexArrayMap[vertexArray] = vertexArrayObject;
     }
 
-    mState.vertexArray = vertexArray;
+    mState.setVertexArrayBinding(getVertexArray(vertexArray));
 }
 
 void Context::bindSampler(GLuint textureUnit, GLuint sampler)
 {
-    ASSERT(textureUnit < ArraySize(mState.samplers));
+    ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
     mResourceManager->checkSamplerAllocation(sampler);
 
-    mState.samplers[textureUnit] = sampler;
+    mState.setSamplerBinding(textureUnit, getSampler(sampler));
 }
 
 void Context::bindGenericUniformBuffer(GLuint buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.genericUniformBuffer.set(getBuffer(buffer));
+    mState.setGenericUniformBufferBinding(getBuffer(buffer));
 }
 
 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.uniformBuffers[index].set(getBuffer(buffer), offset, size);
+    mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
 }
 
 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.genericTransformFeedbackBuffer.set(getBuffer(buffer));
+    mState.setGenericTransformFeedbackBufferBinding(getBuffer(buffer));
 }
 
 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.transformFeedbackBuffers[index].set(getBuffer(buffer), offset, size);
+    mState.setIndexedTransformFeedbackBufferBinding(index, getBuffer(buffer), offset, size);
 }
 
 void Context::bindCopyReadBuffer(GLuint buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.copyReadBuffer.set(getBuffer(buffer));
+    mState.setCopyReadBufferBinding(getBuffer(buffer));
 }
 
 void Context::bindCopyWriteBuffer(GLuint buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.copyWriteBuffer.set(getBuffer(buffer));
+    mState.setCopyWriteBufferBinding(getBuffer(buffer));
 }
 
 void Context::bindPixelPackBuffer(GLuint buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.pack.pixelBuffer.set(getBuffer(buffer));
+    mState.setPixelPackBufferBinding(getBuffer(buffer));
 }
 
 void Context::bindPixelUnpackBuffer(GLuint buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
-    mState.unpack.pixelBuffer.set(getBuffer(buffer));
+    mState.setPixelUnpackBufferBinding(getBuffer(buffer));
 }
 
 void Context::useProgram(GLuint program)
 {
-    GLuint priorProgram = mState.currentProgram;
-    mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
+    GLuint priorProgramId = mState.getCurrentProgramId();
+    Program *priorProgram = mResourceManager->getProgram(priorProgramId);
 
-    if (priorProgram != program)
+    if (priorProgramId != program)
     {
-        Program *newProgram = mResourceManager->getProgram(program);
-        Program *oldProgram = mResourceManager->getProgram(priorProgram);
-        mCurrentProgramBinary.set(NULL);
+        mState.setCurrentProgram(program, mResourceManager->getProgram(program));
 
-        if (newProgram)
+        if (priorProgram)
         {
-            newProgram->addRef();
-            mCurrentProgramBinary.set(newProgram->getProgramBinary());
-        }
-
-        if (oldProgram)
-        {
-            oldProgram->release();
+            priorProgram->release();
         }
     }
 }
@@ -1347,101 +643,111 @@
 {
     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
-    if (linked && program == mState.currentProgram)
+    if (linked && program == mState.getCurrentProgramId())
     {
-        mCurrentProgramBinary.set(programObject->getProgramBinary());
+        mState.setCurrentProgramBinary(programObject->getProgramBinary());
     }
 }
 
-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
-    if (loaded && program == mState.currentProgram)
+    if (loaded && program == mState.getCurrentProgramId())
     {
-        mCurrentProgramBinary.set(programObject->getProgramBinary());
+        mState.setCurrentProgramBinary(programObject->getProgramBinary());
     }
 
 }
 
 void Context::bindTransformFeedback(GLuint transformFeedback)
 {
-    TransformFeedback *transformFeedbackObject = getTransformFeedback(transformFeedback);
-    mState.transformFeedback.set(transformFeedbackObject);
+    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
-    mState.activeQueries[target].set(queryObject);
-
     // begin query
-    queryObject->begin();
+    Error error = queryObject->begin();
+    if (error.isError())
+    {
+        return error;
+    }
+
+    // set query as active for specified target only if begin succeeded
+    mState.setActiveQuery(target, queryObject);
+
+    return Error(GL_NO_ERROR);
 }
 
-void Context::endQuery(GLenum target)
+Error Context::endQuery(GLenum target)
 {
-    Query *queryObject = mState.activeQueries[target].get();
+    Query *queryObject = mState.getActiveQuery(target);
     ASSERT(queryObject);
 
-    queryObject->end();
+    gl::Error error = queryObject->end();
 
-    mState.activeQueries[target].set(NULL);
+    // 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)
 {
+    // First, check to see if the old default framebuffer
+    // was set for draw or read framebuffer, and change
+    // the bindings to point to the new one before deleting it.
+    if (mState.getDrawFramebuffer()->id() == 0)
+    {
+        mState.setDrawFramebufferBinding(buffer);
+    }
+
+    if (mState.getReadFramebuffer()->id() == 0)
+    {
+        mState.setReadFramebufferBinding(buffer);
+    }
+
     delete mFramebufferMap[0];
     mFramebufferMap[0] = buffer;
-    if (mState.drawFramebuffer == 0)
-    {
-        mBoundDrawFramebuffer = buffer;
-    }
 }
 
 void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
 {
-    const bool color = gl::IsColorRenderingSupported(internalformat, this);
-    const bool depth = gl::IsDepthRenderingSupported(internalformat, this);
-    const bool stencil = gl::IsStencilRenderingSupported(internalformat, this);
+    ASSERT(getTextureCaps().get(internalformat).renderable);
 
     RenderbufferStorage *renderbuffer = NULL;
 
-    if (color)
-    {
-        renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
-    }
-    else if (depth && stencil)
+    const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+    if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
     {
         renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
     }
-    else if (depth)
+    else if (formatInfo.depthBits > 0)
     {
         renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
     }
-    else if (stencil)
+    else if (formatInfo.stencilBits > 0)
     {
         renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
     }
     else
     {
-        UNREACHABLE();
-        return;
+        renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples);
     }
 
-    FramebufferAttachment *renderbufferObject = mState.renderbuffer.get();
-    renderbufferObject->setStorage(renderbuffer);
+    mState.getCurrentRenderbuffer()->setStorage(renderbuffer);
 }
 
 Framebuffer *Context::getFramebuffer(unsigned int handle) const
@@ -1484,44 +790,13 @@
     {
         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;
     }
 }
 
-Buffer *Context::getTargetBuffer(GLenum target) const
-{
-    switch (target)
-    {
-      case GL_ARRAY_BUFFER:              return mState.arrayBuffer.get();
-      case GL_COPY_READ_BUFFER:          return mState.copyReadBuffer.get();
-      case GL_COPY_WRITE_BUFFER:         return mState.copyWriteBuffer.get();
-      case GL_ELEMENT_ARRAY_BUFFER:      return getCurrentVertexArray()->getElementArrayBuffer();
-      case GL_PIXEL_PACK_BUFFER:         return mState.pack.pixelBuffer.get();
-      case GL_PIXEL_UNPACK_BUFFER:       return mState.unpack.pixelBuffer.get();
-      case GL_TRANSFORM_FEEDBACK_BUFFER: return mState.genericTransformFeedbackBuffer.get();
-      case GL_UNIFORM_BUFFER:            return mState.genericUniformBuffer.get();
-      default: UNREACHABLE();            return NULL;
-    }
-}
-
-Buffer *Context::getArrayBuffer()
-{
-    return mState.arrayBuffer.get();
-}
-
-Buffer *Context::getElementArrayBuffer() const
-{
-    return getCurrentVertexArray()->getElementArrayBuffer();
-}
-
-ProgramBinary *Context::getCurrentProgramBinary()
-{
-    return mCurrentProgramBinary.get();
-}
-
 Texture *Context::getTargetTexture(GLenum target) const
 {
     if (!ValidTextureTarget(this, target))
@@ -1539,96 +814,36 @@
     }
 }
 
-GLuint Context::getTargetFramebufferHandle(GLenum target) const
-{
-    if (!ValidFramebufferTarget(target))
-    {
-        return GL_INVALID_INDEX;
-    }
-
-    if (target == GL_READ_FRAMEBUFFER_ANGLE)
-    {
-        return mState.readFramebuffer;
-    }
-    else
-    {
-        return mState.drawFramebuffer;
-    }
-}
-
-Framebuffer *Context::getTargetFramebuffer(GLenum target) const
-{
-    GLuint framebufferHandle = getTargetFramebufferHandle(target);
-    return (framebufferHandle == GL_INVALID_INDEX ? NULL : getFramebuffer(framebufferHandle));
-}
-
 Texture2D *Context::getTexture2D() const
 {
-    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
+    return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D));
 }
 
 TextureCubeMap *Context::getTextureCubeMap() const
 {
-    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
+    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP));
 }
 
 Texture3D *Context::getTexture3D() const
 {
-    return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
+    return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D));
 }
 
 Texture2DArray *Context::getTexture2DArray() const
 {
-    return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
+    return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY));
 }
 
-Buffer *Context::getGenericUniformBuffer()
+Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
 {
-    return mState.genericUniformBuffer.get();
-}
-
-Buffer *Context::getGenericTransformFeedbackBuffer()
-{
-    return mState.genericTransformFeedbackBuffer.get();
-}
-
-Buffer *Context::getCopyReadBuffer()
-{
-    return mState.copyReadBuffer.get();
-}
-
-Buffer *Context::getCopyWriteBuffer()
-{
-    return mState.copyWriteBuffer.get();
-}
-
-Buffer *Context::getPixelPackBuffer()
-{
-    return mState.pack.pixelBuffer.get();
-}
-
-Buffer *Context::getPixelUnpackBuffer()
-{
-    return mState.unpack.pixelBuffer.get();
-}
-
-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
-{
-    GLuint texid = mState.samplerTexture[type][sampler].id();
-
-    if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
+    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();
     }
-
-    return mState.samplerTexture[type][sampler].get();
+    else
+    {
+        return mState.getSamplerTexture(sampler, type);
+    }
 }
 
 void Context::getBooleanv(GLenum pname, GLboolean *params)
@@ -1636,200 +851,77 @@
     switch (pname)
     {
       case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
-      case GL_SAMPLE_COVERAGE_INVERT:    *params = mState.sampleCoverageInvert;         break;
-      case GL_DEPTH_WRITEMASK:           *params = mState.depthStencil.depthMask;       break;
-      case GL_COLOR_WRITEMASK:
-        params[0] = mState.blend.colorMaskRed;
-        params[1] = mState.blend.colorMaskGreen;
-        params[2] = mState.blend.colorMaskBlue;
-        params[3] = mState.blend.colorMaskAlpha;
-        break;
-      case GL_CULL_FACE:                 *params = mState.rasterizer.cullFace;          break;
-      case GL_POLYGON_OFFSET_FILL:       *params = mState.rasterizer.polygonOffsetFill; break;
-      case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mState.blend.sampleAlphaToCoverage;  break;
-      case GL_SAMPLE_COVERAGE:           *params = mState.sampleCoverage;               break;
-      case GL_SCISSOR_TEST:              *params = mState.scissorTest;                  break;
-      case GL_STENCIL_TEST:              *params = mState.depthStencil.stencilTest;     break;
-      case GL_DEPTH_TEST:                *params = mState.depthStencil.depthTest;       break;
-      case GL_BLEND:                     *params = mState.blend.blend;                  break;
-      case GL_DITHER:                    *params = mState.blend.dither;                 break;
       case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
-      case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
-      case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused();  break;
       default:
-        UNREACHABLE();
+        mState.getBooleanv(pname, params);
         break;
     }
 }
 
 void Context::getFloatv(GLenum pname, GLfloat *params)
 {
-    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
-    // GetIntegerv as its native query function. As it would require conversion in any
-    // case, this should make no difference to the calling application.
+    // Queries about context capabilities and maximums are answered by Context.
+    // Queries about current GL state values are answered by State.
     switch (pname)
     {
-      case GL_LINE_WIDTH:               *params = mState.lineWidth;                         break;
-      case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;               break;
-      case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;                   break;
-      case GL_POLYGON_OFFSET_FACTOR:    *params = mState.rasterizer.polygonOffsetFactor;    break;
-      case GL_POLYGON_OFFSET_UNITS:     *params = mState.rasterizer.polygonOffsetUnits;     break;
       case GL_ALIASED_LINE_WIDTH_RANGE:
-        params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
-        params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
+        params[0] = mCaps.minAliasedLineWidth;
+        params[1] = mCaps.maxAliasedLineWidth;
         break;
       case GL_ALIASED_POINT_SIZE_RANGE:
-        params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
-        params[1] = getMaximumPointSize();
-        break;
-      case GL_DEPTH_RANGE:
-        params[0] = mState.zNear;
-        params[1] = mState.zFar;
-        break;
-      case GL_COLOR_CLEAR_VALUE:
-        params[0] = mState.colorClearValue.red;
-        params[1] = mState.colorClearValue.green;
-        params[2] = mState.colorClearValue.blue;
-        params[3] = mState.colorClearValue.alpha;
-        break;
-      case GL_BLEND_COLOR:
-        params[0] = mState.blendColor.red;
-        params[1] = mState.blendColor.green;
-        params[2] = mState.blendColor.blue;
-        params[3] = mState.blendColor.alpha;
+        params[0] = mCaps.minAliasedPointSize;
+        params[1] = mCaps.maxAliasedPointSize;
         break;
       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
-        ASSERT(supportsTextureFilterAnisotropy());
-        *params = mMaxTextureAnisotropy;
+        ASSERT(mExtensions.textureFilterAnisotropic);
+        *params = mExtensions.maxTextureAnisotropy;
         break;
       default:
-        UNREACHABLE();
+        mState.getFloatv(pname, params);
         break;
     }
 }
 
 void Context::getIntegerv(GLenum pname, GLint *params)
 {
-    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
-    {
-        unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
-        ASSERT(colorAttachment < mRenderer->getMaxRenderTargets());
-        Framebuffer *framebuffer = getDrawFramebuffer();
-        *params = framebuffer->getDrawBufferState(colorAttachment);
-        return;
-    }
+    // Queries about context capabilities and maximums are answered by Context.
+    // Queries about current GL state values are answered by State.
 
-    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
-    // GetIntegerv as its native query function. As it would require conversion in any
-    // case, this should make no difference to the calling application. You may find it in
-    // Context::getFloatv.
     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_RENDERBUFFER_SIZE:                    *params = getMaximumRenderbufferDimension();                    break;
-      case GL_MAX_COLOR_ATTACHMENTS_EXT:                *params = mRenderer->getMaxRenderTargets();                     break;
-      case GL_MAX_DRAW_BUFFERS_EXT:                     *params = mRenderer->getMaxRenderTargets();                     break;
-      case GL_NUM_SHADER_BINARY_FORMATS:                *params = 0;                                                    break;
-      case GL_SHADER_BINARY_FORMATS:                    /* no shader binary formats are supported */                    break;
-      case GL_ARRAY_BUFFER_BINDING:                     *params = mState.arrayBuffer.id();                              break;
-      case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getCurrentVertexArray()->getElementArrayBufferId();   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_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
-      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mState.drawFramebuffer;                               break;
-      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mState.readFramebuffer;                               break;
-      case GL_RENDERBUFFER_BINDING:                     *params = mState.renderbuffer.id();                             break;
-      case GL_VERTEX_ARRAY_BINDING:                     *params = mState.vertexArray;                                   break;
-      case GL_CURRENT_PROGRAM:                          *params = mState.currentProgram;                                break;
-      case GL_PACK_ALIGNMENT:                           *params = mState.pack.alignment;                                break;
-      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mState.pack.reverseRowOrder;                          break;
-      case GL_UNPACK_ALIGNMENT:                         *params = mState.unpack.alignment;                              break;
-      case GL_GENERATE_MIPMAP_HINT:                     *params = mState.generateMipmapHint;                            break;
-      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mState.fragmentShaderDerivativeHint;                  break;
-      case GL_ACTIVE_TEXTURE:                           *params = (mState.activeSampler + GL_TEXTURE0);                 break;
-      case GL_STENCIL_FUNC:                             *params = mState.depthStencil.stencilFunc;                      break;
-      case GL_STENCIL_REF:                              *params = mState.stencilRef;                                    break;
-      case GL_STENCIL_VALUE_MASK:                       *params = clampToInt(mState.depthStencil.stencilMask);          break;
-      case GL_STENCIL_BACK_FUNC:                        *params = mState.depthStencil.stencilBackFunc;                  break;
-      case GL_STENCIL_BACK_REF:                         *params = mState.stencilBackRef;                                break;
-      case GL_STENCIL_BACK_VALUE_MASK:                  *params = clampToInt(mState.depthStencil.stencilBackMask);      break;
-      case GL_STENCIL_FAIL:                             *params = mState.depthStencil.stencilFail;                      break;
-      case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mState.depthStencil.stencilPassDepthFail;             break;
-      case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mState.depthStencil.stencilPassDepthPass;             break;
-      case GL_STENCIL_BACK_FAIL:                        *params = mState.depthStencil.stencilBackFail;                  break;
-      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mState.depthStencil.stencilBackPassDepthFail;         break;
-      case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mState.depthStencil.stencilBackPassDepthPass;         break;
-      case GL_DEPTH_FUNC:                               *params = mState.depthStencil.depthFunc;                        break;
-      case GL_BLEND_SRC_RGB:                            *params = mState.blend.sourceBlendRGB;                          break;
-      case GL_BLEND_SRC_ALPHA:                          *params = mState.blend.sourceBlendAlpha;                        break;
-      case GL_BLEND_DST_RGB:                            *params = mState.blend.destBlendRGB;                            break;
-      case GL_BLEND_DST_ALPHA:                          *params = mState.blend.destBlendAlpha;                          break;
-      case GL_BLEND_EQUATION_RGB:                       *params = mState.blend.blendEquationRGB;                        break;
-      case GL_BLEND_EQUATION_ALPHA:                     *params = mState.blend.blendEquationAlpha;                      break;
-      case GL_STENCIL_WRITEMASK:                        *params = clampToInt(mState.depthStencil.stencilWritemask);     break;
-      case GL_STENCIL_BACK_WRITEMASK:                   *params = clampToInt(mState.depthStencil.stencilBackWritemask); break;
-      case GL_STENCIL_CLEAR_VALUE:                      *params = mState.stencilClearValue;                             break;
       case GL_SUBPIXEL_BITS:                            *params = 4;                                                    break;
-      case GL_MAX_TEXTURE_SIZE:                         *params = getMaximum2DTextureDimension();                       break;
-      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:                *params = getMaximumCubeTextureDimension();                     break;
-      case GL_MAX_3D_TEXTURE_SIZE:                      *params = getMaximum3DTextureDimension();                       break;
-      case GL_MAX_ARRAY_TEXTURE_LAYERS:                 *params = getMaximum2DArrayTextureLayers();                     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_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 = 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_SAMPLES_ANGLE:
-        *params = static_cast<GLint>(getMaxSupportedSamples());
-        break;
-      case GL_SAMPLE_BUFFERS:
-      case GL_SAMPLES:
-        {
-            gl::Framebuffer *framebuffer = getDrawFramebuffer();
-            if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
-            {
-                switch (pname)
-                {
-                  case GL_SAMPLE_BUFFERS:
-                    if (framebuffer->getSamples() != 0)
-                    {
-                        *params = 1;
-                    }
-                    else
-                    {
-                        *params = 0;
-                    }
-                    break;
-                  case GL_SAMPLES:
-                    *params = framebuffer->getSamples();
-                    break;
-                }
-            }
-            else
-            {
-                *params = 0;
-            }
-        }
-        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:
         {
@@ -1843,174 +935,57 @@
         break;
       case GL_MAX_VIEWPORT_DIMS:
         {
-            params[0] = mMaxViewportDimension;
-            params[1] = mMaxViewportDimension;
+            params[0] = mCaps.maxViewportWidth;
+            params[1] = mCaps.maxViewportHeight;
         }
         break;
       case GL_COMPRESSED_TEXTURE_FORMATS:
-        {
-            if (supportsDXT1Textures())
-            {
-                *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
-                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
-            }
-            if (supportsDXT3Textures())
-            {
-                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
-            }
-            if (supportsDXT5Textures())
-            {
-                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
-            }
-        }
-        break;
-      case GL_VIEWPORT:
-        params[0] = mState.viewport.x;
-        params[1] = mState.viewport.y;
-        params[2] = mState.viewport.width;
-        params[3] = mState.viewport.height;
-        break;
-      case GL_SCISSOR_BOX:
-        params[0] = mState.scissor.x;
-        params[1] = mState.scissor.y;
-        params[2] = mState.scissor.width;
-        params[3] = mState.scissor.height;
-        break;
-      case GL_CULL_FACE_MODE:                   *params = mState.rasterizer.cullMode;   break;
-      case GL_FRONT_FACE:                       *params = mState.rasterizer.frontFace;  break;
-      case GL_RED_BITS:
-      case GL_GREEN_BITS:
-      case GL_BLUE_BITS:
-      case GL_ALPHA_BITS:
-        {
-            gl::Framebuffer *framebuffer = getDrawFramebuffer();
-            gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
-
-            if (colorbuffer)
-            {
-                switch (pname)
-                {
-                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
-                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
-                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
-                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
-                }
-            }
-            else
-            {
-                *params = 0;
-            }
-        }
-        break;
-      case GL_DEPTH_BITS:
-        {
-            gl::Framebuffer *framebuffer = getDrawFramebuffer();
-            gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
-
-            if (depthbuffer)
-            {
-                *params = depthbuffer->getDepthSize();
-            }
-            else
-            {
-                *params = 0;
-            }
-        }
-        break;
-      case GL_STENCIL_BITS:
-        {
-            gl::Framebuffer *framebuffer = getDrawFramebuffer();
-            gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
-
-            if (stencilbuffer)
-            {
-                *params = stencilbuffer->getStencilSize();
-            }
-            else
-            {
-                *params = 0;
-            }
-        }
-        break;
-      case GL_TEXTURE_BINDING_2D:
-        ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
-        *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
-        break;
-      case GL_TEXTURE_BINDING_CUBE_MAP:
-        ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
-        *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
-        break;
-      case GL_TEXTURE_BINDING_3D:
-        ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
-        *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].id();
-        break;
-      case GL_TEXTURE_BINDING_2D_ARRAY:
-        ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
-        *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].id();
+        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_UNIFORM_BUFFER_BINDING:
-        *params = mState.genericUniformBuffer.id();
+      case GL_NUM_PROGRAM_BINARY_FORMATS:
+        *params = mCaps.programBinaryFormats.size();
         break;
-      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-        *params = mState.genericTransformFeedbackBuffer.id();
-        break;
-      case GL_COPY_READ_BUFFER_BINDING:
-        *params = mState.copyReadBuffer.id();
-        break;
-      case GL_COPY_WRITE_BUFFER_BINDING:
-        *params = mState.copyWriteBuffer.id();
-        break;
-      case GL_PIXEL_PACK_BUFFER_BINDING:
-        *params = mState.pack.pixelBuffer.id();
-        break;
-      case GL_PIXEL_UNPACK_BUFFER_BINDING:
-        *params = mState.unpack.pixelBuffer.id();
+      case GL_PROGRAM_BINARY_FORMATS:
+        std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
         break;
       case GL_NUM_EXTENSIONS:
-        *params = static_cast<GLint>(getNumExtensions());
+        *params = static_cast<GLint>(mExtensionStrings.size());
         break;
       default:
-        UNREACHABLE();
+        mState.getIntegerv(pname, params);
         break;
     }
 }
 
 void Context::getInteger64v(GLenum pname, GLint64 *params)
 {
+    // Queries about context capabilities and maximums are answered by Context.
+    // Queries about current GL state values are answered by State.
     switch (pname)
     {
       case GL_MAX_ELEMENT_INDEX:
-        *params = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
+        *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();
@@ -2020,60 +995,20 @@
 
 bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
 {
-    switch (target)
-    {
-      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
-        {
-            *data = mState.transformFeedbackBuffers[index].id();
-        }
-        break;
-      case GL_UNIFORM_BUFFER_BINDING:
-        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
-        {
-            *data = mState.uniformBuffers[index].id();
-        }
-        break;
-      default:
-        return false;
-    }
-
-    return true;
+    // Queries about context capabilities and maximums are answered by Context.
+    // Queries about current GL state values are answered by State.
+    // Indexed integer queries all refer to current state, so this function is a 
+    // mere passthrough.
+    return mState.getIndexedIntegerv(target, index, data);
 }
 
 bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
 {
-    switch (target)
-    {
-      case GL_TRANSFORM_FEEDBACK_BUFFER_START:
-        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
-        {
-            *data = mState.transformFeedbackBuffers[index].getOffset();
-        }
-        break;
-      case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
-        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
-        {
-            *data = mState.transformFeedbackBuffers[index].getSize();
-        }
-        break;
-      case GL_UNIFORM_BUFFER_START:
-        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
-        {
-            *data = mState.uniformBuffers[index].getOffset();
-        }
-        break;
-      case GL_UNIFORM_BUFFER_SIZE:
-        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
-        {
-            *data = mState.uniformBuffers[index].getSize();
-        }
-        break;
-      default:
-        return false;
-    }
-
-    return true;
+    // Queries about context capabilities and maximums are answered by Context.
+    // Queries about current GL state values are answered by State.
+    // Indexed integer queries all refer to current state, so this function is a 
+    // mere passthrough.
+    return mState.getIndexedInteger64v(target, index, data);
 }
 
 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
@@ -2097,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:
@@ -2172,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;
@@ -2180,7 +1120,7 @@
         return true;
       case GL_MAX_SAMPLES_ANGLE:
         {
-            if (getMaxSupportedSamples() != 0)
+            if (mExtensions.framebufferMultisample)
             {
                 *type = GL_INT;
                 *numParams = 1;
@@ -2194,7 +1134,7 @@
       case GL_PIXEL_PACK_BUFFER_BINDING:
       case GL_PIXEL_UNPACK_BUFFER_BINDING:
         {
-            if (supportsPBOs())
+            if (mExtensions.pixelBufferObject)
             {
                 *type = GL_INT;
                 *numParams = 1;
@@ -2268,7 +1208,7 @@
         }
         return true;
       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
-        if (!supportsTextureFilterAnisotropy())
+        if (!mExtensions.maxTextureAnisotropy)
         {
             return false;
         }
@@ -2370,42 +1310,40 @@
 
 // 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 = getDrawFramebuffer();
-
-    if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
-    {
-        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
-    }
+    Framebuffer *framebufferObject = mState.getDrawFramebuffer();
+    ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
 
     mRenderer->applyRenderTarget(framebufferObject);
 
-    if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
-                                ignoreViewport))
-    {
-        return false;
-    }
+    float nearZ, farZ;
+    mState.getDepthRange(&nearZ, &farZ);
+    mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
+                           ignoreViewport);
 
-    mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
-
-    return true;
+    mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
 }
 
 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
 void Context::applyState(GLenum drawMode)
 {
-    Framebuffer *framebufferObject = getDrawFramebuffer();
+    Framebuffer *framebufferObject = mState.getDrawFramebuffer();
     int samples = framebufferObject->getSamples();
 
-    mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
-    mState.rasterizer.multiSample = (samples != 0);
-    mRenderer->setRasterizerState(mState.rasterizer);
+    RasterizerState rasterizer = mState.getRasterizerState();
+    rasterizer.pointDrawMode = (drawMode == GL_POINTS);
+    rasterizer.multiSample = (samples != 0);
+
+    mRenderer->setRasterizerState(rasterizer);
 
     unsigned int mask = 0;
-    if (mState.sampleCoverage)
+    if (mState.isSampleCoverageEnabled())
     {
-        if (mState.sampleCoverageValue != 0)
+        GLclampf coverageValue;
+        bool coverageInvert = false;
+        mState.getSampleCoverageParams(&coverageValue, &coverageInvert);
+        if (coverageValue != 0)
         {
 
             float threshold = 0.5f;
@@ -2414,7 +1352,7 @@
             {
                 mask <<= 1;
 
-                if ((i + 1) * mState.sampleCoverageValue >= threshold)
+                if ((i + 1) * coverageValue >= threshold)
                 {
                     threshold += 1.0f;
                     mask |= 1;
@@ -2422,7 +1360,7 @@
             }
         }
 
-        if (mState.sampleCoverageInvert)
+        if (coverageInvert)
         {
             mask = ~mask;
         }
@@ -2431,147 +1369,152 @@
     {
         mask = 0xFFFFFFFF;
     }
-    mRenderer->setBlendState(framebufferObject, mState.blend, mState.blendColor, mask);
+    mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
 
-    mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
-                                    mState.rasterizer.frontFace == GL_CCW);
+    mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
+                                    rasterizer.frontFace == GL_CCW);
 }
 
 // Applies the shaders and shader constants to the Direct3D 9 device
 void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
 {
-    const VertexAttribute *vertexAttributes = getCurrentVertexArray()->getVertexAttributes();
+    const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
 
-    VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
-    VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.vertexAttribCurrentValues);
+    VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
+    VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
 
-    mRenderer->applyShaders(programBinary, mState.rasterizer.rasterizerDiscard, transformFeedbackActive, inputLayout);
+    const Framebuffer *fbo = mState.getDrawFramebuffer();
+
+    mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
 
     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]->getSamplerState(&outSamplers[i]);
-            if (mState.samplers[textureUnit] != 0)
+            Texture* texture = getSamplerTexture(textureUnit, textureType);
+            if (texture->getSamplerState().swizzleRequired())
             {
-                Sampler *samplerObject = getSampler(mState.samplers[textureUnit]);
-                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]->isSwizzled())
-        {
-            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);
                 mRenderer->setTexture(shaderType, samplerIndex, texture);
-                texture->resetDirty();
             }
             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);
-                incompleteTexture->resetDirty();
             }
         }
         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.currentProgram);
+    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++)
     {
         GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
-        const OffsetBindingPointer<Buffer>& boundBuffer = mState.uniformBuffers[blockBinding];
-        if (boundBuffer.id() == 0)
+
+        if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0)
         {
             // undefined behaviour
             return false;
         }
         else
         {
-            gl::Buffer *uniformBuffer = boundBuffer.get();
+            Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding);
             ASSERT(uniformBuffer);
             boundBuffers.push_back(uniformBuffer);
         }
     }
 
-    return programBinary->applyUniformBuffers(boundBuffers);
+    return programBinary->applyUniformBuffers(boundBuffers, getCaps());
 }
 
 bool Context::applyTransformFeedbackBuffers()
 {
-    TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
+    TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback();
     if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
     {
         Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
         GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
         for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
         {
-            transformFeedbackBuffers[i] = mState.transformFeedbackBuffers[i].get();
-            transformFeedbackOffsets[i] = mState.transformFeedbackBuffers[i].getOffset();
+            transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i);
+            transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i);
         }
         mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
         return true;
@@ -2586,7 +1529,7 @@
 {
     for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
     {
-        Buffer *buffer = mState.transformFeedbackBuffers[i].get();
+        Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i);
         if (buffer)
         {
             buffer->markTransformFeedbackUsage();
@@ -2594,88 +1537,29 @@
     }
 }
 
-void Context::clear(GLbitfield mask)
+Error Context::clear(GLbitfield mask)
 {
-    if (isRasterizerDiscardEnabled())
+    if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
-    ClearParameters clearParams = { 0 };
-    for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
-    {
-        clearParams.clearColor[i] = false;
-    }
-    clearParams.colorFClearValue = mState.colorClearValue;
-    clearParams.colorClearType = GL_FLOAT;
-    clearParams.colorMaskRed = mState.blend.colorMaskRed;
-    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
-    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
-    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
-    clearParams.clearDepth = false;
-    clearParams.depthClearValue = mState.depthClearValue;
-    clearParams.clearStencil = false;
-    clearParams.stencilClearValue = mState.stencilClearValue;
-    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
-    clearParams.scissorEnabled = mState.scissorTest;
-    clearParams.scissor = mState.scissor;
+    ClearParameters clearParams = mState.getClearParameters(mask);
 
-    Framebuffer *framebufferObject = getDrawFramebuffer();
-    if (mask & GL_COLOR_BUFFER_BIT)
-    {
-        if (framebufferObject->hasEnabledColorAttachment())
-        {
-            for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
-            {
-                clearParams.clearColor[i] = true;
-            }
-        }
-    }
+    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
 
-    if (mask & GL_DEPTH_BUFFER_BIT)
-    {
-        if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
-        {
-            clearParams.clearDepth = true;
-        }
-    }
-
-    if (mask & GL_STENCIL_BUFFER_BIT)
-    {
-        if (framebufferObject->getStencilbufferType() != GL_NONE)
-        {
-            rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
-            if (!depthStencil)
-            {
-                ERR("Depth stencil pointer unexpectedly null.");
-                return;
-            }
-
-            if (gl::GetStencilBits(depthStencil->getActualFormat(), mClientVersion) > 0)
-            {
-                clearParams.clearStencil = true;
-            }
-        }
-    }
-
-
-    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
-    {
-        return;
-    }
-
-    mRenderer->clear(clearParams, framebufferObject);
+    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 (isRasterizerDiscardEnabled())
+    if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     // glClearBufferfv can be called to clear the color buffer or depth buffer
-    ClearParameters clearParams = { 0 };
+    ClearParameters clearParams = mState.getClearParameters(0);
 
     if (buffer == GL_COLOR)
     {
@@ -2686,90 +1570,48 @@
         clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
         clearParams.colorClearType = GL_FLOAT;
     }
-    else
-    {
-        for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
-        {
-            clearParams.clearColor[i] = false;
-        }
-        clearParams.colorFClearValue = mState.colorClearValue;
-        clearParams.colorClearType = GL_FLOAT;
-    }
-
-    clearParams.colorMaskRed = mState.blend.colorMaskRed;
-    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
-    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
-    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
 
     if (buffer == GL_DEPTH)
     {
         clearParams.clearDepth = true;
         clearParams.depthClearValue = values[0];
     }
-    else
-    {
-        clearParams.clearDepth = false;
-        clearParams.depthClearValue = mState.depthClearValue;
-    }
 
-    clearParams.clearStencil = false;
-    clearParams.stencilClearValue = mState.stencilClearValue;
-    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
-    clearParams.scissorEnabled = mState.scissorTest;
-    clearParams.scissor = mState.scissor;
+    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
 
-    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
-    {
-        return;
-    }
-
-    mRenderer->clear(clearParams, 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 (isRasterizerDiscardEnabled())
+    if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     // glClearBufferuv can only be called to clear a color buffer
-    ClearParameters clearParams = { 0 };
+    ClearParameters clearParams = mState.getClearParameters(0);
     for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
     {
         clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
     }
     clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
     clearParams.colorClearType = GL_UNSIGNED_INT;
-    clearParams.colorMaskRed = mState.blend.colorMaskRed;
-    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
-    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
-    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
-    clearParams.clearDepth = false;
-    clearParams.depthClearValue = mState.depthClearValue;
-    clearParams.clearStencil = false;
-    clearParams.stencilClearValue = mState.stencilClearValue;
-    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
-    clearParams.scissorEnabled = mState.scissorTest;
-    clearParams.scissor = mState.scissor;
 
-    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, 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 (isRasterizerDiscardEnabled())
+    if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     // glClearBufferfv can be called to clear the color buffer or stencil buffer
-    ClearParameters clearParams = { 0 };
+    ClearParameters clearParams = mState.getClearParameters(0);
 
     if (buffer == GL_COLOR)
     {
@@ -2780,155 +1622,84 @@
         clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
         clearParams.colorClearType = GL_INT;
     }
-    else
-    {
-        for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
-        {
-            clearParams.clearColor[i] = false;
-        }
-        clearParams.colorFClearValue = mState.colorClearValue;
-        clearParams.colorClearType = GL_FLOAT;
-    }
-
-    clearParams.colorMaskRed = mState.blend.colorMaskRed;
-    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
-    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
-    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
-
-    clearParams.clearDepth = false;
-    clearParams.depthClearValue = mState.depthClearValue;
 
     if (buffer == GL_STENCIL)
     {
         clearParams.clearStencil = true;
         clearParams.stencilClearValue = values[1];
     }
-    else
-    {
-        clearParams.clearStencil = false;
-        clearParams.stencilClearValue = mState.stencilClearValue;
-    }
-    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
 
-    clearParams.scissorEnabled = mState.scissorTest;
-    clearParams.scissor = mState.scissor;
+    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
 
-    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
-    {
-        return;
-    }
-
-    mRenderer->clear(clearParams, 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 (isRasterizerDiscardEnabled())
+    if (mState.isRasterizerDiscardEnabled())
     {
-        return;
+        return Error(GL_NO_ERROR);
     }
 
     // glClearBufferfi can only be called to clear a depth stencil buffer
-    ClearParameters clearParams = { 0 };
-    for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
-    {
-        clearParams.clearColor[i] = false;
-    }
-    clearParams.colorFClearValue = mState.colorClearValue;
-    clearParams.colorClearType = GL_FLOAT;
-    clearParams.colorMaskRed = mState.blend.colorMaskRed;
-    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
-    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
-    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
+    ClearParameters clearParams = mState.getClearParameters(0);
     clearParams.clearDepth = true;
     clearParams.depthClearValue = depth;
     clearParams.clearStencil = true;
     clearParams.stencilClearValue = stencil;
-    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
-    clearParams.scissorEnabled = mState.scissorTest;
-    clearParams.scissor = mState.scissor;
 
-    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, 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 = getReadFramebuffer();
+    Framebuffer *framebuffer = mState.getReadFramebuffer();
 
-    bool isSized = IsSizedInternalFormat(format, mClientVersion);
-    GLenum sizedInternalFormat = (isSized ? format : GetSizedInternalFormat(format, type, mClientVersion));
-    GLuint outputPitch = GetRowPitch(sizedInternalFormat, type, mClientVersion, width, mState.pack.alignment);
+    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.pack, 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)
 {
-    if (!mState.currentProgram)
-    {
-        return gl::error(GL_INVALID_OPERATION);
-    }
+    ASSERT(mState.getCurrentProgramId() != 0);
 
-    ProgramBinary *programBinary = getCurrentProgramBinary();
-    programBinary->applyUniforms();
+    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, getCurrentVertexArray()->getVertexAttributes(), mState.vertexAttribCurrentValues, 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())
     {
         return;
     }
 
-    if (!programBinary->validateSamplers(NULL))
-    {
-        return gl::error(GL_INVALID_OPERATION);
-    }
-
     if (!skipDraw(mode))
     {
         mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
@@ -2940,59 +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)
 {
-    if (!mState.currentProgram)
-    {
-        return gl::error(GL_INVALID_OPERATION);
-    }
+    ASSERT(mState.getCurrentProgramId() != 0);
 
-    VertexArray *vao = getCurrentVertexArray();
-    if (!indices && !vao->getElementArrayBuffer())
-    {
-        return gl::error(GL_INVALID_OPERATION);
-    }
+    ProgramBinary *programBinary = mState.getCurrentProgramBinary();
+    programBinary->updateSamplerMapping();
 
-    ProgramBinary *programBinary = getCurrentProgramBinary();
-    programBinary->applyUniforms();
-
-    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.vertexAttribCurrentValues, 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();
@@ -3002,22 +1755,13 @@
 
     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())
     {
         return;
     }
 
-    if (!programBinary->validateSamplers(NULL))
-    {
-        return gl::error(GL_INVALID_OPERATION);
-    }
-
     if (!skipDraw(mode))
     {
         mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
@@ -3030,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()
@@ -3131,241 +1832,56 @@
     return mClientVersion;
 }
 
-int Context::getMajorShaderModel() const
+const Caps &Context::getCaps() const
 {
-    return mMajorShaderModel;
+    return mCaps;
 }
 
-float Context::getMaximumPointSize() const
+const TextureCapsMap &Context::getTextureCaps() const
 {
-    return mMaximumPointSize;
+    return mTextureCaps;
 }
 
-unsigned int Context::getMaximumCombinedTextureImageUnits() const
+const Extensions &Context::getExtensions() const
 {
-    return mRenderer->getMaxCombinedTextureImageUnits();
-}
-
-unsigned int Context::getMaximumCombinedUniformBufferBindings() const
-{
-    return mRenderer->getMaxVertexShaderUniformBuffers() +
-           mRenderer->getMaxFragmentShaderUniformBuffers();
-}
-
-int Context::getMaxSupportedSamples() const
-{
-    return mRenderer->getMaxSupportedSamples();
-}
-
-GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const
-{
-    return mRenderer->getMaxSupportedFormatSamples(internalFormat);
-}
-
-GLsizei Context::getNumSampleCounts(GLenum internalFormat) const
-{
-    return mRenderer->getNumSampleCounts(internalFormat);
-}
-
-void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
-{
-    mRenderer->getSampleCounts(internalFormat, bufSize, params);
-}
-
-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());
-}
-
-unsigned int Context::getMaximumRenderTargets() const
-{
-    return mRenderer->getMaxRenderTargets();
-}
-
-bool Context::supportsEventQueries() const
-{
-    return mSupportsEventQueries;
-}
-
-bool Context::supportsOcclusionQueries() const
-{
-    return mSupportsOcclusionQueries;
-}
-
-bool Context::supportsBGRATextures() const
-{
-    return mSupportsBGRATextures;
-}
-
-bool Context::supportsDXT1Textures() const
-{
-    return mSupportsDXT1Textures;
-}
-
-bool Context::supportsDXT3Textures() const
-{
-    return mSupportsDXT3Textures;
-}
-
-bool Context::supportsDXT5Textures() const
-{
-    return mSupportsDXT5Textures;
-}
-
-bool Context::supportsFloat32Textures() const
-{
-    return mSupportsFloat32Textures;
-}
-
-bool Context::supportsFloat32LinearFilter() const
-{
-    return mSupportsFloat32LinearFilter;
-}
-
-bool Context::supportsFloat32RenderableTextures() const
-{
-    return mSupportsFloat32RenderableTextures;
-}
-
-bool Context::supportsFloat16Textures() const
-{
-    return mSupportsFloat16Textures;
-}
-
-bool Context::supportsFloat16LinearFilter() const
-{
-    return mSupportsFloat16LinearFilter;
-}
-
-bool Context::supportsFloat16RenderableTextures() const
-{
-    return mSupportsFloat16RenderableTextures;
-}
-
-int Context::getMaximumRenderbufferDimension() const
-{
-    return mMaxRenderbufferDimension;
-}
-
-int Context::getMaximum2DTextureDimension() const
-{
-    return mMax2DTextureDimension;
-}
-
-int Context::getMaximumCubeTextureDimension() const
-{
-    return mMaxCubeTextureDimension;
-}
-
-int Context::getMaximum3DTextureDimension() const
-{
-    return mMax3DTextureDimension;
-}
-
-int Context::getMaximum2DArrayTextureLayers() const
-{
-    return mMax2DArrayTextureLayers;
-}
-
-int Context::getMaximum2DTextureLevel() const
-{
-    return mMax2DTextureLevel;
-}
-
-int Context::getMaximumCubeTextureLevel() const
-{
-    return mMaxCubeTextureLevel;
-}
-
-int Context::getMaximum3DTextureLevel() const
-{
-    return mMax3DTextureLevel;
-}
-
-int Context::getMaximum2DArrayTextureLevel() const
-{
-    return mMax2DArrayTextureLevel;
-}
-
-bool Context::supportsLuminanceTextures() const
-{
-    return mSupportsLuminanceTextures;
-}
-
-bool Context::supportsLuminanceAlphaTextures() const
-{
-    return mSupportsLuminanceAlphaTextures;
-}
-
-bool Context::supportsRGTextures() const
-{
-    return mSupportsRGTextures;
-}
-
-bool Context::supportsDepthTextures() const
-{
-    return mSupportsDepthTextures;
-}
-
-bool Context::supports32bitIndices() const
-{
-    return mSupports32bitIndices;
-}
-
-bool Context::supportsNonPower2Texture() const
-{
-    return mSupportsNonPower2Texture;
-}
-
-bool Context::supportsInstancing() const
-{
-    return mSupportsInstancing;
-}
-
-bool Context::supportsTextureFilterAnisotropy() const
-{
-    return mSupportsTextureFilterAnisotropy;
-}
-
-bool Context::supportsPBOs() const
-{
-    return mSupportsPBOs;
-}
-
-float Context::getTextureMaxAnisotropy() const
-{
-    return mMaxTextureAnisotropy;
+    return mExtensions;
 }
 
 void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
 {
-    Framebuffer *framebuffer = getReadFramebuffer();
+    Framebuffer *framebuffer = mState.getReadFramebuffer();
     ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE);
 
     FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
     ASSERT(attachment);
 
-    *internalFormat = attachment->getActualFormat();
-    *format = gl::GetFormat(attachment->getActualFormat(), mClientVersion);
-    *type = gl::GetType(attachment->getActualFormat(), mClientVersion);
+    GLenum actualFormat = attachment->getActualFormat();
+    const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualFormat);
+
+    *internalFormat = actualFormat;
+    *format = actualFormatInfo.format;
+    *type = actualFormatInfo.type;
+}
+
+void Context::detachTexture(GLuint texture)
+{
+    // Simple pass-through to State's detachTexture method, as textures do not require
+    // allocation map management either here or in the resource manager at detach time.
+    // Zero textures are held by the Context, and we don't attempt to request them from
+    // the State.
+    mState.detachTexture(texture);
 }
 
 void Context::detachBuffer(GLuint buffer)
 {
+    // Buffer detachment is handled by Context, because the buffer must also be 
+    // attached from any VAOs in existence, and Context holds the VAO map.
+
     // [OpenGL ES 2.0.24] section 2.9 page 22:
     // If a buffer object is deleted while it is bound, all bindings to that object in the current context
     // (i.e. in the thread that called Delete-Buffers) are reset to zero.
 
-    if (mState.arrayBuffer.id() == buffer)
-    {
-        mState.arrayBuffer.set(NULL);
-    }
+    mState.removeArrayBufferBinding(buffer);
 
     // mark as freed among the vertex array objects
     for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++)
@@ -3374,54 +1890,22 @@
     }
 }
 
-void Context::detachTexture(GLuint texture)
-{
-    // [OpenGL ES 2.0.24] section 3.8 page 84:
-    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
-    // rebound to texture object zero
-
-    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
-    {
-        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
-        {
-            if (mState.samplerTexture[type][sampler].id() == texture)
-            {
-                mState.samplerTexture[type][sampler].set(NULL);
-            }
-        }
-    }
-
-    // [OpenGL ES 2.0.24] section 4.4 page 112:
-    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
-    // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
-    // image was attached in the currently bound framebuffer.
-
-    Framebuffer *readFramebuffer = getReadFramebuffer();
-    Framebuffer *drawFramebuffer = getDrawFramebuffer();
-
-    if (readFramebuffer)
-    {
-        readFramebuffer->detachTexture(texture);
-    }
-
-    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
-    {
-        drawFramebuffer->detachTexture(texture);
-    }
-}
-
 void Context::detachFramebuffer(GLuint framebuffer)
 {
+    // Framebuffer detachment is handled by Context, because 0 is a valid
+    // Framebuffer object, and a pointer to it must be passed from Context
+    // to State at binding time.
+
     // [OpenGL ES 2.0.24] section 4.4 page 107:
     // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
     // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
 
-    if (mState.readFramebuffer == framebuffer)
+    if (mState.removeReadFramebufferBinding(framebuffer))
     {
         bindReadFramebuffer(0);
     }
 
-    if (mState.drawFramebuffer == framebuffer)
+    if (mState.removeDrawFramebufferBinding(framebuffer))
     {
         bindDrawFramebuffer(0);
     }
@@ -3429,40 +1913,19 @@
 
 void Context::detachRenderbuffer(GLuint renderbuffer)
 {
-    // [OpenGL ES 2.0.24] section 4.4 page 109:
-    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
-    // had been executed with the target RENDERBUFFER and name of zero.
-
-    if (mState.renderbuffer.id() == renderbuffer)
-    {
-        bindRenderbuffer(0);
-    }
-
-    // [OpenGL ES 2.0.24] section 4.4 page 111:
-    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
-    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
-    // point to which this image was attached in the currently bound framebuffer.
-
-    Framebuffer *readFramebuffer = getReadFramebuffer();
-    Framebuffer *drawFramebuffer = getDrawFramebuffer();
-
-    if (readFramebuffer)
-    {
-        readFramebuffer->detachRenderbuffer(renderbuffer);
-    }
-
-    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
-    {
-        drawFramebuffer->detachRenderbuffer(renderbuffer);
-    }
+    mState.detachRenderbuffer(renderbuffer);
 }
 
 void Context::detachVertexArray(GLuint vertexArray)
 {
+    // Vertex array detachment is handled by Context, because 0 is a valid 
+    // VAO, and a pointer to it must be passed from Context to State at 
+    // binding time.
+
     // [OpenGL ES 3.0.2] section 2.10 page 43:
     // If a vertex array object that is currently bound is deleted, the binding
     // for that object reverts to zero and the default vertex array becomes current.
-    if (mState.vertexArray == vertexArray)
+    if (mState.removeVertexArrayBinding(vertexArray))
     {
         bindVertexArray(0);
     }
@@ -3470,53 +1933,39 @@
 
 void Context::detachTransformFeedback(GLuint transformFeedback)
 {
-    if (mState.transformFeedback.id() == transformFeedback)
-    {
-        bindTransformFeedback(0);
-    }
+    mState.detachTransformFeedback(transformFeedback);
 }
 
 void Context::detachSampler(GLuint sampler)
 {
-    // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
-    // 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(mState.samplers); textureUnit++)
-    {
-        if (mState.samplers[textureUnit] == sampler)
-        {
-            mState.samplers[textureUnit] = 0;
-        }
-    }
+    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, 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, 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);
@@ -3529,18 +1978,18 @@
             }
             break;
 
-          case TEXTURE_3D:
+          case GL_TEXTURE_3D:
             {
-                Texture3D *incomplete3d = new Texture3D(mRenderer, 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, 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;
@@ -3551,7 +2000,7 @@
         mIncompleteTextures[type].set(t);
     }
 
-    return t;
+    return mIncompleteTextures[type].get();
 }
 
 bool Context::skipDraw(GLenum drawMode)
@@ -3561,7 +2010,7 @@
         // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
         // which affects varying interpolation. Since the value of gl_PointSize is
         // undefined when not written, just skip drawing to avoid unexpected results.
-        if (!getCurrentProgramBinary()->usesPointSize())
+        if (!mState.getCurrentProgramBinary()->usesPointSize())
         {
             // This is stictly speaking not an error, but developers should be
             // notified of risking undefined behavior.
@@ -3572,7 +2021,7 @@
     }
     else if (IsTriangleMode(drawMode))
     {
-        if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
+        if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
         {
             return true;
         }
@@ -3581,27 +2030,9 @@
     return false;
 }
 
-void Context::setVertexAttribf(GLuint index, const GLfloat values[4])
-{
-    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
-    mState.vertexAttribCurrentValues[index].setFloatValues(values);
-}
-
-void Context::setVertexAttribu(GLuint index, const GLuint values[4])
-{
-    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
-    mState.vertexAttribCurrentValues[index].setUnsignedIntValues(values);
-}
-
-void Context::setVertexAttribi(GLuint index, const GLint values[4])
-{
-    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
-    mState.vertexAttribCurrentValues[index].setIntValues(values);
-}
-
 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
 {
-    getCurrentVertexArray()->setVertexAttribDivisor(index, divisor);
+    mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
 }
 
 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
@@ -3640,8 +2071,8 @@
       case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(uiround<GLenum>(param));           break;
       case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(uiround<GLenum>(param));           break;
       case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(uiround<GLenum>(param));           break;
-      case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                                      break;
-      case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                                      break;
+      case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                           break;
+      case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                           break;
       case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(uiround<GLenum>(param));  break;
       case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(uiround<GLenum>(param));  break;
       default:                       UNREACHABLE(); break;
@@ -3692,175 +2123,6 @@
     }
 }
 
-// keep list sorted in following order
-// OES extensions
-// EXT extensions
-// Vendor extensions
-void Context::initExtensionString()
-{
-    // Do not report extension in GLES 3 contexts for now
-    if (mClientVersion == 2)
-    {
-        // OES extensions
-        if (supports32bitIndices())
-        {
-            mExtensionStringList.push_back("GL_OES_element_index_uint");
-        }
-
-        mExtensionStringList.push_back("GL_OES_packed_depth_stencil");
-        mExtensionStringList.push_back("GL_OES_get_program_binary");
-        mExtensionStringList.push_back("GL_OES_rgb8_rgba8");
-
-        if (supportsPBOs())
-        {
-            mExtensionStringList.push_back("NV_pixel_buffer_object");
-            mExtensionStringList.push_back("GL_OES_mapbuffer");
-            mExtensionStringList.push_back("GL_EXT_map_buffer_range");
-        }
-
-        if (mRenderer->getDerivativeInstructionSupport())
-        {
-            mExtensionStringList.push_back("GL_OES_standard_derivatives");
-        }
-
-        if (supportsFloat16Textures())
-        {
-            mExtensionStringList.push_back("GL_OES_texture_half_float");
-        }
-        if (supportsFloat16LinearFilter())
-        {
-            mExtensionStringList.push_back("GL_OES_texture_half_float_linear");
-        }
-        if (supportsFloat32Textures())
-        {
-            mExtensionStringList.push_back("GL_OES_texture_float");
-        }
-        if (supportsFloat32LinearFilter())
-        {
-            mExtensionStringList.push_back("GL_OES_texture_float_linear");
-        }
-
-        if (supportsRGTextures())
-        {
-            mExtensionStringList.push_back("GL_EXT_texture_rg");
-        }
-
-        if (supportsNonPower2Texture())
-        {
-            mExtensionStringList.push_back("GL_OES_texture_npot");
-        }
-
-        // Multi-vendor (EXT) extensions
-        if (supportsOcclusionQueries())
-        {
-            mExtensionStringList.push_back("GL_EXT_occlusion_query_boolean");
-        }
-
-        mExtensionStringList.push_back("GL_EXT_read_format_bgra");
-        mExtensionStringList.push_back("GL_EXT_robustness");
-        mExtensionStringList.push_back("GL_EXT_shader_texture_lod");
-
-        if (supportsDXT1Textures())
-        {
-            mExtensionStringList.push_back("GL_EXT_texture_compression_dxt1");
-        }
-
-        if (supportsTextureFilterAnisotropy())
-        {
-            mExtensionStringList.push_back("GL_EXT_texture_filter_anisotropic");
-        }
-
-        if (supportsBGRATextures())
-        {
-            mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
-        }
-
-        if (mRenderer->getMaxRenderTargets() > 1)
-        {
-            mExtensionStringList.push_back("GL_EXT_draw_buffers");
-        }
-
-        mExtensionStringList.push_back("GL_EXT_texture_storage");
-        mExtensionStringList.push_back("GL_EXT_frag_depth");
-        mExtensionStringList.push_back("GL_EXT_blend_minmax");
-
-        // ANGLE-specific extensions
-        if (supportsDepthTextures())
-        {
-            mExtensionStringList.push_back("GL_ANGLE_depth_texture");
-        }
-
-        mExtensionStringList.push_back("GL_ANGLE_framebuffer_blit");
-        if (getMaxSupportedSamples() != 0)
-        {
-            mExtensionStringList.push_back("GL_ANGLE_framebuffer_multisample");
-        }
-
-        if (supportsInstancing())
-        {
-            mExtensionStringList.push_back("GL_ANGLE_instanced_arrays");
-        }
-
-        mExtensionStringList.push_back("GL_ANGLE_pack_reverse_row_order");
-
-        if (supportsDXT3Textures())
-        {
-            mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt3");
-        }
-        if (supportsDXT5Textures())
-        {
-            mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt5");
-        }
-
-        mExtensionStringList.push_back("GL_ANGLE_texture_usage");
-        mExtensionStringList.push_back("GL_ANGLE_translated_shader_source");
-
-        // Other vendor-specific extensions
-        if (supportsEventQueries())
-        {
-            mExtensionStringList.push_back("GL_NV_fence");
-        }
-    }
-
-    if (mClientVersion == 3)
-    {
-        mExtensionStringList.push_back("GL_EXT_color_buffer_float");
-
-        mExtensionStringList.push_back("GL_EXT_read_format_bgra");
-
-        if (supportsBGRATextures())
-        {
-            mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
-        }
-    }
-
-    // Join the extension strings to one long string for use with GetString
-    std::stringstream strstr;
-    for (unsigned int extensionIndex = 0; extensionIndex < mExtensionStringList.size(); extensionIndex++)
-    {
-        strstr << mExtensionStringList[extensionIndex];
-        strstr << " ";
-    }
-
-    mCombinedExtensionsString = makeStaticString(strstr.str());
-}
-
-const char *Context::getCombinedExtensionsString() const
-{
-    return mCombinedExtensionsString;
-}
-
-const char *Context::getExtensionString(const GLuint index) const
-{
-    ASSERT(index < mExtensionStringList.size());
-    return mExtensionStringList[index].c_str();
-}
-
-unsigned int Context::getNumExtensions() const
-{
-    return mExtensionStringList.size();
-}
-
 void Context::initRendererString()
 {
     std::ostringstream rendererString;
@@ -3868,32 +2130,58 @@
     rendererString << mRenderer->getRendererDescription();
     rendererString << ")";
 
-    mRendererString = makeStaticString(rendererString.str());
+    mRendererString = MakeStaticString(rendererString.str());
 }
 
-const char *Context::getRendererString() const
+const std::string &Context::getRendererString() const
 {
     return mRendererString;
 }
 
+void Context::initExtensionStrings()
+{
+    mExtensionStrings = mExtensions.getStrings();
+
+    std::ostringstream combinedStringStream;
+    std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
+    mExtensionString = combinedStringStream.str();
+}
+
+const std::string &Context::getExtensionString() const
+{
+    return mExtensionString;
+}
+
+const std::string &Context::getExtensionString(size_t idx) const
+{
+    return mExtensionStrings[idx];
+}
+
+size_t Context::getExtensionStringCount() const
+{
+    return mExtensionStrings.size();
+}
+
 size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
 {
     size_t serialCount = 0;
 
-    Framebuffer *drawFramebuffer = getDrawFramebuffer();
+    Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
     {
         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);
@@ -3904,8 +2192,8 @@
 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                               GLbitfield mask, GLenum filter)
 {
-    Framebuffer *readFramebuffer = getReadFramebuffer();
-    Framebuffer *drawFramebuffer = getDrawFramebuffer();
+    Framebuffer *readFramebuffer = mState.getReadFramebuffer();
+    Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
 
     bool blitRenderTarget = false;
     bool blitDepth = false;
@@ -3923,114 +2211,79 @@
         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.scissorTest ? &mState.scissor : 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 = getDrawFramebuffer();
-        break;
-      case GL_READ_FRAMEBUFFER:
-        frameBuffer = 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();
 }
 
-bool Context::hasMappedBuffer(GLenum target) const
+void Context::initCaps(GLuint clientVersion)
 {
-    if (target == GL_ARRAY_BUFFER)
+    mCaps = mRenderer->getRendererCaps();
+
+    mExtensions = mRenderer->getRendererExtensions();
+
+    if (clientVersion < 3)
     {
-        for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
+        // Disable ES3+ extensions
+        mExtensions.colorBufferFloat = false;
+    }
+
+    if (clientVersion > 2)
+    {
+        // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
+        //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++)
+    {
+        GLenum format = i->first;
+        TextureCaps formatCaps = i->second;
+
+        const InternalFormat &formatInfo = GetInternalFormatInfo(format);
+        if (formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions))
         {
-            const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
-            gl::Buffer *boundBuffer = vertexAttrib.mBoundBuffer.get();
-            if (vertexAttrib.mArrayEnabled && boundBuffer && boundBuffer->mapped())
+            // Update the format caps based on the client version and extensions
+            formatCaps.renderable = formatInfo.renderSupport(clientVersion, mExtensions);
+            formatCaps.filterable = formatInfo.filterSupport(clientVersion, mExtensions);
+
+            // OpenGL ES does not support multisampling with integer formats
+            if (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
             {
-                return true;
+                formatCaps.sampleCounts.clear();
             }
+            maxSamples = std::max(maxSamples, formatCaps.getMaxSamples());
+
+            if (formatInfo.compressed)
+            {
+                mCaps.compressedTextureFormats.push_back(format);
+            }
+
+            mTextureCaps.insert(format, formatCaps);
         }
     }
-    else if (target == GL_ELEMENT_ARRAY_BUFFER)
-    {
-        Buffer *elementBuffer = getElementArrayBuffer();
-        return (elementBuffer && elementBuffer->mapped());
-    }
-    else if (target == GL_TRANSFORM_FEEDBACK_BUFFER)
-    {
-        UNIMPLEMENTED();
-    }
-    else UNREACHABLE();
-    return false;
+
+    mExtensions.maxSamples = maxSamples;
 }
 
 }
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index ab79004..bf886a8 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -10,11 +10,17 @@
 #ifndef LIBGLESV2_CONTEXT_H_
 #define LIBGLESV2_CONTEXT_H_
 
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.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 <string>
 #include <set>
@@ -22,13 +28,6 @@
 #include <unordered_map>
 #include <array>
 
-#include "common/angleutils.h"
-#include "common/RefCountObject.h"
-#include "libGLESv2/HandleAllocator.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/VertexAttribute.h"
-
 namespace rx
 {
 class Renderer;
@@ -50,7 +49,7 @@
 class Texture3D;
 class Texture2DArray;
 class Framebuffer;
-class FramebufferAttachment;
+class Renderbuffer;
 class RenderbufferStorage;
 class Colorbuffer;
 class Depthbuffer;
@@ -61,71 +60,11 @@
 class Query;
 class ResourceManager;
 class Buffer;
-class VertexAttribute;
+struct VertexAttribute;
 class VertexArray;
 class Sampler;
 class TransformFeedback;
 
-// Helper structure to store all raw state
-struct State
-{
-    ColorF colorClearValue;
-    GLclampf depthClearValue;
-    int stencilClearValue;
-
-    RasterizerState rasterizer;
-    bool scissorTest;
-    Rectangle scissor;
-
-    BlendState blend;
-    ColorF blendColor;
-    bool sampleCoverage;
-    GLclampf sampleCoverageValue;
-    bool sampleCoverageInvert;
-
-    DepthStencilState depthStencil;
-    GLint stencilRef;
-    GLint stencilBackRef;
-
-    GLfloat lineWidth;
-
-    GLenum generateMipmapHint;
-    GLenum fragmentShaderDerivativeHint;
-
-    Rectangle viewport;
-    float zNear;
-    float zFar;
-
-    unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0
-    BindingPointer<Buffer> arrayBuffer;
-    GLuint readFramebuffer;
-    GLuint drawFramebuffer;
-    BindingPointer<FramebufferAttachment> renderbuffer;
-    GLuint currentProgram;
-
-    VertexAttribCurrentValueData vertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
-    unsigned int vertexArray;
-
-    BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-    GLuint samplers[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
-    typedef std::map< GLenum, BindingPointer<Query> > ActiveQueryMap;
-    ActiveQueryMap activeQueries;
-
-    BindingPointer<Buffer> genericUniformBuffer;
-    OffsetBindingPointer<Buffer> uniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
-
-    BindingPointer<TransformFeedback> transformFeedback;
-    BindingPointer<Buffer> genericTransformFeedbackBuffer;
-    OffsetBindingPointer<Buffer> transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
-
-    BindingPointer<Buffer> copyReadBuffer;
-    BindingPointer<Buffer> copyWriteBuffer;
-
-    PixelUnpackState unpack;
-    PixelPackState pack;
-};
-
 class Context
 {
   public:
@@ -138,115 +77,6 @@
     virtual void markContextLost();
     bool isContextLost();
 
-    // State manipulation
-    void setCap(GLenum cap, bool enabled);
-    bool getCap(GLenum cap);
-
-    void setClearColor(float red, float green, float blue, float alpha);
-
-    void setClearDepth(float depth);
-
-    void setClearStencil(int stencil);
-
-    void setRasterizerDiscard(bool enabled);
-    bool isRasterizerDiscardEnabled() const;
-
-    void setCullFace(bool enabled);
-    bool isCullFaceEnabled() const;
-
-    void setCullMode(GLenum mode);
-
-    void setFrontFace(GLenum front);
-
-    void setDepthTest(bool enabled);
-    bool isDepthTestEnabled() const;
-
-    void setDepthFunc(GLenum depthFunc);
-
-    void setDepthRange(float zNear, float zFar);
-    
-    void setBlend(bool enabled);
-    bool isBlendEnabled() const;
-
-    void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
-    void setBlendColor(float red, float green, float blue, float alpha);
-    void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
-
-    void setStencilTest(bool enabled);
-    bool isStencilTestEnabled() const;
-
-    void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
-    void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
-    void setStencilWritemask(GLuint stencilWritemask);
-    void setStencilBackWritemask(GLuint stencilBackWritemask);
-    void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);
-    void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass);
-
-    void setPolygonOffsetFill(bool enabled);
-    bool isPolygonOffsetFillEnabled() const;
-
-    void setPolygonOffsetParams(GLfloat factor, GLfloat units);
-
-    void setSampleAlphaToCoverage(bool enabled);
-    bool isSampleAlphaToCoverageEnabled() const;
-
-    void setSampleCoverage(bool enabled);
-    bool isSampleCoverageEnabled() const;
-
-    void setSampleCoverageParams(GLclampf value, bool invert);
-
-    void setScissorTest(bool enabled);
-    bool isScissorTestEnabled() const;
-
-    void setDither(bool enabled);
-    bool isDitherEnabled() const;
-
-    void setLineWidth(GLfloat width);
-
-    void setGenerateMipmapHint(GLenum hint);
-    void setFragmentShaderDerivativeHint(GLenum hint);
-
-    void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
-
-    void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
-    void getScissorParams(GLint *x, GLint *y, GLsizei *width, GLsizei *height);
-
-    void setColorMask(bool red, bool green, bool blue, bool alpha);
-    void setDepthMask(bool mask);
-
-    void setActiveSampler(unsigned int active);
-
-    GLuint getReadFramebufferHandle() const;
-    GLuint getDrawFramebufferHandle() const;
-    GLuint getRenderbufferHandle() const;
-    GLuint getVertexArrayHandle() const;
-    GLuint getSamplerHandle(GLuint textureUnit) const;
-    unsigned int getActiveSampler() const;
-
-    GLuint getArrayBufferHandle() const;
-
-    bool isQueryActive() const;
-    const Query *getActiveQuery(GLenum target) const;
-    GLuint getActiveQueryId(GLenum target) const;
-
-    void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
-    const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
-    const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
-    void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
-                              bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
-    const void *getVertexAttribPointer(unsigned int attribNum) const;
-
-    void setUnpackAlignment(GLint alignment);
-    GLint getUnpackAlignment() const;
-    const PixelUnpackState &getUnpackState() const;
-
-    void setPackAlignment(GLint alignment);
-    GLint getPackAlignment() const;
-    const PixelPackState &getPackState() const;
-
-    void setPackReverseRowOrder(bool reverseRowOrder);
-    bool getPackReverseRowOrder() const;
-
     // These create  and destroy methods are merely pass-throughs to 
     // ResourceManager, which owns these object types
     GLuint createBuffer();
@@ -285,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);
@@ -304,19 +131,16 @@
     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);
 
     void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
 
-    void setVertexAttribf(GLuint index, const GLfloat values[4]);
-    void setVertexAttribu(GLuint index, const GLuint values[4]);
-    void setVertexAttribi(GLuint index, const GLint values[4]);
     void setVertexAttribDivisor(GLuint index, GLuint divisor);
 
     void samplerParameteri(GLuint sampler, GLenum pname, GLint param);
@@ -329,39 +153,21 @@
     FenceSync *getFenceSync(GLsync handle) const;
     Shader *getShader(GLuint handle) const;
     Program *getProgram(GLuint handle) const;
-    Texture *getTexture(GLuint handle);
+    Texture *getTexture(GLuint handle) const;
     Framebuffer *getFramebuffer(GLuint handle) const;
-    FramebufferAttachment *getRenderbuffer(GLuint handle);
+    Renderbuffer *getRenderbuffer(GLuint handle);
     VertexArray *getVertexArray(GLuint handle) const;
     Sampler *getSampler(GLuint handle) const;
     Query *getQuery(GLuint handle, bool create, GLenum type);
     TransformFeedback *getTransformFeedback(GLuint handle) const;
 
-    Buffer *getTargetBuffer(GLenum target) const;
-    Buffer *getArrayBuffer();
-    Buffer *getElementArrayBuffer() const;
-    ProgramBinary *getCurrentProgramBinary();
-
     Texture *getTargetTexture(GLenum target) const;
     Texture2D *getTexture2D() const;
     TextureCubeMap *getTextureCubeMap() const;
     Texture3D *getTexture3D() const;
     Texture2DArray *getTexture2DArray() const;
 
-    Buffer *getGenericUniformBuffer();
-    Buffer *getGenericTransformFeedbackBuffer();
-    Buffer *getCopyReadBuffer();
-    Buffer *getCopyWriteBuffer();
-    Buffer *getPixelPackBuffer();
-    Buffer *getPixelUnpackBuffer();
-    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
-
-    Framebuffer *getTargetFramebuffer(GLenum target) const;
-    GLuint getTargetFramebufferHandle(GLenum target) const;
-    Framebuffer *getReadFramebuffer();
-    Framebuffer *getDrawFramebuffer();
-    VertexArray *getCurrentVertexArray() const;
-    TransformFeedback *getCurrentTransformFeedback() const;
+    Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
 
     bool isSampler(GLuint samplerName) const;
 
@@ -376,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();
@@ -399,78 +203,40 @@
 
     virtual int getClientVersion() const;
 
-    int getMajorShaderModel() const;
-    float getMaximumPointSize() const;
-    unsigned int getMaximumCombinedTextureImageUnits() const;
-    unsigned int getMaximumCombinedUniformBufferBindings() const;
-    int getMaximumRenderbufferDimension() const;
-    int getMaximum2DTextureDimension() const;
-    int getMaximumCubeTextureDimension() const;
-    int getMaximum3DTextureDimension() const;
-    int getMaximum2DArrayTextureLayers() const;
-    int getMaximum2DTextureLevel() const;
-    int getMaximumCubeTextureLevel() const;
-    int getMaximum3DTextureLevel() const;
-    int getMaximum2DArrayTextureLevel() const;
-    unsigned int getMaximumRenderTargets() const;
-    GLsizei getMaxSupportedSamples() const;
-    GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const;
-    GLsizei getNumSampleCounts(GLenum internalFormat) const;
-    void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const;
-    unsigned int getMaxTransformFeedbackBufferBindings() const;
-    GLintptr getUniformBufferOffsetAlignment() const;
-    const char *getCombinedExtensionsString() const;
-    const char *getExtensionString(const GLuint index) const;
-    unsigned int getNumExtensions() const;
-    const char *getRendererString() const;
-    bool supportsEventQueries() const;
-    bool supportsOcclusionQueries() const;
-    bool supportsBGRATextures() const;
-    bool supportsDXT1Textures() const;
-    bool supportsDXT3Textures() const;
-    bool supportsDXT5Textures() const;
-    bool supportsFloat32Textures() const;
-    bool supportsFloat32LinearFilter() const;
-    bool supportsFloat32RenderableTextures() const;
-    bool supportsFloat16Textures() const;
-    bool supportsFloat16LinearFilter() const;
-    bool supportsFloat16RenderableTextures() const;
-    bool supportsLuminanceTextures() const;
-    bool supportsLuminanceAlphaTextures() const;
-    bool supportsRGTextures() const;
-    bool supportsDepthTextures() const;
-    bool supports32bitIndices() const;
-    bool supportsNonPower2Texture() const;
-    bool supportsInstancing() const;
-    bool supportsTextureFilterAnisotropy() const;
-    bool supportsPBOs() const;
+    const Caps &getCaps() const;
+    const TextureCapsMap &getTextureCaps() const;
+    const Extensions &getExtensions() const;
+
+    const std::string &getRendererString() const;
+
+    const std::string &getExtensionString() const;
+    const std::string &getExtensionString(size_t idx) const;
+    size_t getExtensionStringCount() const;
 
     void getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type);
 
-    float getTextureMaxAnisotropy() const;
-
     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);
-
-    bool hasMappedBuffer(GLenum target) const;
-
     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();
@@ -483,28 +249,33 @@
     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);
 
-    void initExtensionString();
     void initRendererString();
+    void initExtensionStrings();
 
     size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray);
 
+    void initCaps(GLuint clientVersion);
+
+    // Caps to use for validation
+    Caps mCaps;
+    TextureCapsMap mTextureCaps;
+    Extensions mExtensions;
+
     rx::Renderer *const mRenderer;
+    State mState;
 
     int mClientVersion;
 
-    State mState;
-
-    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;
@@ -527,18 +298,13 @@
     TransformFeedbackMap mTransformFeedbackMap;
     HandleAllocator mTransformFeedbackAllocator;
 
-    std::vector<std::string> mExtensionStringList;
-    const char *mCombinedExtensionsString;
-    const char *mRendererString;
-    
-    BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
+    std::string mRendererString;
+    std::string mExtensionString;
+    std::vector<std::string> mExtensionStrings;
 
     // 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;
@@ -547,46 +313,6 @@
     GLenum mResetStrategy;
     bool mRobustAccess;
 
-    BindingPointer<ProgramBinary> mCurrentProgramBinary;
-    Framebuffer *mBoundDrawFramebuffer;
-
-    int mMajorShaderModel;
-    float mMaximumPointSize;
-    bool mSupportsVertexTexture;
-    bool mSupportsNonPower2Texture;
-    bool mSupportsInstancing;
-    int  mMaxViewportDimension;
-    int  mMaxRenderbufferDimension;
-    int  mMax2DTextureDimension;
-    int  mMaxCubeTextureDimension;
-    int  mMax3DTextureDimension;
-    int  mMax2DArrayTextureLayers;
-    int  mMax2DTextureLevel;
-    int  mMaxCubeTextureLevel;
-    int  mMax3DTextureLevel;
-    int  mMax2DArrayTextureLevel;
-    float mMaxTextureAnisotropy;
-    bool mSupportsEventQueries;
-    bool mSupportsOcclusionQueries;
-    bool mSupportsBGRATextures;
-    bool mSupportsDXT1Textures;
-    bool mSupportsDXT3Textures;
-    bool mSupportsDXT5Textures;
-    bool mSupportsFloat32Textures;
-    bool mSupportsFloat32LinearFilter;
-    bool mSupportsFloat32RenderableTextures;
-    bool mSupportsFloat16Textures;
-    bool mSupportsFloat16LinearFilter;
-    bool mSupportsFloat16RenderableTextures;
-    bool mSupportsLuminanceTextures;
-    bool mSupportsLuminanceAlphaTextures;
-    bool mSupportsRGTextures;
-    bool mSupportsDepthTextures;
-    bool mSupports32bitIndices;
-    bool mSupportsTextureFilterAnisotropy;
-    bool mSupportsPBOs;
-    int mNumCompressedTextureFormats;
-
     ResourceManager *mResourceManager;
 };
 }
diff --git a/src/libGLESv2/DynamicHLSL.cpp b/src/libGLESv2/DynamicHLSL.cpp
deleted file mode 100644
index 20e4a20..0000000
--- a/src/libGLESv2/DynamicHLSL.cpp
+++ /dev/null
@@ -1,1057 +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.cpp: Implementation for link and run-time HLSL generation
-//
-
-#include "precompiled.h"
-
-#include "libGLESv2/DynamicHLSL.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/blocklayout.h"
-
-static std::string Str(int i)
-{
-    char buffer[20];
-    snprintf(buffer, sizeof(buffer), "%d", i);
-    return buffer;
-}
-
-namespace gl_d3d
-{
-
-std::string HLSLComponentTypeString(GLenum componentType)
-{
-    switch (componentType)
-    {
-      case GL_UNSIGNED_INT:         return "uint";
-      case GL_INT:                  return "int";
-      case GL_UNSIGNED_NORMALIZED:
-      case GL_SIGNED_NORMALIZED:
-      case GL_FLOAT:                return "float";
-      default: UNREACHABLE();       return "not-component-type";
-    }
-}
-
-std::string HLSLComponentTypeString(GLenum componentType, int componentCount)
-{
-    return HLSLComponentTypeString(componentType) + (componentCount > 1 ? Str(componentCount) : "");
-}
-
-std::string HLSLMatrixTypeString(GLenum type)
-{
-    switch (type)
-    {
-      case GL_FLOAT_MAT2:     return "float2x2";
-      case GL_FLOAT_MAT3:     return "float3x3";
-      case GL_FLOAT_MAT4:     return "float4x4";
-      case GL_FLOAT_MAT2x3:   return "float2x3";
-      case GL_FLOAT_MAT3x2:   return "float3x2";
-      case GL_FLOAT_MAT2x4:   return "float2x4";
-      case GL_FLOAT_MAT4x2:   return "float4x2";
-      case GL_FLOAT_MAT3x4:   return "float3x4";
-      case GL_FLOAT_MAT4x3:   return "float4x3";
-      default: UNREACHABLE(); return "not-matrix-type";
-    }
-}
-
-std::string HLSLTypeString(GLenum type)
-{
-    if (gl::IsMatrixType(type))
-    {
-        return HLSLMatrixTypeString(type);
-    }
-
-    return HLSLComponentTypeString(gl::UniformComponentType(type), gl::UniformComponentCount(type));
-}
-
-}
-
-namespace gl
-{
-
-std::string ArrayString(unsigned int i)
-{
-    return (i == GL_INVALID_INDEX ? "" : "[" + Str(i) + "]");
-}
-
-const std::string DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
-
-DynamicHLSL::DynamicHLSL(rx::Renderer *const renderer)
-    : mRenderer(renderer)
-{
-}
-
-static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, VaryingPacking packing)
-{
-    GLenum transposedType = TransposeMatrixType(varying->type);
-
-    // matrices within varying structs are not transposed
-    int registers = (varying->isStruct() ? HLSLVariableRegisterCount(*varying) : VariableRowCount(transposedType)) * varying->elementCount();
-    int elements = (varying->isStruct() ? 4 : VariableColumnCount(transposedType));
-
-    if (elements >= 2 && elements <= 4)
-    {
-        for (int r = 0; r <= maxVaryingVectors - registers; r++)
-        {
-            bool available = true;
-
-            for (int y = 0; y < registers && available; y++)
-            {
-                for (int x = 0; x < elements && available; x++)
-                {
-                    if (packing[r + y][x])
-                    {
-                        available = false;
-                    }
-                }
-            }
-
-            if (available)
-            {
-                varying->registerIndex = r;
-
-                for (int y = 0; y < registers; y++)
-                {
-                    for (int x = 0; x < elements; x++)
-                    {
-                        packing[r + y][x] = &*varying;
-                    }
-                }
-
-                return true;
-            }
-        }
-
-        if (elements == 2)
-        {
-            for (int r = maxVaryingVectors - registers; r >= 0; r--)
-            {
-                bool available = true;
-
-                for (int y = 0; y < registers && available; y++)
-                {
-                    for (int x = 2; x < 4 && available; x++)
-                    {
-                        if (packing[r + y][x])
-                        {
-                            available = false;
-                        }
-                    }
-                }
-
-                if (available)
-                {
-                    varying->registerIndex = r;
-
-                    for (int y = 0; y < registers; y++)
-                    {
-                        for (int x = 2; x < 4; x++)
-                        {
-                            packing[r + y][x] = &*varying;
-                        }
-                    }
-
-                    return true;
-                }
-            }
-        }
-    }
-    else if (elements == 1)
-    {
-        int space[4] = { 0 };
-
-        for (int y = 0; y < maxVaryingVectors; y++)
-        {
-            for (int x = 0; x < 4; x++)
-            {
-                space[x] += packing[y][x] ? 0 : 1;
-            }
-        }
-
-        int column = 0;
-
-        for (int x = 0; x < 4; x++)
-        {
-            if (space[x] >= registers && space[x] < space[column])
-            {
-                column = x;
-            }
-        }
-
-        if (space[column] >= registers)
-        {
-            for (int r = 0; r < maxVaryingVectors; r++)
-            {
-                if (!packing[r][column])
-                {
-                    varying->registerIndex = r;
-
-                    for (int y = r; y < r + registers; y++)
-                    {
-                        packing[y][column] = &*varying;
-                    }
-
-                    break;
-                }
-            }
-
-            return true;
-        }
-    }
-    else UNREACHABLE();
-
-    return false;
-}
-
-// 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)
-{
-    const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
-
-    vertexShader->resetVaryingsRegisterAssignment();
-    fragmentShader->resetVaryingsRegisterAssignment();
-
-    std::set<std::string> packedVaryings;
-
-    for (unsigned int varyingIndex = 0; varyingIndex < fragmentShader->mVaryings.size(); varyingIndex++)
-    {
-        PackedVarying *varying = &fragmentShader->mVaryings[varyingIndex];
-        if (packVarying(varying, maxVaryingVectors, packing))
-        {
-            packedVaryings.insert(varying->name);
-        }
-        else
-        {
-            infoLog.append("Could not pack varying %s", varying->name.c_str());
-            return -1;
-        }
-    }
-
-    for (unsigned int feedbackVaryingIndex = 0; feedbackVaryingIndex < transformFeedbackVaryings.size(); feedbackVaryingIndex++)
-    {
-        const std::string &transformFeedbackVarying = transformFeedbackVaryings[feedbackVaryingIndex];
-        if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end())
-        {
-            bool found = false;
-            for (unsigned int varyingIndex = 0; varyingIndex < vertexShader->mVaryings.size(); varyingIndex++)
-            {
-                PackedVarying *varying = &vertexShader->mVaryings[varyingIndex];
-                if (transformFeedbackVarying == varying->name)
-                {
-                    if (!packVarying(varying, maxVaryingVectors, packing))
-                    {
-                        infoLog.append("Could not pack varying %s", varying->name.c_str());
-                        return -1;
-                    }
-
-                    found = true;
-                    break;
-                }
-            }
-
-            if (!found && transformFeedbackVarying != "gl_Position" && transformFeedbackVarying != "gl_PointSize")
-            {
-                infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str());
-                return -1;
-            }
-        }
-    }
-
-    // Return the number of used registers
-    int registers = 0;
-
-    for (int r = 0; r < maxVaryingVectors; r++)
-    {
-        if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
-        {
-            registers++;
-        }
-    }
-
-    return registers;
-}
-
-std::string DynamicHLSL::generateVaryingHLSL(VertexShader *shader, const std::string &varyingSemantic,
-                                             std::vector<LinkedVarying> *linkedVaryings) const
-{
-    std::string varyingHLSL;
-
-    for (unsigned int varyingIndex = 0; varyingIndex < shader->mVaryings.size(); varyingIndex++)
-    {
-        const PackedVarying &varying = shader->mVaryings[varyingIndex];
-        if (varying.registerAssigned())
-        {
-            GLenum transposedType = TransposeMatrixType(varying.type);
-            int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
-
-            for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++)
-            {
-                for (int row = 0; row < variableRows; row++)
-                {
-                    switch (varying.interpolation)
-                    {
-                      case INTERPOLATION_SMOOTH:   varyingHLSL += "    ";                 break;
-                      case INTERPOLATION_FLAT:     varyingHLSL += "    nointerpolation "; break;
-                      case INTERPOLATION_CENTROID: varyingHLSL += "    centroid ";        break;
-                      default:  UNREACHABLE();
-                    }
-
-                    unsigned int semanticIndex = elementIndex * variableRows + varying.registerIndex + row;
-                    std::string n = Str(semanticIndex);
-
-                    std::string typeString;
-
-                    if (varying.isStruct())
-                    {
-                        // matrices within structs are not transposed, so
-                        // do not use the special struct prefix "rm"
-                        typeString = decorateVariable(varying.structName);
-                    }
-                    else
-                    {
-                        GLenum componentType = UniformComponentType(transposedType);
-                        int columnCount = VariableColumnCount(transposedType);
-                        typeString = gl_d3d::HLSLComponentTypeString(componentType, columnCount);
-                    }
-                    varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n";
-                }
-            }
-
-            if (linkedVaryings)
-            {
-                linkedVaryings->push_back(LinkedVarying(varying.name, varying.type, varying.elementCount(),
-                                                        varyingSemantic, varying.registerIndex,
-                                                        variableRows * varying.elementCount()));
-            }
-        }
-    }
-
-    return varyingHLSL;
-}
-
-std::string DynamicHLSL::generateInputLayoutHLSL(const VertexFormat inputLayout[], const Attribute shaderAttributes[]) const
-{
-    std::string structHLSL, initHLSL;
-
-    int semanticIndex = 0;
-    unsigned int inputIndex = 0;
-
-    for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
-    {
-        ASSERT(inputIndex < MAX_VERTEX_ATTRIBS);
-
-        const VertexFormat &vertexFormat = inputLayout[inputIndex];
-        const Attribute &shaderAttribute = shaderAttributes[attributeIndex];
-
-        if (!shaderAttribute.name.empty())
-        {
-            // HLSL code for input structure
-            if (IsMatrixType(shaderAttribute.type))
-            {
-                // Matrix types are always transposed
-                structHLSL += "    " + gl_d3d::HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
-            }
-            else
-            {
-                GLenum componentType = mRenderer->getVertexComponentType(vertexFormat);
-                structHLSL += "    " + gl_d3d::HLSLComponentTypeString(componentType, UniformComponentCount(shaderAttribute.type));
-            }
-
-            structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
-            semanticIndex += AttributeRegisterCount(shaderAttribute.type);
-
-            // HLSL code for initialization
-            initHLSL += "    " + decorateVariable(shaderAttribute.name) + " = ";
-
-            // Mismatched vertex attribute to vertex input may result in an undefined
-            // data reinterpretation (eg for pure integer->float, float->pure integer)
-            // TODO: issue warning with gl debug info extension, when supported
-            if (IsMatrixType(shaderAttribute.type) ||
-                (mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0)
-            {
-                initHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute);
-            }
-            else
-            {
-                initHLSL += "input." + decorateVariable(shaderAttribute.name);
-            }
-
-            initHLSL += ";\n";
-
-            inputIndex += VariableRowCount(TransposeMatrixType(shaderAttribute.type));
-        }
-    }
-
-    return "struct VS_INPUT\n"
-           "{\n" +
-           structHLSL +
-           "};\n"
-           "\n"
-           "void initAttributes(VS_INPUT input)\n"
-           "{\n" +
-           initHLSL +
-           "}\n";
-}
-
-bool DynamicHLSL::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) const
-{
-    if (pixelHLSL.empty() || vertexHLSL.empty())
-    {
-        return false;
-    }
-
-    bool usesMRT = fragmentShader->mUsesMultipleRenderTargets;
-    bool usesFragColor = fragmentShader->mUsesFragColor;
-    bool usesFragData = fragmentShader->mUsesFragData;
-    if (usesFragColor && usesFragData)
-    {
-        infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader.");
-        return false;
-    }
-
-    // Write the HLSL input/output declarations
-    const int shaderModel = mRenderer->getMajorShaderModel();
-    const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
-
-    const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0);
-
-    // Two cases when writing to gl_FragColor and using ESSL 1.0:
-    // - with a 3.0 context, the output color is copied to channel 0
-    // - with a 2.0 context, the output color is broadcast to all channels
-    const bool broadcast = (fragmentShader->mUsesFragColor && mRenderer->getCurrentClientVersion() < 3);
-    const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getMaxRenderTargets() : 1);
-
-    int shaderVersion = vertexShader->getShaderVersion();
-
-    if (registersNeeded > maxVaryingVectors)
-    {
-        infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
-
-        return false;
-    }
-
-    std::string varyingSemantic = (vertexShader->mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD";
-    std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR";
-    std::string dxPositionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION";
-    std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH";
-
-    std::string varyingHLSL = generateVaryingHLSL(vertexShader, varyingSemantic, linkedVaryings);
-
-    // special varyings that use reserved registers
-    int reservedRegisterIndex = registers;
-
-    unsigned int glPositionSemanticIndex = reservedRegisterIndex++;
-    std::string glPositionSemantic = varyingSemantic;
-
-    std::string fragCoordSemantic;
-    unsigned int fragCoordSemanticIndex = 0;
-    if (fragmentShader->mUsesFragCoord)
-    {
-        fragCoordSemanticIndex = reservedRegisterIndex++;
-        fragCoordSemantic = varyingSemantic;
-    }
-
-    std::string pointCoordSemantic;
-    unsigned int pointCoordSemanticIndex = 0;
-    if (fragmentShader->mUsesPointCoord)
-    {
-        // Shader model 3 uses a special TEXCOORD semantic for point sprite texcoords.
-        // In DX11 we compute this in the GS.
-        if (shaderModel == 3)
-        {
-            pointCoordSemanticIndex = 0;
-            pointCoordSemantic = "TEXCOORD0";
-        }
-        else if (shaderModel >= 4)
-        {
-            pointCoordSemanticIndex = reservedRegisterIndex++;
-            pointCoordSemantic = varyingSemantic;
-        }
-    }
-
-    // Add stub string to be replaced when shader is dynamically defined by its layout
-    vertexHLSL += "\n" + VERTEX_ATTRIBUTE_STUB_STRING + "\n";
-
-    vertexHLSL += "struct VS_OUTPUT\n"
-                  "{\n";
-
-    if (shaderModel < 4)
-    {
-        vertexHLSL += "    float4 _dx_Position : " + dxPositionSemantic + ";\n";
-        vertexHLSL += "    float4 gl_Position : " + glPositionSemantic + Str(glPositionSemanticIndex) + ";\n";
-        linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, glPositionSemantic, glPositionSemanticIndex, 1));
-
-    }
-
-    vertexHLSL += varyingHLSL;
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        vertexHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + Str(fragCoordSemanticIndex) + ";\n";
-        linkedVaryings->push_back(LinkedVarying("gl_FragCoord", GL_FLOAT_VEC4, 1, fragCoordSemantic, fragCoordSemanticIndex, 1));
-    }
-
-    if (vertexShader->mUsesPointSize && shaderModel >= 3)
-    {
-        vertexHLSL += "    float gl_PointSize : PSIZE;\n";
-        linkedVaryings->push_back(LinkedVarying("gl_PointSize", GL_FLOAT, 1, "PSIZE", 0, 1));
-    }
-
-    if (shaderModel >= 4)
-    {
-        vertexHLSL += "    float4 _dx_Position : " + dxPositionSemantic + ";\n";
-        vertexHLSL += "    float4 gl_Position : " + glPositionSemantic + Str(glPositionSemanticIndex) + ";\n";
-        linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, glPositionSemantic, glPositionSemanticIndex, 1));
-    }
-
-    vertexHLSL += "};\n"
-                  "\n"
-                  "VS_OUTPUT main(VS_INPUT input)\n"
-                  "{\n"
-                  "    initAttributes(input);\n";
-
-    if (shaderModel >= 4)
-    {
-        vertexHLSL += "\n"
-                      "    gl_main();\n"
-                      "\n"
-                      "    VS_OUTPUT output;\n"
-                      "    output.gl_Position = gl_Position;\n"
-                      "    output._dx_Position.x = gl_Position.x;\n"
-                      "    output._dx_Position.y = -gl_Position.y;\n"
-                      "    output._dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
-                      "    output._dx_Position.w = gl_Position.w;\n";
-    }
-    else
-    {
-        vertexHLSL += "\n"
-                      "    gl_main();\n"
-                      "\n"
-                      "    VS_OUTPUT output;\n"
-                      "    output.gl_Position = gl_Position;\n"
-                      "    output._dx_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n"
-                      "    output._dx_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n"
-                      "    output._dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
-                      "    output._dx_Position.w = gl_Position.w;\n";
-    }
-
-    if (vertexShader->mUsesPointSize && shaderModel >= 3)
-    {
-        vertexHLSL += "    output.gl_PointSize = gl_PointSize;\n";
-    }
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        vertexHLSL += "    output.gl_FragCoord = gl_Position;\n";
-    }
-
-    for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexShader->mVaryings.size(); vertVaryingIndex++)
-    {
-        const PackedVarying &varying = vertexShader->mVaryings[vertVaryingIndex];
-        if (varying.registerAssigned())
-        {
-            for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++)
-            {
-                int variableRows = (varying.isStruct() ? 1 : VariableRowCount(TransposeMatrixType(varying.type)));
-
-                for (int row = 0; row < variableRows; row++)
-                {
-                    int r = varying.registerIndex + 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())
-                    {
-                        vertexHLSL += ArrayString(elementIndex);
-                    }
-
-                    if (variableRows > 1)
-                    {
-                        vertexHLSL += ArrayString(row);
-                    }
-
-                    vertexHLSL += ";\n";
-                }
-            }
-        }
-    }
-
-    vertexHLSL += "\n"
-                  "    return output;\n"
-                  "}\n";
-
-    pixelHLSL += "struct PS_INPUT\n"
-                 "{\n";
-
-    pixelHLSL += varyingHLSL;
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        pixelHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + Str(fragCoordSemanticIndex) + ";\n";
-    }
-
-    if (fragmentShader->mUsesPointCoord && shaderModel >= 3)
-    {
-        pixelHLSL += "    float2 gl_PointCoord : " + pointCoordSemantic + Str(pointCoordSemanticIndex) + ";\n";
-    }
-
-    // Must consume the PSIZE element if the geometry shader is not active
-    // We won't know if we use a GS until we draw
-    if (vertexShader->mUsesPointSize && shaderModel >= 4)
-    {
-        pixelHLSL += "    float gl_PointSize : PSIZE;\n";
-    }
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        if (shaderModel >= 4)
-        {
-            pixelHLSL += "    float4 dx_VPos : SV_Position;\n";
-        }
-        else if (shaderModel >= 3)
-        {
-            pixelHLSL += "    float2 dx_VPos : VPOS;\n";
-        }
-    }
-
-    pixelHLSL += "};\n"
-                 "\n"
-                 "struct PS_OUTPUT\n"
-                 "{\n";
-
-    if (shaderVersion < 300)
-    {
-        for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
-        {
-            pixelHLSL += "    float4 gl_Color" + Str(renderTargetIndex) + " : " + targetSemantic + Str(renderTargetIndex) + ";\n";
-        }
-
-        if (fragmentShader->mUsesFragDepth)
-        {
-            pixelHLSL += "    float gl_Depth : " + depthSemantic + ";\n";
-        }
-    }
-    else
-    {
-        defineOutputVariables(fragmentShader, programOutputVars);
-
-        const std::vector<Attribute> &shaderOutputVars = fragmentShader->getOutputVariables();
-        for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++)
-        {
-            const VariableLocation &outputLocation = locationIt->second;
-            const ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
-            const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
-
-            pixelHLSL += "    " + gl_d3d::HLSLTypeString(outputVariable.type) +
-                         " out_" + outputLocation.name + elementString +
-                         " : " + targetSemantic + Str(locationIt->first) + ";\n";
-        }
-    }
-
-    pixelHLSL += "};\n"
-                 "\n";
-
-    if (fragmentShader->mUsesFrontFacing)
-    {
-        if (shaderModel >= 4)
-        {
-            pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n"
-                         "{\n";
-        }
-        else
-        {
-            pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n"
-                         "{\n";
-        }
-    }
-    else
-    {
-        pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n"
-                     "{\n";
-    }
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        pixelHLSL += "    float rhw = 1.0 / input.gl_FragCoord.w;\n";
-
-        if (shaderModel >= 4)
-        {
-            pixelHLSL += "    gl_FragCoord.x = input.dx_VPos.x;\n"
-                         "    gl_FragCoord.y = input.dx_VPos.y;\n";
-        }
-        else if (shaderModel >= 3)
-        {
-            pixelHLSL += "    gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
-                         "    gl_FragCoord.y = input.dx_VPos.y + 0.5;\n";
-        }
-        else
-        {
-            // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport()
-            pixelHLSL += "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n"
-                         "    gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n";
-        }
-
-        pixelHLSL += "    gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n"
-                     "    gl_FragCoord.w = rhw;\n";
-    }
-
-    if (fragmentShader->mUsesPointCoord && shaderModel >= 3)
-    {
-        pixelHLSL += "    gl_PointCoord.x = input.gl_PointCoord.x;\n";
-        pixelHLSL += "    gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
-    }
-
-    if (fragmentShader->mUsesFrontFacing)
-    {
-        if (shaderModel <= 3)
-        {
-            pixelHLSL += "    gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n";
-        }
-        else
-        {
-            pixelHLSL += "    gl_FrontFacing = isFrontFace;\n";
-        }
-    }
-
-    for (unsigned int varyingIndex = 0; varyingIndex < fragmentShader->mVaryings.size(); varyingIndex++)
-    {
-        const PackedVarying &varying = fragmentShader->mVaryings[varyingIndex];
-        if (varying.registerAssigned())
-        {
-            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);
-                    pixelHLSL += "    _" + varying.name;
-
-                    if (varying.isArray())
-                    {
-                        pixelHLSL += ArrayString(elementIndex);
-                    }
-
-                    if (variableRows > 1)
-                    {
-                        pixelHLSL += ArrayString(row);
-                    }
-
-                    if (varying.isStruct())
-                    {
-                        pixelHLSL += " = input.v" + n + ";\n";   break;
-                    }
-                    else
-                    {
-                        switch (VariableColumnCount(transposedType))
-                        {
-                          case 1: pixelHLSL += " = input.v" + n + ".x;\n";   break;
-                          case 2: pixelHLSL += " = input.v" + n + ".xy;\n";  break;
-                          case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break;
-                          case 4: pixelHLSL += " = input.v" + n + ";\n";     break;
-                          default: UNREACHABLE();
-                        }
-                    }
-                }
-            }
-        }
-        else UNREACHABLE();
-    }
-
-    pixelHLSL += "\n"
-                 "    gl_main();\n"
-                 "\n"
-                 "    PS_OUTPUT output;\n";
-
-    if (shaderVersion < 300)
-    {
-        for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
-        {
-            unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex;
-
-            pixelHLSL += "    output.gl_Color" + Str(renderTargetIndex) + " = gl_Color[" + Str(sourceColorIndex) + "];\n";
-        }
-
-        if (fragmentShader->mUsesFragDepth)
-        {
-            pixelHLSL += "    output.gl_Depth = gl_Depth;\n";
-        }
-    }
-    else
-    {
-        for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++)
-        {
-            const VariableLocation &outputLocation = locationIt->second;
-            const std::string &variableName = "out_" + outputLocation.name;
-            const std::string &outVariableName = variableName + (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
-            const std::string &staticVariableName = variableName + ArrayString(outputLocation.element);
-
-            pixelHLSL += "    output." + outVariableName + " = " + staticVariableName + ";\n";
-        }
-    }
-
-    pixelHLSL += "\n"
-                 "    return output;\n"
-                 "}\n";
-
-    return true;
-}
-
-void DynamicHLSL::defineOutputVariables(FragmentShader *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
-{
-    const std::vector<Attribute> &shaderOutputVars = fragmentShader->getOutputVariables();
-
-    for (unsigned int outputVariableIndex = 0; outputVariableIndex < shaderOutputVars.size(); outputVariableIndex++)
-    {
-        const Attribute &outputVariable = shaderOutputVars[outputVariableIndex];
-        const int baseLocation = outputVariable.location == -1 ? 0 : outputVariable.location;
-
-        if (outputVariable.arraySize > 0)
-        {
-            for (unsigned int elementIndex = 0; elementIndex < outputVariable.arraySize; elementIndex++)
-            {
-                const int location = baseLocation + elementIndex;
-                ASSERT(programOutputVars->count(location) == 0);
-                (*programOutputVars)[location] = VariableLocation(outputVariable.name, elementIndex, outputVariableIndex);
-            }
-        }
-        else
-        {
-            ASSERT(programOutputVars->count(baseLocation) == 0);
-            (*programOutputVars)[baseLocation] = VariableLocation(outputVariable.name, GL_INVALID_INDEX, outputVariableIndex);
-        }
-    }
-}
-
-std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *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
-{
-    ASSERT(registers >= 0);
-    ASSERT(vertexShader->mUsesPointSize);
-    ASSERT(mRenderer->getMajorShaderModel() >= 4);
-
-    std::string geomHLSL;
-
-    std::string varyingSemantic = "TEXCOORD";
-
-    std::string fragCoordSemantic;
-    std::string pointCoordSemantic;
-
-    int reservedRegisterIndex = registers;
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        fragCoordSemantic = varyingSemantic + Str(reservedRegisterIndex++);
-    }
-
-    if (fragmentShader->mUsesPointCoord)
-    {
-        pointCoordSemantic = varyingSemantic + Str(reservedRegisterIndex++);
-    }
-
-    geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n"
-                "\n"
-                "struct GS_INPUT\n"
-                "{\n";
-
-    std::string varyingHLSL = generateVaryingHLSL(vertexShader, varyingSemantic, NULL);
-
-    geomHLSL += varyingHLSL;
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        geomHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
-    }
-
-    geomHLSL += "    float gl_PointSize : PSIZE;\n"
-                "    float4 gl_Position : SV_Position;\n"
-                "};\n"
-                "\n"
-                "struct GS_OUTPUT\n"
-                "{\n";
-
-    geomHLSL += varyingHLSL;
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        geomHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
-    }
-
-    if (fragmentShader->mUsesPointCoord)
-    {
-        geomHLSL += "    float2 gl_PointCoord : " + pointCoordSemantic + ";\n";
-    }
-
-    geomHLSL +=   "    float gl_PointSize : PSIZE;\n"
-                  "    float4 gl_Position : SV_Position;\n"
-                  "};\n"
-                  "\n"
-                  "static float2 pointSpriteCorners[] = \n"
-                  "{\n"
-                  "    float2( 0.5f, -0.5f),\n"
-                  "    float2( 0.5f,  0.5f),\n"
-                  "    float2(-0.5f, -0.5f),\n"
-                  "    float2(-0.5f,  0.5f)\n"
-                  "};\n"
-                  "\n"
-                  "static float2 pointSpriteTexcoords[] = \n"
-                  "{\n"
-                  "    float2(1.0f, 1.0f),\n"
-                  "    float2(1.0f, 0.0f),\n"
-                  "    float2(0.0f, 1.0f),\n"
-                  "    float2(0.0f, 0.0f)\n"
-                  "};\n"
-                  "\n"
-                  "static float minPointSize = " + Str(ALIASED_POINT_SIZE_RANGE_MIN) + ".0f;\n"
-                  "static float maxPointSize = " + Str(mRenderer->getMaxPointSize()) + ".0f;\n"
-                  "\n"
-                  "[maxvertexcount(4)]\n"
-                  "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
-                  "{\n"
-                  "    GS_OUTPUT output = (GS_OUTPUT)0;\n"
-                  "    output.gl_PointSize = input[0].gl_PointSize;\n";
-
-    for (int r = 0; r < registers; r++)
-    {
-        geomHLSL += "    output.v" + Str(r) + " = input[0].v" + Str(r) + ";\n";
-    }
-
-    if (fragmentShader->mUsesFragCoord)
-    {
-        geomHLSL += "    output.gl_FragCoord = input[0].gl_FragCoord;\n";
-    }
-
-    geomHLSL += "    \n"
-                "    float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n"
-                "    float4 gl_Position = input[0].gl_Position;\n"
-                "    float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * gl_Position.w;\n";
-
-    for (int corner = 0; corner < 4; corner++)
-    {
-        geomHLSL += "    \n"
-                    "    output.gl_Position = gl_Position + float4(pointSpriteCorners[" + Str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
-
-        if (fragmentShader->mUsesPointCoord)
-        {
-            geomHLSL += "    output.gl_PointCoord = pointSpriteTexcoords[" + Str(corner) + "];\n";
-        }
-
-        geomHLSL += "    outStream.Append(output);\n";
-    }
-
-    geomHLSL += "    \n"
-                "    outStream.RestartStrip();\n"
-                "}\n";
-
-    return geomHLSL;
-}
-
-// This method needs to match OutputHLSL::decorate
-std::string DynamicHLSL::decorateVariable(const std::string &name)
-{
-    if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0)
-    {
-        return "_" + name;
-    }
-
-    return name;
-}
-
-std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const ShaderVariable &shaderAttrib) const
-{
-    std::string attribString = "input." + decorateVariable(shaderAttrib.name);
-
-    // Matrix
-    if (IsMatrixType(shaderAttrib.type))
-    {
-        return "transpose(" + attribString + ")";
-    }
-
-    GLenum shaderComponentType = UniformComponentType(shaderAttrib.type);
-    int shaderComponentCount = UniformComponentCount(shaderAttrib.type);
-
-    // Perform integer to float conversion (if necessary)
-    bool requiresTypeConversion = (shaderComponentType == GL_FLOAT && vertexFormat.mType != GL_FLOAT);
-
-    if (requiresTypeConversion)
-    {
-        // TODO: normalization for 32-bit integer formats
-        ASSERT(!vertexFormat.mNormalized && !vertexFormat.mPureInteger);
-        return "float" + Str(shaderComponentCount) + "(" + attribString + ")";
-    }
-
-    // No conversion necessary
-    return attribString;
-}
-
-void DynamicHLSL::getInputLayoutSignature(const VertexFormat inputLayout[], GLenum signature[]) const
-{
-    for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++)
-    {
-        const VertexFormat &vertexFormat = inputLayout[inputIndex];
-
-        if (vertexFormat.mType == GL_NONE)
-        {
-            signature[inputIndex] = GL_NONE;
-        }
-        else
-        {
-            bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0);
-            signature[inputIndex] = (gpuConverted ? GL_TRUE : GL_FALSE);
-        }
-    }
-}
-
-}
diff --git a/src/libGLESv2/DynamicHLSL.h b/src/libGLESv2/DynamicHLSL.h
deleted file mode 100644
index 07c2a2f..0000000
--- a/src/libGLESv2/DynamicHLSL.h
+++ /dev/null
@@ -1,78 +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 gl
-{
-
-class InfoLog;
-class FragmentShader;
-class VertexShader;
-struct VariableLocation;
-struct LinkedVarying;
-class VertexAttribute;
-struct VertexFormat;
-struct ShaderVariable;
-struct Varying;
-struct Attribute;
-struct PackedVarying;
-
-typedef const PackedVarying *VaryingPacking[IMPLEMENTATION_MAX_VARYING_VECTORS][4];
-
-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 generateInputLayoutHLSL(const VertexFormat inputLayout[], const Attribute shaderAttributes[]) 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) const;
-
-    std::string generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const;
-    void getInputLayoutSignature(const VertexFormat inputLayout[], GLenum signature[]) const;
-
-    static const std::string VERTEX_ATTRIBUTE_STUB_STRING;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(DynamicHLSL);
-
-    rx::Renderer *const mRenderer;
-
-    std::string generateVaryingHLSL(VertexShader *shader, const std::string &varyingSemantic,
-                                    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 ShaderVariable &shaderAttrib) const;
-};
-
-// Utility method shared between ProgramBinary and DynamicHLSL
-std::string ArrayString(unsigned int i);
-
-}
-
-#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 b78419f..64617a5 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -9,41 +8,96 @@
 // 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
 {
 
-Framebuffer::Framebuffer(rx::Renderer *renderer)
-    : mRenderer(renderer)
+Framebuffer::Framebuffer(rx::Renderer *renderer, GLuint id)
+    : mRenderer(renderer),
+      mId(id),
+      mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
+      mDepthbuffer(NULL),
+      mStencilbuffer(NULL)
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
+        mColorbuffers[colorAttachment] = NULL;
         mDrawBufferStates[colorAttachment] = GL_NONE;
     }
     mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
-    mReadBufferState = GL_COLOR_ATTACHMENT0_EXT;
 }
 
 Framebuffer::~Framebuffer()
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mColorbuffers[colorAttachment]);
     }
-    mDepthbuffer.set(NULL, GL_NONE, 0, 0);
-    mStencilbuffer.set(NULL, GL_NONE, 0, 0);
+    SafeDelete(mDepthbuffer);
+    SafeDelete(mStencilbuffer);
 }
 
-FramebufferAttachment *Framebuffer::lookupAttachment(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)
+    {
+        return NULL;
+    }
+
     gl::Context *context = gl::getContext();
 
     switch (type)
@@ -52,14 +106,14 @@
         return NULL;
 
       case GL_RENDERBUFFER:
-        return 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)
             {
-                return static_cast<Texture2D*>(texture)->getAttachment(level);
+                return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
             }
             else
             {
@@ -77,7 +131,7 @@
             Texture *texture = context->getTexture(handle);
             if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
             {
-                return static_cast<TextureCubeMap*>(texture)->getAttachment(type, level);
+                return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
             }
             else
             {
@@ -90,7 +144,7 @@
             Texture *texture = context->getTexture(handle);
             if (texture && texture->getTarget() == GL_TEXTURE_3D)
             {
-                return static_cast<Texture3D*>(texture)->getAttachment(level, layer);
+                return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
             }
             else
             {
@@ -103,7 +157,7 @@
             Texture *texture = context->getTexture(handle);
             if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
             {
-                return static_cast<Texture2DArray*>(texture)->getAttachment(level, layer);
+                return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
             }
             else
             {
@@ -120,167 +174,115 @@
 void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    FramebufferAttachment *attachment = lookupAttachment(type, colorbuffer, level, layer);
-    if (attachment)
-    {
-        mColorbuffers[colorAttachment].set(attachment, type, level, layer);
-    }
-    else
-    {
-        mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
-    }
+    SafeDelete(mColorbuffers[colorAttachment]);
+    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)
 {
-    FramebufferAttachment *attachment = lookupAttachment(type, depthbuffer, level, layer);
-    if (attachment)
-    {
-        mDepthbuffer.set(attachment, type, level, layer);
-    }
-    else
-    {
-        mDepthbuffer.set(NULL, GL_NONE, 0, 0);
-    }
+    SafeDelete(mDepthbuffer);
+    mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
 }
 
 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
 {
-    FramebufferAttachment *attachment = lookupAttachment(type, stencilbuffer, level, layer);
-    if (attachment)
-    {
-        mStencilbuffer.set(attachment, type, level, layer);
-    }
-    else
-    {
-        mStencilbuffer.set(NULL, GL_NONE, 0, 0);
-    }
+    SafeDelete(mStencilbuffer);
+    mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
 }
 
 void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
 {
-    FramebufferAttachment *attachment = lookupAttachment(type, depthStencilBuffer, level, layer);
+    FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
+
+    SafeDelete(mDepthbuffer);
+    SafeDelete(mStencilbuffer);
+
+    // ensure this is a legitimate depth+stencil format
     if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
     {
-        mDepthbuffer.set(attachment, type, level, layer);
-        mStencilbuffer.set(attachment, type, level, layer);
-    }
-    else
-    {
-        mDepthbuffer.set(NULL, GL_NONE, 0, 0);
-        mStencilbuffer.set(NULL, GL_NONE, 0, 0);
+        mDepthbuffer = attachment;
+
+        // Make a new attachment object to ensure we do not double-delete
+        // See angle issue 686
+        mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
     }
 }
 
-void Framebuffer::detachTexture(GLuint texture)
+void Framebuffer::detachTexture(GLuint textureId)
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (mColorbuffers[colorAttachment].id() == texture &&
-            IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
+        FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
+
+        if (attachment && attachment->isTextureWithId(textureId))
         {
-            mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
+            SafeDelete(mColorbuffers[colorAttachment]);
         }
     }
 
-    if (mDepthbuffer.id() == texture && IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
+    if (mDepthbuffer && mDepthbuffer->isTextureWithId(textureId))
     {
-        mDepthbuffer.set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mDepthbuffer);
     }
 
-    if (mStencilbuffer.id() == texture && IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
+    if (mStencilbuffer && mStencilbuffer->isTextureWithId(textureId))
     {
-        mStencilbuffer.set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mStencilbuffer);
     }
 }
 
-void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
+void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (mColorbuffers[colorAttachment].id() == renderbuffer && mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
+        FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
+
+        if (attachment && attachment->isRenderbufferWithId(renderbufferId))
         {
-            mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
+            SafeDelete(mColorbuffers[colorAttachment]);
         }
     }
 
-    if (mDepthbuffer.id() == renderbuffer && mDepthbuffer.type() == GL_RENDERBUFFER)
+    if (mDepthbuffer && mDepthbuffer->isRenderbufferWithId(renderbufferId))
     {
-        mDepthbuffer.set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mDepthbuffer);
     }
 
-    if (mStencilbuffer.id() == renderbuffer && mStencilbuffer.type() == GL_RENDERBUFFER)
+    if (mStencilbuffer && mStencilbuffer->isRenderbufferWithId(renderbufferId))
     {
-        mStencilbuffer.set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mStencilbuffer);
     }
 }
 
-unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const
-{
-    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-
-    FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment].get();
-
-    if (colorbuffer)
-    {
-        return colorbuffer->getSerial();
-    }
-
-    return 0;
-}
-
-unsigned int Framebuffer::getDepthbufferSerial() const
-{
-    FramebufferAttachment *depthbuffer = mDepthbuffer.get();
-
-    if (depthbuffer)
-    {
-        return depthbuffer->getSerial();
-    }
-
-    return 0;
-}
-
-unsigned int Framebuffer::getStencilbufferSerial() const
-{
-    FramebufferAttachment *stencilbuffer = mStencilbuffer.get();
-
-    if (stencilbuffer)
-    {
-        return stencilbuffer->getSerial();
-    }
-
-    return 0;
-}
-
 FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].get();
+    return mColorbuffers[colorAttachment];
 }
 
 FramebufferAttachment *Framebuffer::getDepthbuffer() const
 {
-    return mDepthbuffer.get();
+    return mDepthbuffer;
 }
 
 FramebufferAttachment *Framebuffer::getStencilbuffer() const
 {
-    return mStencilbuffer.get();
+    return mStencilbuffer;
 }
 
 FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
 {
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.get() : NULL;
+    return (hasValidDepthStencil() ? mDepthbuffer : NULL);
 }
 
 FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
 {
-    FramebufferAttachment *depthstencilbuffer = mDepthbuffer.get();
+    FramebufferAttachment *depthstencilbuffer = mDepthbuffer;
     
     if (!depthstencilbuffer)
     {
-        depthstencilbuffer = mStencilbuffer.get();
+        depthstencilbuffer = mStencilbuffer;
     }
 
     return depthstencilbuffer;
@@ -289,110 +291,49 @@
 FramebufferAttachment *Framebuffer::getReadColorbuffer() const
 {
     // Will require more logic if glReadBuffers is supported
-    return mColorbuffers[0].get();
+    return mColorbuffers[0];
 }
 
 GLenum Framebuffer::getReadColorbufferType() const
 {
     // Will require more logic if glReadBuffers is supported
-    return mColorbuffers[0].type();
+    return (mColorbuffers[0] ? mColorbuffers[0]->type() : GL_NONE);
 }
 
 FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (mColorbuffers[colorAttachment].type() != GL_NONE)
+        if (mColorbuffers[colorAttachment])
         {
-            return mColorbuffers[colorAttachment].get();
+            return mColorbuffers[colorAttachment];
         }
     }
 
     return NULL;
 }
 
-GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const
+FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
 {
-    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].type();
-}
-
-GLenum Framebuffer::getDepthbufferType() const
-{
-    return mDepthbuffer.type();
-}
-
-GLenum Framebuffer::getStencilbufferType() const
-{
-    return mStencilbuffer.type();
-}
-
-GLenum Framebuffer::getDepthStencilbufferType() const
-{
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.type() : GL_NONE;
-}
-
-GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const
-{
-    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].id();
-}
-
-GLuint Framebuffer::getDepthbufferHandle() const
-{
-    return mDepthbuffer.id();
-}
-
-GLuint Framebuffer::getStencilbufferHandle() const
-{
-    return mStencilbuffer.id();
-}
-
-GLenum Framebuffer::getDepthStencilbufferHandle() const
-{
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.id() : 0;
-}
-
-GLenum Framebuffer::getColorbufferMipLevel(unsigned int colorAttachment) const
-{
-    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].mipLevel();
-}
-
-GLenum Framebuffer::getDepthbufferMipLevel() const
-{
-    return mDepthbuffer.mipLevel();
-}
-
-GLenum Framebuffer::getStencilbufferMipLevel() const
-{
-    return mStencilbuffer.mipLevel();
-}
-
-GLenum Framebuffer::getDepthStencilbufferMipLevel() const
-{
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.mipLevel() : 0;
-}
-
-GLenum Framebuffer::getColorbufferLayer(unsigned int colorAttachment) const
-{
-    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].layer();
-}
-
-GLenum Framebuffer::getDepthbufferLayer() const
-{
-    return mDepthbuffer.layer();
-}
-
-GLenum Framebuffer::getStencilbufferLayer() const
-{
-    return mStencilbuffer.layer();
-}
-
-GLenum Framebuffer::getDepthStencilbufferLayer() const
-{
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.layer() : 0;
+    if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
+    {
+        return getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
+    }
+    else
+    {
+        switch (attachment)
+        {
+          case GL_DEPTH_ATTACHMENT:
+            return getDepthbuffer();
+          case GL_STENCIL_ATTACHMENT:
+            return getStencilbuffer();
+          case GL_DEPTH_STENCIL_ATTACHMENT:
+            return getDepthStencilBuffer();
+          default:
+            UNREACHABLE();
+            return NULL;
+        }
+    }
 }
 
 GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
@@ -407,7 +348,7 @@
 
 bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
 {
-    return (mColorbuffers[colorAttachment].type() != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE);
+    return (mColorbuffers[colorAttachment] && mDrawBufferStates[colorAttachment] != GL_NONE);
 }
 
 bool Framebuffer::hasEnabledColorAttachment() const
@@ -425,17 +366,7 @@
 
 bool Framebuffer::hasStencil() const
 {
-    if (mStencilbuffer.type() != GL_NONE)
-    {
-        const FramebufferAttachment *stencilbufferObject = getStencilbuffer();
-
-        if (stencilbufferObject)
-        {
-            return stencilbufferObject->getStencilSize() > 0;
-        }
-    }
-
-    return false;
+    return (mStencilbuffer && mStencilbuffer->getStencilSize() > 0);
 }
 
 bool Framebuffer::usingExtendedDrawBuffers() const
@@ -462,46 +393,37 @@
 
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (mColorbuffers[colorAttachment].type() != GL_NONE)
+        const FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
+
+        if (colorbuffer)
         {
-            const FramebufferAttachment *colorbuffer = getColorbuffer(colorAttachment);
-
-            if (!colorbuffer)
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-
             if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
 
-            if (mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
+            GLenum internalformat = colorbuffer->getInternalFormat();
+            // TODO(geofflang): use context's texture caps
+            const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+            const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+            if (colorbuffer->isTexture())
             {
-                if (!gl::IsColorRenderingSupported(colorbuffer->getInternalFormat(), mRenderer))
-                {
-                    return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-                }
-            }
-            else if (IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
-            {
-                GLenum internalformat = colorbuffer->getInternalFormat();
-
-                if (!gl::IsColorRenderingSupported(internalformat, mRenderer))
+                if (!formatCaps.renderable)
                 {
                     return GL_FRAMEBUFFER_UNSUPPORTED;
                 }
 
-                if (gl::GetDepthBits(internalformat, clientVersion) > 0 ||
-                    gl::GetStencilBits(internalformat, clientVersion) > 0)
+                if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
                 {
                     return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
                 }
             }
             else
             {
-                UNREACHABLE();
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+                if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+                {
+                    return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+                }
             }
 
             if (!missingAttachment)
@@ -523,7 +445,7 @@
                 // in GLES 3.0, there is no such restriction
                 if (clientVersion < 3)
                 {
-                    if (gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion) != colorbufferSize)
+                    if (formatInfo.pixelBytes != colorbufferSize)
                     {
                         return GL_FRAMEBUFFER_UNSUPPORTED;
                     }
@@ -532,7 +454,11 @@
                 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
                 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
                 {
-                    if (mColorbuffers[colorAttachment].get() == mColorbuffers[previousColorAttachment].get())
+                    const FramebufferAttachment *previousAttachment = mColorbuffers[previousColorAttachment];
+
+                    if (previousAttachment &&
+                        (colorbuffer->id() == previousAttachment->id() &&
+                         colorbuffer->type() == previousAttachment->type()))
                     {
                         return GL_FRAMEBUFFER_UNSUPPORTED;
                     }
@@ -543,129 +469,118 @@
                 width = colorbuffer->getWidth();
                 height = colorbuffer->getHeight();
                 samples = colorbuffer->getSamples();
-                colorbufferSize = gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion);
+                colorbufferSize = formatInfo.pixelBytes;
                 missingAttachment = false;
             }
         }
     }
 
-    const FramebufferAttachment *depthbuffer = NULL;
-    const FramebufferAttachment *stencilbuffer = NULL;
-
-    if (mDepthbuffer.type() != GL_NONE)
+    if (mDepthbuffer)
     {
-        depthbuffer = getDepthbuffer();
-
-        if (!depthbuffer)
+        if (mDepthbuffer->getWidth() == 0 || mDepthbuffer->getHeight() == 0)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
+        GLenum internalformat = mDepthbuffer->getInternalFormat();
+        // TODO(geofflang): use context's texture caps
+        const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+        const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+        if (mDepthbuffer->isTexture())
         {
-            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-        }
-
-        if (mDepthbuffer.type() == GL_RENDERBUFFER)
-        {
-            if (!gl::IsDepthRenderingSupported(depthbuffer->getInternalFormat(), mRenderer))
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-        }
-        else if (IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
-        {
-            GLenum internalformat = depthbuffer->getInternalFormat();
-
             // depth texture attachments require OES/ANGLE_depth_texture
-            if (!mRenderer->getDepthTextureSupport())
+            // TODO(geofflang): use context's extensions
+            if (!mRenderer->getRendererExtensions().depthTextures)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
 
-            if (gl::GetDepthBits(internalformat, clientVersion) == 0)
+            if (!formatCaps.renderable)
+            {
+                return GL_FRAMEBUFFER_UNSUPPORTED;
+            }
+
+            if (formatInfo.depthBits == 0)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
         }
         else
         {
-            UNREACHABLE();
-            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+            if (!formatCaps.renderable || formatInfo.depthBits == 0)
+            {
+                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+            }
         }
 
         if (missingAttachment)
         {
-            width = depthbuffer->getWidth();
-            height = depthbuffer->getHeight();
-            samples = depthbuffer->getSamples();
+            width = mDepthbuffer->getWidth();
+            height = mDepthbuffer->getHeight();
+            samples = mDepthbuffer->getSamples();
             missingAttachment = false;
         }
-        else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
+        else if (width != mDepthbuffer->getWidth() || height != mDepthbuffer->getHeight())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
         }
-        else if (samples != depthbuffer->getSamples())
+        else if (samples != mDepthbuffer->getSamples())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
     }
 
-    if (mStencilbuffer.type() != GL_NONE)
+    if (mStencilbuffer)
     {
-        stencilbuffer = getStencilbuffer();
-
-        if (!stencilbuffer)
+        if (mStencilbuffer->getWidth() == 0 || mStencilbuffer->getHeight() == 0)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
+        GLenum internalformat = mStencilbuffer->getInternalFormat();
+        // TODO(geofflang): use context's texture caps
+        const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+        const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+        if (mStencilbuffer->isTexture())
         {
-            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-        }
-
-        if (mStencilbuffer.type() == GL_RENDERBUFFER)
-        {
-            if (!gl::IsStencilRenderingSupported(stencilbuffer->getInternalFormat(), mRenderer))
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-        }
-        else if (IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
-        {
-            GLenum internalformat = stencilbuffer->getInternalFormat();
-
             // texture stencil attachments come along as part
             // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
-            if (!mRenderer->getDepthTextureSupport())
+            // TODO(geofflang): use context's extensions
+            if (!mRenderer->getRendererExtensions().depthTextures)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
 
-            if (gl::GetStencilBits(internalformat, clientVersion) == 0)
+            if (!formatCaps.renderable)
+            {
+                return GL_FRAMEBUFFER_UNSUPPORTED;
+            }
+
+            if (formatInfo.stencilBits == 0)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
         }
         else
         {
-            UNREACHABLE();
-            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+            if (!formatCaps.renderable || formatInfo.stencilBits == 0)
+            {
+                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+            }
         }
 
         if (missingAttachment)
         {
-            width = stencilbuffer->getWidth();
-            height = stencilbuffer->getHeight();
-            samples = stencilbuffer->getSamples();
+            width = mStencilbuffer->getWidth();
+            height = mStencilbuffer->getHeight();
+            samples = mStencilbuffer->getSamples();
             missingAttachment = false;
         }
-        else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
+        else if (width != mStencilbuffer->getWidth() || height != mStencilbuffer->getHeight())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
         }
-        else if (samples != stencilbuffer->getSamples())
+        else if (samples != mStencilbuffer->getSamples())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
@@ -673,7 +588,7 @@
 
     // if we have both a depth and stencil buffer, they must refer to the same object
     // since we only support packed_depth_stencil and not separate depth and stencil
-    if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
+    if (mDepthbuffer && mStencilbuffer && !hasValidDepthStencil())
     {
         return GL_FRAMEBUFFER_UNSUPPORTED;
     }
@@ -687,14 +602,58 @@
     return GL_FRAMEBUFFER_COMPLETE;
 }
 
-DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
-    : Framebuffer(renderer)
+void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
 {
-    mColorbuffers[0].set(new FramebufferAttachment(mRenderer, 0, colorbuffer), GL_RENDERBUFFER, 0, 0);
+    GLuint maxDimension = caps.maxRenderbufferSize;
+    invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+}
 
-    FramebufferAttachment *depthStencilRenderbuffer = new FramebufferAttachment(mRenderer, 0, depthStencil);
-    mDepthbuffer.set(depthStencilRenderbuffer, (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
-    mStencilbuffer.set(depthStencilRenderbuffer, (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
+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(GL_BACK, colorRenderbuffer);
+
+    GLenum depthStencilActualFormat = depthStencil->getActualFormat();
+    const gl::InternalFormat &depthStencilFormatInfo = GetInternalFormatInfo(depthStencilActualFormat);
+
+    if (depthStencilFormatInfo.depthBits != 0 || depthStencilFormatInfo.stencilBits != 0)
+    {
+        Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
+
+        // Make a new attachment objects to ensure we do not double-delete
+        // See angle issue 686
+        mDepthbuffer = (depthStencilFormatInfo.depthBits != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
+        mStencilbuffer = (depthStencilFormatInfo.stencilBits != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
+    }
+    else
+    {
+        // This method transfers ownership, so delete the unused storage if we don't keep it.
+        SafeDelete(depthStencil);
+    }
 
     mDrawBufferStates[0] = GL_BACK;
     mReadBufferState = GL_BACK;
@@ -708,9 +667,9 @@
         // in this case return the first nonzero sample size
         for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
         {
-            if (mColorbuffers[colorAttachment].type() != GL_NONE)
+            if (mColorbuffers[colorAttachment])
             {
-                return getColorbuffer(colorAttachment)->getSamples();
+                return mColorbuffers[colorAttachment]->getSamples();
             }
         }
     }
@@ -718,6 +677,40 @@
     return 0;
 }
 
+bool Framebuffer::hasValidDepthStencil() const
+{
+    // A valid depth-stencil attachment has the same resource bound to both the
+    // depth and stencil attachment points.
+    return (mDepthbuffer && mStencilbuffer &&
+            mDepthbuffer->type() == mStencilbuffer->type() &&
+            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
@@ -725,4 +718,23 @@
     return GL_FRAMEBUFFER_COMPLETE;
 }
 
+FramebufferAttachment *DefaultFramebuffer::getAttachment(GLenum attachment) const
+{
+    switch (attachment)
+    {
+      case GL_COLOR:
+      case GL_BACK:
+        return getColorbuffer(0);
+      case GL_DEPTH:
+        return getDepthbuffer();
+      case GL_STENCIL:
+        return getStencilbuffer();
+      case GL_DEPTH_STENCIL:
+        return getDepthStencilBuffer();
+      default:
+        UNREACHABLE();
+        return NULL;
+    }
+}
+
 }
diff --git a/src/libGLESv2/Framebuffer.h b/src/libGLESv2/Framebuffer.h
index 1a5e2b6..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,14 +28,19 @@
 class Depthbuffer;
 class Stencilbuffer;
 class DepthStencilbuffer;
+struct Caps;
+
+typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
 
 class Framebuffer
 {
   public:
-    explicit Framebuffer(rx::Renderer *renderer);
+    Framebuffer(rx::Renderer *renderer, GLuint id);
 
     virtual ~Framebuffer();
 
+    GLuint id() const { return mId; }
+
     void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer);
     void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer);
     void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer);
@@ -42,10 +49,6 @@
     void detachTexture(GLuint texture);
     void detachRenderbuffer(GLuint renderbuffer);
 
-    unsigned int getRenderTargetSerial(unsigned int colorAttachment) const;
-    unsigned int getDepthbufferSerial() const;
-    unsigned int getStencilbufferSerial() const;
-
     FramebufferAttachment *getColorbuffer(unsigned int colorAttachment) const;
     FramebufferAttachment *getDepthbuffer() const;
     FramebufferAttachment *getStencilbuffer() const;
@@ -55,25 +58,7 @@
     GLenum getReadColorbufferType() const;
     FramebufferAttachment *getFirstColorbuffer() const;
 
-    GLenum getColorbufferType(unsigned int colorAttachment) const;
-    GLenum getDepthbufferType() const;
-    GLenum getStencilbufferType() const;
-    GLenum getDepthStencilbufferType() const;
-
-    GLuint getColorbufferHandle(unsigned int colorAttachment) const;
-    GLuint getDepthbufferHandle() const;
-    GLuint getStencilbufferHandle() const;
-    GLenum getDepthStencilbufferHandle() const;
-
-    GLenum getColorbufferMipLevel(unsigned int colorAttachment) const;
-    GLenum getDepthbufferMipLevel() const;
-    GLenum getStencilbufferMipLevel() const;
-    GLenum getDepthStencilbufferMipLevel() const;
-
-    GLenum getColorbufferLayer(unsigned int colorAttachment) const;
-    GLenum getDepthbufferLayer() const;
-    GLenum getStencilbufferLayer() const;
-    GLenum getDepthStencilbufferLayer() const;
+    virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
 
     GLenum getDrawBufferState(unsigned int colorAttachment) const;
     void setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer);
@@ -85,21 +70,33 @@
     bool usingExtendedDrawBuffers() const;
 
     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:
-    FramebufferTextureBindingPointer<FramebufferAttachment> mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
+    rx::Renderer *mRenderer;
+
+    GLuint mId;
+
+    FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
     GLenum mDrawBufferStates[IMPLEMENTATION_MAX_DRAW_BUFFERS];
     GLenum mReadBufferState;
 
-    FramebufferTextureBindingPointer<FramebufferAttachment> mDepthbuffer;
-    FramebufferTextureBindingPointer<FramebufferAttachment> mStencilbuffer;
-
-    rx::Renderer *mRenderer;
+    FramebufferAttachment *mDepthbuffer;
+    FramebufferAttachment *mStencilbuffer;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Framebuffer);
 
-    FramebufferAttachment *lookupAttachment(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
@@ -108,6 +105,7 @@
     DefaultFramebuffer(rx::Renderer *Renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
 
     virtual GLenum completeness() const;
+    virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(DefaultFramebuffer);
@@ -115,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 574ce7e..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,483 +8,223 @@
 // 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/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
 {
 
-FramebufferAttachmentInterface::FramebufferAttachmentInterface()
-{
-}
-
-// The default case for classes inherited from FramebufferAttachmentInterface is not to
-// need to do anything upon the reference count to the parent FramebufferAttachment incrementing
-// or decrementing.
-void FramebufferAttachmentInterface::addProxyRef(const FramebufferAttachment *proxy)
-{
-}
-
-void FramebufferAttachmentInterface::releaseProxy(const FramebufferAttachment *proxy)
-{
-}
-
-///// Texture2DAttachment Implementation ////////
-
-Texture2DAttachment::Texture2DAttachment(Texture2D *texture, GLint level) : mLevel(level)
-{
-    mTexture2D.set(texture);
-}
-
-Texture2DAttachment::~Texture2DAttachment()
-{
-    mTexture2D.set(NULL);
-}
-
-// Textures need to maintain their own reference count for references via
-// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
-void Texture2DAttachment::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mTexture2D->addProxyRef(proxy);
-}
-
-void Texture2DAttachment::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mTexture2D->releaseProxy(proxy);
-}
-
-rx::RenderTarget *Texture2DAttachment::getRenderTarget()
-{
-    return mTexture2D->getRenderTarget(mLevel);
-}
-
-rx::RenderTarget *Texture2DAttachment::getDepthStencil()
-{
-    return mTexture2D->getDepthSencil(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
-{
-    return 0;
-}
-
-unsigned int Texture2DAttachment::getSerial() const
-{
-    return mTexture2D->getRenderTargetSerial(mLevel);
-}
-
-bool Texture2DAttachment::isTexture() const
-{
-    return true;
-}
-
-unsigned int Texture2DAttachment::getTextureSerial() const
-{
-    return mTexture2D->getTextureSerial();
-}
-
-///// TextureCubeMapAttachment Implementation ////////
-
-TextureCubeMapAttachment::TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level)
-    : mFaceTarget(faceTarget), mLevel(level)
-{
-    mTextureCubeMap.set(texture);
-}
-
-TextureCubeMapAttachment::~TextureCubeMapAttachment()
-{
-    mTextureCubeMap.set(NULL);
-}
-
-// Textures need to maintain their own reference count for references via
-// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
-void TextureCubeMapAttachment::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mTextureCubeMap->addProxyRef(proxy);
-}
-
-void TextureCubeMapAttachment::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mTextureCubeMap->releaseProxy(proxy);
-}
-
-rx::RenderTarget *TextureCubeMapAttachment::getRenderTarget()
-{
-    return mTextureCubeMap->getRenderTarget(mFaceTarget, mLevel);
-}
-
-rx::RenderTarget *TextureCubeMapAttachment::getDepthStencil()
-{
-    return mTextureCubeMap->getDepthStencil(mFaceTarget, mLevel);
-}
-
-rx::TextureStorage *TextureCubeMapAttachment::getTextureStorage()
-{
-    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);
-}
-
-bool TextureCubeMapAttachment::isTexture() const
-{
-    return true;
-}
-
-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);
-}
-
-// Textures need to maintain their own reference count for references via
-// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
-void Texture3DAttachment::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mTexture3D->addProxyRef(proxy);
-}
-
-void Texture3DAttachment::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mTexture3D->releaseProxy(proxy);
-}
-
-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);
-}
-
-bool Texture3DAttachment::isTexture() const
-{
-    return true;
-}
-
-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);
-}
-
-void Texture2DArrayAttachment::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mTexture2DArray->addProxyRef(proxy);
-}
-
-void Texture2DArrayAttachment::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mTexture2DArray->releaseProxy(proxy);
-}
-
-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);
-}
-
-bool Texture2DArrayAttachment::isTexture() const
-{
-    return true;
-}
-
-unsigned int Texture2DArrayAttachment::getTextureSerial() const
-{
-    return mTexture2DArray->getTextureSerial();
-}
-
 ////// FramebufferAttachment Implementation //////
 
-FramebufferAttachment::FramebufferAttachment(rx::Renderer *renderer, GLuint id, FramebufferAttachmentInterface *instance) : RefCountObject(id)
+FramebufferAttachment::FramebufferAttachment(GLenum binding)
+    : mBinding(binding)
 {
-    ASSERT(instance != NULL);
-    mInstance = instance;
-
-    ASSERT(renderer != NULL);
-    mRenderer = renderer;
 }
 
 FramebufferAttachment::~FramebufferAttachment()
 {
-    delete mInstance;
-}
-
-// The FramebufferAttachmentInterface contained in this FramebufferAttachment may need to maintain
-// its own reference count, so we pass it on here.
-void FramebufferAttachment::addRef() const
-{
-    mInstance->addProxyRef(this);
-
-    RefCountObject::addRef();
-}
-
-void FramebufferAttachment::release() const
-{
-    mInstance->releaseProxy(this);
-
-    RefCountObject::release();
-}
-
-rx::RenderTarget *FramebufferAttachment::getRenderTarget()
-{
-    return mInstance->getRenderTarget();
-}
-
-rx::RenderTarget *FramebufferAttachment::getDepthStencil()
-{
-    return mInstance->getDepthStencil();
-}
-
-rx::TextureStorage *FramebufferAttachment::getTextureStorage()
-{
-    return mInstance->getTextureStorage();
-}
-
-GLsizei FramebufferAttachment::getWidth() const
-{
-    return mInstance->getWidth();
-}
-
-GLsizei FramebufferAttachment::getHeight() const
-{
-    return mInstance->getHeight();
-}
-
-GLenum FramebufferAttachment::getInternalFormat() const
-{
-    return mInstance->getInternalFormat();
-}
-
-GLenum FramebufferAttachment::getActualFormat() const
-{
-    return mInstance->getActualFormat();
 }
 
 GLuint FramebufferAttachment::getRedSize() const
 {
-    return gl::GetRedBits(getActualFormat(), mRenderer->getCurrentClientVersion());
+    return (GetInternalFormatInfo(getInternalFormat()).redBits > 0) ? GetInternalFormatInfo(getActualFormat()).redBits : 0;
 }
 
 GLuint FramebufferAttachment::getGreenSize() const
 {
-    return gl::GetGreenBits(getActualFormat(), mRenderer->getCurrentClientVersion());
+    return (GetInternalFormatInfo(getInternalFormat()).greenBits > 0) ? GetInternalFormatInfo(getActualFormat()).greenBits : 0;
 }
 
 GLuint FramebufferAttachment::getBlueSize() const
 {
-    return gl::GetBlueBits(getActualFormat(), mRenderer->getCurrentClientVersion());
+    return (GetInternalFormatInfo(getInternalFormat()).blueBits > 0) ? GetInternalFormatInfo(getActualFormat()).blueBits : 0;
 }
 
 GLuint FramebufferAttachment::getAlphaSize() const
 {
-    return gl::GetAlphaBits(getActualFormat(), mRenderer->getCurrentClientVersion());
+    return (GetInternalFormatInfo(getInternalFormat()).alphaBits > 0) ? GetInternalFormatInfo(getActualFormat()).alphaBits : 0;
 }
 
 GLuint FramebufferAttachment::getDepthSize() const
 {
-    return gl::GetDepthBits(getActualFormat(), mRenderer->getCurrentClientVersion());
+    return (GetInternalFormatInfo(getInternalFormat()).depthBits > 0) ? GetInternalFormatInfo(getActualFormat()).depthBits : 0;
 }
 
 GLuint FramebufferAttachment::getStencilSize() const
 {
-    return gl::GetStencilBits(getActualFormat(), mRenderer->getCurrentClientVersion());
+    return (GetInternalFormatInfo(getInternalFormat()).stencilBits > 0) ? GetInternalFormatInfo(getActualFormat()).stencilBits : 0;
 }
 
 GLenum FramebufferAttachment::getComponentType() const
 {
-    return gl::GetComponentType(getActualFormat(), mRenderer->getCurrentClientVersion());
+    return GetInternalFormatInfo(getActualFormat()).componentType;
 }
 
 GLenum FramebufferAttachment::getColorEncoding() const
 {
-    return gl::GetColorEncoding(getActualFormat(), mRenderer->getCurrentClientVersion());
-}
-
-GLsizei FramebufferAttachment::getSamples() const
-{
-    return mInstance->getSamples();
-}
-
-unsigned int FramebufferAttachment::getSerial() const
-{
-    return mInstance->getSerial();
+    return GetInternalFormatInfo(getActualFormat()).colorEncoding;
 }
 
 bool FramebufferAttachment::isTexture() const
 {
-    return mInstance->isTexture();
+    return (type() != GL_RENDERBUFFER);
 }
 
-unsigned int FramebufferAttachment::getTextureSerial() const
+///// TextureAttachment Implementation ////////
+
+TextureAttachment::TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index)
+    : FramebufferAttachment(binding),
+      mIndex(index)
 {
-    return mInstance->getTextureSerial();
+    mTexture.set(texture);
 }
 
-void FramebufferAttachment::setStorage(RenderbufferStorage *newStorage)
+TextureAttachment::~TextureAttachment()
 {
-    ASSERT(newStorage != NULL);
+    mTexture.set(NULL);
+}
 
-    delete mInstance;
-    mInstance = newStorage;
+GLsizei TextureAttachment::getSamples() const
+{
+    return 0;
+}
+
+GLuint TextureAttachment::id() const
+{
+    return mTexture->id();
+}
+
+GLsizei TextureAttachment::getWidth() const
+{
+    return mTexture->getWidth(mIndex);
+}
+
+GLsizei TextureAttachment::getHeight() const
+{
+    return mTexture->getHeight(mIndex);
+}
+
+GLenum TextureAttachment::getInternalFormat() const
+{
+    return mTexture->getInternalFormat(mIndex);
+}
+
+GLenum TextureAttachment::getActualFormat() const
+{
+    return mTexture->getActualFormat(mIndex);
+}
+
+GLenum TextureAttachment::type() const
+{
+    return mIndex.type;
+}
+
+GLint TextureAttachment::mipLevel() const
+{
+    return mIndex.mipIndex;
+}
+
+GLint TextureAttachment::layer() const
+{
+    return mIndex.layerIndex;
+}
+
+Texture *TextureAttachment::getTexture()
+{
+    return mTexture.get();
+}
+
+const ImageIndex *TextureAttachment::getTextureImageIndex() const
+{
+    return &mIndex;
+}
+
+Renderbuffer *TextureAttachment::getRenderbuffer()
+{
+    UNREACHABLE();
+    return NULL;
+}
+
+////// RenderbufferAttachment Implementation //////
+
+RenderbufferAttachment::RenderbufferAttachment(GLenum binding, Renderbuffer *renderbuffer)
+    : FramebufferAttachment(binding)
+{
+    ASSERT(renderbuffer);
+    mRenderbuffer.set(renderbuffer);
+}
+
+RenderbufferAttachment::~RenderbufferAttachment()
+{
+    mRenderbuffer.set(NULL);
+}
+
+GLsizei RenderbufferAttachment::getWidth() const
+{
+    return mRenderbuffer->getWidth();
+}
+
+GLsizei RenderbufferAttachment::getHeight() const
+{
+    return mRenderbuffer->getHeight();
+}
+
+GLenum RenderbufferAttachment::getInternalFormat() const
+{
+    return mRenderbuffer->getInternalFormat();
+}
+
+GLenum RenderbufferAttachment::getActualFormat() const
+{
+    return mRenderbuffer->getActualFormat();
+}
+
+GLsizei RenderbufferAttachment::getSamples() const
+{
+    return mRenderbuffer->getStorage()->getSamples();
+}
+
+GLuint RenderbufferAttachment::id() const
+{
+    return mRenderbuffer->id();
+}
+
+GLenum RenderbufferAttachment::type() const
+{
+    return GL_RENDERBUFFER;
+}
+
+GLint RenderbufferAttachment::mipLevel() const
+{
+    return 0;
+}
+
+GLint RenderbufferAttachment::layer() const
+{
+    return 0;
+}
+
+Texture *RenderbufferAttachment::getTexture()
+{
+    UNREACHABLE();
+    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 9ba63cc..c18ef73 100644
--- a/src/libGLESv2/FramebufferAttachment.h
+++ b/src/libGLESv2/FramebufferAttachment.h
@@ -10,11 +10,11 @@
 #ifndef LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
 #define LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
+#include "Texture.h"
+
+#include "angle_gl.h"
 
 namespace rx
 {
@@ -25,39 +25,21 @@
 
 namespace gl
 {
-class Texture2D;
-class TextureCubeMap;
-class Texture3D;
-class Texture2DArray;
-class FramebufferAttachment;
-class FramebufferAttachmentInterface;
-class RenderbufferStorage;
+class Renderbuffer;
 
-// FramebufferAttachment implements the GL renderbuffer object.
-// It's only a proxy for a FramebufferAttachmentInterface instance; the internal object
-// can change whenever glRenderbufferStorage is called.
-class FramebufferAttachment : public RefCountObject
+// FramebufferAttachment implements a GL framebuffer attachment.
+// Attachments are "light" containers, which store pointers to ref-counted GL objects.
+// We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments.
+// Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for
+// framebuffer attachments, which confused their usage.
+
+class FramebufferAttachment
 {
   public:
-    FramebufferAttachment(rx::Renderer *renderer, GLuint id, FramebufferAttachmentInterface *storage);
-
+    explicit FramebufferAttachment(GLenum binding);
     virtual ~FramebufferAttachment();
 
-    // These functions from RefCountObject are overloaded here because
-    // Textures need to maintain their own count of references to them via
-    // Renderbuffers/RenderbufferTextures. These functions invoke those
-    // reference counting functions on the FramebufferAttachmentInterface.
-    void addRef() const;
-    void release() const;
-
-    rx::RenderTarget *getRenderTarget();
-    rx::RenderTarget *getDepthStencil();
-    rx::TextureStorage *getTextureStorage();
-
-    GLsizei getWidth() const;
-    GLsizei getHeight() const;
-    GLenum getInternalFormat() const;
-    GLenum getActualFormat() const;
+    // Helper methods
     GLuint getRedSize() const;
     GLuint getGreenSize() const;
     GLuint getBlueSize() const;
@@ -66,64 +48,70 @@
     GLuint getStencilSize() const;
     GLenum getComponentType() const;
     GLenum getColorEncoding() const;
-    GLsizei getSamples() const;
-
-    unsigned int getSerial() const;
-
     bool isTexture() const;
-    unsigned int getTextureSerial() const;
 
-    void setStorage(RenderbufferStorage *newStorage);
+    bool isTextureWithId(GLuint textureId) const { return isTexture() && id() == textureId; }
+    bool isRenderbufferWithId(GLuint renderbufferId) const { return !isTexture() && id() == renderbufferId; }
 
-  private:
-    DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
+    GLenum getBinding() const { return mBinding; }
 
-    rx::Renderer const *mRenderer;
-    FramebufferAttachmentInterface *mInstance;
-};
-
-class FramebufferAttachmentInterface
-{
-  public:
-    FramebufferAttachmentInterface();
-
-    virtual ~FramebufferAttachmentInterface() {};
-
-    virtual void addProxyRef(const FramebufferAttachment *proxy);
-    virtual void releaseProxy(const FramebufferAttachment *proxy);
-
-    virtual rx::RenderTarget *getRenderTarget() = 0;
-    virtual rx::RenderTarget *getDepthStencil() = 0;
-    virtual rx::TextureStorage *getTextureStorage() = 0;
-
+    // 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 bool isTexture() 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(FramebufferAttachmentInterface);
+    DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
+
+    GLenum mBinding;
 };
 
-class Texture2DAttachment : public FramebufferAttachmentInterface
+class TextureAttachment : public FramebufferAttachment
 {
   public:
-    Texture2DAttachment(Texture2D *texture, GLint level);
+    TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index);
+    virtual ~TextureAttachment();
 
-    virtual ~Texture2DAttachment();
+    virtual GLsizei getSamples() const;
+    virtual GLuint id() const;
 
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
+    virtual GLsizei getWidth() const;
+    virtual GLsizei getHeight() const;
+    virtual GLenum getInternalFormat() const;
+    virtual GLenum getActualFormat() const;
 
-    rx::RenderTarget *getRenderTarget();
-    rx::RenderTarget *getDepthStencil();
-    rx::TextureStorage *getTextureStorage();
+    virtual GLenum type() const;
+    virtual GLint mipLevel() const;
+    virtual GLint layer() const;
+
+    virtual Texture *getTexture();
+    virtual const ImageIndex *getTextureImageIndex() const;
+    virtual Renderbuffer *getRenderbuffer();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureAttachment);
+
+    BindingPointer<Texture> mTexture;
+    ImageIndex mIndex;
+};
+
+class RenderbufferAttachment : public FramebufferAttachment
+{
+  public:
+    RenderbufferAttachment(GLenum binding, Renderbuffer *renderbuffer);
+
+    virtual ~RenderbufferAttachment();
 
     virtual GLsizei getWidth() const;
     virtual GLsizei getHeight() const;
@@ -131,115 +119,19 @@
     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 bool isTexture() 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(RenderbufferAttachment);
 
-    BindingPointer <Texture2D> mTexture2D;
-    const GLint mLevel;
-};
-
-class TextureCubeMapAttachment : public FramebufferAttachmentInterface
-{
-  public:
-    TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level);
-
-    virtual ~TextureCubeMapAttachment();
-
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
-    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 bool isTexture() const;
-    virtual unsigned int getTextureSerial() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(TextureCubeMapAttachment);
-
-    BindingPointer <TextureCubeMap> mTextureCubeMap;
-    const GLint mLevel;
-    const GLenum mFaceTarget;
-};
-
-class Texture3DAttachment : public FramebufferAttachmentInterface
-{
-  public:
-    Texture3DAttachment(Texture3D *texture, GLint level, GLint layer);
-
-    virtual ~Texture3DAttachment();
-
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
-    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 bool isTexture() const;
-    virtual unsigned int getTextureSerial() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Texture3DAttachment);
-
-    BindingPointer<Texture3D> mTexture3D;
-    const GLint mLevel;
-    const GLint mLayer;
-};
-
-class Texture2DArrayAttachment : public FramebufferAttachmentInterface
-{
-  public:
-    Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer);
-
-    virtual ~Texture2DArrayAttachment();
-
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
-    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 bool isTexture() const;
-    virtual unsigned int getTextureSerial() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Texture2DArrayAttachment);
-
-    BindingPointer<Texture2DArray> mTexture2DArray;
-    const GLint mLevel;
-    const GLint mLayer;
+    BindingPointer<Renderbuffer> mRenderbuffer;
 };
 
 }
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 e23010d..a89cc86 100644
--- a/src/libGLESv2/HandleAllocator.h
+++ b/src/libGLESv2/HandleAllocator.h
@@ -10,13 +10,12 @@
 #ifndef LIBGLESV2_HANDLEALLOCATOR_H_
 #define LIBGLESV2_HANDLEALLOCATOR_H_
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.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 7576be4..6528dd1 100644
--- a/src/libGLESv2/Program.h
+++ b/src/libGLESv2/Program.h
@@ -10,12 +10,16 @@
 #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
 {
@@ -24,10 +28,8 @@
 
 namespace gl
 {
+struct Caps;
 class ResourceManager;
-class FragmentShader;
-class VertexShader;
-class ProgramBinary;
 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 e3ffa47..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
@@ -10,31 +9,64 @@
 
 #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/VertexDataManager.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
 {
 
+GLenum GetTextureType(GLenum samplerType)
+{
+    switch (samplerType)
+    {
+      case GL_SAMPLER_2D:
+      case GL_INT_SAMPLER_2D:
+      case GL_UNSIGNED_INT_SAMPLER_2D:
+      case GL_SAMPLER_2D_SHADOW:
+        return GL_TEXTURE_2D;
+      case GL_SAMPLER_3D:
+      case GL_INT_SAMPLER_3D:
+      case GL_UNSIGNED_INT_SAMPLER_3D:
+        return GL_TEXTURE_3D;
+      case GL_SAMPLER_CUBE:
+      case GL_SAMPLER_CUBE_SHADOW:
+        return GL_TEXTURE_CUBE_MAP;
+      case GL_INT_SAMPLER_CUBE:
+      case GL_UNSIGNED_INT_SAMPLER_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 GL_TEXTURE_2D_ARRAY;
+      default: UNREACHABLE();
+    }
+
+    return GL_TEXTURE_2D;
+}
+
 unsigned int ParseAndStripArrayIndex(std::string* name)
 {
     unsigned int subscript = GL_INVALID_INDEX;
@@ -51,14 +83,14 @@
     return subscript;
 }
 
-void GetInputLayoutFromShader(const std::vector<gl::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++)
     {
         ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS);
 
-        const gl::Attribute &shaderAttr = shaderAttributes[attributeIndex];
+        const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
 
         if (shaderAttr.type != GL_NONE)
         {
@@ -68,7 +100,7 @@
             {
                 VertexFormat *defaultFormat = &inputLayout[layoutIndex];
 
-                defaultFormat->mType = UniformComponentType(transposedType);
+                defaultFormat->mType = VariableComponentType(transposedType);
                 defaultFormat->mNormalized = false;
                 defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
                 defaultFormat->mComponents = VariableColumnCount(transposedType);
@@ -77,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)
@@ -84,8 +136,7 @@
 {
 }
 
-ProgramBinary::VertexExecutable::VertexExecutable(rx::Renderer *const renderer,
-                                                  const VertexFormat inputLayout[],
+ProgramBinary::VertexExecutable::VertexExecutable(const VertexFormat inputLayout[],
                                                   const GLenum signature[],
                                                   rx::ShaderExecutable *shaderExecutable)
     : mShaderExecutable(shaderExecutable)
@@ -99,7 +150,7 @@
 
 ProgramBinary::VertexExecutable::~VertexExecutable()
 {
-    delete mShaderExecutable;
+    SafeDelete(mShaderExecutable);
 }
 
 bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const
@@ -115,6 +166,17 @@
     return true;
 }
 
+ProgramBinary::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable)
+    : mOutputSignature(outputSignature),
+      mShaderExecutable(shaderExecutable)
+{
+}
+
+ProgramBinary::PixelExecutable::~PixelExecutable()
+{
+    SafeDelete(mShaderExecutable);
+}
+
 LinkedVarying::LinkedVarying()
 {
 }
@@ -127,66 +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),
-      mPixelExecutable(NULL),
+      mProgram(impl),
       mGeometryExecutable(NULL),
       mUsedVertexSamplerRange(0),
       mUsedPixelSamplerRange(0),
       mUsesPointSize(false),
       mShaderVersion(100),
-      mVertexUniformStorage(NULL),
-      mFragmentUniformStorage(NULL),
+      mDirtySamplerMapping(true),
       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()
 {
-    while (!mVertexExecutables.empty())
-    {
-        delete mVertexExecutables.back();
-        mVertexExecutables.pop_back();
-    }
-
-    SafeDelete(mGeometryExecutable);
-    SafeDelete(mPixelExecutable);
-
-    while (!mUniforms.empty())
-    {
-        delete mUniforms.back();
-        mUniforms.pop_back();
-    }
-
-    while (!mUniformBlocks.empty())
-    {
-        delete mUniformBlocks.back();
-        mUniformBlocks.pop_back();
-    }
-
-    SafeDelete(mVertexUniformStorage);
-    SafeDelete(mFragmentUniformStorage);
-    SafeDelete(mDynamicHLSL);
+    reset();
+    SafeDelete(mProgram);
 }
 
 unsigned int ProgramBinary::getSerial() const
@@ -204,15 +230,61 @@
     return mCurrentSerial++;
 }
 
-rx::ShaderExecutable *ProgramBinary::getPixelExecutable() const
+rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
 {
-    return mPixelExecutable;
+    std::vector<GLenum> outputs;
+
+    const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
+
+    for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
+    {
+        const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+        if (colorbuffer)
+        {
+            outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
+        }
+        else
+        {
+            outputs.push_back(GL_NONE);
+        }
+    }
+
+    return getPixelExecutableForOutputLayout(outputs);
+}
+
+rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature)
+{
+    for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
+    {
+        if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
+        {
+            return mPixelExecutables[executableIndex]->shaderExecutable();
+        }
+    }
+
+    InfoLog tempInfoLog;
+    rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature,
+            mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
+    if (!pixelExecutable)
+    {
+        std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
+        tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
+        ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
+    }
+    else
+    {
+        mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
+    }
+
+    return pixelExecutable;
 }
 
 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++)
     {
@@ -222,21 +294,9 @@
         }
     }
 
-    // Generate new dynamic layout with attribute conversions
-    const std::string &layoutHLSL = mDynamicHLSL->generateInputLayoutHLSL(inputLayout, mShaderAttributes);
-
-    // Generate new shader source by replacing the attributes stub with the defined input layout
-    std::string vertexHLSL = mVertexHLSL;
-    size_t insertPos = vertexHLSL.find(DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING);
-    vertexHLSL.replace(insertPos, DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING.length(), layoutHLSL);
-
-    // Generate new vertex executable
     InfoLog tempInfoLog;
-    rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, vertexHLSL.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)
     {
@@ -246,7 +306,7 @@
     }
     else
     {
-        mVertexExecutables.push_back(new VertexExecutable(mRenderer, inputLayout, signature, vertexExecutable));
+        mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
     }
 
     return vertexExecutable;
@@ -302,7 +362,7 @@
 
 bool ProgramBinary::usesPointSpriteEmulation() const
 {
-    return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
+    return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4;
 }
 
 bool ProgramBinary::usesGeometryShader() const
@@ -310,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 < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
-
-        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 < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
-
-        if (mSamplersVS[samplerIndex].active)
+        ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
+        if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
         {
             logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
         }
@@ -337,7 +393,7 @@
       default: UNREACHABLE();
     }
 
-    if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)mRenderer->getMaxCombinedTextureImageUnits())
+    if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
     {
         return logicalTextureUnit;
     }
@@ -347,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 < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
+        ASSERT(samplerIndex < mSamplersPS.size());
         ASSERT(mSamplersPS[samplerIndex].active);
         return mSamplersPS[samplerIndex].textureType;
       case SAMPLER_VERTEX:
-        ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
+        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)
@@ -487,8 +543,8 @@
 template <typename T>
 void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
 {
-    const int components = UniformComponentCount(targetUniformType);
-    const GLenum targetBoolType = UniformBoolVectorType(targetUniformType);
+    const int components = VariableComponentCount(targetUniformType);
+    const GLenum targetBoolType = VariableBoolVectorType(targetUniformType);
 
     LinkedUniform *targetUniform = getUniformByLocation(location);
 
@@ -498,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();
@@ -697,41 +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();
+    setUniform(location, count, v, GL_INT);
 }
 
 void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
@@ -770,36 +818,26 @@
 }
 
 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 = UniformExternalSize(targetUniform->type);
-        if (*bufSize < requiredBytes)
-        {
-            return false;
-        }
-    }
-
     if (IsMatrixType(targetUniform->type))
     {
         const int rows = VariableRowCount(targetUniform->type);
         const int cols = VariableColumnCount(targetUniform->type);
         transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows);
     }
-    else if (uniformType == UniformComponentType(targetUniform->type))
+    else if (uniformType == VariableComponentType(targetUniform->type))
     {
-        unsigned int size = UniformComponentCount(targetUniform->type);
+        unsigned int size = VariableComponentCount(targetUniform->type);
         memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T),
                 size * sizeof(T));
     }
     else
     {
-        unsigned int size = UniformComponentCount(targetUniform->type);
-        switch (UniformComponentType(targetUniform->type))
+        unsigned int size = VariableComponentCount(targetUniform->type);
+        switch (VariableComponentType(targetUniform->type))
         {
           case GL_BOOL:
             {
@@ -848,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()
@@ -876,9 +912,15 @@
     }
 }
 
-// Applies all the uniforms set for this program object to the renderer
-void ProgramBinary::applyUniforms()
+void ProgramBinary::updateSamplerMapping()
 {
+    if (!mDirtySamplerMapping)
+    {
+        return;
+    }
+
+    mDirtySamplerMapping = false;
+
     // Retrieve sampler uniform values
     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
     {
@@ -889,7 +931,7 @@
             if (IsSampler(targetUniform->type))
             {
                 int count = targetUniform->elementCount();
-                GLint (*v)[4] = (GLint(*)[4])targetUniform->data;
+                GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
 
                 if (targetUniform->isReferencedByFragmentShader())
                 {
@@ -899,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];
@@ -915,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];
@@ -925,8 +967,14 @@
             }
         }
     }
+}
 
-    mRenderer->applyUniforms(*this);
+// Applies all the uniforms set for this program object to the renderer
+void ProgramBinary::applyUniforms()
+{
+    updateSamplerMapping();
+
+    mProgram->getRenderer()->applyUniforms(*this);
 
     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
     {
@@ -934,36 +982,40 @@
     }
 }
 
-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());
 
     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
     {
-        gl::UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex);
+        UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex);
         gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
 
         ASSERT(uniformBlock && uniformBuffer);
 
-        if (uniformBuffer->size() < uniformBlock->dataSize)
+        if (uniformBuffer->getSize() < uniformBlock->dataSize)
         {
             // undefined behaviour
             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;
         }
 
@@ -971,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();
@@ -989,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;
@@ -1016,15 +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;
@@ -1064,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);
@@ -1104,7 +1173,7 @@
         int matrixStride = stream.readInt<int>();
         bool isRowMajorMatrix = stream.readBool();
 
-        const gl::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
+        const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
 
         LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo);
 
@@ -1175,12 +1244,7 @@
         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++)
     {
         VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
@@ -1195,10 +1259,8 @@
         }
 
         unsigned int vertexShaderSize = stream.readInt<unsigned int>();
-
-        const char *vertexShaderFunction = (const char*) binary + stream.offset();
-
-        rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
+        const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
+        rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
                                                                            vertexShaderSize, rx::SHADER_VERTEX,
                                                                            mTransformFeedbackLinkedVaryings,
                                                                            (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
@@ -1210,70 +1272,97 @@
 
         // 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(mRenderer, inputLayout, signature, shaderExecutable));
+        mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
 
         stream.skip(vertexShaderSize);
     }
 
-    unsigned int pixelShaderSize = stream.readInt<unsigned int>();
-
-    const char *pixelShaderFunction = (const char*) binary + stream.offset();
-    mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction),
-                                                 pixelShaderSize, rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings,
-                                                 (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-    if (!mPixelExecutable)
+    const size_t pixelShaderCount = stream.readInt<unsigned int>();
+    for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
     {
-        infoLog.append("Could not create pixel shader.");
-        return false;
+        const size_t outputCount = stream.readInt<unsigned int>();
+        std::vector<GLenum> outputs(outputCount);
+        for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
+        {
+            stream.readInt(&outputs[outputIndex]);
+        }
+
+        const size_t pixelShaderSize = stream.readInt<unsigned int>();
+        const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
+        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.");
+            return false;
+        }
+
+        // add new binary
+        mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
+
+        stream.skip(pixelShaderSize);
     }
-    stream.skip(pixelShaderSize);
 
     unsigned int geometryShaderSize = stream.readInt<unsigned int>();
 
     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.");
-            SafeDelete(mPixelExecutable);
             return false;
         }
         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<unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
+    stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
     stream.writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
 
     for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
@@ -1285,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);
@@ -1367,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++)
     {
@@ -1387,26 +1475,49 @@
         size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
         stream.writeInt(vertexShaderSize);
 
-        unsigned char *vertexBlob = static_cast<unsigned char *>(vertexExecutable->shaderExecutable()->getFunction());
+        const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
         stream.writeBytes(vertexBlob, vertexShaderSize);
     }
 
-    size_t pixelShaderSize = mPixelExecutable->getLength();
-    stream.writeInt(pixelShaderSize);
+    stream.writeInt(mPixelExecutables.size());
+    for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
+    {
+        PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
 
-    unsigned char *pixelBlob = static_cast<unsigned char *>(mPixelExecutable->getFunction());
-    stream.writeBytes(pixelBlob, pixelShaderSize);
+        const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
+        stream.writeInt(outputs.size());
+        for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
+        {
+            stream.writeInt(outputs[outputIndex]);
+        }
+
+        size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
+        stream.writeInt(pixelShaderSize);
+
+        const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
+        stream.writeBytes(pixelBlob, pixelShaderSize);
+    }
 
     size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
     stream.writeInt(geometryShaderSize);
 
     if (mGeometryExecutable != NULL && geometryShaderSize > 0)
     {
-        unsigned char *geometryBlob = static_cast<unsigned char *>(mGeometryExecutable->getFunction());
+        const uint8_t *geometryBlob = mGeometryExecutable->getFunction();
         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();
@@ -1446,7 +1557,7 @@
 GLint ProgramBinary::getLength()
 {
     GLint length;
-    if (save(NULL, INT_MAX, &length))
+    if (save(NULL, NULL, INT_MAX, &length))
     {
         return length;
     }
@@ -1456,78 +1567,71 @@
     }
 }
 
-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);
 
-    mTransformFeedbackLinkedVaryings.clear();
+    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());
 
-    std::string pixelHLSL = fragmentShader->getHLSL();
-    mVertexHLSL = vertexShader->getHLSL();
-    mVertexWorkarounds = vertexShader->getD3DWorkarounds();
+    mShaderVersion = vertexShaderD3D->getShaderVersion();
 
-    // 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, pixelHLSL, mVertexHLSL,
-                                              fragmentShader, vertexShader, transformFeedbackVaryings,
-                                              &linkedVaryings, &mOutputVariables))
+    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->getUniforms(), fragmentShader->getUniforms()))
+    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())
     {
-        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, BlockMemberInfo::getDefaultBlockInfo()));
-        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, BlockMemberInfo::getDefaultBlockInfo()));
-        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, BlockMemberInfo::getDefaultBlockInfo()));
+        const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
+
+        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo));
+        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo));
+        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
     }
 
-    if (!linkUniformBlocks(infoLog, vertexShader->getInterfaceBlocks(), fragmentShader->getInterfaceBlocks()))
+    if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
     {
         success = false;
     }
 
     if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
-                                               transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings))
+                                               transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps))
     {
         success = false;
     }
@@ -1535,38 +1639,26 @@
     if (success)
     {
         VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
-        GetInputLayoutFromShader(vertexShader->activeAttributes(), defaultInputLayout);
-
+        GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
         rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
-        mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL,
-                                                          mTransformFeedbackLinkedVaryings,
-                                                          (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
-                                                          fragmentShader->getD3DWorkarounds());
+
+        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 || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
+        if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
         {
             infoLog.append("Failed to create D3D shaders.");
             success = false;
-
-            while (!mVertexExecutables.empty())
-            {
-                delete mVertexExecutables.back();
-                mVertexExecutables.pop_back();
-            }
-
-            SafeDelete(mGeometryExecutable);
-            SafeDelete(mPixelExecutable);
-
-            mTransformFeedbackLinkedVaryings.clear();
+            reset();
         }
     }
 
@@ -1574,22 +1666,27 @@
 }
 
 // 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<gl::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 gl::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;
 
         if (location != -1)   // Set by glBindAttribLocation or by location layout qualifier
         {
-            const int rows = AttributeRegisterCount(attribute.type);
+            const int rows = VariableRegisterCount(attribute.type);
 
             if (rows + location > MAX_VERTEX_ATTRIBS)
             {
@@ -1601,7 +1698,7 @@
             for (int row = 0; row < rows; row++)
             {
                 const int rowLocation = location + row;
-                gl::ShaderVariable &linkedAttribute = mLinkedAttribute[rowLocation];
+                sh::ShaderVariable &linkedAttribute = mLinkedAttribute[rowLocation];
 
                 // In GLSL 3.00, attribute aliasing produces a link error
                 // In GLSL 1.00, attribute aliasing is allowed
@@ -1621,14 +1718,17 @@
     }
 
     // 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 gl::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
         {
-            int rows = AttributeRegisterCount(attribute.type);
+            int rows = VariableRegisterCount(attribute.type);
             int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
 
             if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
@@ -1644,8 +1744,8 @@
 
     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
     {
-        int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
-        int rows = AttributeRegisterCount(mLinkedAttribute[attributeIndex].type);
+        int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
+        int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type);
 
         for (int r = 0; r < rows; r++)
         {
@@ -1658,7 +1758,8 @@
     return true;
 }
 
-bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const gl::ShaderVariable &vertexVariable, const gl::ShaderVariable &fragmentVariable, bool validatePrecision)
+bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable,
+                                              const sh::ShaderVariable &fragmentVariable, bool validatePrecision)
 {
     if (vertexVariable.type != fragmentVariable.type)
     {
@@ -1676,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;
         }
@@ -1710,22 +1808,17 @@
     return true;
 }
 
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const gl::Uniform &vertexUniform, const gl::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<gl::Uniform>(infoLog, uniformName, vertexUniform, fragmentUniform))
-    {
-        return false;
-    }
-
     return true;
 }
 
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const gl::Varying &vertexVarying, const gl::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))
     {
@@ -1738,56 +1831,52 @@
         return false;
     }
 
-    if (!linkValidateFields<gl::Varying>(infoLog, varyingName, vertexVarying, fragmentVarying))
-    {
-        return false;
-    }
-
     return true;
 }
 
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const gl::InterfaceBlockField &vertexUniform, const gl::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<gl::InterfaceBlockField>(infoLog, uniformName, vertexUniform, fragmentUniform))
-    {
-        return false;
-    }
-
     return true;
 }
 
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<gl::Uniform> &vertexUniforms, const std::vector<gl::Uniform> &fragmentUniforms)
+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();
+
     // Check that uniforms defined in the vertex and fragment shaders are identical
-    typedef std::map<std::string, const gl::Uniform*> UniformMap;
+    typedef std::map<std::string, const sh::Uniform*> UniformMap;
     UniformMap linkedUniforms;
 
     for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++)
     {
-        const gl::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
+        const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
         linkedUniforms[vertexUniform.name] = &vertexUniform;
     }
 
     for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++)
     {
-        const gl::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
+        const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
         UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name);
         if (entry != linkedUniforms.end())
         {
-            const gl::Uniform &vertexUniform = *entry->second;
+            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;
             }
@@ -1796,213 +1885,206 @@
 
     for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
     {
-        if (!defineUniform(GL_VERTEX_SHADER, vertexUniforms[uniformIndex], infoLog))
+        const sh::Uniform &uniform = vertexUniforms[uniformIndex];
+
+        if (uniform.staticUse)
         {
-            return false;
+            defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
         }
     }
 
     for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
     {
-        if (!defineUniform(GL_FRAGMENT_SHADER, fragmentUniforms[uniformIndex], infoLog))
+        const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
+
+        if (uniform.staticUse)
         {
-            return false;
+            defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
         }
     }
 
-    initializeUniformStorage();
-
-    return true;
-}
-
-TextureType ProgramBinary::getTextureType(GLenum samplerType, InfoLog &infoLog)
-{
-    switch(samplerType)
-    {
-      case GL_SAMPLER_2D:
-      case GL_INT_SAMPLER_2D:
-      case GL_UNSIGNED_INT_SAMPLER_2D:
-      case GL_SAMPLER_2D_SHADOW:
-        return TEXTURE_2D;
-      case GL_SAMPLER_3D:
-      case GL_INT_SAMPLER_3D:
-      case GL_UNSIGNED_INT_SAMPLER_3D:
-        return TEXTURE_3D;
-      case GL_SAMPLER_CUBE:
-      case GL_SAMPLER_CUBE_SHADOW:
-        return TEXTURE_CUBE;
-      case GL_INT_SAMPLER_CUBE:
-      case GL_UNSIGNED_INT_SAMPLER_CUBE:
-        return TEXTURE_CUBE;
-      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;
-      default: UNREACHABLE();
-    }
-
-    return TEXTURE_2D;
-}
-
-bool ProgramBinary::defineUniform(GLenum shader, const gl::Uniform &constant, InfoLog &infoLog)
-{
-    if (constant.isStruct())
-    {
-        if (constant.arraySize > 0)
-        {
-            ShShaderOutput outputType = Shader::getCompilerOutputType(shader);
-            const unsigned int elementRegisterCount = HLSLVariableRegisterCount(constant, outputType) / constant.arraySize;
-
-            for (unsigned int elementIndex = 0; elementIndex < constant.arraySize; elementIndex++)
-            {
-                const unsigned int elementRegisterOffset = elementRegisterCount * elementIndex;
-
-                for (size_t fieldIndex = 0; fieldIndex < constant.fields.size(); fieldIndex++)
-                {
-                    const gl::Uniform &field = constant.fields[fieldIndex];
-                    const std::string &uniformName = constant.name + ArrayString(elementIndex) + "." + field.name;
-                    const unsigned int fieldRegisterIndex = field.registerIndex + elementRegisterOffset;
-                    gl::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize,
-                                             fieldRegisterIndex, field.elementIndex);
-
-                    fieldUniform.fields = field.fields;
-                    if (!defineUniform(shader, fieldUniform, infoLog))
-                    {
-                        return false;
-                    }
-                }
-            }
-        }
-        else
-        {
-            for (size_t fieldIndex = 0; fieldIndex < constant.fields.size(); fieldIndex++)
-            {
-                const gl::Uniform &field = constant.fields[fieldIndex];
-                const std::string &uniformName = constant.name + "." + field.name;
-
-                gl::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize,
-                                         field.registerIndex, field.elementIndex);
-
-                fieldUniform.fields = field.fields;
-
-                if (!defineUniform(shader, fieldUniform, infoLog))
-                {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    if (IsSampler(constant.type))
-    {
-        unsigned int samplerIndex = constant.registerIndex;
-
-        do
-        {
-            if (shader == GL_VERTEX_SHADER)
-            {
-                if (samplerIndex < mRenderer->getMaxVertexTextureImageUnits())
-                {
-                    mSamplersVS[samplerIndex].active = true;
-                    mSamplersVS[samplerIndex].textureType = getTextureType(constant.type, infoLog);
-                    mSamplersVS[samplerIndex].logicalTextureUnit = 0;
-                    mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange);
-                }
-                else
-                {
-                    infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", mRenderer->getMaxVertexTextureImageUnits());
-                    return false;
-                }
-            }
-            else if (shader == GL_FRAGMENT_SHADER)
-            {
-                if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
-                {
-                    mSamplersPS[samplerIndex].active = true;
-                    mSamplersPS[samplerIndex].textureType = getTextureType(constant.type, infoLog);
-                    mSamplersPS[samplerIndex].logicalTextureUnit = 0;
-                    mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange);
-                }
-                else
-                {
-                    infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
-                    return false;
-                }
-            }
-            else UNREACHABLE();
-
-            samplerIndex++;
-        }
-        while (samplerIndex < constant.registerIndex + constant.arraySize);
-    }
-
-    LinkedUniform *uniform = NULL;
-    GLint location = getUniformLocation(constant.name);
-
-    if (location >= 0)   // Previously defined, type and precision must match
-    {
-        uniform = mUniforms[mUniformIndex[location].index];
-    }
-    else
-    {
-        uniform = new LinkedUniform(constant.type, constant.precision, constant.name, constant.arraySize,
-                                    -1, BlockMemberInfo::getDefaultBlockInfo());
-        uniform->registerElement = constant.elementIndex;
-    }
-
-    if (!uniform)
+    if (!indexUniforms(infoLog, caps))
     {
         return false;
     }
 
-    if (shader == GL_FRAGMENT_SHADER)
-    {
-        uniform->psRegisterIndex = constant.registerIndex;
-    }
-    else if (shader == GL_VERTEX_SHADER)
-    {
-        uniform->vsRegisterIndex = constant.registerIndex;
-    }
-    else UNREACHABLE();
-
-    if (location >= 0)
-    {
-        return uniform->type == constant.type;
-    }
-
-    mUniforms.push_back(uniform);
-    unsigned int uniformIndex = mUniforms.size() - 1;
-
-    for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform->elementCount(); arrayElementIndex++)
-    {
-        mUniformIndex.push_back(VariableLocation(uniform->name, arrayElementIndex, uniformIndex));
-    }
-
-    if (shader == GL_VERTEX_SHADER)
-    {
-        if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedVertexUniformVectors() + mRenderer->getMaxVertexUniformVectors())
-        {
-            infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", mRenderer->getMaxVertexUniformVectors());
-            return false;
-        }
-    }
-    else if (shader == GL_FRAGMENT_SHADER)
-    {
-        if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedFragmentUniformVectors() + mRenderer->getMaxFragmentUniformVectors())
-        {
-            infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", mRenderer->getMaxFragmentUniformVectors());
-            return false;
-        }
-    }
-    else UNREACHABLE();
+    mProgram->initializeUniformStorage(mUniforms);
 
     return true;
 }
 
-bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const gl::InterfaceBlock &vertexInterfaceBlock, const gl::InterfaceBlock &fragmentInterfaceBlock)
+void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
+{
+    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::ShaderVariable &uniform,
+                                  const std::string &fullName, sh::HLSLBlockEncoder *encoder)
+{
+    if (uniform.isStruct())
+    {
+        for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
+        {
+            const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
+
+            encoder->enterAggregateType();
+
+            for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
+            {
+                const sh::ShaderVariable &field = uniform.fields[fieldIndex];
+                const std::string &fieldFullName = (fullName + elementString + "." + field.name);
+
+                defineUniform(shader, field, fieldFullName, encoder);
+            }
+
+            encoder->exitAggregateType();
+        }
+    }
+    else // Not a struct
+    {
+        // Arrays are treated as aggregate types
+        if (uniform.isArray())
+        {
+            encoder->enterAggregateType();
+        }
+
+        LinkedUniform *linkedUniform = getUniformByName(fullName);
+
+        if (!linkedUniform)
+        {
+            linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
+                                              -1, sh::BlockMemberInfo::getDefaultBlockInfo());
+            ASSERT(linkedUniform);
+            linkedUniform->registerElement = encoder->getCurrentElement();
+            mUniforms.push_back(linkedUniform);
+        }
+
+        ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
+
+        if (shader == GL_FRAGMENT_SHADER)
+        {
+            linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
+        }
+        else if (shader == GL_VERTEX_SHADER)
+        {
+            linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
+        }
+        else UNREACHABLE();
+
+        // Advance the uniform offset, to track registers allocation for structs
+        encoder->encodeType(uniform.type, uniform.arraySize, false);
+
+        // Arrays are treated as aggregate types
+        if (uniform.isArray())
+        {
+            encoder->exitAggregateType();
+        }
+    }
+}
+
+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);
+
+    if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
+    {
+        if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
+                            &mUsedVertexSamplerRange))
+        {
+            infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
+                           mSamplersVS.size());
+            return false;
+        }
+
+        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)",
+                           caps.maxVertexUniformVectors);
+            return false;
+        }
+    }
+
+    if (uniform.psRegisterIndex != GL_INVALID_INDEX)
+    {
+        if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
+                            &mUsedPixelSamplerRange))
+        {
+            infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
+                           mSamplersPS.size());
+            return false;
+        }
+
+        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)",
+                           caps.maxFragmentUniformVectors);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
+{
+    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+    {
+        const LinkedUniform &uniform = *mUniforms[uniformIndex];
+
+        if (IsSampler(uniform.type))
+        {
+            if (!indexSamplerUniform(uniform, infoLog, caps))
+            {
+                return false;
+            }
+        }
+
+        for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++)
+        {
+            mUniformIndex.push_back(VariableLocation(uniform.name, arrayElementIndex, uniformIndex));
+        }
+    }
+
+    return true;
+}
+
+bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
+                                   GLenum samplerType,
+                                   unsigned int samplerCount,
+                                   std::vector<Sampler> &outSamplers,
+                                   GLuint *outUsedRange)
+{
+    unsigned int samplerIndex = startSamplerIndex;
+
+    do
+    {
+        if (samplerIndex < outSamplers.size())
+        {
+            Sampler& sampler = outSamplers[samplerIndex];
+            sampler.active = true;
+            sampler.textureType = GetTextureType(samplerType);
+            sampler.logicalTextureUnit = 0;
+            *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
+        }
+        else
+        {
+            return false;
+        }
+
+        samplerIndex++;
+    } while (samplerIndex < startSamplerIndex + samplerCount);
+
+    return true;
+}
+
+bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock)
 {
     const char* blockName = vertexInterfaceBlock.name.c_str();
 
@@ -2028,8 +2110,8 @@
     const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
     for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
     {
-        const gl::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
-        const gl::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
+        const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
+        const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
 
         if (vertexMember.name != fragmentMember.name)
         {
@@ -2038,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;
         }
@@ -2048,26 +2130,28 @@
     return true;
 }
 
-bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const std::vector<gl::InterfaceBlock> &vertexInterfaceBlocks,
-                                      const std::vector<gl::InterfaceBlock> &fragmentInterfaceBlocks)
+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();
+
     // Check that interface blocks defined in the vertex and fragment shaders are identical
-    typedef std::map<std::string, const gl::InterfaceBlock*> UniformBlockMap;
+    typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
     UniformBlockMap linkedUniformBlocks;
 
     for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
     {
-        const gl::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
+        const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
         linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
     }
 
     for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
     {
-        const gl::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
+        const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
         UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
         if (entry != linkedUniformBlocks.end())
         {
-            const gl::InterfaceBlock &vertexInterfaceBlock = *entry->second;
+            const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
             if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
             {
                 return false;
@@ -2077,17 +2161,29 @@
 
     for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
     {
-        if (!defineUniformBlock(infoLog, GL_VERTEX_SHADER, 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, GL_FRAGMENT_SHADER, 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;
+            }
         }
     }
 
@@ -2097,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();
@@ -2123,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;
                 }
 
@@ -2142,53 +2237,60 @@
         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<gl::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, 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 gl::InterfaceBlockField &field = fields[uniformIndex];
+        const VarT &field = fields[uniformIndex];
         const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
 
-        if (!field.fields.empty())
+        if (field.isStruct())
         {
-            if (field.arraySize > 0)
+            bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
+
+            for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
             {
-                for (unsigned int arrayElement = 0; arrayElement < field.arraySize; arrayElement++)
-                {
-                    const std::string uniformElementName = fieldName + ArrayString(arrayElement);
-                    defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, blockInfoItr, blockUniformIndexes);
-                }
-            }
-            else
-            {
-                defineUniformBlockMembers(field.fields, fieldName, blockIndex, blockInfoItr, blockUniformIndexes);
+                encoder->enterAggregateType();
+
+                const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
+                defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
+
+                encoder->exitAggregateType();
             }
         }
         else
         {
+            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, **blockInfoItr);
+                                                          blockIndex, memberInfo);
 
             // add to uniform list, but not index, since uniform block uniforms have no location
             blockUniformIndexes->push_back(mUniforms.size());
             mUniforms.push_back(newUniform);
-            (*blockInfoItr)++;
         }
     }
 }
 
-bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, GLenum shader, const gl::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)
     {
@@ -2196,68 +2298,83 @@
         const unsigned int blockIndex = mUniformBlocks.size();
 
         // define member uniforms
-        BlockInfoItr blockInfoItr = interfaceBlock.blockInfo.cbegin();
-        defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, &blockInfoItr, &blockUniformIndexes);
+        sh::BlockLayoutEncoder *encoder = NULL;
+
+        if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD)
+        {
+            encoder = new sh::Std140BlockEncoder;
+        }
+        else
+        {
+            encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED);
+        }
+        ASSERT(encoder);
+
+        defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
+
+        size_t dataSize = encoder->getBlockSize();
 
         // create all the uniform blocks
         if (interfaceBlock.arraySize > 0)
         {
             for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++)
             {
-                gl::UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, interfaceBlock.dataSize);
+                UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize);
                 newUniformBlock->memberUniformIndexes = blockUniformIndexes;
                 mUniformBlocks.push_back(newUniformBlock);
             }
         }
         else
         {
-            gl::UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, interfaceBlock.dataSize);
+            UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize);
             newUniformBlock->memberUniformIndexes = blockUniformIndexes;
             mUniformBlocks.push_back(newUniformBlock);
         }
     }
 
-    // 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());
-
-    for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
+    if (interfaceBlock.staticUse)
     {
-        gl::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, interfaceBlock.registerIndex + 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;
         }
     }
@@ -2427,6 +2544,19 @@
     return mUniforms[mUniformIndex[location].index];
 }
 
+LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const
+{
+    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+    {
+        if (mUniforms[uniformIndex]->name == name)
+        {
+            return mUniforms[uniformIndex];
+        }
+    }
+
+    return NULL;
+}
+
 void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
 {
     ASSERT(uniformBlockIndex < mUniformBlocks.size());   // index must be smaller than getActiveUniformBlockCount()
@@ -2514,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;
     }
@@ -2527,19 +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)
     {
@@ -2547,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)
                     {
@@ -2571,7 +2696,7 @@
             }
             else
             {
-                textureUnitType[unit] = mSamplersPS[i].textureType;
+                textureUnitTypes[unit] = mSamplersPS[i].textureType;
             }
         }
     }
@@ -2582,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)
                     {
@@ -2606,7 +2731,7 @@
             }
             else
             {
-                textureUnitType[unit] = mSamplersVS[i].textureType;
+                textureUnitTypes[unit] = mSamplersVS[i].textureType;
             }
         }
     }
@@ -2614,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)
 {
 }
 
@@ -2662,30 +2787,33 @@
     }
 }
 
-void ProgramBinary::initializeUniformStorage()
+void ProgramBinary::reset()
 {
-    // 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];
+    SafeDeleteContainer(mVertexExecutables);
+    SafeDeleteContainer(mPixelExecutables);
 
-        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);
-            }
-        }
-    }
+    SafeDelete(mGeometryExecutable);
 
-    mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u);
-    mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
+    mTransformFeedbackBufferMode = GL_NONE;
+    mTransformFeedbackLinkedVaryings.clear();
+
+    mSamplersPS.clear();
+    mSamplersVS.clear();
+
+    mUsedVertexSamplerRange = 0;
+    mUsedPixelSamplerRange = 0;
+    mUsesPointSize = false;
+    mShaderVersion = 0;
+    mDirtySamplerMapping = true;
+
+    SafeDeleteContainer(mUniforms);
+    SafeDeleteContainer(mUniformBlocks);
+    mUniformIndex.clear();
+    mOutputVariables.clear();
+
+    mProgram->reset();
+
+    mValidated = false;
 }
 
 }
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index 839923b..738d63f 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -10,21 +10,36 @@
 #ifndef LIBGLESV2_PROGRAM_BINARY_H_
 #define LIBGLESV2_PROGRAM_BINARY_H_
 
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <string>
-#include <vector>
-
 #include "common/RefCountObject.h"
 #include "angletypes.h"
 #include "common/mathutil.h"
 #include "libGLESv2/Uniform.h"
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Constants.h"
-#include "libGLESv2/renderer/VertexDataManager.h"
+#include "libGLESv2/renderer/d3d/VertexDataManager.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
 {
@@ -32,16 +47,17 @@
 class Renderer;
 struct TranslatedAttribute;
 class UniformStorage;
-class DynamicHLSL;
+class ProgramImpl;
 }
 
 namespace gl
 {
-class FragmentShader;
-class VertexShader;
+struct Caps;
+class Shader;
 class InfoLog;
 class AttributeBindings;
 class Buffer;
+class Framebuffer;
 
 // Struct used for correlating uniforms/elements of uniform arrays to handles
 struct VariableLocation
@@ -79,18 +95,22 @@
 class ProgramBinary : public RefCountObject
 {
   public:
-    explicit ProgramBinary(rx::Renderer *renderer);
+    explicit ProgramBinary(rx::ProgramImpl *impl);
     ~ProgramBinary();
 
-    rx::ShaderExecutable *getPixelExecutable() const;
+    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]);
     rx::ShaderExecutable *getGeometryExecutable() const;
 
     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;
@@ -121,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;
@@ -147,6 +167,7 @@
     GLint getActiveUniformi(GLuint index, GLenum pname) const;
     bool isValidUniformLocation(GLint location) const;
     LinkedUniform *getUniformByLocation(GLint location) const;
+    LinkedUniform *getUniformByName(const std::string &name) const;
 
     void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
     void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
@@ -160,9 +181,10 @@
     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();
 
     unsigned int getSerial() const;
     int getShaderVersion() const;
@@ -171,37 +193,55 @@
     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);
 
-    bool linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShader, VertexShader *vertexShader);
-    bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
+    struct Sampler
+    {
+        Sampler();
 
-    typedef std::vector<BlockMemberInfo>::const_iterator BlockInfoItr;
+        bool active;
+        GLint logicalTextureUnit;
+        GLenum textureType;
+    };
 
-    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 ShaderVariable &vertexVariable, const ShaderVariable &fragmentVariable, bool validatePrecision);
+    void reset();
 
-    bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const Uniform &vertexUniform, const Uniform &fragmentUniform);
-    bool linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const Varying &vertexVarying, const Varying &fragmentVarying);
-    bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const InterfaceBlockField &vertexUniform, const InterfaceBlockField &fragmentUniform);
-    bool linkUniforms(InfoLog &infoLog, const std::vector<Uniform> &vertexUniforms, const std::vector<Uniform> &fragmentUniforms);
-    bool defineUniform(GLenum shader, const Uniform &constant, InfoLog &infoLog);
-    bool areMatchingInterfaceBlocks(InfoLog &infoLog, const InterfaceBlock &vertexInterfaceBlock, const InterfaceBlock &fragmentInterfaceBlock);
-    bool linkUniformBlocks(InfoLog &infoLog, const std::vector<InterfaceBlock> &vertexUniformBlocks, const std::vector<InterfaceBlock> &fragmentUniformBlocks);
+    bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
+
+    static bool linkValidateVariablesBase(InfoLog &infoLog,
+                                          const std::string &variableName,
+                                          const sh::ShaderVariable &vertexVariable,
+                                          const sh::ShaderVariable &fragmentVariable,
+                                          bool validatePrecision);
+
+    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::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,
+                               std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
+    bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock);
+    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<InterfaceBlockField> &fields, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes);
-    bool defineUniformBlock(InfoLog &infoLog, GLenum shader, const 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);
@@ -210,15 +250,12 @@
     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);
-
-    static TextureType getTextureType(GLenum samplerType, InfoLog &infoLog);
+    void getUniformv(GLint location, T *params, GLenum uniformType);
 
     class VertexExecutable
     {
       public:
-        VertexExecutable(rx::Renderer *const renderer,
-                         const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS],
+        VertexExecutable(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS],
                          const GLenum signature[MAX_VERTEX_ATTRIBS],
                          rx::ShaderExecutable *shaderExecutable);
         ~VertexExecutable();
@@ -235,45 +272,49 @@
         rx::ShaderExecutable *mShaderExecutable;
     };
 
-    rx::Renderer *const mRenderer;
-    DynamicHLSL *mDynamicHLSL;
+    class PixelExecutable
+    {
+      public:
+        PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable);
+        ~PixelExecutable();
 
-    std::string mVertexHLSL;
-    rx::D3DWorkaroundType mVertexWorkarounds;
+        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; }
+
+      private:
+        std::vector<GLenum> mOutputSignature;
+        rx::ShaderExecutable *mShaderExecutable;
+    };
+
+    rx::ProgramImpl *mProgram;
+
     std::vector<VertexExecutable *> mVertexExecutables;
-    rx::ShaderExecutable *mGeometryExecutable;
-    rx::ShaderExecutable *mPixelExecutable;
+    std::vector<PixelExecutable *> mPixelExecutables;
 
-    Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
-    Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS];
+    rx::ShaderExecutable *mGeometryExecutable;
+
+    sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
+    sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS];
     int mSemanticIndex[MAX_VERTEX_ATTRIBS];
     int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
 
     GLenum mTransformFeedbackBufferMode;
     std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
 
-    struct Sampler
-    {
-        Sampler();
-
-        bool active;
-        GLint logicalTextureUnit;
-        TextureType textureType;
-    };
-
-    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;
     int mShaderVersion;
+    bool mDirtySamplerMapping;
 
     std::vector<LinkedUniform*> mUniforms;
     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 4eb236f..a7ec404 100644
--- a/src/libGLESv2/Query.h
+++ b/src/libGLESv2/Query.h
@@ -9,15 +9,14 @@
 #ifndef LIBGLESV2_QUERY_H_
 #define LIBGLESV2_QUERY_H_
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-
+#include "libGLESv2/Error.h"
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
 
+#include "angle_gl.h"
+
 namespace rx
 {
-class Renderer;
 class QueryImpl;
 }
 
@@ -27,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 dade014..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,18 +9,104 @@
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
 
 #include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/Texture.h"
+#include "libGLESv2/formatutils.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/RenderTarget.h"
 
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/TextureStorage.h"
 #include "common/utilities.h"
-#include "libGLESv2/formatutils.h"
 
 namespace gl
 {
 unsigned int RenderbufferStorage::mCurrentSerial = 1;
 
+Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *newStorage)
+  : RefCountObject(id),
+    mStorage(newStorage)
+{
+    ASSERT(mStorage);
+}
+
+Renderbuffer::~Renderbuffer()
+{
+    SafeDelete(mStorage);
+}
+
+void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
+{
+    ASSERT(newStorage);
+
+    SafeDelete(mStorage);
+    mStorage = newStorage;
+}
+
+RenderbufferStorage *Renderbuffer::getStorage()
+{
+    ASSERT(mStorage);
+    return mStorage;
+}
+
+GLsizei Renderbuffer::getWidth() const
+{
+    ASSERT(mStorage);
+    return mStorage->getWidth();
+}
+
+GLsizei Renderbuffer::getHeight() const
+{
+    ASSERT(mStorage);
+    return mStorage->getHeight();
+}
+
+GLenum Renderbuffer::getInternalFormat() const
+{
+    ASSERT(mStorage);
+    return mStorage->getInternalFormat();
+}
+
+GLenum Renderbuffer::getActualFormat() const
+{
+    ASSERT(mStorage);
+    return mStorage->getActualFormat();
+}
+
+GLsizei Renderbuffer::getSamples() const
+{
+    ASSERT(mStorage);
+    return mStorage->getSamples();
+}
+
+GLuint Renderbuffer::getRedSize() const
+{
+    return GetInternalFormatInfo(getActualFormat()).redBits;
+}
+
+GLuint Renderbuffer::getGreenSize() const
+{
+    return GetInternalFormatInfo(getActualFormat()).greenBits;
+}
+
+GLuint Renderbuffer::getBlueSize() const
+{
+    return GetInternalFormatInfo(getActualFormat()).blueBits;
+}
+
+GLuint Renderbuffer::getAlphaSize() const
+{
+    return GetInternalFormatInfo(getActualFormat()).alphaBits;
+}
+
+GLuint Renderbuffer::getDepthSize() const
+{
+    return GetInternalFormatInfo(getActualFormat()).depthBits;
+}
+
+GLuint Renderbuffer::getStencilSize() const
+{
+    return GetInternalFormatInfo(getActualFormat()).stencilBits;
+}
+
 RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1))
 {
     mWidth = 0;
@@ -40,16 +125,6 @@
     return NULL;
 }
 
-rx::RenderTarget *RenderbufferStorage::getDepthStencil()
-{
-    return NULL;
-}
-
-rx::TextureStorage *RenderbufferStorage::getTextureStorage()
-{
-    return NULL;
-}
-
 GLsizei RenderbufferStorage::getWidth() const
 {
     return mWidth;
@@ -80,7 +155,7 @@
     return mSerial;
 }
 
-unsigned int RenderbufferStorage::issueSerials(GLuint count)
+unsigned int RenderbufferStorage::issueSerials(unsigned int count)
 {
     unsigned int firstSerial = mCurrentSerial;
     mCurrentSerial += count;
@@ -171,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 4da447a..71bcb0e 100644
--- a/src/libGLESv2/Renderbuffer.h
+++ b/src/libGLESv2/Renderbuffer.h
@@ -12,12 +12,10 @@
 #ifndef LIBGLESV2_RENDERBUFFER_H_
 #define LIBGLESV2_RENDERBUFFER_H_
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
+#include "angle_gl.h"
 
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
-#include "libGLESv2/FramebufferAttachment.h"
 
 namespace rx
 {
@@ -29,11 +27,43 @@
 
 namespace gl
 {
+class RenderbufferStorage;
+class FramebufferAttachment;
+
+// A GL renderbuffer object is usually used as a depth or stencil buffer attachment
+// for a framebuffer object. The renderbuffer itself is a distinct GL object, see
+// FramebufferAttachment and Framebuffer for how they are applied to an FBO via an
+// attachment point.
+
+class Renderbuffer : public RefCountObject
+{
+  public:
+    Renderbuffer(GLuint id, RenderbufferStorage *newStorage);
+    virtual ~Renderbuffer();
+
+    void setStorage(RenderbufferStorage *newStorage);
+    RenderbufferStorage *getStorage();
+
+    GLsizei getWidth() const;
+    GLsizei getHeight() const;
+    GLenum getInternalFormat() const;
+    GLenum getActualFormat() const;
+    GLsizei getSamples() const;
+    GLuint getRedSize() const;
+    GLuint getGreenSize() const;
+    GLuint getBlueSize() const;
+    GLuint getAlphaSize() const;
+    GLuint getDepthSize() const;
+    GLuint getStencilSize() const;
+
+  private:
+    RenderbufferStorage *mStorage;
+};
 
 // A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
 // is called. The specific concrete type depends on whether the internal format is
 // colour depth, stencil or packed depth/stencil.
-class RenderbufferStorage : public FramebufferAttachmentInterface
+class RenderbufferStorage
 {
   public:
     RenderbufferStorage();
@@ -41,8 +71,6 @@
     virtual ~RenderbufferStorage() = 0;
 
     virtual rx::RenderTarget *getRenderTarget();
-    virtual rx::RenderTarget *getDepthStencil();
-    virtual rx::TextureStorage *getTextureStorage();
 
     virtual GLsizei getWidth() const;
     virtual GLsizei getHeight() const;
@@ -55,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;
@@ -96,7 +124,7 @@
 
     ~DepthStencilbuffer();
 
-    virtual rx::RenderTarget *getDepthStencil();
+    virtual rx::RenderTarget *getRenderTarget();
 
   protected:
     rx::RenderTarget  *mDepthStencil;
@@ -126,6 +154,7 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
 };
+
 }
 
 #endif   // LIBGLESV2_RENDERBUFFER_H_
diff --git a/src/libGLESv2/RenderbufferProxySet.cpp b/src/libGLESv2/RenderbufferProxySet.cpp
deleted file mode 100644
index f4fbe51..0000000
--- a/src/libGLESv2/RenderbufferProxySet.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// RenderbufferProxySet.cpp: Implements the gl::RenderbufferProxySet, a class for
-// maintaining a Texture's weak references to the Renderbuffers that represent it.
-
-#include "libGLESv2/RenderbufferProxySet.h"
-#include "common/debug.h"
-
-namespace gl
-{
-
-void RenderbufferProxySet::addRef(const FramebufferAttachment *proxy)
-{
-    RefCountMap::iterator i = mRefCountMap.find(proxy);
-    if (i != mRefCountMap.end())
-    {
-        i->second++;
-    }
-}
-
-void RenderbufferProxySet::release(const FramebufferAttachment *proxy)
-{
-    RefCountMap::iterator i = mRefCountMap.find(proxy);
-    if (i != mRefCountMap.end())
-    {
-        if (i->second > 0)
-        {
-            i->second--;
-        }
-
-        if (i->second == 0)
-        {
-            // Clear the buffer map of references to this FramebufferAttachment
-            BufferMap::iterator j = mBufferMap.begin();
-            while (j != mBufferMap.end())
-            {
-                if (j->second == proxy)
-                {
-                    j = mBufferMap.erase(j);
-                }
-                else
-                {
-                    ++j;
-                }
-            }
-
-            mRefCountMap.erase(i);
-        }
-    }
-}
-
-void RenderbufferProxySet::add(unsigned int mipLevel, unsigned int layer, FramebufferAttachment *renderBuffer)
-{
-    if (mRefCountMap.find(renderBuffer) == mRefCountMap.end())
-    {
-        mRefCountMap.insert(std::make_pair(renderBuffer, 0));
-    }
-
-    RenderbufferKey key;
-    key.mipLevel = mipLevel;
-    key.layer = layer;
-    if (mBufferMap.find(key) == mBufferMap.end())
-    {
-        mBufferMap.insert(std::make_pair(key, renderBuffer));
-    }
-}
-
-FramebufferAttachment *RenderbufferProxySet::get(unsigned int mipLevel, unsigned int layer) const
-{
-    RenderbufferKey key;
-    key.mipLevel = mipLevel;
-    key.layer = layer;
-    BufferMap::const_iterator i = mBufferMap.find(key);
-    return (i != mBufferMap.end()) ? i->second : NULL;
-}
-
-bool RenderbufferProxySet::RenderbufferKey::operator<(const RenderbufferKey &other) const
-{
-    return (mipLevel != other.mipLevel) ? mipLevel < other.mipLevel : layer < other.layer;
-}
-
-}
diff --git a/src/libGLESv2/RenderbufferProxySet.h b/src/libGLESv2/RenderbufferProxySet.h
deleted file mode 100644
index f151151..0000000
--- a/src/libGLESv2/RenderbufferProxySet.h
+++ /dev/null
@@ -1,46 +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.
-//
-
-// RenderbufferProxySet.h: Defines the gl::RenderbufferProxySet, a class for
-// maintaining a Texture's weak references to the Renderbuffers that represent it.
-
-#ifndef LIBGLESV2_RENDERBUFFERPROXYSET_H_
-#define LIBGLESV2_RENDERBUFFERPROXYSET_H_
-
-#include <map>
-
-namespace gl
-{
-class FramebufferAttachment;
-
-class RenderbufferProxySet
-{
-  public:
-    void addRef(const FramebufferAttachment *proxy);
-    void release(const FramebufferAttachment *proxy);
-
-    void add(unsigned int mipLevel, unsigned int layer, FramebufferAttachment *renderBuffer);
-    FramebufferAttachment *get(unsigned int mipLevel, unsigned int layer) const;
-
-  private:
-    struct RenderbufferKey
-    {
-        unsigned int mipLevel;
-        unsigned int layer;
-
-        bool operator<(const RenderbufferKey &other) const;
-    };
-
-    typedef std::map<RenderbufferKey, FramebufferAttachment*> BufferMap;
-    BufferMap mBufferMap;
-
-    typedef std::map<const FramebufferAttachment*, unsigned int> RefCountMap;
-    RefCountMap mRefCountMap;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERBUFFERPROXYSET_H_
diff --git a/src/libGLESv2/ResourceManager.cpp b/src/libGLESv2/ResourceManager.cpp
index cf0812d..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
@@ -17,6 +16,7 @@
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/Sampler.h"
 #include "libGLESv2/Fence.h"
+#include "libGLESv2/renderer/Renderer.h"
 
 namespace gl
 {
@@ -92,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();
 
@@ -150,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;
 }
@@ -311,7 +309,7 @@
     }
 }
 
-FramebufferAttachment *ResourceManager::getRenderbuffer(unsigned int handle)
+Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
 {
     RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
 
@@ -353,7 +351,7 @@
     }
 }
 
-void ResourceManager::setRenderbuffer(GLuint handle, FramebufferAttachment *buffer)
+void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
 {
     mRenderbufferMap[handle] = buffer;
 }
@@ -362,33 +360,33 @@
 {
     if (buffer != 0 && !getBuffer(buffer))
     {
-        Buffer *bufferObject = new Buffer(mRenderer, buffer);
+        Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer);
         mBufferMap[buffer] = bufferObject;
         bufferObject->addRef();
     }
 }
 
-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, 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, 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, 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, texture);
+            textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
         }
         else
         {
@@ -405,7 +403,7 @@
 {
     if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
     {
-        FramebufferAttachment *renderbufferObject = new FramebufferAttachment(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
+        Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
         mRenderbufferMap[renderbuffer] = renderbufferObject;
         renderbufferObject->addRef();
     }
diff --git a/src/libGLESv2/ResourceManager.h b/src/libGLESv2/ResourceManager.h
index a08a6aa..7d53bd4 100644
--- a/src/libGLESv2/ResourceManager.h
+++ b/src/libGLESv2/ResourceManager.h
@@ -10,15 +10,14 @@
 #ifndef LIBGLESV2_RESOURCEMANAGER_H_
 #define LIBGLESV2_RESOURCEMANAGER_H_
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.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;
@@ -30,7 +29,7 @@
 class Shader;
 class Program;
 class Texture;
-class FramebufferAttachment;
+class Renderbuffer;
 class Sampler;
 class FenceSync;
 
@@ -63,14 +62,14 @@
     Shader *getShader(GLuint handle);
     Program *getProgram(GLuint handle);
     Texture *getTexture(GLuint handle);
-    FramebufferAttachment *getRenderbuffer(GLuint handle);
+    Renderbuffer *getRenderbuffer(GLuint handle);
     Sampler *getSampler(GLuint handle);
     FenceSync *getFenceSync(GLuint handle);
-    
-    void setRenderbuffer(GLuint handle, FramebufferAttachment *renderbuffer);
+
+    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);
 
@@ -97,7 +96,7 @@
     TextureMap mTextureMap;
     HandleAllocator mTextureHandleAllocator;
 
-    typedef std::unordered_map<GLuint, FramebufferAttachment*> RenderbufferMap;
+    typedef std::unordered_map<GLuint, Renderbuffer*> RenderbufferMap;
     RenderbufferMap mRenderbufferMap;
     HandleAllocator mRenderbufferHandleAllocator;
 
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 7d0d781..e3da2b1 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -10,27 +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;
 
-Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
-    : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
+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)
 {
-    uncompile();
-    initializeCompiler();
-
-    mRefCount = 0;
-    mDeleteStatus = false;
-    mShaderVersion = 100;
+    ASSERT(impl);
 }
 
 Shader::~Shader()
@@ -56,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
@@ -65,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';
     }
@@ -84,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;
 
@@ -112,32 +114,12 @@
 
 void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
 {
-    getSourceImpl(mHlsl, bufSize, length, buffer);
+    getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
 }
 
-const std::vector<Uniform> &Shader::getUniforms() const
+void Shader::compile()
 {
-    return mActiveUniforms;
-}
-
-const std::vector<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()
@@ -170,434 +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);
-
-            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 = mRenderer->getMaxRenderTargets();
-            resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport();
-            resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1;
-            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(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
-            mVertexCompiler = ShConstructCompiler(SH_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())
-    {
-        std::vector<Varying> *activeVaryings;
-        ShGetInfoPointer(compiler, SH_ACTIVE_VARYINGS_ARRAY, reinterpret_cast<void**>(&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
-
-        delete[] outputHLSL;
-
-        void *activeUniforms;
-        ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
-        mActiveUniforms = *(std::vector<Uniform>*)activeUniforms;
-
-        void *activeInterfaceBlocks;
-        ShGetInfoPointer(compiler, SH_ACTIVE_INTERFACE_BLOCKS_ARRAY, &activeInterfaceBlocks);
-        mActiveInterfaceBlocks = *(std::vector<InterfaceBlock>*)activeInterfaceBlocks;
-    }
-    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();
 }
 
-// [OpenGL ES SL 3.00.4] Section 11 p. 120
-// Vertex Outs/Fragment Ins packing priorities
-static const GLenum varyingPriorityList[] =
+std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks()
 {
-    // 1. Arrays of mat4 and mat4
-    GL_FLOAT_MAT4,
-
-    // Non-square matrices of type matCxR consume the same space as a square
-    // matrix of type matN where N is the greater of C and R
-    GL_FLOAT_MAT3x4,
-    GL_FLOAT_MAT4x3,
-    GL_FLOAT_MAT2x4,
-    GL_FLOAT_MAT4x2,
-
-    // 2. Arrays of mat2 and mat2 (since they occupy full rows)
-    GL_FLOAT_MAT2,
-
-    // 3. Arrays of vec4 and vec4
-    GL_FLOAT_VEC4,
-    GL_INT_VEC4,
-    GL_UNSIGNED_INT_VEC4,
-
-    // 4. Arrays of mat3 and mat3
-    GL_FLOAT_MAT3,
-    GL_FLOAT_MAT2x3,
-    GL_FLOAT_MAT3x2,
-
-    // 5. Arrays of vec3 and vec3
-    GL_FLOAT_VEC3,
-    GL_INT_VEC3,
-    GL_UNSIGNED_INT_VEC3,
-
-    // 6. Arrays of vec2 and vec2
-    GL_FLOAT_VEC2,
-    GL_INT_VEC2,
-    GL_UNSIGNED_INT_VEC2,
-
-    // 7. Arrays of float and float
-    GL_FLOAT,
-    GL_INT,
-    GL_UNSIGNED_INT,
-};
-
-// true if varying x has a higher priority in packing than y
-bool Shader::compareVarying(const PackedVarying &x, const 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;
-    }
-
-    unsigned int xPriority = GL_INVALID_INDEX;
-    unsigned int yPriority = GL_INVALID_INDEX;
-
-    for (unsigned int priorityIndex = 0; priorityIndex < ArraySize(varyingPriorityList); priorityIndex++)
-    {
-        if (varyingPriorityList[priorityIndex] == x.type) xPriority = priorityIndex;
-        if (varyingPriorityList[priorityIndex] == y.type) yPriority = priorityIndex;
-        if (xPriority != GL_INVALID_INDEX && yPriority != GL_INVALID_INDEX) break;
-    }
-
-    ASSERT(xPriority != GL_INVALID_INDEX && yPriority != GL_INVALID_INDEX);
-
-    return xPriority <= yPriority;
+    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()
-{
-    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 ShaderVariable &attribute = mActiveAttributes[attributeIndex];
-
-            if (attribute.name == attributeName)
-            {
-                return semanticIndex;
-            }
-
-            semanticIndex += AttributeRegisterCount(attribute.type);
-        }
-    }
-
-    return -1;
-}
-
-void VertexShader::parseAttributes()
-{
-    const std::string &hlsl = getHLSL();
-    if (!hlsl.empty())
-    {
-        void *activeAttributes;
-        ShGetInfoPointer(mVertexCompiler, SH_ACTIVE_ATTRIBUTES_ARRAY, &activeAttributes);
-        mActiveAttributes = *(std::vector<Attribute>*)activeAttributes;
-    }
-}
-
-FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
-    : Shader(manager, renderer, handle)
-{
-}
-
-FragmentShader::~FragmentShader()
-{
-}
-
-GLenum FragmentShader::getType()
-{
-    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())
-    {
-        void *activeOutputVariables;
-        ShGetInfoPointer(mFragmentCompiler, SH_ACTIVE_OUTPUT_VARIABLES_ARRAY, &activeOutputVariables);
-        mActiveOutputVariables = *(std::vector<Attribute>*)activeOutputVariables;
-    }
-}
-
-void FragmentShader::uncompile()
-{
-    Shader::uncompile();
-
-    mActiveOutputVariables.clear();
-}
-
-const std::vector<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 a418949..7ba3bd1 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -12,36 +12,39 @@
 #ifndef LIBGLESV2_SHADER_H_
 #define LIBGLESV2_SHADER_H_
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
+
 #include <string>
 #include <list>
 #include <vector>
 
-#include "common/shadervars.h"
+#include "angle_gl.h"
+#include <GLSLANG/ShaderLang.h>
+
 #include "common/angleutils.h"
 #include "libGLESv2/angletypes.h"
-#include "GLSLANG/ShaderLang.h"
 
 namespace rx
 {
-class Renderer;
+class ShaderImpl;
 }
 
 namespace gl
 {
 class ResourceManager;
 
-struct PackedVarying : public Varying
+struct PackedVarying : public sh::Varying
 {
     unsigned int registerIndex; // Assigned during link
+    unsigned int columnIndex; // Assigned during link, defaults to 0
 
-    PackedVarying(const Varying &varying)
-      : Varying(varying),
-        registerIndex(GL_INVALID_INDEX)
+    PackedVarying(const sh::Varying &varying)
+      : sh::Varying(varying),
+        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() = 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,118 +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<Uniform> &getUniforms() const;
-    const std::vector<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);
+    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<Uniform> mActiveUniforms;
-    std::vector<InterfaceBlock> mActiveInterfaceBlocks;
+    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();
-    virtual void compile();
-    virtual void uncompile();
-    int getSemanticIndex(const std::string &attributeName);
-
-    const std::vector<Attribute> &activeAttributes() const { return mActiveAttributes; }
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(VertexShader);
-
-    void parseAttributes();
-
-    std::vector<Attribute> mActiveAttributes;
-};
-
-class FragmentShader : public Shader
-{
-  public:
-    FragmentShader(ResourceManager *manager,const rx::Renderer *renderer, GLuint handle);
-
-    ~FragmentShader();
-
-    virtual GLenum getType();
-    virtual void compile();
-    virtual void uncompile();
-    const std::vector<Attribute> &getOutputVariables() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(FragmentShader);
-
-    std::vector<Attribute> mActiveOutputVariables;
-};
 }
 
 #endif   // LIBGLESV2_SHADER_H_
diff --git a/src/libGLESv2/State.cpp b/src/libGLESv2/State.cpp
new file mode 100644
index 0000000..3c03b90
--- /dev/null
+++ b/src/libGLESv2/State.cpp
@@ -0,0 +1,1455 @@
+//
+// 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.
+//
+
+// State.cpp: Implements the State class, encapsulating raw GL state.
+
+#include "libGLESv2/State.h"
+
+#include "libGLESv2/Context.h"
+#include "libGLESv2/Caps.h"
+#include "libGLESv2/VertexArray.h"
+#include "libGLESv2/Query.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/formatutils.h"
+
+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);
+
+    mDepthClearValue = 1.0f;
+    mStencilClearValue = 0;
+
+    mRasterizer.rasterizerDiscard = false;
+    mRasterizer.cullFace = false;
+    mRasterizer.cullMode = GL_BACK;
+    mRasterizer.frontFace = GL_CCW;
+    mRasterizer.polygonOffsetFill = false;
+    mRasterizer.polygonOffsetFactor = 0.0f;
+    mRasterizer.polygonOffsetUnits = 0.0f;
+    mRasterizer.pointDrawMode = false;
+    mRasterizer.multiSample = false;
+    mScissorTest = false;
+    mScissor.x = 0;
+    mScissor.y = 0;
+    mScissor.width = 0;
+    mScissor.height = 0;
+
+    mBlend.blend = false;
+    mBlend.sourceBlendRGB = GL_ONE;
+    mBlend.sourceBlendAlpha = GL_ONE;
+    mBlend.destBlendRGB = GL_ZERO;
+    mBlend.destBlendAlpha = GL_ZERO;
+    mBlend.blendEquationRGB = GL_FUNC_ADD;
+    mBlend.blendEquationAlpha = GL_FUNC_ADD;
+    mBlend.sampleAlphaToCoverage = false;
+    mBlend.dither = true;
+
+    mBlendColor.red = 0;
+    mBlendColor.green = 0;
+    mBlendColor.blue = 0;
+    mBlendColor.alpha = 0;
+
+    mDepthStencil.depthTest = false;
+    mDepthStencil.depthFunc = GL_LESS;
+    mDepthStencil.depthMask = true;
+    mDepthStencil.stencilTest = false;
+    mDepthStencil.stencilFunc = GL_ALWAYS;
+    mDepthStencil.stencilMask = -1;
+    mDepthStencil.stencilWritemask = -1;
+    mDepthStencil.stencilBackFunc = GL_ALWAYS;
+    mDepthStencil.stencilBackMask = -1;
+    mDepthStencil.stencilBackWritemask = -1;
+    mDepthStencil.stencilFail = GL_KEEP;
+    mDepthStencil.stencilPassDepthFail = GL_KEEP;
+    mDepthStencil.stencilPassDepthPass = GL_KEEP;
+    mDepthStencil.stencilBackFail = GL_KEEP;
+    mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
+    mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
+
+    mStencilRef = 0;
+    mStencilBackRef = 0;
+
+    mSampleCoverage = false;
+    mSampleCoverageValue = 1.0f;
+    mSampleCoverageInvert = false;
+    mGenerateMipmapHint = GL_DONT_CARE;
+    mFragmentShaderDerivativeHint = GL_DONT_CARE;
+
+    mLineWidth = 1.0f;
+
+    mViewport.x = 0;
+    mViewport.y = 0;
+    mViewport.width = 0;
+    mViewport.height = 0;
+    mNearZ = 0.0f;
+    mFarZ = 1.0f;
+
+    mBlend.colorMaskRed = true;
+    mBlend.colorMaskGreen = true;
+    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);
+    }
+
+    mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
+    mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
+    if (clientVersion >= 3)
+    {
+        // TODO: These could also be enabled via extension
+        mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
+        mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
+    }
+
+    mSamplers.resize(caps.maxCombinedTextureImageUnits);
+
+    mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
+    mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
+    mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
+
+    mCurrentProgramId = 0;
+    mCurrentProgramBinary.set(NULL);
+
+    mReadFramebuffer = NULL;
+    mDrawFramebuffer = NULL;
+}
+
+void State::reset()
+{
+    for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
+    {
+        TextureBindingVector &textureVector = bindingVec->second;
+        for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
+        {
+            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++)
+    {
+        mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
+    }
+
+    mArrayBuffer.set(NULL);
+    mRenderbuffer.set(NULL);
+
+    mTransformFeedback.set(NULL);
+
+    for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
+    {
+        i->second.set(NULL);
+    }
+
+    mGenericUniformBuffer.set(NULL);
+    for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
+    {
+        mUniformBuffers[i].set(NULL);
+    }
+
+    mGenericTransformFeedbackBuffer.set(NULL);
+    for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+    {
+        mTransformFeedbackBuffers[i].set(NULL);
+    }
+
+    mCopyReadBuffer.set(NULL);
+    mCopyWriteBuffer.set(NULL);
+
+    mPack.pixelBuffer.set(NULL);
+    mUnpack.pixelBuffer.set(NULL);
+}
+
+const RasterizerState &State::getRasterizerState() const
+{
+    return mRasterizer;
+}
+
+const BlendState &State::getBlendState() const
+{
+    return mBlend;
+}
+
+const DepthStencilState &State::getDepthStencilState() const
+{
+    return mDepthStencil;
+}
+
+void State::setClearColor(float red, float green, float blue, float alpha)
+{
+    mColorClearValue.red = red;
+    mColorClearValue.green = green;
+    mColorClearValue.blue = blue;
+    mColorClearValue.alpha = alpha;
+}
+
+void State::setClearDepth(float depth)
+{
+    mDepthClearValue = depth;
+}
+
+void State::setClearStencil(int stencil)
+{
+    mStencilClearValue = stencil;
+}
+
+ClearParameters State::getClearParameters(GLbitfield mask) const
+{
+    ClearParameters clearParams = { 0 };
+    for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+    {
+        clearParams.clearColor[i] = false;
+    }
+    clearParams.colorFClearValue = mColorClearValue;
+    clearParams.colorClearType = GL_FLOAT;
+    clearParams.colorMaskRed = mBlend.colorMaskRed;
+    clearParams.colorMaskGreen = mBlend.colorMaskGreen;
+    clearParams.colorMaskBlue = mBlend.colorMaskBlue;
+    clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
+    clearParams.clearDepth = false;
+    clearParams.depthClearValue = mDepthClearValue;
+    clearParams.clearStencil = false;
+    clearParams.stencilClearValue = mStencilClearValue;
+    clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
+    clearParams.scissorEnabled = mScissorTest;
+    clearParams.scissor = mScissor;
+
+    const Framebuffer *framebufferObject = getDrawFramebuffer();
+    if (mask & GL_COLOR_BUFFER_BIT)
+    {
+        if (framebufferObject->hasEnabledColorAttachment())
+        {
+            for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+            {
+                clearParams.clearColor[i] = true;
+            }
+        }
+    }
+
+    if (mask & GL_DEPTH_BUFFER_BIT)
+    {
+        if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
+        {
+            clearParams.clearDepth = true;
+        }
+    }
+
+    if (mask & GL_STENCIL_BUFFER_BIT)
+    {
+        if (framebufferObject->getStencilbuffer() != NULL)
+        {
+            GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
+            if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
+            {
+                clearParams.clearStencil = true;
+            }
+        }
+    }
+
+    return clearParams;
+}
+
+void State::setColorMask(bool red, bool green, bool blue, bool alpha)
+{
+    mBlend.colorMaskRed = red;
+    mBlend.colorMaskGreen = green;
+    mBlend.colorMaskBlue = blue;
+    mBlend.colorMaskAlpha = alpha;
+}
+
+void State::setDepthMask(bool mask)
+{
+    mDepthStencil.depthMask = mask;
+}
+
+bool State::isRasterizerDiscardEnabled() const
+{
+    return mRasterizer.rasterizerDiscard;
+}
+
+void State::setRasterizerDiscard(bool enabled)
+{
+    mRasterizer.rasterizerDiscard = enabled;
+}
+
+bool State::isCullFaceEnabled() const
+{
+    return mRasterizer.cullFace;
+}
+
+void State::setCullFace(bool enabled)
+{
+    mRasterizer.cullFace = enabled;
+}
+
+void State::setCullMode(GLenum mode)
+{
+    mRasterizer.cullMode = mode;
+}
+
+void State::setFrontFace(GLenum front)
+{
+    mRasterizer.frontFace = front;
+}
+
+bool State::isDepthTestEnabled() const
+{
+    return mDepthStencil.depthTest;
+}
+
+void State::setDepthTest(bool enabled)
+{
+    mDepthStencil.depthTest = enabled;
+}
+
+void State::setDepthFunc(GLenum depthFunc)
+{
+     mDepthStencil.depthFunc = depthFunc;
+}
+
+void State::setDepthRange(float zNear, float zFar)
+{
+    mNearZ = zNear;
+    mFarZ = zFar;
+}
+
+void State::getDepthRange(float *zNear, float *zFar) const
+{
+    *zNear = mNearZ;
+    *zFar = mFarZ;
+}
+
+bool State::isBlendEnabled() const
+{
+    return mBlend.blend;
+}
+
+void State::setBlend(bool enabled)
+{
+    mBlend.blend = enabled;
+}
+
+void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
+{
+    mBlend.sourceBlendRGB = sourceRGB;
+    mBlend.destBlendRGB = destRGB;
+    mBlend.sourceBlendAlpha = sourceAlpha;
+    mBlend.destBlendAlpha = destAlpha;
+}
+
+void State::setBlendColor(float red, float green, float blue, float alpha)
+{
+    mBlendColor.red = red;
+    mBlendColor.green = green;
+    mBlendColor.blue = blue;
+    mBlendColor.alpha = alpha;
+}
+
+void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
+{
+    mBlend.blendEquationRGB = rgbEquation;
+    mBlend.blendEquationAlpha = alphaEquation;
+}
+
+const ColorF &State::getBlendColor() const
+{
+    return mBlendColor;
+}
+
+bool State::isStencilTestEnabled() const
+{
+    return mDepthStencil.stencilTest;
+}
+
+void State::setStencilTest(bool enabled)
+{
+    mDepthStencil.stencilTest = enabled;
+}
+
+void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
+{
+    mDepthStencil.stencilFunc = stencilFunc;
+    mStencilRef = (stencilRef > 0) ? stencilRef : 0;
+    mDepthStencil.stencilMask = stencilMask;
+}
+
+void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
+{
+    mDepthStencil.stencilBackFunc = stencilBackFunc;
+    mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
+    mDepthStencil.stencilBackMask = stencilBackMask;
+}
+
+void State::setStencilWritemask(GLuint stencilWritemask)
+{
+    mDepthStencil.stencilWritemask = stencilWritemask;
+}
+
+void State::setStencilBackWritemask(GLuint stencilBackWritemask)
+{
+    mDepthStencil.stencilBackWritemask = stencilBackWritemask;
+}
+
+void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
+{
+    mDepthStencil.stencilFail = stencilFail;
+    mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
+    mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
+}
+
+void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
+{
+    mDepthStencil.stencilBackFail = stencilBackFail;
+    mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
+    mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
+}
+
+GLint State::getStencilRef() const
+{
+    return mStencilRef;
+}
+
+GLint State::getStencilBackRef() const
+{
+    return mStencilBackRef;
+}
+
+bool State::isPolygonOffsetFillEnabled() const
+{
+    return mRasterizer.polygonOffsetFill;
+}
+
+void State::setPolygonOffsetFill(bool enabled)
+{
+     mRasterizer.polygonOffsetFill = enabled;
+}
+
+void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
+{
+    // An application can pass NaN values here, so handle this gracefully
+    mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
+    mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
+}
+
+bool State::isSampleAlphaToCoverageEnabled() const
+{
+    return mBlend.sampleAlphaToCoverage;
+}
+
+void State::setSampleAlphaToCoverage(bool enabled)
+{
+    mBlend.sampleAlphaToCoverage = enabled;
+}
+
+bool State::isSampleCoverageEnabled() const
+{
+    return mSampleCoverage;
+}
+
+void State::setSampleCoverage(bool enabled)
+{
+    mSampleCoverage = enabled;
+}
+
+void State::setSampleCoverageParams(GLclampf value, bool invert)
+{
+    mSampleCoverageValue = value;
+    mSampleCoverageInvert = invert;
+}
+
+void State::getSampleCoverageParams(GLclampf *value, bool *invert)
+{
+    ASSERT(value != NULL && invert != NULL);
+
+    *value = mSampleCoverageValue;
+    *invert = mSampleCoverageInvert;
+}
+
+bool State::isScissorTestEnabled() const
+{
+    return mScissorTest;
+}
+
+void State::setScissorTest(bool enabled)
+{
+    mScissorTest = enabled;
+}
+
+void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    mScissor.x = x;
+    mScissor.y = y;
+    mScissor.width = width;
+    mScissor.height = height;
+}
+
+const Rectangle &State::getScissor() const
+{
+    return mScissor;
+}
+
+bool State::isDitherEnabled() const
+{
+    return mBlend.dither;
+}
+
+void State::setDither(bool enabled)
+{
+    mBlend.dither = enabled;
+}
+
+void State::setEnableFeature(GLenum feature, bool enabled)
+{
+    switch (feature)
+    {
+      case GL_CULL_FACE:                     setCullFace(enabled);              break;
+      case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
+      case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
+      case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
+      case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
+      case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
+      case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
+      case GL_BLEND:                         setBlend(enabled);                 break;
+      case GL_DITHER:                        setDither(enabled);                break;
+      case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED();                   break;
+      case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
+      default:                               UNREACHABLE();
+    }
+}
+
+bool State::getEnableFeature(GLenum feature)
+{
+    switch (feature)
+    {
+      case GL_CULL_FACE:                     return isCullFaceEnabled();
+      case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
+      case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
+      case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
+      case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
+      case GL_STENCIL_TEST:                  return isStencilTestEnabled();
+      case GL_DEPTH_TEST:                    return isDepthTestEnabled();
+      case GL_BLEND:                         return isBlendEnabled();
+      case GL_DITHER:                        return isDitherEnabled();
+      case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
+      case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
+      default:                               UNREACHABLE(); return false;
+    }
+}
+
+void State::setLineWidth(GLfloat width)
+{
+    mLineWidth = width;
+}
+
+void State::setGenerateMipmapHint(GLenum hint)
+{
+    mGenerateMipmapHint = hint;
+}
+
+void State::setFragmentShaderDerivativeHint(GLenum hint)
+{
+    mFragmentShaderDerivativeHint = hint;
+    // TODO: Propagate the hint to shader translator so we can write
+    // ddx, ddx_coarse, or ddx_fine depending on the hint.
+    // Ignore for now. It is valid for implementations to ignore hint.
+}
+
+void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    mViewport.x = x;
+    mViewport.y = y;
+    mViewport.width = width;
+    mViewport.height = height;
+}
+
+const Rectangle &State::getViewport() const
+{
+    return mViewport;
+}
+
+void State::setActiveSampler(unsigned int active)
+{
+    mActiveSampler = active;
+}
+
+unsigned int State::getActiveSampler() const
+{
+    return mActiveSampler;
+}
+
+void State::setSamplerTexture(GLenum type, Texture *texture)
+{
+    mSamplerTextures[type][mActiveSampler].set(texture);
+}
+
+Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
+{
+    const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
+
+    if (binding.id() == 0)   // Special case: 0 refers to default textures held by Context
+    {
+        return NULL;
+    }
+
+    return binding.get();
+}
+
+GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
+{
+    return mSamplerTextures.at(type)[sampler].id();
+}
+
+void State::detachTexture(GLuint texture)
+{
+    // Textures have a detach method on State rather than a simple
+    // removeBinding, because the zero/null texture objects are managed
+    // separately, and don't have to go through the Context's maps or
+    // the ResourceManager.
+
+    // [OpenGL ES 2.0.24] section 3.8 page 84:
+    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
+    // rebound to texture object zero
+
+    for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
+    {
+        TextureBindingVector &textureVector = bindingVec->second;
+        for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
+        {
+            BindingPointer<Texture> &binding = textureVector[textureIdx];
+            if (binding.id() == texture)
+            {
+                binding.set(NULL);
+            }
+        }
+    }
+
+    // [OpenGL ES 2.0.24] section 4.4 page 112:
+    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
+    // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
+    // image was attached in the currently bound framebuffer.
+
+    if (mReadFramebuffer)
+    {
+        mReadFramebuffer->detachTexture(texture);
+    }
+
+    if (mDrawFramebuffer)
+    {
+        mDrawFramebuffer->detachTexture(texture);
+    }
+}
+
+void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
+{
+    mSamplers[textureUnit].set(sampler);
+}
+
+GLuint State::getSamplerId(GLuint textureUnit) const
+{
+    ASSERT(textureUnit < mSamplers.size());
+    return mSamplers[textureUnit].id();
+}
+
+Sampler *State::getSampler(GLuint textureUnit) const
+{
+    return mSamplers[textureUnit].get();
+}
+
+void State::detachSampler(GLuint sampler)
+{
+    // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
+    // 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 (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
+    {
+        BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
+        if (samplerBinding.id() == sampler)
+        {
+            samplerBinding.set(NULL);
+        }
+    }
+}
+
+void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
+{
+    mRenderbuffer.set(renderbuffer);
+}
+
+GLuint State::getRenderbufferId() const
+{
+    return mRenderbuffer.id();
+}
+
+Renderbuffer *State::getCurrentRenderbuffer()
+{
+    return mRenderbuffer.get();
+}
+
+void State::detachRenderbuffer(GLuint renderbuffer)
+{
+    // [OpenGL ES 2.0.24] section 4.4 page 109:
+    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
+    // had been executed with the target RENDERBUFFER and name of zero.
+
+    if (mRenderbuffer.id() == renderbuffer)
+    {
+        mRenderbuffer.set(NULL);
+    }
+
+    // [OpenGL ES 2.0.24] section 4.4 page 111:
+    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
+    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
+    // point to which this image was attached in the currently bound framebuffer.
+
+    Framebuffer *readFramebuffer = mReadFramebuffer;
+    Framebuffer *drawFramebuffer = mDrawFramebuffer;
+
+    if (readFramebuffer)
+    {
+        readFramebuffer->detachRenderbuffer(renderbuffer);
+    }
+
+    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
+    {
+        drawFramebuffer->detachRenderbuffer(renderbuffer);
+    }
+
+}
+
+void State::setReadFramebufferBinding(Framebuffer *framebuffer)
+{
+    mReadFramebuffer = framebuffer;
+}
+
+void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
+{
+    mDrawFramebuffer = framebuffer;
+}
+
+Framebuffer *State::getTargetFramebuffer(GLenum target) const
+{
+    switch (target)
+    {
+    case GL_READ_FRAMEBUFFER_ANGLE:  return mReadFramebuffer;
+    case GL_DRAW_FRAMEBUFFER_ANGLE:
+    case GL_FRAMEBUFFER:             return mDrawFramebuffer;
+    default:                         UNREACHABLE(); return NULL;
+    }
+}
+
+Framebuffer *State::getReadFramebuffer()
+{
+    return mReadFramebuffer;
+}
+
+Framebuffer *State::getDrawFramebuffer()
+{
+    return mDrawFramebuffer;
+}
+
+const Framebuffer *State::getReadFramebuffer() const
+{
+    return mReadFramebuffer;
+}
+
+const Framebuffer *State::getDrawFramebuffer() const
+{
+    return mDrawFramebuffer;
+}
+
+bool State::removeReadFramebufferBinding(GLuint framebuffer)
+{
+    if (mReadFramebuffer->id() == framebuffer)
+    {
+        mReadFramebuffer = NULL;
+        return true;
+    }
+
+    return false;
+}
+
+bool State::removeDrawFramebufferBinding(GLuint framebuffer)
+{
+    if (mDrawFramebuffer->id() == framebuffer)
+    {
+        mDrawFramebuffer = NULL;
+        return true;
+    }
+
+    return false;
+}
+
+void State::setVertexArrayBinding(VertexArray *vertexArray)
+{
+    mVertexArray = vertexArray;
+}
+
+GLuint State::getVertexArrayId() const
+{
+    ASSERT(mVertexArray != NULL);
+    return mVertexArray->id();
+}
+
+VertexArray *State::getVertexArray() const
+{
+    ASSERT(mVertexArray != NULL);
+    return mVertexArray;
+}
+
+bool State::removeVertexArrayBinding(GLuint vertexArray)
+{
+    if (mVertexArray->id() == vertexArray)
+    {
+        mVertexArray = NULL;
+        return true;
+    }
+
+    return false;
+}
+
+void State::setCurrentProgram(GLuint programId, Program *newProgram)
+{
+    mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion
+    mCurrentProgramBinary.set(NULL);
+
+    if (newProgram)
+    {
+        newProgram->addRef();
+        mCurrentProgramBinary.set(newProgram->getProgramBinary());
+    }
+}
+
+void State::setCurrentProgramBinary(ProgramBinary *binary)
+{
+    mCurrentProgramBinary.set(binary);
+}
+
+GLuint State::getCurrentProgramId() const
+{
+    return mCurrentProgramId;
+}
+
+ProgramBinary *State::getCurrentProgramBinary() const
+{
+    return mCurrentProgramBinary.get();
+}
+
+void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
+{
+    mTransformFeedback.set(transformFeedback);
+}
+
+TransformFeedback *State::getCurrentTransformFeedback() const
+{
+    return mTransformFeedback.get();
+}
+
+void State::detachTransformFeedback(GLuint transformFeedback)
+{
+    if (mTransformFeedback.id() == transformFeedback)
+    {
+        mTransformFeedback.set(NULL);
+    }
+}
+
+bool State::isQueryActive() const
+{
+    for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
+        i != mActiveQueries.end(); i++)
+    {
+        if (i->second.get() != NULL)
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void State::setActiveQuery(GLenum target, Query *query)
+{
+    mActiveQueries[target].set(query);
+}
+
+GLuint State::getActiveQueryId(GLenum target) const
+{
+    const Query *query = getActiveQuery(target);
+    return (query ? query->id() : 0u);
+}
+
+Query *State::getActiveQuery(GLenum target) const
+{
+    // All query types should already exist in the activeQueries map
+    ASSERT(mActiveQueries.find(target) != mActiveQueries.end());
+
+    return mActiveQueries.at(target).get();
+}
+
+void State::setArrayBufferBinding(Buffer *buffer)
+{
+    mArrayBuffer.set(buffer);
+}
+
+GLuint State::getArrayBufferId() const
+{
+    return mArrayBuffer.id();
+}
+
+bool State::removeArrayBufferBinding(GLuint buffer)
+{
+    if (mArrayBuffer.id() == buffer)
+    {
+        mArrayBuffer.set(NULL);
+        return true;
+    }
+
+    return false;
+}
+
+void State::setGenericUniformBufferBinding(Buffer *buffer)
+{
+    mGenericUniformBuffer.set(buffer);
+}
+
+void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
+{
+    mUniformBuffers[index].set(buffer, offset, size);
+}
+
+GLuint State::getIndexedUniformBufferId(GLuint index) const
+{
+    ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
+
+    return mUniformBuffers[index].id();
+}
+
+Buffer *State::getIndexedUniformBuffer(GLuint index) const
+{
+    ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
+
+    return mUniformBuffers[index].get();
+}
+
+void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
+{
+    mGenericTransformFeedbackBuffer.set(buffer);
+}
+
+void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
+{
+    mTransformFeedbackBuffers[index].set(buffer, offset, size);
+}
+
+GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
+{
+    ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+
+    return mTransformFeedbackBuffers[index].id();
+}
+
+Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
+{
+    ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+
+    return mTransformFeedbackBuffers[index].get();
+}
+
+GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
+{
+    ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+
+    return mTransformFeedbackBuffers[index].getOffset();
+}
+
+void State::setCopyReadBufferBinding(Buffer *buffer)
+{
+    mCopyReadBuffer.set(buffer);
+}
+
+void State::setCopyWriteBufferBinding(Buffer *buffer)
+{
+    mCopyWriteBuffer.set(buffer);
+}
+
+void State::setPixelPackBufferBinding(Buffer *buffer)
+{
+    mPack.pixelBuffer.set(buffer);
+}
+
+void State::setPixelUnpackBufferBinding(Buffer *buffer)
+{
+    mUnpack.pixelBuffer.set(buffer);
+}
+
+Buffer *State::getTargetBuffer(GLenum target) const
+{
+    switch (target)
+    {
+      case GL_ARRAY_BUFFER:              return mArrayBuffer.get();
+      case GL_COPY_READ_BUFFER:          return mCopyReadBuffer.get();
+      case GL_COPY_WRITE_BUFFER:         return mCopyWriteBuffer.get();
+      case GL_ELEMENT_ARRAY_BUFFER:      return getVertexArray()->getElementArrayBuffer();
+      case GL_PIXEL_PACK_BUFFER:         return mPack.pixelBuffer.get();
+      case GL_PIXEL_UNPACK_BUFFER:       return mUnpack.pixelBuffer.get();
+      case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
+      case GL_UNIFORM_BUFFER:            return mGenericUniformBuffer.get();
+      default: UNREACHABLE();            return NULL;
+    }
+}
+
+void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
+{
+    getVertexArray()->enableAttribute(attribNum, enabled);
+}
+
+void State::setVertexAttribf(GLuint index, const GLfloat values[4])
+{
+    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+    mVertexAttribCurrentValues[index].setFloatValues(values);
+}
+
+void State::setVertexAttribu(GLuint index, const GLuint values[4])
+{
+    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+    mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
+}
+
+void State::setVertexAttribi(GLuint index, const GLint values[4])
+{
+    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+    mVertexAttribCurrentValues[index].setIntValues(values);
+}
+
+void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
+    bool pureInteger, GLsizei stride, const void *pointer)
+{
+    getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
+}
+
+const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
+{
+    return getVertexArray()->getVertexAttribute(attribNum);
+}
+
+const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
+{
+    ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
+    return mVertexAttribCurrentValues[attribNum];
+}
+
+const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const
+{
+    return mVertexAttribCurrentValues;
+}
+
+const void *State::getVertexAttribPointer(unsigned int attribNum) const
+{
+    return getVertexArray()->getVertexAttribute(attribNum).pointer;
+}
+
+void State::setPackAlignment(GLint alignment)
+{
+    mPack.alignment = alignment;
+}
+
+GLint State::getPackAlignment() const
+{
+    return mPack.alignment;
+}
+
+void State::setPackReverseRowOrder(bool reverseRowOrder)
+{
+    mPack.reverseRowOrder = reverseRowOrder;
+}
+
+bool State::getPackReverseRowOrder() const
+{
+    return mPack.reverseRowOrder;
+}
+
+const PixelPackState &State::getPackState() const
+{
+    return mPack;
+}
+
+void State::setUnpackAlignment(GLint alignment)
+{
+    mUnpack.alignment = alignment;
+}
+
+GLint State::getUnpackAlignment() const
+{
+    return mUnpack.alignment;
+}
+
+const PixelUnpackState &State::getUnpackState() const
+{
+    return mUnpack;
+}
+
+void State::getBooleanv(GLenum pname, GLboolean *params)
+{
+    switch (pname)
+    {
+      case GL_SAMPLE_COVERAGE_INVERT:    *params = mSampleCoverageInvert;         break;
+      case GL_DEPTH_WRITEMASK:           *params = mDepthStencil.depthMask;       break;
+      case GL_COLOR_WRITEMASK:
+        params[0] = mBlend.colorMaskRed;
+        params[1] = mBlend.colorMaskGreen;
+        params[2] = mBlend.colorMaskBlue;
+        params[3] = mBlend.colorMaskAlpha;
+        break;
+      case GL_CULL_FACE:                 *params = mRasterizer.cullFace;          break;
+      case GL_POLYGON_OFFSET_FILL:       *params = mRasterizer.polygonOffsetFill; break;
+      case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mBlend.sampleAlphaToCoverage;  break;
+      case GL_SAMPLE_COVERAGE:           *params = mSampleCoverage;               break;
+      case GL_SCISSOR_TEST:              *params = mScissorTest;                  break;
+      case GL_STENCIL_TEST:              *params = mDepthStencil.stencilTest;     break;
+      case GL_DEPTH_TEST:                *params = mDepthStencil.depthTest;       break;
+      case GL_BLEND:                     *params = mBlend.blend;                  break;
+      case GL_DITHER:                    *params = mBlend.dither;                 break;
+      case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
+      case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused();  break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+}
+
+void State::getFloatv(GLenum pname, GLfloat *params)
+{
+    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
+    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+    // GetIntegerv as its native query function. As it would require conversion in any
+    // case, this should make no difference to the calling application.
+    switch (pname)
+    {
+      case GL_LINE_WIDTH:               *params = mLineWidth;                         break;
+      case GL_SAMPLE_COVERAGE_VALUE:    *params = mSampleCoverageValue;               break;
+      case GL_DEPTH_CLEAR_VALUE:        *params = mDepthClearValue;                   break;
+      case GL_POLYGON_OFFSET_FACTOR:    *params = mRasterizer.polygonOffsetFactor;    break;
+      case GL_POLYGON_OFFSET_UNITS:     *params = mRasterizer.polygonOffsetUnits;     break;
+      case GL_DEPTH_RANGE:
+        params[0] = mNearZ;
+        params[1] = mFarZ;
+        break;
+      case GL_COLOR_CLEAR_VALUE:
+        params[0] = mColorClearValue.red;
+        params[1] = mColorClearValue.green;
+        params[2] = mColorClearValue.blue;
+        params[3] = mColorClearValue.alpha;
+        break;
+      case GL_BLEND_COLOR:
+        params[0] = mBlendColor.red;
+        params[1] = mBlendColor.green;
+        params[2] = mBlendColor.blue;
+        params[3] = mBlendColor.alpha;
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+}
+
+void State::getIntegerv(GLenum pname, GLint *params)
+{
+    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
+    {
+        unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
+        ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers);
+        Framebuffer *framebuffer = mDrawFramebuffer;
+        *params = framebuffer->getDrawBufferState(colorAttachment);
+        return;
+    }
+
+    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
+    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+    // GetIntegerv as its native query function. As it would require conversion in any
+    // case, this should make no difference to the calling application. You may find it in
+    // State::getFloatv.
+    switch (pname)
+    {
+      case GL_ARRAY_BUFFER_BINDING:                     *params = mArrayBuffer.id();                              break;
+      case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getVertexArray()->getElementArrayBufferId();    break;
+        //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mDrawFramebuffer->id();                         break;
+      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mReadFramebuffer->id();                         break;
+      case GL_RENDERBUFFER_BINDING:                     *params = mRenderbuffer.id();                             break;
+      case GL_VERTEX_ARRAY_BINDING:                     *params = mVertexArray->id();                             break;
+      case GL_CURRENT_PROGRAM:                          *params = mCurrentProgramId;                              break;
+      case GL_PACK_ALIGNMENT:                           *params = mPack.alignment;                                break;
+      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mPack.reverseRowOrder;                          break;
+      case GL_UNPACK_ALIGNMENT:                         *params = mUnpack.alignment;                              break;
+      case GL_GENERATE_MIPMAP_HINT:                     *params = mGenerateMipmapHint;                            break;
+      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mFragmentShaderDerivativeHint;                  break;
+      case GL_ACTIVE_TEXTURE:                           *params = (mActiveSampler + GL_TEXTURE0);                 break;
+      case GL_STENCIL_FUNC:                             *params = mDepthStencil.stencilFunc;                      break;
+      case GL_STENCIL_REF:                              *params = mStencilRef;                                    break;
+      case GL_STENCIL_VALUE_MASK:                       *params = clampToInt(mDepthStencil.stencilMask);          break;
+      case GL_STENCIL_BACK_FUNC:                        *params = mDepthStencil.stencilBackFunc;                  break;
+      case GL_STENCIL_BACK_REF:                         *params = mStencilBackRef;                                break;
+      case GL_STENCIL_BACK_VALUE_MASK:                  *params = clampToInt(mDepthStencil.stencilBackMask);      break;
+      case GL_STENCIL_FAIL:                             *params = mDepthStencil.stencilFail;                      break;
+      case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mDepthStencil.stencilPassDepthFail;             break;
+      case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mDepthStencil.stencilPassDepthPass;             break;
+      case GL_STENCIL_BACK_FAIL:                        *params = mDepthStencil.stencilBackFail;                  break;
+      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mDepthStencil.stencilBackPassDepthFail;         break;
+      case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mDepthStencil.stencilBackPassDepthPass;         break;
+      case GL_DEPTH_FUNC:                               *params = mDepthStencil.depthFunc;                        break;
+      case GL_BLEND_SRC_RGB:                            *params = mBlend.sourceBlendRGB;                          break;
+      case GL_BLEND_SRC_ALPHA:                          *params = mBlend.sourceBlendAlpha;                        break;
+      case GL_BLEND_DST_RGB:                            *params = mBlend.destBlendRGB;                            break;
+      case GL_BLEND_DST_ALPHA:                          *params = mBlend.destBlendAlpha;                          break;
+      case GL_BLEND_EQUATION_RGB:                       *params = mBlend.blendEquationRGB;                        break;
+      case GL_BLEND_EQUATION_ALPHA:                     *params = mBlend.blendEquationAlpha;                      break;
+      case GL_STENCIL_WRITEMASK:                        *params = clampToInt(mDepthStencil.stencilWritemask);     break;
+      case GL_STENCIL_BACK_WRITEMASK:                   *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
+      case GL_STENCIL_CLEAR_VALUE:                      *params = mStencilClearValue;                             break;
+      case GL_SAMPLE_BUFFERS:
+      case GL_SAMPLES:
+        {
+            gl::Framebuffer *framebuffer = mDrawFramebuffer;
+            if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+            {
+                switch (pname)
+                {
+                  case GL_SAMPLE_BUFFERS:
+                    if (framebuffer->getSamples() != 0)
+                    {
+                        *params = 1;
+                    }
+                    else
+                    {
+                        *params = 0;
+                    }
+                    break;
+                  case GL_SAMPLES:
+                    *params = framebuffer->getSamples();
+                    break;
+                }
+            }
+            else
+            {
+                *params = 0;
+            }
+        }
+        break;
+      case GL_VIEWPORT:
+        params[0] = mViewport.x;
+        params[1] = mViewport.y;
+        params[2] = mViewport.width;
+        params[3] = mViewport.height;
+        break;
+      case GL_SCISSOR_BOX:
+        params[0] = mScissor.x;
+        params[1] = mScissor.y;
+        params[2] = mScissor.width;
+        params[3] = mScissor.height;
+        break;
+      case GL_CULL_FACE_MODE:                   *params = mRasterizer.cullMode;   break;
+      case GL_FRONT_FACE:                       *params = mRasterizer.frontFace;  break;
+      case GL_RED_BITS:
+      case GL_GREEN_BITS:
+      case GL_BLUE_BITS:
+      case GL_ALPHA_BITS:
+        {
+            gl::Framebuffer *framebuffer = getDrawFramebuffer();
+            gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
+
+            if (colorbuffer)
+            {
+                switch (pname)
+                {
+                case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
+                case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
+                case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
+                case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
+                }
+            }
+            else
+            {
+                *params = 0;
+            }
+        }
+        break;
+      case GL_DEPTH_BITS:
+        {
+            gl::Framebuffer *framebuffer = getDrawFramebuffer();
+            gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
+
+            if (depthbuffer)
+            {
+                *params = depthbuffer->getDepthSize();
+            }
+            else
+            {
+                *params = 0;
+            }
+        }
+        break;
+      case GL_STENCIL_BITS:
+        {
+            gl::Framebuffer *framebuffer = getDrawFramebuffer();
+            gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
+
+            if (stencilbuffer)
+            {
+                *params = stencilbuffer->getStencilSize();
+            }
+            else
+            {
+                *params = 0;
+            }
+        }
+        break;
+      case GL_TEXTURE_BINDING_2D:
+        ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+        *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
+        break;
+      case GL_TEXTURE_BINDING_CUBE_MAP:
+        ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+        *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
+        break;
+      case GL_TEXTURE_BINDING_3D:
+        ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
+        *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
+        break;
+      case GL_TEXTURE_BINDING_2D_ARRAY:
+        ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+        *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
+        break;
+      case GL_UNIFORM_BUFFER_BINDING:
+        *params = mGenericUniformBuffer.id();
+        break;
+      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+        *params = mGenericTransformFeedbackBuffer.id();
+        break;
+      case GL_COPY_READ_BUFFER_BINDING:
+        *params = mCopyReadBuffer.id();
+        break;
+      case GL_COPY_WRITE_BUFFER_BINDING:
+        *params = mCopyWriteBuffer.id();
+        break;
+      case GL_PIXEL_PACK_BUFFER_BINDING:
+        *params = mPack.pixelBuffer.id();
+        break;
+      case GL_PIXEL_UNPACK_BUFFER_BINDING:
+        *params = mUnpack.pixelBuffer.id();
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+}
+
+bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
+{
+    switch (target)
+    {
+      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+        {
+            *data = mTransformFeedbackBuffers[index].id();
+        }
+        break;
+      case GL_UNIFORM_BUFFER_BINDING:
+        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+        {
+            *data = mUniformBuffers[index].id();
+        }
+        break;
+      default:
+        return false;
+    }
+
+    return true;
+}
+
+bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
+{
+    switch (target)
+    {
+      case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+        {
+            *data = mTransformFeedbackBuffers[index].getOffset();
+        }
+        break;
+      case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+        {
+            *data = mTransformFeedbackBuffers[index].getSize();
+        }
+        break;
+      case GL_UNIFORM_BUFFER_START:
+        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+        {
+            *data = mUniformBuffers[index].getOffset();
+        }
+        break;
+      case GL_UNIFORM_BUFFER_SIZE:
+        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+        {
+            *data = mUniformBuffers[index].getSize();
+        }
+        break;
+      default:
+        return false;
+    }
+
+    return true;
+}
+
+bool State::hasMappedBuffer(GLenum target) const
+{
+    if (target == GL_ARRAY_BUFFER)
+    {
+        for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
+        {
+            const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
+            gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
+            if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    else
+    {
+        Buffer *buffer = getTargetBuffer(target);
+        return (buffer && buffer->isMapped());
+    }
+}
+
+}
diff --git a/src/libGLESv2/State.h b/src/libGLESv2/State.h
new file mode 100644
index 0000000..5f04331
--- /dev/null
+++ b/src/libGLESv2/State.h
@@ -0,0 +1,319 @@
+//
+// 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.
+//
+
+// State.h: Defines the State class, encapsulating raw GL state
+
+#ifndef LIBGLESV2_STATE_H_
+#define LIBGLESV2_STATE_H_
+
+#include "common/angleutils.h"
+#include "common/RefCountObject.h"
+#include "libGLESv2/angletypes.h"
+#include "libGLESv2/VertexAttribute.h"
+#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/Texture.h"
+#include "libGLESv2/TransformFeedback.h"
+#include "libGLESv2/Program.h"
+#include "libGLESv2/Sampler.h"
+
+namespace gl
+{
+class Query;
+class VertexArray;
+class Context;
+struct Caps;
+
+class State
+{
+  public:
+    State();
+    ~State();
+
+    void initialize(const Caps& caps, GLuint clientVersion);
+    void reset();
+
+    void setContext(Context *context) { mContext = context; }
+
+    // State chunk getters
+    const RasterizerState &getRasterizerState() const;
+    const BlendState &getBlendState() const;
+    const DepthStencilState &getDepthStencilState() const;
+
+    // Clear behavior setters & state parameter block generation function
+    void setClearColor(float red, float green, float blue, float alpha);
+    void setClearDepth(float depth);
+    void setClearStencil(int stencil);
+    ClearParameters getClearParameters(GLbitfield mask) const;
+
+    // Write mask manipulation
+    void setColorMask(bool red, bool green, bool blue, bool alpha);
+    void setDepthMask(bool mask);
+
+    // Discard toggle & query
+    bool isRasterizerDiscardEnabled() const;
+    void setRasterizerDiscard(bool enabled);
+
+    // Face culling state manipulation
+    bool isCullFaceEnabled() const;
+    void setCullFace(bool enabled);
+    void setCullMode(GLenum mode);
+    void setFrontFace(GLenum front);
+
+    // Depth test state manipulation
+    bool isDepthTestEnabled() const;
+    void setDepthTest(bool enabled);
+    void setDepthFunc(GLenum depthFunc);
+    void setDepthRange(float zNear, float zFar);
+    void getDepthRange(float *zNear, float *zFar) const;
+
+    // Blend state manipulation
+    bool isBlendEnabled() const;
+    void setBlend(bool enabled);
+    void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
+    void setBlendColor(float red, float green, float blue, float alpha);
+    void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
+    const ColorF &getBlendColor() const;
+
+    // Stencil state maniupulation
+    bool isStencilTestEnabled() const;
+    void setStencilTest(bool enabled);
+    void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
+    void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
+    void setStencilWritemask(GLuint stencilWritemask);
+    void setStencilBackWritemask(GLuint stencilBackWritemask);
+    void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);
+    void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass);
+    GLint getStencilRef() const;
+    GLint getStencilBackRef() const;
+
+    // Depth bias/polygon offset state manipulation
+    bool isPolygonOffsetFillEnabled() const;
+    void setPolygonOffsetFill(bool enabled);
+    void setPolygonOffsetParams(GLfloat factor, GLfloat units);
+
+    // Multisample coverage state manipulation
+    bool isSampleAlphaToCoverageEnabled() const;
+    void setSampleAlphaToCoverage(bool enabled);
+    bool isSampleCoverageEnabled() const;
+    void setSampleCoverage(bool enabled);
+    void setSampleCoverageParams(GLclampf value, bool invert);
+    void getSampleCoverageParams(GLclampf *value, bool *invert);
+
+    // Scissor test state toggle & query
+    bool isScissorTestEnabled() const;
+    void setScissorTest(bool enabled);
+    void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
+    const Rectangle &getScissor() const;
+
+    // Dither state toggle & query
+    bool isDitherEnabled() const;
+    void setDither(bool enabled);
+
+    // Generic state toggle & query
+    void setEnableFeature(GLenum feature, bool enabled);
+    bool getEnableFeature(GLenum feature);
+
+    // Line width state setter
+    void setLineWidth(GLfloat width);
+
+    // Hint setters
+    void setGenerateMipmapHint(GLenum hint);
+    void setFragmentShaderDerivativeHint(GLenum hint);
+
+    // Viewport state setter/getter
+    void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
+    const Rectangle &getViewport() const;
+
+    // Texture binding & active texture unit manipulation
+    void setActiveSampler(unsigned int active);
+    unsigned int getActiveSampler() const;
+    void setSamplerTexture(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
+    void setSamplerBinding(GLuint textureUnit, Sampler *sampler);
+    GLuint getSamplerId(GLuint textureUnit) const;
+    Sampler *getSampler(GLuint textureUnit) const;
+    void detachSampler(GLuint sampler);
+
+    // Renderbuffer binding manipulation
+    void setRenderbufferBinding(Renderbuffer *renderbuffer);
+    GLuint getRenderbufferId() const;
+    Renderbuffer *getCurrentRenderbuffer();
+    void detachRenderbuffer(GLuint renderbuffer);
+
+    // Framebuffer binding manipulation
+    void setReadFramebufferBinding(Framebuffer *framebuffer);
+    void setDrawFramebufferBinding(Framebuffer *framebuffer);
+    Framebuffer *getTargetFramebuffer(GLenum target) const;
+    Framebuffer *getReadFramebuffer();
+    Framebuffer *getDrawFramebuffer();
+    const Framebuffer *getReadFramebuffer() const;
+    const Framebuffer *getDrawFramebuffer() const;
+    bool removeReadFramebufferBinding(GLuint framebuffer);
+    bool removeDrawFramebufferBinding(GLuint framebuffer);
+
+    // Vertex array object binding manipulation
+    void setVertexArrayBinding(VertexArray *vertexArray);
+    GLuint getVertexArrayId() const;
+    VertexArray *getVertexArray() const;
+    bool removeVertexArrayBinding(GLuint vertexArray);
+
+    // Program binding manipulation
+    void setCurrentProgram(GLuint programId, Program *newProgram);
+    void setCurrentProgramBinary(ProgramBinary *binary);
+    GLuint getCurrentProgramId() const;
+    ProgramBinary *getCurrentProgramBinary() const;
+
+    // Transform feedback object (not buffer) binding manipulation
+    void setTransformFeedbackBinding(TransformFeedback *transformFeedback);
+    TransformFeedback *getCurrentTransformFeedback() const;
+    void detachTransformFeedback(GLuint transformFeedback);
+
+    // Query binding manipulation
+    bool isQueryActive() const;
+    void setActiveQuery(GLenum target, Query *query);
+    GLuint getActiveQueryId(GLenum target) const;
+    Query *getActiveQuery(GLenum target) const;
+
+    //// Typed buffer binding point manipulation ////
+    // GL_ARRAY_BUFFER
+    void setArrayBufferBinding(Buffer *buffer);
+    GLuint getArrayBufferId() const;
+    bool removeArrayBufferBinding(GLuint buffer);
+
+    // GL_UNIFORM_BUFFER - Both indexed and generic targets
+    void setGenericUniformBufferBinding(Buffer *buffer);
+    void setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size);
+    GLuint getIndexedUniformBufferId(GLuint index) const;
+    Buffer *getIndexedUniformBuffer(GLuint index) const;
+
+    // GL_TRANSFORM_FEEDBACK_BUFFER - Both indexed and generic targets
+    void setGenericTransformFeedbackBufferBinding(Buffer *buffer);
+    void setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size);
+    GLuint getIndexedTransformFeedbackBufferId(GLuint index) const;
+    Buffer *getIndexedTransformFeedbackBuffer(GLuint index) const;
+    GLuint getIndexedTransformFeedbackBufferOffset(GLuint index) const;
+
+    // GL_COPY_[READ/WRITE]_BUFFER
+    void setCopyReadBufferBinding(Buffer *buffer);
+    void setCopyWriteBufferBinding(Buffer *buffer);
+
+    // GL_PIXEL[PACK/UNPACK]_BUFFER
+    void setPixelPackBufferBinding(Buffer *buffer);
+    void setPixelUnpackBufferBinding(Buffer *buffer);
+
+    // Retrieve typed buffer by target (non-indexed)
+    Buffer *getTargetBuffer(GLenum target) const;
+
+    // Vertex attrib manipulation
+    void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
+    void setVertexAttribf(GLuint index, const GLfloat values[4]);
+    void setVertexAttribu(GLuint index, const GLuint values[4]);
+    void setVertexAttribi(GLuint index, const GLint values[4]);
+    void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
+                              bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
+    const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
+    const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
+    const VertexAttribCurrentValueData *getVertexAttribCurrentValues() const;
+    const void *getVertexAttribPointer(unsigned int attribNum) const;
+
+    // Pixel pack state manipulation
+    void setPackAlignment(GLint alignment);
+    GLint getPackAlignment() const;
+    void setPackReverseRowOrder(bool reverseRowOrder);
+    bool getPackReverseRowOrder() const;
+    const PixelPackState &getPackState() const;
+
+    // Pixel unpack state manipulation
+    void setUnpackAlignment(GLint alignment);
+    GLint getUnpackAlignment() const;
+    const PixelUnpackState &getUnpackState() const;
+
+    // State query functions
+    void getBooleanv(GLenum pname, GLboolean *params);
+    void getFloatv(GLenum pname, GLfloat *params);
+    void getIntegerv(GLenum pname, GLint *params);
+    bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data);
+    bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data);
+
+    bool hasMappedBuffer(GLenum target) const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(State);
+
+    Context *mContext;
+
+    ColorF mColorClearValue;
+    GLclampf mDepthClearValue;
+    int mStencilClearValue;
+
+    RasterizerState mRasterizer;
+    bool mScissorTest;
+    Rectangle mScissor;
+
+    BlendState mBlend;
+    ColorF mBlendColor;
+    bool mSampleCoverage;
+    GLclampf mSampleCoverageValue;
+    bool mSampleCoverageInvert;
+
+    DepthStencilState mDepthStencil;
+    GLint mStencilRef;
+    GLint mStencilBackRef;
+
+    GLfloat mLineWidth;
+
+    GLenum mGenerateMipmapHint;
+    GLenum mFragmentShaderDerivativeHint;
+
+    Rectangle mViewport;
+    float mNearZ;
+    float mFarZ;
+
+    BindingPointer<Buffer> mArrayBuffer;
+    Framebuffer *mReadFramebuffer;
+    Framebuffer *mDrawFramebuffer;
+    BindingPointer<Renderbuffer> mRenderbuffer;
+    GLuint mCurrentProgramId;
+    BindingPointer<ProgramBinary> mCurrentProgramBinary;
+
+    VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
+    VertexArray *mVertexArray;
+
+    // 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;
+
+    BindingPointer<Buffer> mGenericUniformBuffer;
+    OffsetBindingPointer<Buffer> mUniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
+
+    BindingPointer<TransformFeedback> mTransformFeedback;
+    BindingPointer<Buffer> mGenericTransformFeedbackBuffer;
+    OffsetBindingPointer<Buffer> mTransformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
+
+    BindingPointer<Buffer> mCopyReadBuffer;
+    BindingPointer<Buffer> mCopyWriteBuffer;
+
+    PixelUnpackState mUnpack;
+    PixelPackState mPack;
+};
+
+}
+
+#endif // LIBGLESV2_STATE_H_
+
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index baa5bc6..3ec492d 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -10,24 +9,23 @@
 // 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/Renderer.h"
-#include "libGLESv2/renderer/TextureStorage.h"
+#include "libGLESv2/renderer/d3d/TextureStorage.h"
+
 #include "libEGL/Surface.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/renderer/BufferStorage.h"
-#include "libGLESv2/renderer/RenderTarget.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
 
 namespace gl
 {
 
-bool IsMipmapFiltered(const SamplerState &samplerState)
+bool IsMipmapFiltered(const gl::SamplerState &samplerState)
 {
     switch (samplerState.minFilter)
     {
@@ -44,42 +42,23 @@
     }
 }
 
-bool IsRenderTargetUsage(GLenum usage)
+bool IsPointSampled(const gl::SamplerState &samplerState)
 {
-    return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+    return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
 }
 
-Texture::Texture(rx::Renderer *renderer, GLuint id, GLenum target) : RefCountObject(id)
+Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
+    : RefCountObject(id),
+      mTexture(impl),
+      mUsage(GL_NONE),
+      mImmutable(false),
+      mTarget(target)
 {
-    mRenderer = renderer;
-
-    mSamplerState.minFilter = GL_NEAREST_MIPMAP_LINEAR;
-    mSamplerState.magFilter = GL_LINEAR;
-    mSamplerState.wrapS = GL_REPEAT;
-    mSamplerState.wrapT = GL_REPEAT;
-    mSamplerState.wrapR = GL_REPEAT;
-    mSamplerState.maxAnisotropy = 1.0f;
-    mSamplerState.baseLevel = 0;
-    mSamplerState.maxLevel = 1000;
-    mSamplerState.minLod = -1000.0f;
-    mSamplerState.maxLod = 1000.0f;
-    mSamplerState.compareMode = GL_NONE;
-    mSamplerState.compareFunc = GL_LEQUAL;
-    mSamplerState.swizzleRed = GL_RED;
-    mSamplerState.swizzleGreen = GL_GREEN;
-    mSamplerState.swizzleBlue = GL_BLUE;
-    mSamplerState.swizzleAlpha = GL_ALPHA;
-    mUsage = GL_NONE;
-
-    mDirtyImages = true;
-
-    mImmutable = false;
-
-    mTarget = target;
 }
 
 Texture::~Texture()
 {
+    SafeDelete(mTexture);
 }
 
 GLenum Texture::getTarget() const
@@ -87,185 +66,18 @@
     return mTarget;
 }
 
-void Texture::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mRenderbufferProxies.addRef(proxy);
-}
-
-void Texture::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mRenderbufferProxies.release(proxy);
-}
-
-void Texture::setMinFilter(GLenum filter)
-{
-    mSamplerState.minFilter = filter;
-}
-
-void Texture::setMagFilter(GLenum filter)
-{
-    mSamplerState.magFilter = filter;
-}
-
-void Texture::setWrapS(GLenum wrap)
-{
-    mSamplerState.wrapS = wrap;
-}
-
-void Texture::setWrapT(GLenum wrap)
-{
-    mSamplerState.wrapT = wrap;
-}
-
-void Texture::setWrapR(GLenum wrap)
-{
-    mSamplerState.wrapR = wrap;
-}
-
-void Texture::setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy)
-{
-    mSamplerState.maxAnisotropy = std::min(textureMaxAnisotropy, contextMaxAnisotropy);
-}
-
-void Texture::setCompareMode(GLenum mode)
-{
-    mSamplerState.compareMode = mode;
-}
-
-void Texture::setCompareFunc(GLenum func)
-{
-    mSamplerState.compareFunc = func;
-}
-
-void Texture::setSwizzleRed(GLenum swizzle)
-{
-    mSamplerState.swizzleRed = swizzle;
-}
-
-void Texture::setSwizzleGreen(GLenum swizzle)
-{
-    mSamplerState.swizzleGreen = swizzle;
-}
-
-void Texture::setSwizzleBlue(GLenum swizzle)
-{
-    mSamplerState.swizzleBlue = swizzle;
-}
-
-void Texture::setSwizzleAlpha(GLenum swizzle)
-{
-    mSamplerState.swizzleAlpha = swizzle;
-}
-
-void Texture::setBaseLevel(GLint baseLevel)
-{
-    mSamplerState.baseLevel = baseLevel;
-}
-
-void Texture::setMaxLevel(GLint maxLevel)
-{
-    mSamplerState.maxLevel = maxLevel;
-}
-
-void Texture::setMinLod(GLfloat minLod)
-{
-    mSamplerState.minLod = minLod;
-}
-
-void Texture::setMaxLod(GLfloat maxLod)
-{
-    mSamplerState.maxLod = maxLod;
-}
-
 void Texture::setUsage(GLenum usage)
 {
     mUsage = usage;
+    getImplementation()->setUsage(usage);
 }
 
-GLenum Texture::getMinFilter() const
-{
-    return mSamplerState.minFilter;
-}
-
-GLenum Texture::getMagFilter() const
-{
-    return mSamplerState.magFilter;
-}
-
-GLenum Texture::getWrapS() const
-{
-    return mSamplerState.wrapS;
-}
-
-GLenum Texture::getWrapT() const
-{
-    return mSamplerState.wrapT;
-}
-
-GLenum Texture::getWrapR() const
-{
-    return mSamplerState.wrapR;
-}
-
-float Texture::getMaxAnisotropy() const
-{
-    return mSamplerState.maxAnisotropy;
-}
-
-GLenum Texture::getSwizzleRed() const
-{
-    return mSamplerState.swizzleRed;
-}
-
-GLenum Texture::getSwizzleGreen() const
-{
-    return mSamplerState.swizzleGreen;
-}
-
-GLenum Texture::getSwizzleBlue() const
-{
-    return mSamplerState.swizzleBlue;
-}
-
-GLenum Texture::getSwizzleAlpha() const
-{
-    return mSamplerState.swizzleAlpha;
-}
-
-GLint Texture::getBaseLevel() const
-{
-    return mSamplerState.baseLevel;
-}
-
-GLint Texture::getMaxLevel() const
-{
-    return mSamplerState.maxLevel;
-}
-
-GLfloat Texture::getMinLod() const
-{
-    return mSamplerState.minLod;
-}
-
-GLfloat Texture::getMaxLod() const
-{
-    return mSamplerState.maxLod;
-}
-
-bool Texture::isSwizzled() const
-{
-    return mSamplerState.swizzleRed   != GL_RED   ||
-           mSamplerState.swizzleGreen != GL_GREEN ||
-           mSamplerState.swizzleBlue  != GL_BLUE  ||
-           mSamplerState.swizzleAlpha != GL_ALPHA;
-}
-
-void Texture::getSamplerState(SamplerState *sampler)
+void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
 {
     *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;
 }
@@ -302,127 +114,48 @@
     return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
 }
 
-void Texture::setImage(const PixelUnpackState &unpack, GLenum type, const void *pixels, rx::Image *image)
+GLsizei Texture::getWidth(const ImageIndex &index) const
 {
-    // No-op
-    if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
-    {
-        return;
-    }
-
-    // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
-    // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
-    const void *pixelData = pixels;
-
-    if (unpack.pixelBuffer.id() != 0)
-    {
-        // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
-        Buffer *pixelBuffer = unpack.pixelBuffer.get();
-        ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
-        const void *bufferData = pixelBuffer->getStorage()->getData();
-        pixelData = static_cast<const unsigned char *>(bufferData) + offset;
-    }
-
-    if (pixelData != NULL)
-    {
-        image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
-        mDirtyImages = true;
-    }
+    rx::Image *image = mTexture->getImage(index);
+    return image->getWidth();
 }
 
-bool Texture::isFastUnpackable(const PixelUnpackState &unpack, GLenum sizedInternalFormat)
+GLsizei Texture::getHeight(const ImageIndex &index) const
 {
-    return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
+    rx::Image *image = mTexture->getImage(index);
+    return image->getHeight();
 }
 
-bool Texture::fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea,
-                               GLenum sizedInternalFormat, GLenum type, rx::RenderTarget *destRenderTarget)
+GLenum Texture::getInternalFormat(const ImageIndex &index) const
 {
-    if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
-    {
-        return true;
-    }
-
-    // In order to perform the fast copy through the shader, we must have the right format, and be able
-    // to create a render target.
-    ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat));
-
-    unsigned int offset = reinterpret_cast<unsigned int>(pixels);
-
-    return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
+    rx::Image *image = mTexture->getImage(index);
+    return image->getInternalFormat();
 }
 
-void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image)
+GLenum Texture::getActualFormat(const ImageIndex &index) const
 {
-    if (pixels != NULL)
-    {
-        image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels);
-        mDirtyImages = true;
-    }
+    rx::Image *image = mTexture->getImage(index);
+    return image->getActualFormat();
 }
 
-bool Texture::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                       GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels, rx::Image *image)
+rx::TextureStorage *Texture::getNativeTexture()
 {
-    const void *pixelData = pixels;
-
-    // CPU readback & copy where direct GPU copy is not supported
-    if (unpack.pixelBuffer.id() != 0)
-    {
-        Buffer *pixelBuffer = unpack.pixelBuffer.get();
-        unsigned int offset = reinterpret_cast<unsigned int>(pixels);
-        const void *bufferData = pixelBuffer->getStorage()->getData();
-        pixelData = static_cast<const unsigned char *>(bufferData) + offset;
-    }
-
-    if (pixelData != NULL)
-    {
-        image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData);
-        mDirtyImages = true;
-    }
-
-    return true;
+    return getImplementation()->getNativeTexture();
 }
 
-bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                                 GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image)
+void Texture::generateMipmaps()
 {
-    if (pixels != NULL)
-    {
-        image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels);
-        mDirtyImages = true;
-    }
-
-    return true;
+    getImplementation()->generateMipmaps();
 }
 
-rx::TextureStorageInterface *Texture::getNativeTexture()
+void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
 {
-    // ensure the underlying texture is created
-    initializeStorage(false);
-
-    rx::TextureStorageInterface *storage = getBaseLevelStorage();
-    if (storage)
-    {
-        updateStorage();
-    }
-
-    return storage;
-}
-
-bool Texture::hasDirtyImages() const
-{
-    return mDirtyImages;
-}
-
-void Texture::resetDirty()
-{
-    mDirtyImages = false;
+    getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
 }
 
 unsigned int Texture::getTextureSerial()
 {
-    rx::TextureStorageInterface *texture = getNativeTexture();
+    rx::TextureStorage *texture = getNativeTexture();
     return texture ? texture->getTextureSerial() : 0;
 }
 
@@ -433,21 +166,7 @@
 
 int Texture::immutableLevelCount()
 {
-    return (mImmutable ? getNativeTexture()->getStorageInstance()->getLevelCount() : 0);
-}
-
-GLint Texture::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const
-{
-    if ((isPow2(width) && isPow2(height) && isPow2(depth)) || mRenderer->getNonPower2TextureSupport())
-    {
-        // Maximum number of levels
-        return log2(std::max(std::max(width, height), depth)) + 1;
-    }
-    else
-    {
-        // OpenGL ES 2.0 without GL_OES_texture_npot does not permit NPOT mipmaps.
-        return 1;
-    }
+    return (mImmutable ? getNativeTexture()->getLevelCount() : 0);
 }
 
 int Texture::mipLevels() const
@@ -455,38 +174,30 @@
     return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
 }
 
-Texture2D::Texture2D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D)
+const rx::Image *Texture::getBaseLevelImage() const
 {
-    mTexStorage = NULL;
-    mSurface = NULL;
+    return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
+}
 
-    for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
-    {
-        mImageArray[i] = renderer->createImage();
-    }
+Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
+    : Texture(impl, id, GL_TEXTURE_2D)
+{
+    mSurface = NULL;
 }
 
 Texture2D::~Texture2D()
 {
-    delete mTexStorage;
-    mTexStorage = NULL;
-    
     if (mSurface)
     {
         mSurface->setBoundTexture(NULL);
         mSurface = NULL;
     }
-
-    for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
-    {
-        delete mImageArray[i];
-    }
 }
 
 GLsizei Texture2D::getWidth(GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[level]->getWidth();
+        return mTexture->getImage(level, 0)->getWidth();
     else
         return 0;
 }
@@ -494,7 +205,7 @@
 GLsizei Texture2D::getHeight(GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[level]->getHeight();
+        return mTexture->getImage(level, 0)->getHeight();
     else
         return 0;
 }
@@ -502,7 +213,7 @@
 GLenum Texture2D::getInternalFormat(GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[level]->getInternalFormat();
+        return mTexture->getImage(level, 0)->getInternalFormat();
     else
         return GL_NONE;
 }
@@ -510,86 +221,24 @@
 GLenum Texture2D::getActualFormat(GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[level]->getActualFormat();
+        return mTexture->getImage(level, 0)->getActualFormat();
     else
         return GL_NONE;
 }
 
-void Texture2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height)
+void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
     releaseTexImage();
 
-    // If there currently is a corresponding storage texture image, it has these parameters
-    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
-    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
-    const GLenum storageFormat = getBaseLevelInternalFormat();
-
-    mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, width, height, 1, false);
-
-    if (mTexStorage)
-    {
-        const int storageLevels = mTexStorage->getLevelCount();
-
-        if ((level >= storageLevels && storageLevels != 0) ||
-            width != storageWidth ||
-            height != storageHeight ||
-            internalformat != storageFormat)   // Discard mismatched storage
-        {
-            for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
-            {
-                mImageArray[i]->markDirty();
-            }
-
-            delete mTexStorage;
-            mTexStorage = NULL;
-            mDirtyImages = true;
-        }
-    }
-}
-
-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat
-                                                                                      : GetSizedInternalFormat(format, type, clientVersion);
-    redefineImage(level, sizedInternalFormat, width, height);
-
-    bool fastUnpacked = false;
-
-    // Attempt a fast gpu copy of the pixel data to the surface
-    if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level))
-    {
-        // Will try to create RT storage if it does not exist
-        rx::RenderTarget *destRenderTarget = getRenderTarget(level);
-        Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
-
-        if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
-        {
-            // Ensure we don't overwrite our newly initialized data
-            mImageArray[level]->markClean();
-
-            fastUnpacked = true;
-        }
-    }
-
-    if (!fastUnpacked)
-    {
-        Texture::setImage(unpack, type, pixels, mImageArray[level]);
-    }
+    mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
 }
 
 void Texture2D::bindTexImage(egl::Surface *surface)
 {
     releaseTexImage();
 
-    GLenum internalformat = surface->getFormat();
+    mTexture->bindTexImage(surface);
 
-    mImageArray[0]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, surface->getWidth(), surface->getHeight(), 1, true);
-
-    delete mTexStorage;
-    mTexStorage = new rx::TextureStorageInterface2D(mRenderer, surface->getSwapChain());
-
-    mDirtyImages = true;
     mSurface = surface;
     mSurface->setBoundTexture(this);
 }
@@ -601,172 +250,43 @@
         mSurface->setBoundTexture(NULL);
         mSurface = NULL;
 
-        if (mTexStorage)
-        {
-            delete mTexStorage;
-            mTexStorage = NULL;
-        }
-
-        for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
-        {
-            mImageArray[i]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
-        }
+        mTexture->releaseTexImage();
     }
 }
 
 void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
 {
-    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    redefineImage(level, format, width, height);
+    releaseTexImage();
 
-    Texture::setCompressedImage(imageSize, pixels, mImageArray[level]);
-}
-
-void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
-    if (isValidLevel(level))
-    {
-        rx::Image *image = mImageArray[level];
-        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, width, height))
-        {
-            image->markClean();
-        }
-    }
+    mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
 }
 
 void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    bool fastUnpacked = false;
-
-    if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
-    {
-        rx::RenderTarget *renderTarget = getRenderTarget(level);
-        Box destArea(xoffset, yoffset, 0, width, height, 1);
-
-        if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget))
-        {
-            // Ensure we don't overwrite our newly initialized data
-            mImageArray[level]->markClean();
-
-            fastUnpacked = true;
-        }
-    }
-
-    if (!fastUnpacked && Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[level]))
-    {
-        commitRect(level, xoffset, yoffset, width, height);
-    }
+    mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
 }
 
 void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
 {
-    if (Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level]))
-    {
-        commitRect(level, xoffset, yoffset, width, height);
-    }
+    mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
 }
 
 void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
 {
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format
-                                                                              : GetSizedInternalFormat(format, GL_UNSIGNED_BYTE, clientVersion);
-    redefineImage(level, sizedInternalFormat, width, height);
+    releaseTexImage();
 
-    if (!mImageArray[level]->isRenderableFormat())
-    {
-        mImageArray[level]->copy(0, 0, 0, x, y, width, height, source);
-        mDirtyImages = true;
-    }
-    else
-    {
-        ensureRenderTarget();
-        mImageArray[level]->markClean();
-
-        if (width != 0 && height != 0 && isValidLevel(level))
-        {
-            gl::Rectangle sourceRect;
-            sourceRect.x = x;
-            sourceRect.width = width;
-            sourceRect.y = y;
-            sourceRect.height = height;
-
-            mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, level);
-        }
-    }
-}
-
-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
-    // the current level we're copying to is defined (with appropriate format, width & height)
-    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
-
-    if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
-    {
-        mImageArray[level]->copy(xoffset, yoffset, 0, x, y, width, height, source);
-        mDirtyImages = true;
-    }
-    else
-    {
-        ensureRenderTarget();
-        
-        if (isValidLevel(level))
-        {
-            updateStorageLevel(level);
-
-            GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-            gl::Rectangle sourceRect;
-            sourceRect.x = x;
-            sourceRect.width = width;
-            sourceRect.y = y;
-            sourceRect.height = height;
-
-            mRenderer->copyImage(source, sourceRect,
-                                 gl::GetFormat(getBaseLevelInternalFormat(), clientVersion),
-                                 xoffset, yoffset, mTexStorage, level);
-        }
-    }
+    mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
 }
 
 void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
 {
-    for (int level = 0; level < levels; level++)
-    {
-        GLsizei levelWidth = std::max(1, width >> level);
-        GLsizei levelHeight = std::max(1, height >> level);
-        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, levelWidth, levelHeight, 1, true);
-    }
-
-    for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
-    {
-        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
-    }
-
     mImmutable = true;
 
-    setCompleteTexStorage(new rx::TextureStorageInterface2D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, levels));
-}
-
-void Texture2D::setCompleteTexStorage(rx::TextureStorageInterface2D *newCompleteTexStorage)
-{
-    SafeDelete(mTexStorage);
-    mTexStorage = newCompleteTexStorage;
-
-    if (mTexStorage && mTexStorage->isManaged())
-    {
-        for (int level = 0; level < mTexStorage->getLevelCount(); level++)
-        {
-            mImageArray[level]->setManagedSurface(mTexStorage, level);
-        }
-    }
-
-    mDirtyImages = true;
+    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
+bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
 {
     GLsizei width = getBaseLevelWidth();
     GLsizei height = getBaseLevelHeight();
@@ -776,21 +296,17 @@
         return false;
     }
 
-    if (!IsTextureFilteringSupported(getInternalFormat(0), mRenderer))
+    if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
     {
-        if (samplerState.magFilter != GL_NEAREST ||
-            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
-        {
-            return false;
-        }
+        return false;
     }
 
-    bool npotSupport = mRenderer->getNonPower2TextureSupport();
+    bool npotSupport = extensions.textureNPOT;
 
     if (!npotSupport)
     {
-        if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !isPow2(width)) ||
-            (samplerState.wrapT != GL_CLAMP_TO_EDGE && !isPow2(height)))
+        if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
+            (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
         {
             return false;
         }
@@ -800,7 +316,7 @@
     {
         if (!npotSupport)
         {
-            if (!isPow2(width) || !isPow2(height))
+            if (!gl::isPow2(width) || !gl::isPow2(height))
             {
                 return false;
             }
@@ -817,13 +333,13 @@
     // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
     // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
     // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
-    if (gl::GetDepthBits(getInternalFormat(0), mRenderer->getCurrentClientVersion()) > 0 &&
-        mRenderer->getCurrentClientVersion() > 2)
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
+    if (formatInfo.depthBits > 0 && clientVersion > 2)
     {
-        if (mSamplerState.compareMode == GL_NONE)
+        if (samplerState.compareMode == GL_NONE)
         {
-            if ((mSamplerState.minFilter != GL_NEAREST && mSamplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
-                mSamplerState.magFilter != GL_NEAREST)
+            if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
+                samplerState.magFilter != GL_NEAREST)
             {
                 return false;
             }
@@ -833,6 +349,23 @@
     return true;
 }
 
+bool Texture2D::isCompressed(GLint level) const
+{
+    return GetInternalFormatInfo(getInternalFormat(level)).compressed;
+}
+
+bool Texture2D::isDepth(GLint level) const
+{
+    return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
+}
+
+void Texture2D::generateMipmaps()
+{
+    releaseTexImage();
+
+    mTexture->generateMipmaps();
+}
+
 // Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
 bool Texture2D::isMipmapComplete() const
 {
@@ -872,8 +405,8 @@
         return true;
     }
 
-    ASSERT(level >= 1 && level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
-    rx::Image *image = mImageArray[level];
+    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())
     {
@@ -893,230 +426,19 @@
     return true;
 }
 
-bool Texture2D::isCompressed(GLint level) const
+TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
+    : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
 {
-    return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion());
-}
-
-bool Texture2D::isDepth(GLint level) const
-{
-    return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0;
-}
-
-// Constructs a native texture resource from the texture images
-void Texture2D::initializeStorage(bool renderTarget)
-{
-    // Only initialize the first time this texture is used as a render target or shader resource
-    if (mTexStorage)
-    {
-        return;
-    }
-
-    // do not attempt to create storage for nonexistant data
-    if (!isLevelComplete(0))
-    {
-        return;
-    }
-
-    bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
-
-    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
-    ASSERT(mTexStorage);
-
-    // flush image data to the storage
-    updateStorage();
-}
-
-rx::TextureStorageInterface2D *Texture2D::createCompleteStorage(bool renderTarget) const
-{
-    GLsizei width = getBaseLevelWidth();
-    GLsizei height = getBaseLevelHeight();
-
-    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 rx::TextureStorageInterface2D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, levels);
-}
-
-void Texture2D::updateStorage()
-{
-    ASSERT(mTexStorage != NULL);
-    GLint storageLevels = mTexStorage->getLevelCount();
-    for (int level = 0; level < storageLevels; level++)
-    {
-        if (mImageArray[level]->isDirty() && isLevelComplete(level))
-        {
-            updateStorageLevel(level);
-        }
-    }
-}
-
-void Texture2D::updateStorageLevel(int level)
-{
-    ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
-    ASSERT(isLevelComplete(level));
-
-    if (mImageArray[level]->isDirty())
-    {
-        commitRect(level, 0, 0, getWidth(level), getHeight(level));
-    }
-}
-
-bool Texture2D::ensureRenderTarget()
-{
-    initializeStorage(true);
-
-    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0)
-    {
-        ASSERT(mTexStorage);
-        if (!mTexStorage->isRenderTarget())
-        {
-            rx::TextureStorageInterface2D *newRenderTargetStorage = createCompleteStorage(true);
-
-            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
-            {
-                delete newRenderTargetStorage;
-                return gl::error(GL_OUT_OF_MEMORY, false);
-            }
-
-            setCompleteTexStorage(newRenderTargetStorage);
-        }
-    }
-
-    return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-void Texture2D::generateMipmaps()
-{
-    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
-    int levelCount = mipLevels();
-    for (int level = 1; level < levelCount; level++)
-    {
-        redefineImage(level, getBaseLevelInternalFormat(),
-                      std::max(getBaseLevelWidth() >> level, 1),
-                      std::max(getBaseLevelHeight() >> level, 1));
-    }
-
-    if (mTexStorage && mTexStorage->isRenderTarget())
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            mTexStorage->generateMipmap(level);
-
-            mImageArray[level]->markClean();
-        }
-    }
-    else
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
-        }
-    }
-}
-
-const rx::Image *Texture2D::getBaseLevelImage() const
-{
-    return mImageArray[0];
-}
-
-rx::TextureStorageInterface *Texture2D::getBaseLevelStorage()
-{
-    return mTexStorage;
-}
-
-FramebufferAttachment *Texture2D::getAttachment(GLint level)
-{
-    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, 0);
-    if (!attachment)
-    {
-        attachment = new FramebufferAttachment(mRenderer, id(), new Texture2DAttachment(this, level));
-        mRenderbufferProxies.add(level, 0, attachment);
-    }
-
-    return attachment;
-}
-
-unsigned int Texture2D::getRenderTargetSerial(GLint level)
-{
-    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level) : 0);
-}
-
-rx::RenderTarget *Texture2D::getRenderTarget(GLint level)
-{
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageLevel(level);
-
-    // ensure this is NOT a depth texture
-    if (isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level);
-}
-
-rx::RenderTarget *Texture2D::getDepthSencil(GLint level)
-{
-    // 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);
-}
-
-bool Texture2D::isValidLevel(int level) const
-{
-    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false);
-}
-
-TextureCubeMap::TextureCubeMap(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_CUBE_MAP)
-{
-    mTexStorage = NULL;
-    for (int i = 0; i < 6; i++)
-    {
-        for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
-        {
-            mImageArray[i][j] = renderer->createImage();
-        }
-    }
 }
 
 TextureCubeMap::~TextureCubeMap()
 {
-    for (int i = 0; i < 6; i++)
-    {
-        for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
-        {
-            delete mImageArray[i][j];
-        }
-    }
-
-    delete mTexStorage;
-    mTexStorage = NULL;
 }
 
 GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[targetToIndex(target)][level]->getWidth();
+        return mTexture->getImage(level, targetToLayerIndex(target))->getWidth();
     else
         return 0;
 }
@@ -1124,7 +446,7 @@
 GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[targetToIndex(target)][level]->getHeight();
+        return mTexture->getImage(level, targetToLayerIndex(target))->getHeight();
     else
         return 0;
 }
@@ -1132,7 +454,7 @@
 GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[targetToIndex(target)][level]->getInternalFormat();
+        return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
     else
         return GL_NONE;
 }
@@ -1140,118 +462,54 @@
 GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[targetToIndex(target)][level]->getActualFormat();
+        return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
     else
         return GL_NONE;
 }
 
 void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    setImage(0, level, width, height, internalFormat, format, type, unpack, pixels);
+    mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
 }
 
 void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    setImage(1, level, width, height, internalFormat, format, type, unpack, pixels);
+    mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
 }
 
 void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    setImage(2, level, width, height, internalFormat, format, type, unpack, pixels);
+    mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
 }
 
 void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    setImage(3, level, width, height, internalFormat, format, type, unpack, pixels);
+    mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
 }
 
 void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    setImage(4, level, width, height, internalFormat, format, type, unpack, pixels);
+    mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
 }
 
 void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    setImage(5, level, width, height, internalFormat, format, type, unpack, pixels);
+    mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
 }
 
 void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
 {
-    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    int faceIndex = targetToIndex(target);
-    redefineImage(faceIndex, level, format, width, height);
-
-    Texture::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]);
-}
-
-void TextureCubeMap::commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
-    if (isValidFaceLevel(faceIndex, level))
-    {
-        rx::Image *image = mImageArray[faceIndex][level];
-        if (image->copyToStorage(mTexStorage, faceIndex, level, xoffset, yoffset, width, height))
-            image->markClean();
-    }
+    mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
 }
 
 void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    int faceIndex = targetToIndex(target);
-    if (Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[faceIndex][level]))
-    {
-        commitRect(faceIndex, level, xoffset, yoffset, width, height);
-    }
+    mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
 }
 
 void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
 {
-    int faceIndex = targetToIndex(target);
-    if (Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[faceIndex][level]))
-    {
-        commitRect(faceIndex, level, xoffset, yoffset, width, height);
-    }
-}
-
-// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.
-bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState) const
-{
-    int size = getBaseLevelWidth();
-
-    bool mipmapping = IsMipmapFiltered(samplerState);
-
-    if (!IsTextureFilteringSupported(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0), mRenderer))
-    {
-        if (samplerState.magFilter != GL_NEAREST ||
-            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
-        {
-            return false;
-        }
-    }
-
-    if (!isPow2(size) && !mRenderer->getNonPower2TextureSupport())
-    {
-        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;
+    mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
 }
 
 // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -1268,11 +526,11 @@
 
     for (int faceIndex = 1; faceIndex < 6; faceIndex++)
     {
-        const rx::Image &faceBaseImage = *mImageArray[faceIndex][0];
+        const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
 
-        if (faceBaseImage.getWidth()          != baseWidth  ||
-            faceBaseImage.getHeight()         != baseHeight ||
-            faceBaseImage.getInternalFormat() != baseFormat )
+        if (faceBaseImage->getWidth()          != baseWidth  ||
+            faceBaseImage->getHeight()         != baseHeight ||
+            faceBaseImage->getInternalFormat() != baseFormat )
         {
             return false;
         }
@@ -1281,7 +539,89 @@
     return true;
 }
 
-bool TextureCubeMap::isMipmapCubeComplete() const
+bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
+{
+    return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
+}
+
+bool TextureCubeMap::isDepth(GLenum target, GLint level) const
+{
+    return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
+}
+
+void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+    mTexture->copyImage(target, level, format, x, y, width, height, source);
+}
+
+void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
+{
+    mImmutable = true;
+
+    mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
+}
+
+// Tests for texture sampling completeness
+bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
+{
+    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)
+{
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
+
+    return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+}
+
+GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
+{
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
+    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
+
+    return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
+}
+
+bool TextureCubeMap::isMipmapComplete() const
 {
     if (isImmutable())
     {
@@ -1311,7 +651,7 @@
 
 bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
 {
-    ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
+    ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
 
     if (isImmutable())
     {
@@ -1334,7 +674,7 @@
     }
 
     // Check that non-zero levels are consistent with the base level.
-    const rx::Image *faceLevelImage = mImageArray[faceIndex][level];
+    const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
 
     if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
     {
@@ -1349,609 +689,79 @@
     return true;
 }
 
-bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
+
+Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
+    : Texture(impl, id, GL_TEXTURE_3D)
 {
-    return IsFormatCompressed(getInternalFormat(target, level), mRenderer->getCurrentClientVersion());
-}
-
-bool TextureCubeMap::isDepth(GLenum target, GLint level) const
-{
-    return GetDepthBits(getInternalFormat(target, level), mRenderer->getCurrentClientVersion()) > 0;
-}
-
-void TextureCubeMap::initializeStorage(bool renderTarget)
-{
-    // Only initialize the first time this texture is used as a render target or shader resource
-    if (mTexStorage)
-    {
-        return;
-    }
-
-    // do not attempt to create storage for nonexistant data
-    if (!isFaceLevelComplete(0, 0))
-    {
-        return;
-    }
-
-    bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
-
-    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
-    ASSERT(mTexStorage);
-
-    // flush image data to the storage
-    updateStorage();
-}
-
-rx::TextureStorageInterfaceCube *TextureCubeMap::createCompleteStorage(bool renderTarget) const
-{
-    GLsizei size = getBaseLevelWidth();
-
-    ASSERT(size > 0);
-
-    // use existing storage level count, when previously specified by TexStorage*D
-    GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
-
-    return new rx::TextureStorageInterfaceCube(mRenderer, getBaseLevelInternalFormat(), renderTarget, size, levels);
-}
-
-void TextureCubeMap::setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage)
-{
-    SafeDelete(mTexStorage);
-    mTexStorage = newCompleteTexStorage;
-
-    if (mTexStorage && mTexStorage->isManaged())
-    {
-        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-        {
-            for (int level = 0; level < mTexStorage->getLevelCount(); level++)
-            {
-                mImageArray[faceIndex][level]->setManagedSurface(mTexStorage, faceIndex, level);
-            }
-        }
-    }
-
-    mDirtyImages = true;
-}
-
-void TextureCubeMap::updateStorage()
-{
-    ASSERT(mTexStorage != NULL);
-    GLint storageLevels = mTexStorage->getLevelCount();
-    for (int face = 0; face < 6; face++)
-    {
-        for (int level = 0; level < storageLevels; level++)
-        {
-            if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
-            {
-                updateStorageFaceLevel(face, level);
-            }
-        }
-    }
-}
-
-void TextureCubeMap::updateStorageFaceLevel(int faceIndex, int level)
-{
-    ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
-    rx::Image *image = mImageArray[faceIndex][level];
-
-    if (image->isDirty())
-    {
-        commitRect(faceIndex, level, 0, 0, image->getWidth(), image->getHeight());
-    }
-}
-
-bool TextureCubeMap::ensureRenderTarget()
-{
-    initializeStorage(true);
-
-    if (getBaseLevelWidth() > 0)
-    {
-        ASSERT(mTexStorage);
-        if (!mTexStorage->isRenderTarget())
-        {
-            rx::TextureStorageInterfaceCube *newRenderTargetStorage = createCompleteStorage(true);
-
-            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
-            {
-                delete newRenderTargetStorage;
-                return gl::error(GL_OUT_OF_MEMORY, false);
-            }
-
-            setCompleteTexStorage(newRenderTargetStorage);
-        }
-    }
-
-    return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-void TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat
-                                                                                      : GetSizedInternalFormat(format, type, clientVersion);
-
-    redefineImage(faceIndex, level, sizedInternalFormat, width, height);
-
-    Texture::setImage(unpack, type, pixels, mImageArray[faceIndex][level]);
-}
-
-int TextureCubeMap::targetToIndex(GLenum target)
-{
-    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
-    META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
-    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
-    META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
-    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
-
-    return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
-}
-
-void TextureCubeMap::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height)
-{
-    // If there currently is a corresponding storage texture image, it has these parameters
-    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
-    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
-    const GLenum storageFormat = getBaseLevelInternalFormat();
-
-    mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, width, height, 1, false);
-
-    if (mTexStorage)
-    {
-        const int storageLevels = mTexStorage->getLevelCount();
-
-        if ((level >= storageLevels && storageLevels != 0) ||
-            width != storageWidth ||
-            height != storageHeight ||
-            internalformat != storageFormat)   // Discard mismatched storage
-        {
-            for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
-            {
-                for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-                {
-                    mImageArray[faceIndex][level]->markDirty();
-                }
-            }
-
-            delete mTexStorage;
-            mTexStorage = NULL;
-
-            mDirtyImages = true;
-        }
-    }
-}
-
-void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-    int faceIndex = targetToIndex(target);
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format
-                                                                              : GetSizedInternalFormat(format, GL_UNSIGNED_BYTE, clientVersion);
-    redefineImage(faceIndex, level, sizedInternalFormat, width, height);
-
-    if (!mImageArray[faceIndex][level]->isRenderableFormat())
-    {
-        mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
-        mDirtyImages = true;
-    }
-    else
-    {
-        ensureRenderTarget();
-        mImageArray[faceIndex][level]->markClean();
-
-        ASSERT(width == height);
-
-        if (width > 0 && isValidFaceLevel(faceIndex, level))
-        {
-            gl::Rectangle sourceRect;
-            sourceRect.x = x;
-            sourceRect.width = width;
-            sourceRect.y = y;
-            sourceRect.height = height;
-
-            mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, target, level);
-        }
-    }
-}
-
-void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-    int faceIndex = targetToIndex(target);
-
-    // We can only make our texture storage to a render target if the level we're copying *to* is complete
-    // and the base level is cube-complete. The base level must be cube complete (common case) because we cannot
-    // rely on the "getBaseLevel*" methods reliably otherwise.
-    bool canCreateRenderTarget = isFaceLevelComplete(faceIndex, level) && isCubeComplete();
-
-    if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
-    {
-        mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
-        mDirtyImages = true;
-    }
-    else
-    {
-        ensureRenderTarget();
-        
-        if (isValidFaceLevel(faceIndex, level))
-        {
-            updateStorageFaceLevel(faceIndex, level);
-
-            GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-            gl::Rectangle sourceRect;
-            sourceRect.x = x;
-            sourceRect.width = width;
-            sourceRect.y = y;
-            sourceRect.height = height;
-
-            mRenderer->copyImage(source, sourceRect, gl::GetFormat(getBaseLevelInternalFormat(), clientVersion),
-                                 xoffset, yoffset, mTexStorage, target, level);
-        }
-    }
-}
-
-void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
-{
-    for (int level = 0; level < levels; level++)
-    {
-        GLsizei mipSize = std::max(1, size >> level);
-        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-        {
-            mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, mipSize, mipSize, 1, true);
-        }
-    }
-
-    for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
-    {
-        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-        {
-            mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, GL_NONE, 0, 0, 0, true);
-        }
-    }
-
-    mImmutable = true;
-
-    setCompleteTexStorage(new rx::TextureStorageInterfaceCube(mRenderer, internalformat, IsRenderTargetUsage(mUsage), size, levels));
-}
-
-void TextureCubeMap::generateMipmaps()
-{
-    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
-    int levelCount = mipLevels();
-    for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            int faceLevelSize = (std::max(mImageArray[faceIndex][0]->getWidth() >> level, 1));
-            redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
-        }
-    }
-
-    if (mTexStorage && mTexStorage->isRenderTarget())
-    {
-        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-        {
-            for (int level = 1; level < levelCount; level++)
-            {
-                mTexStorage->generateMipmap(faceIndex, level);
-
-                mImageArray[faceIndex][level]->markClean();
-            }
-        }
-    }
-    else
-    {
-        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-        {
-            for (int level = 1; level < levelCount; level++)
-            {
-                mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]);
-            }
-        }
-    }
-}
-
-const rx::Image *TextureCubeMap::getBaseLevelImage() const
-{
-    // Note: if we are not cube-complete, there is no single base level image that can describe all
-    // cube faces, so this method is only well-defined for a cube-complete base level.
-    return mImageArray[0][0];
-}
-
-rx::TextureStorageInterface *TextureCubeMap::getBaseLevelStorage()
-{
-    return mTexStorage;
-}
-
-FramebufferAttachment *TextureCubeMap::getAttachment(GLenum target, GLint level)
-{
-    ASSERT(!IsCubemapTextureTarget(target));
-    int faceIndex = targetToIndex(target);
-
-    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, faceIndex);
-    if (!attachment)
-    {
-        attachment = new FramebufferAttachment(mRenderer, id(), new TextureCubeMapAttachment(this, target, level));
-        mRenderbufferProxies.add(level, faceIndex, attachment);
-    }
-
-    return attachment;
-}
-
-unsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level)
-{
-    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(target, level) : 0);
-}
-
-rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target, GLint level)
-{
-    ASSERT(IsCubemapTextureTarget(target));
-
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageFaceLevel(targetToIndex(target), level);
-
-    // ensure this is NOT a depth texture
-    if (isDepth(target, level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(target, level);
-}
-
-rx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level)
-{
-    ASSERT(IsCubemapTextureTarget(target));
-
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageFaceLevel(targetToIndex(target), level);
-
-    // ensure this is a depth texture
-    if (!isDepth(target, level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(target, level);
-}
-
-bool TextureCubeMap::isValidFaceLevel(int faceIndex, int level) const
-{
-    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
-}
-
-Texture3D::Texture3D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_3D)
-{
-    mTexStorage = NULL;
-
-    for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
-    {
-        mImageArray[i] = renderer->createImage();
-    }
 }
 
 Texture3D::~Texture3D()
 {
-    delete mTexStorage;
-    mTexStorage = NULL;
-
-    for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
-    {
-        delete mImageArray[i];
-    }
 }
 
 GLsizei Texture3D::getWidth(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getWidth() : 0;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
 }
 
 GLsizei Texture3D::getHeight(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getHeight() : 0;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
 }
 
 GLsizei Texture3D::getDepth(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getDepth() : 0;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
 }
 
 GLenum Texture3D::getInternalFormat(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getInternalFormat() : GL_NONE;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
 }
 
 GLenum Texture3D::getActualFormat(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getActualFormat() : GL_NONE;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
 }
 
 bool Texture3D::isCompressed(GLint level) const
 {
-    return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion());
+    return GetInternalFormatInfo(getInternalFormat(level)).compressed;
 }
 
 bool Texture3D::isDepth(GLint level) const
 {
-    return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0;
+    return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
 }
 
 void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat
-                                                                                      : GetSizedInternalFormat(format, type, clientVersion);
-    redefineImage(level, sizedInternalFormat, width, height, depth);
-
-    bool fastUnpacked = false;
-
-    // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
-    if (isFastUnpackable(unpack, sizedInternalFormat))
-    {
-        // Will try to create RT storage if it does not exist
-        rx::RenderTarget *destRenderTarget = getRenderTarget(level);
-        Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
-
-        if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
-        {
-            // Ensure we don't overwrite our newly initialized data
-            mImageArray[level]->markClean();
-
-            fastUnpacked = true;
-        }
-    }
-
-    if (!fastUnpacked)
-    {
-        Texture::setImage(unpack, type, pixels, mImageArray[level]);
-    }
+    mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
 }
 
 void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
 {
-    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    redefineImage(level, format, width, height, depth);
-
-    Texture::setCompressedImage(imageSize, pixels, mImageArray[level]);
+    mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
 }
 
 void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    bool fastUnpacked = false;
-
-    // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
-    if (isFastUnpackable(unpack, getInternalFormat(level)))
-    {
-        rx::RenderTarget *destRenderTarget = getRenderTarget(level);
-        Box destArea(xoffset, yoffset, zoffset, width, height, depth);
-
-        if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget))
-        {
-            // Ensure we don't overwrite our newly initialized data
-            mImageArray[level]->markClean();
-
-            fastUnpacked = true;
-        }
-    }
-
-    if (!fastUnpacked && Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, mImageArray[level]))
-    {
-        commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
-    }
+    mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
 }
 
 void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
 {
-    if (Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, mImageArray[level]))
-    {
-        commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
-    }
+    mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
 }
 
 void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
 {
-    for (int level = 0; level < levels; level++)
-    {
-        GLsizei levelWidth = std::max(1, width >> level);
-        GLsizei levelHeight = std::max(1, height >> level);
-        GLsizei levelDepth = std::max(1, depth >> level);
-        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, levelWidth, levelHeight, levelDepth, true);
-    }
-
-    for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
-    {
-        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, GL_NONE, 0, 0, 0, true);
-    }
-
     mImmutable = true;
 
-    setCompleteTexStorage(new rx::TextureStorageInterface3D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels));
+    mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
 }
 
-void Texture3D::generateMipmaps()
-{
-    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
-    int levelCount = mipLevels();
-    for (int level = 1; level < levelCount; level++)
-    {
-        redefineImage(level, getBaseLevelInternalFormat(),
-                      std::max(getBaseLevelWidth() >> level, 1),
-                      std::max(getBaseLevelHeight() >> level, 1),
-                      std::max(getBaseLevelDepth() >> level, 1));
-    }
-
-    if (mTexStorage && mTexStorage->isRenderTarget())
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            mTexStorage->generateMipmap(level);
-
-            mImageArray[level]->markClean();
-        }
-    }
-    else
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
-        }
-    }
-}
-
-const rx::Image *Texture3D::getBaseLevelImage() const
-{
-    return mImageArray[0];
-}
-
-rx::TextureStorageInterface *Texture3D::getBaseLevelStorage()
-{
-    return mTexStorage;
-}
-
-void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
-    // the current level we're copying to is defined (with appropriate format, width & height)
-    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
-
-    if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
-    {
-        mImageArray[level]->copy(xoffset, yoffset, zoffset, x, y, width, height, source);
-        mDirtyImages = true;
-    }
-    else
-    {
-        ensureRenderTarget();
-
-        if (isValidLevel(level))
-        {
-            updateStorageLevel(level);
-
-            gl::Rectangle sourceRect;
-            sourceRect.x = x;
-            sourceRect.width = width;
-            sourceRect.y = y;
-            sourceRect.height = height;
-
-            GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-            mRenderer->copyImage(source, sourceRect,
-                                 gl::GetFormat(getBaseLevelInternalFormat(), clientVersion),
-                                 xoffset, yoffset, zoffset, mTexStorage, level);
-        }
-    }
-}
-
-bool Texture3D::isSamplerComplete(const SamplerState &samplerState) const
+bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
 {
     GLsizei width = getBaseLevelWidth();
     GLsizei height = getBaseLevelHeight();
@@ -1962,13 +772,9 @@
         return false;
     }
 
-    if (!IsTextureFilteringSupported(getInternalFormat(0), mRenderer))
+    if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
     {
-        if (samplerState.magFilter != GL_NEAREST ||
-            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
-        {
-            return false;
-        }
+        return false;
     }
 
     if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
@@ -1996,7 +802,7 @@
 
 bool Texture3D::isLevelComplete(int level) const
 {
-    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
+    ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
 
     if (isImmutable())
     {
@@ -2017,7 +823,7 @@
         return true;
     }
 
-    rx::Image *levelImage = mImageArray[level];
+    rx::Image *levelImage = mTexture->getImage(level, 0);
 
     if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
     {
@@ -2042,469 +848,78 @@
     return true;
 }
 
-FramebufferAttachment *Texture3D::getAttachment(GLint level, GLint layer)
+Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
+    : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
 {
-    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, layer);
-    if (!attachment)
-    {
-        attachment = new FramebufferAttachment(mRenderer, id(), new Texture3DAttachment(this, level, layer));
-        mRenderbufferProxies.add(level, 0, attachment);
-    }
-
-    return attachment;
-}
-
-unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
-{
-    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0);
-}
-
-bool Texture3D::isValidLevel(int level) const
-{
-    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
-}
-
-void Texture3D::initializeStorage(bool renderTarget)
-{
-    // Only initialize the first time this texture is used as a render target or shader resource
-    if (mTexStorage)
-    {
-        return;
-    }
-
-    // do not attempt to create storage for nonexistant data
-    if (!isLevelComplete(0))
-    {
-        return;
-    }
-
-    bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
-
-    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
-    ASSERT(mTexStorage);
-
-    // flush image data to the storage
-    updateStorage();
-}
-
-rx::TextureStorageInterface3D *Texture3D::createCompleteStorage(bool renderTarget) const
-{
-    GLsizei width = getBaseLevelWidth();
-    GLsizei height = getBaseLevelHeight();
-    GLsizei depth = getBaseLevelDepth();
-
-    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 rx::TextureStorageInterface3D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels);
-}
-
-void Texture3D::setCompleteTexStorage(rx::TextureStorageInterface3D *newCompleteTexStorage)
-{
-    SafeDelete(mTexStorage);
-    mTexStorage = newCompleteTexStorage;
-    mDirtyImages = true;
-
-    // We do not support managed 3D storage, as that is D3D9/ES2-only
-    ASSERT(!mTexStorage->isManaged());
-}
-
-void Texture3D::updateStorage()
-{
-    ASSERT(mTexStorage != NULL);
-    GLint storageLevels = mTexStorage->getLevelCount();
-    for (int level = 0; level < storageLevels; level++)
-    {
-        if (mImageArray[level]->isDirty() && isLevelComplete(level))
-        {
-            updateStorageLevel(level);
-        }
-    }
-}
-
-void Texture3D::updateStorageLevel(int level)
-{
-    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
-    ASSERT(isLevelComplete(level));
-
-    if (mImageArray[level]->isDirty())
-    {
-        commitRect(level, 0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
-    }
-}
-
-bool Texture3D::ensureRenderTarget()
-{
-    initializeStorage(true);
-
-    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0)
-    {
-        ASSERT(mTexStorage);
-        if (!mTexStorage->isRenderTarget())
-        {
-            rx::TextureStorageInterface3D *newRenderTargetStorage = createCompleteStorage(true);
-
-            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
-            {
-                delete newRenderTargetStorage;
-                return gl::error(GL_OUT_OF_MEMORY, false);
-            }
-
-            setCompleteTexStorage(newRenderTargetStorage);
-        }
-    }
-
-    return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-rx::RenderTarget *Texture3D::getRenderTarget(GLint level)
-{
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageLevel(level);
-
-    // ensure this is NOT a depth texture
-    if (isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level);
-}
-
-rx::RenderTarget *Texture3D::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);
-}
-
-rx::RenderTarget *Texture3D::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);
-}
-
-void Texture3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
-{
-    // If there currently is a corresponding storage texture image, it has these parameters
-    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
-    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
-    const int storageDepth = std::max(1, getBaseLevelDepth() >> level);
-    const GLenum storageFormat = getBaseLevelInternalFormat();
-
-    mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, width, height, depth, false);
-
-    if (mTexStorage)
-    {
-        const int storageLevels = mTexStorage->getLevelCount();
-
-        if ((level >= storageLevels && storageLevels != 0) ||
-            width != storageWidth ||
-            height != storageHeight ||
-            depth != storageDepth ||
-            internalformat != storageFormat)   // Discard mismatched storage
-        {
-            for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
-            {
-                mImageArray[i]->markDirty();
-            }
-
-            delete mTexStorage;
-            mTexStorage = NULL;
-            mDirtyImages = true;
-        }
-    }
-}
-
-void Texture3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
-{
-    if (isValidLevel(level))
-    {
-        rx::Image *image = mImageArray[level];
-        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth))
-        {
-            image->markClean();
-        }
-    }
-}
-
-Texture2DArray::Texture2DArray(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D_ARRAY)
-{
-    mTexStorage = NULL;
-
-    for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
-    {
-        mLayerCounts[level] = 0;
-        mImageArray[level] = NULL;
-    }
 }
 
 Texture2DArray::~Texture2DArray()
 {
-    delete mTexStorage;
-    mTexStorage = NULL;
-
-    deleteImages();
-}
-
-void Texture2DArray::deleteImages()
-{
-    for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
-    {
-        for (int layer = 0; layer < mLayerCounts[level]; ++layer)
-        {
-            delete mImageArray[level][layer];
-        }
-        delete[] mImageArray[level];
-        mImageArray[level] = NULL;
-        mLayerCounts[level] = 0;
-    }
 }
 
 GLsizei Texture2DArray::getWidth(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getWidth() : 0;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getWidth() : 0;
 }
 
 GLsizei Texture2DArray::getHeight(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getHeight() : 0;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getHeight() : 0;
 }
 
 GLsizei Texture2DArray::getLayers(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mLayerCounts[level] : 0;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getLayerCount(level) : 0;
 }
 
 GLenum Texture2DArray::getInternalFormat(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getInternalFormat() : GL_NONE;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
 }
 
 GLenum Texture2DArray::getActualFormat(GLint level) const
 {
-    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getActualFormat() : GL_NONE;
+    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
 }
 
 bool Texture2DArray::isCompressed(GLint level) const
 {
-    return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion());
+    return GetInternalFormatInfo(getInternalFormat(level)).compressed;
 }
 
 bool Texture2DArray::isDepth(GLint level) const
 {
-    return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0;
+    return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
 }
 
 void Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat
-                                                                                      : GetSizedInternalFormat(format, type, clientVersion);
-    redefineImage(level, sizedInternalFormat, width, height, depth);
-
-    GLsizei inputDepthPitch = gl::GetDepthPitch(sizedInternalFormat, type, clientVersion, width, height, unpack.alignment);
-
-    for (int i = 0; i < depth; i++)
-    {
-        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
-        Texture::setImage(unpack, type, layerPixels, mImageArray[level][i]);
-    }
+    mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
 }
 
 void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
 {
-    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
-    redefineImage(level, format, width, height, depth);
-
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLsizei inputDepthPitch = gl::GetDepthPitch(format, GL_UNSIGNED_BYTE, clientVersion, width, height, 1);
-
-    for (int i = 0; i < depth; i++)
-    {
-        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
-        Texture::setCompressedImage(imageSize, layerPixels, mImageArray[level][i]);
-    }
+    mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
 }
 
 void Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
 {
-    GLenum internalformat = getInternalFormat(level);
-    GLuint clientVersion =  mRenderer->getCurrentClientVersion();
-    GLsizei inputDepthPitch = gl::GetDepthPitch(internalformat, type, clientVersion, width, height, unpack.alignment);
-
-    for (int i = 0; i < depth; i++)
-    {
-        int layer = zoffset + i;
-        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
-
-        if (Texture::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, mImageArray[level][layer]))
-        {
-            commitRect(level, xoffset, yoffset, layer, width, height);
-        }
-    }
+    mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
 }
 
 void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
 {
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLsizei inputDepthPitch = gl::GetDepthPitch(format, GL_UNSIGNED_BYTE, clientVersion, width, height, 1);
-
-    for (int i = 0; i < depth; i++)
-    {
-        int layer = zoffset + i;
-        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
-
-        if (Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, layerPixels, mImageArray[level][layer]))
-        {
-            commitRect(level, xoffset, yoffset, layer, width, height);
-        }
-    }
+    mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
 }
 
 void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
 {
-    deleteImages();
-
-    for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
-    {
-        GLsizei levelWidth = std::max(1, width >> level);
-        GLsizei levelHeight = std::max(1, height >> level);
-
-        mLayerCounts[level] = (level < levels ? depth : 0);
-
-        if (mLayerCounts[level] > 0)
-        {
-            // Create new images for this level
-            mImageArray[level] = new rx::Image*[mLayerCounts[level]];
-
-            for (int layer = 0; layer < mLayerCounts[level]; layer++)
-            {
-                mImageArray[level][layer] = mRenderer->createImage();
-                mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, levelWidth,
-                                                    levelHeight, 1, true);
-            }
-        }
-    }
-
     mImmutable = true;
-    setCompleteTexStorage(new rx::TextureStorageInterface2DArray(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels));
+
+    mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
 }
 
-void Texture2DArray::generateMipmaps()
-{
-    int baseWidth = getBaseLevelWidth();
-    int baseHeight = getBaseLevelHeight();
-    int baseDepth = getBaseLevelDepth();
-    GLenum baseFormat = getBaseLevelInternalFormat();
-
-    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
-    int levelCount = mipLevels();
-    for (int level = 1; level < levelCount; level++)
-    {
-        redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
-    }
-
-    if (mTexStorage && mTexStorage->isRenderTarget())
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            mTexStorage->generateMipmap(level);
-
-            for (int layer = 0; layer < mLayerCounts[level]; layer++)
-            {
-                mImageArray[level][layer]->markClean();
-            }
-        }
-    }
-    else
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            for (int layer = 0; layer < mLayerCounts[level]; layer++)
-            {
-                mRenderer->generateMipmap(mImageArray[level][layer], mImageArray[level - 1][layer]);
-            }
-        }
-    }
-}
-
-const rx::Image *Texture2DArray::getBaseLevelImage() const
-{
-    return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL);
-}
-
-rx::TextureStorageInterface *Texture2DArray::getBaseLevelStorage()
-{
-    return mTexStorage;
-}
-
-void Texture2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
-    // the current level we're copying to is defined (with appropriate format, width & height)
-    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
-
-    if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
-    {
-        mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, x, y, width, height, source);
-        mDirtyImages = true;
-    }
-    else
-    {
-        ensureRenderTarget();
-
-        if (isValidLevel(level))
-        {
-            updateStorageLevel(level);
-
-            GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-            gl::Rectangle sourceRect;
-            sourceRect.x = x;
-            sourceRect.width = width;
-            sourceRect.y = y;
-            sourceRect.height = height;
-
-            mRenderer->copyImage(source, sourceRect, gl::GetFormat(getInternalFormat(0), clientVersion),
-                                 xoffset, yoffset, zoffset, mTexStorage, level);
-        }
-    }
-}
-
-bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState) const
+bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
 {
     GLsizei width = getBaseLevelWidth();
     GLsizei height = getBaseLevelHeight();
@@ -2515,13 +930,9 @@
         return false;
     }
 
-    if (!IsTextureFilteringSupported(getBaseLevelInternalFormat(), mRenderer))
+    if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
     {
-        if (samplerState.magFilter != GL_NEAREST ||
-            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
-        {
-            return false;
-        }
+        return false;
     }
 
     if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
@@ -2549,7 +960,7 @@
 
 bool Texture2DArray::isLevelComplete(int level) const
 {
-    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray));
+    ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
 
     if (isImmutable())
     {
@@ -2593,227 +1004,4 @@
     return true;
 }
 
-FramebufferAttachment *Texture2DArray::getAttachment(GLint level, GLint layer)
-{
-    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, layer);
-    if (!attachment)
-    {
-        attachment = new FramebufferAttachment(mRenderer, id(), new Texture2DArrayAttachment(this, level, layer));
-        mRenderbufferProxies.add(level, 0, attachment);
-    }
-
-    return attachment;
-}
-
-unsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer)
-{
-    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0);
-}
-
-bool Texture2DArray::isValidLevel(int level) const
-{
-    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
-}
-
-void Texture2DArray::initializeStorage(bool renderTarget)
-{
-    // Only initialize the first time this texture is used as a render target or shader resource
-    if (mTexStorage)
-    {
-        return;
-    }
-
-    // do not attempt to create storage for nonexistant data
-    if (!isLevelComplete(0))
-    {
-        return;
-    }
-
-    bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
-
-    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
-    ASSERT(mTexStorage);
-
-    // flush image data to the storage
-    updateStorage();
-}
-
-rx::TextureStorageInterface2DArray *Texture2DArray::createCompleteStorage(bool renderTarget) const
-{
-    GLsizei width = getBaseLevelWidth();
-    GLsizei height = getBaseLevelHeight();
-    GLsizei depth = getLayers(0);
-
-    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 rx::TextureStorageInterface2DArray(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels);
-}
-
-void Texture2DArray::setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage)
-{
-    SafeDelete(mTexStorage);
-    mTexStorage = newCompleteTexStorage;
-    mDirtyImages = true;
-
-    // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
-    ASSERT(!mTexStorage->isManaged());
-}
-
-void Texture2DArray::updateStorage()
-{
-    ASSERT(mTexStorage != NULL);
-    GLint storageLevels = mTexStorage->getLevelCount();
-    for (int level = 0; level < storageLevels; level++)
-    {
-        if (isLevelComplete(level))
-        {
-            updateStorageLevel(level);
-        }
-    }
-}
-
-void Texture2DArray::updateStorageLevel(int level)
-{
-    ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts));
-    ASSERT(isLevelComplete(level));
-
-    for (int layer = 0; layer < mLayerCounts[level]; layer++)
-    {
-        ASSERT(mImageArray[level] != NULL && mImageArray[level][layer] != NULL);
-        if (mImageArray[level][layer]->isDirty())
-        {
-            commitRect(level, 0, 0, layer, getWidth(level), getHeight(level));
-        }
-    }
-}
-
-bool Texture2DArray::ensureRenderTarget()
-{
-    initializeStorage(true);
-
-    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getLayers(0) > 0)
-    {
-        ASSERT(mTexStorage);
-        if (!mTexStorage->isRenderTarget())
-        {
-            rx::TextureStorageInterface2DArray *newRenderTargetStorage = createCompleteStorage(true);
-
-            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
-            {
-                delete newRenderTargetStorage;
-                return gl::error(GL_OUT_OF_MEMORY, false);
-            }
-
-            setCompleteTexStorage(newRenderTargetStorage);
-        }
-    }
-
-    return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-rx::RenderTarget *Texture2DArray::getRenderTarget(GLint level, GLint layer)
-{
-    // ensure the underlying texture is created
-    if (!ensureRenderTarget())
-    {
-        return NULL;
-    }
-
-    updateStorageLevel(level);
-
-    // ensure this is NOT a depth texture
-    if (isDepth(level))
-    {
-        return NULL;
-    }
-
-    return mTexStorage->getRenderTarget(level, layer);
-}
-
-rx::RenderTarget *Texture2DArray::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);
-}
-
-void Texture2DArray::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
-{
-    // If there currently is a corresponding storage texture image, it has these parameters
-    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
-    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
-    const int storageDepth = getLayers(0);
-    const GLenum storageFormat = getBaseLevelInternalFormat();
-
-    for (int layer = 0; layer < mLayerCounts[level]; layer++)
-    {
-        delete mImageArray[level][layer];
-    }
-    delete[] mImageArray[level];
-    mImageArray[level] = NULL;
-    mLayerCounts[level] = depth;
-
-    if (depth > 0)
-    {
-        mImageArray[level] = new rx::Image*[depth]();
-
-        for (int layer = 0; layer < mLayerCounts[level]; layer++)
-        {
-            mImageArray[level][layer] = mRenderer->createImage();
-            mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, width, height, 1, false);
-        }
-    }
-
-    if (mTexStorage)
-    {
-        const int storageLevels = mTexStorage->getLevelCount();
-
-        if ((level >= storageLevels && storageLevels != 0) ||
-            width != storageWidth ||
-            height != storageHeight ||
-            depth != storageDepth ||
-            internalformat != storageFormat)   // Discard mismatched storage
-        {
-            for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
-            {
-                for (int layer = 0; layer < mLayerCounts[level]; layer++)
-                {
-                    mImageArray[level][layer]->markDirty();
-                }
-            }
-
-            delete mTexStorage;
-            mTexStorage = NULL;
-            mDirtyImages = true;
-        }
-    }
-}
-
-void Texture2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height)
-{
-    if (isValidLevel(level) && layerTarget < getLayers(level))
-    {
-        rx::Image *image = mImageArray[level][layerTarget];
-        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, layerTarget, width, height))
-        {
-            image->markClean();
-        }
-    }
-}
-
 }
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 84ca289..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 <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-
 #include "common/debug.h"
 #include "common/RefCountObject.h"
 #include "libGLESv2/angletypes.h"
-#include "libGLESv2/RenderbufferProxySet.h"
+#include "libGLESv2/constants.h"
+#include "libGLESv2/renderer/TextureImpl.h"
+#include "libGLESv2/Caps.h"
+
+#include "angle_gl.h"
+
+#include <vector>
 
 namespace egl
 {
@@ -28,13 +29,7 @@
 
 namespace rx
 {
-class Renderer;
 class TextureStorageInterface;
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
-class TextureStorageInterface3D;
-class TextureStorageInterface2DArray;
-class RenderTarget;
 class Image;
 }
 
@@ -42,68 +37,24 @@
 {
 class Framebuffer;
 class FramebufferAttachment;
+struct ImageIndex;
 
-enum
-{
-    // These are the maximums the implementation can support
-    // The actual GL caps are limited by the device caps
-    // and should be queried from the Context
-    IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384,
-    IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
-    IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048,
-    IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048,
-
-    IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15   // 1+log2 of MAX_TEXTURE_SIZE
-};
-
-bool IsMipmapFiltered(const SamplerState &samplerState);
+bool IsMipmapFiltered(const gl::SamplerState &samplerState);
 
 class Texture : public RefCountObject
 {
   public:
-    Texture(rx::Renderer *renderer, GLuint id, GLenum target);
+    Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
 
     virtual ~Texture();
 
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
     GLenum getTarget() const;
 
-    void setMinFilter(GLenum filter);
-    void setMagFilter(GLenum filter);
-    void setWrapS(GLenum wrap);
-    void setWrapT(GLenum wrap);
-    void setWrapR(GLenum wrap);
-    void setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy);
-    void setCompareMode(GLenum mode);
-    void setCompareFunc(GLenum func);
-    void setSwizzleRed(GLenum swizzle);
-    void setSwizzleGreen(GLenum swizzle);
-    void setSwizzleBlue(GLenum swizzle);
-    void setSwizzleAlpha(GLenum swizzle);
-    void setBaseLevel(GLint baseLevel);
-    void setMaxLevel(GLint maxLevel);
-    void setMinLod(GLfloat minLod);
-    void setMaxLod(GLfloat maxLod);
-    void setUsage(GLenum usage);
+    const SamplerState &getSamplerState() const { return mSamplerState; }
+    SamplerState &getSamplerState() { return mSamplerState; }
+    void getSamplerStateWithNativeOffset(SamplerState *sampler);
 
-    GLenum getMinFilter() const;
-    GLenum getMagFilter() const;
-    GLenum getWrapS() const;
-    GLenum getWrapT() const;
-    GLenum getWrapR() const;
-    float getMaxAnisotropy() const;
-    GLenum getSwizzleRed() const;
-    GLenum getSwizzleGreen() const;
-    GLenum getSwizzleBlue() const;
-    GLenum getSwizzleAlpha() const;
-    GLint getBaseLevel() const;
-    GLint getMaxLevel() const;
-    GLfloat getMinLod() const;
-    GLfloat getMaxLod() const;
-    bool isSwizzled() const;
-    void getSamplerState(SamplerState *sampler);
+    void setUsage(GLenum usage);
     GLenum getUsage() const;
 
     GLint getBaseLevelWidth() const;
@@ -111,72 +62,52 @@
     GLint getBaseLevelDepth() const;
     GLenum getBaseLevelInternalFormat() const;
 
-    virtual bool isSamplerComplete(const SamplerState &samplerState) const = 0;
+    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;
 
-    virtual void generateMipmaps() = 0;
-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
+    rx::TextureStorage *getNativeTexture();
 
-    bool hasDirtyParameters() const;
-    bool hasDirtyImages() const;
-    void resetDirty();
+    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);
+
     unsigned int getTextureSerial();
 
     bool isImmutable() const;
     int immutableLevelCount();
 
+    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:
-    void setImage(const PixelUnpackState &unpack, GLenum type, const void *pixels, rx::Image *image);
-    bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                  GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels, rx::Image *image);
-    void setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image);
-    bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                            GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image);
-    bool isFastUnpackable(const PixelUnpackState &unpack, GLenum sizedInternalFormat);
-    bool fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea,
-                          GLenum sizedInternalFormat, GLenum type, rx::RenderTarget *destRenderTarget);
-
-    GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
     int mipLevels() const;
 
-    virtual void initializeStorage(bool renderTarget) = 0;
-    virtual void updateStorage() = 0;
-    virtual bool ensureRenderTarget() = 0;
-
-    rx::Renderer *mRenderer;
+    rx::TextureImpl *mTexture;
 
     SamplerState mSamplerState;
     GLenum mUsage;
 
-    bool mDirtyImages;
-
     bool mImmutable;
 
     GLenum mTarget;
 
-    // A specific internal reference count is kept for colorbuffer proxy references,
-    // because, as the renderbuffer acting as proxy will maintain a binding pointer
-    // back to this texture, there would be a circular reference if we used a binding
-    // pointer here. This reference count will cause the pointer to be set to NULL if
-    // the count drops to zero, but will not cause deletion of the FramebufferAttachment.
-    RenderbufferProxySet mRenderbufferProxies;
+    const rx::Image *getBaseLevelImage() const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture);
-
-    virtual rx::TextureStorageInterface *getBaseLevelStorage() = 0;
-    virtual const rx::Image *getBaseLevelImage() const = 0;
 };
 
 class Texture2D : public Texture
 {
   public:
-    Texture2D(rx::Renderer *renderer, GLuint id);
+    Texture2D(rx::TextureImpl *impl, GLuint id);
 
-    ~Texture2D();
+    virtual ~Texture2D();
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
@@ -190,55 +121,29 @@
     void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
     void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, 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;
+    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();
 
-    FramebufferAttachment *getAttachment(GLint level);
-    unsigned int getRenderTargetSerial(GLint level);
-
-  protected:
-    friend class Texture2DAttachment;
-    rx::RenderTarget *getRenderTarget(GLint level);
-    rx::RenderTarget *getDepthSencil(GLint level);
-
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture2D);
 
-    virtual void initializeStorage(bool renderTarget);
-    rx::TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const;
-    void setCompleteTexStorage(rx::TextureStorageInterface2D *newCompleteTexStorage);
-
-    virtual void updateStorage();
-    virtual bool ensureRenderTarget();
-    virtual rx::TextureStorageInterface *getBaseLevelStorage();
-    virtual const rx::Image *getBaseLevelImage() const;
-
     bool isMipmapComplete() const;
-    bool isValidLevel(int level) const;
     bool isLevelComplete(int level) const;
-    void updateStorageLevel(int level);
 
-    void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
-    void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
-
-    rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
-    rx::TextureStorageInterface2D *mTexStorage;
     egl::Surface *mSurface;
 };
 
 class TextureCubeMap : public Texture
 {
   public:
-    TextureCubeMap(rx::Renderer *renderer, 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;
@@ -259,56 +164,28 @@
     void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
     void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
     void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
     void storage(GLsizei levels, GLenum internalformat, GLsizei size);
 
-    virtual bool isSamplerComplete(const SamplerState &samplerState) const;
+    virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
+
     bool isCubeComplete() const;
 
-    virtual void generateMipmaps();
-
-    FramebufferAttachment *getAttachment(GLenum target, GLint level);
-    unsigned int getRenderTargetSerial(GLenum target, GLint level);
-
-    static int targetToIndex(GLenum target);
-
-  protected:
-    friend class TextureCubeMapAttachment;
-    rx::RenderTarget *getRenderTarget(GLenum target, GLint level);
-    rx::RenderTarget *getDepthStencil(GLenum target, GLint level);
+    static int targetToLayerIndex(GLenum target);
+    static GLenum layerIndexToTarget(GLint layer);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
 
-    virtual void initializeStorage(bool renderTarget);
-    rx::TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const;
-    void setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage);
-
-    virtual void updateStorage();
-    virtual bool ensureRenderTarget();
-    virtual rx::TextureStorageInterface *getBaseLevelStorage();
-    virtual const rx::Image *getBaseLevelImage() const;
-
-    bool isMipmapCubeComplete() const;
-    bool isValidFaceLevel(int faceIndex, int level) const;
+    bool isMipmapComplete() const;
     bool isFaceLevelComplete(int faceIndex, int level) const;
-    void updateStorageFaceLevel(int faceIndex, int level);
-
-    void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
-    void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
-    void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
-
-    rx::Image *mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
-    rx::TextureStorageInterfaceCube *mTexStorage;
 };
 
 class Texture3D : public Texture
 {
   public:
-    Texture3D(rx::Renderer *renderer, GLuint id);
+    Texture3D(rx::TextureImpl *impl, GLuint id);
 
-    ~Texture3D();
+    virtual ~Texture3D();
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
@@ -324,52 +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);
 
-    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);
-
-    virtual bool isSamplerComplete(const SamplerState &samplerState) const;
-    virtual bool isMipmapComplete() const;
-
-    FramebufferAttachment *getAttachment(GLint level, GLint layer);
-    unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
-  protected:
-    friend class Texture3DAttachment;
-    rx::RenderTarget *getRenderTarget(GLint level);
-    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);
 
-    virtual void initializeStorage(bool renderTarget);
-    rx::TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const;
-    void setCompleteTexStorage(rx::TextureStorageInterface3D *newCompleteTexStorage);
-
-    virtual void updateStorage();
-    virtual bool ensureRenderTarget();
-
-    virtual rx::TextureStorageInterface *getBaseLevelStorage();
-    virtual const rx::Image *getBaseLevelImage() const;
-
-    void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
-    void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
-
-    bool isValidLevel(int level) const;
+    bool isMipmapComplete() const;
     bool isLevelComplete(int level) const;
-    void updateStorageLevel(int level);
-
-    rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
-    rx::TextureStorageInterface3D *mTexStorage;
 };
 
 class Texture2DArray : public Texture
 {
   public:
-    Texture2DArray(rx::Renderer *renderer, GLuint id);
+    Texture2DArray(rx::TextureImpl *impl, GLuint id);
 
-    ~Texture2DArray();
+    virtual ~Texture2DArray();
 
     GLsizei getWidth(GLint level) const;
     GLsizei getHeight(GLint level) const;
@@ -385,49 +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);
 
-    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);
-
-    virtual bool isSamplerComplete(const SamplerState &samplerState) const;
-    virtual bool isMipmapComplete() const;
-
-    FramebufferAttachment *getAttachment(GLint level, GLint layer);
-    unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
-  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);
 
-    virtual void initializeStorage(bool renderTarget);
-    rx::TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const;
-    void setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage);
-
-    virtual void updateStorage();
-    virtual bool ensureRenderTarget();
-
-    virtual rx::TextureStorageInterface *getBaseLevelStorage();
-    virtual const rx::Image *getBaseLevelImage() const;
-
-    void deleteImages();
-    void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
-    void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height);
-
-    bool isValidLevel(int level) const;
+    bool isMipmapComplete() const;
     bool isLevelComplete(int level) const;
-    void updateStorageLevel(int level);
-
-    // Storing images as an array of single depth textures since D3D11 treats each array level of a
-    // Texture2D object as a separate subresource.  Each layer would have to be looped over
-    // to update all the texture layers since they cannot all be updated at once and it makes the most
-    // sense for the Image class to not have to worry about layer subresource as well as mip subresources.
-    GLsizei mLayerCounts[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-    rx::Image **mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
-    rx::TextureStorageInterface2DArray *mTexStorage;
 };
 
 }
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 183873c..885a4fe 100644
--- a/src/libGLESv2/TransformFeedback.h
+++ b/src/libGLESv2/TransformFeedback.h
@@ -10,8 +10,12 @@
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
+#include "angle_gl.h"
+
+namespace rx
+{
+class TransformFeedbackImpl;
+}
 
 namespace gl
 {
@@ -19,7 +23,7 @@
 class TransformFeedback : public RefCountObject
 {
   public:
-    explicit TransformFeedback(GLuint id);
+    TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id);
     virtual ~TransformFeedback();
 
     void start(GLenum primitiveMode);
@@ -35,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 a5ab7cb..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
@@ -13,7 +12,7 @@
 {
 
 LinkedUniform::LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
-                             const int blockIndex, const BlockMemberInfo &blockInfo)
+                             const int blockIndex, const sh::BlockMemberInfo &blockInfo)
     : type(type),
       precision(precision),
       name(name),
@@ -71,7 +70,7 @@
 size_t LinkedUniform::dataSize() const
 {
     ASSERT(type != GL_STRUCT_ANGLEX);
-    return UniformInternalSize(type) * elementCount();
+    return VariableInternalSize(type) * elementCount();
 }
 
 bool LinkedUniform::isSampler() const
diff --git a/src/libGLESv2/Uniform.h b/src/libGLESv2/Uniform.h
index 221ba48..633d70b 100644
--- a/src/libGLESv2/Uniform.h
+++ b/src/libGLESv2/Uniform.h
@@ -7,23 +7,23 @@
 #ifndef LIBGLESV2_UNIFORM_H_
 #define LIBGLESV2_UNIFORM_H_
 
+#include "common/debug.h"
+#include "common/blocklayout.h"
+
+#include "libGLESv2/angletypes.h"
+
+#include "angle_gl.h"
+
 #include <string>
 #include <vector>
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-
-#include "common/debug.h"
-#include "angletypes.h"
-#include "common/shadervars.h"
-
 namespace gl
 {
 
 // Helper struct representing a single shader uniform
 struct LinkedUniform
 {
-    LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const BlockMemberInfo &blockInfo);
+    LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo);
 
     ~LinkedUniform();
 
@@ -40,7 +40,7 @@
     const std::string name;
     const unsigned int arraySize;
     const int blockIndex;
-    const BlockMemberInfo blockInfo;
+    const sh::BlockMemberInfo blockInfo;
 
     unsigned char *data;
     bool dirty;
diff --git a/src/libGLESv2/VertexArray.cpp b/src/libGLESv2/VertexArray.cpp
index bd2df39..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
@@ -9,31 +8,42 @@
 
 #include "libGLESv2/VertexArray.h"
 #include "libGLESv2/Buffer.h"
+#include "libGLESv2/renderer/VertexArrayImpl.h"
 
 namespace gl
 {
 
-VertexArray::VertexArray(rx::Renderer *renderer, GLuint id)
-    : RefCountObject(id)
+VertexArray::VertexArray(rx::VertexArrayImpl *impl, GLuint id, size_t maxAttribs)
+    : mId(id),
+      mVertexArray(impl),
+      mVertexAttributes(maxAttribs)
 {
+    ASSERT(impl != NULL);
 }
 
 VertexArray::~VertexArray()
 {
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    SafeDelete(mVertexArray);
+
+    for (size_t i = 0; i < getMaxAttribs(); i++)
     {
-        mVertexAttributes[i].mBoundBuffer.set(NULL);
+        mVertexAttributes[i].buffer.set(NULL);
     }
     mElementArrayBuffer.set(NULL);
 }
 
+GLuint VertexArray::id() const
+{
+    return mId;
+}
+
 void VertexArray::detachBuffer(GLuint bufferName)
 {
-    for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+    for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++)
     {
-        if (mVertexAttributes[attribute].mBoundBuffer.id() == bufferName)
+        if (mVertexAttributes[attribute].buffer.id() == bufferName)
         {
-            mVertexAttributes[attribute].mBoundBuffer.set(NULL);
+            mVertexAttributes[attribute].buffer.set(NULL);
         }
     }
 
@@ -43,29 +53,44 @@
     }
 }
 
-const VertexAttribute& VertexArray::getVertexAttribute(unsigned int attributeIndex) const
+const VertexAttribute& VertexArray::getVertexAttribute(size_t attributeIndex) const
 {
-    ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);
+    ASSERT(attributeIndex < getMaxAttribs());
     return mVertexAttributes[attributeIndex];
 }
 
 void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor)
 {
-    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
-    mVertexAttributes[index].mDivisor = divisor;
+    ASSERT(index < getMaxAttribs());
+    mVertexAttributes[index].divisor = divisor;
+    mVertexArray->setAttributeDivisor(index, divisor);
 }
 
 void VertexArray::enableAttribute(unsigned int attributeIndex, bool enabledState)
 {
-    ASSERT(attributeIndex < gl::MAX_VERTEX_ATTRIBS);
-    mVertexAttributes[attributeIndex].mArrayEnabled = enabledState;
+    ASSERT(attributeIndex < getMaxAttribs());
+    mVertexAttributes[attributeIndex].enabled = enabledState;
+    mVertexArray->enableAttribute(attributeIndex, enabledState);
 }
 
 void VertexArray::setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
                                     bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
 {
-    ASSERT(attributeIndex < gl::MAX_VERTEX_ATTRIBS);
-    mVertexAttributes[attributeIndex].setState(boundBuffer, size, type, normalized, pureInteger, stride, pointer);
+    ASSERT(attributeIndex < getMaxAttribs());
+    mVertexAttributes[attributeIndex].buffer.set(boundBuffer);
+    mVertexAttributes[attributeIndex].size = size;
+    mVertexAttributes[attributeIndex].type = type;
+    mVertexAttributes[attributeIndex].normalized = normalized;
+    mVertexAttributes[attributeIndex].pureInteger = pureInteger;
+    mVertexAttributes[attributeIndex].stride = stride;
+    mVertexAttributes[attributeIndex].pointer = pointer;
+    mVertexArray->setAttribute(attributeIndex, mVertexAttributes[attributeIndex]);
+}
+
+void VertexArray::setElementArrayBuffer(Buffer *buffer)
+{
+    mElementArrayBuffer.set(buffer);
+    mVertexArray->setElementArrayBuffer(buffer);
 }
 
 }
\ No newline at end of file
diff --git a/src/libGLESv2/VertexArray.h b/src/libGLESv2/VertexArray.h
index ecfe7ad..993ba04 100644
--- a/src/libGLESv2/VertexArray.h
+++ b/src/libGLESv2/VertexArray.h
@@ -17,35 +17,44 @@
 #include "libGLESv2/constants.h"
 #include "libGLESv2/VertexAttribute.h"
 
+#include <vector>
+
 namespace rx
 {
 class Renderer;
+class VertexArrayImpl;
 }
 
 namespace gl
 {
 class Buffer;
 
-class VertexArray : public RefCountObject
+class VertexArray
 {
   public:
-    VertexArray(rx::Renderer *renderer, GLuint id);
+    VertexArray(rx::VertexArrayImpl *impl, GLuint id, size_t maxAttribs);
     ~VertexArray();
 
-    const VertexAttribute& getVertexAttribute(unsigned int attributeIndex) const;
+    GLuint id() const;
+
+    const VertexAttribute& getVertexAttribute(size_t attributeIndex) const;
     void detachBuffer(GLuint bufferName);
     void setVertexAttribDivisor(GLuint index, GLuint divisor);
     void enableAttribute(unsigned int attributeIndex, bool enabledState);
     void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
                            bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
 
-    const VertexAttribute* getVertexAttributes() const { return mVertexAttributes; }
+    const VertexAttribute* getVertexAttributes() const { return mVertexAttributes.data(); }
     Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); }
-    void setElementArrayBuffer(Buffer *elementArrayBuffer) { mElementArrayBuffer.set(elementArrayBuffer); }
+    void setElementArrayBuffer(Buffer *buffer);
     GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); }
+    size_t getMaxAttribs() const { return mVertexAttributes.size(); }
 
   private:
-    VertexAttribute mVertexAttributes[MAX_VERTEX_ATTRIBS];
+    GLuint mId;
+
+    rx::VertexArrayImpl *mVertexArray;
+    std::vector<VertexAttribute> mVertexAttributes;
     BindingPointer<Buffer> mElementArrayBuffer;
 };
 
diff --git a/src/libGLESv2/VertexAttribute.cpp b/src/libGLESv2/VertexAttribute.cpp
new file mode 100644
index 0000000..1096856
--- /dev/null
+++ b/src/libGLESv2/VertexAttribute.cpp
@@ -0,0 +1,55 @@
+//
+// 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.
+//
+// Implementation of the state class for mananging GLES 3 Vertex Array Objects.
+//
+
+#include "libGLESv2/VertexAttribute.h"
+
+namespace gl
+{
+
+VertexAttribute::VertexAttribute()
+    : enabled(false),
+      type(GL_FLOAT),
+      size(4),
+      normalized(false),
+      pureInteger(false),
+      stride(0),
+      pointer(NULL),
+      divisor(0)
+{
+}
+
+size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib)
+{
+    GLuint size = attrib.size;
+    switch (attrib.type)
+    {
+      case GL_BYTE:                        return size * sizeof(GLbyte);
+      case GL_UNSIGNED_BYTE:               return size * sizeof(GLubyte);
+      case GL_SHORT:                       return size * sizeof(GLshort);
+      case GL_UNSIGNED_SHORT:              return size * sizeof(GLushort);
+      case GL_INT:                         return size * sizeof(GLint);
+      case GL_UNSIGNED_INT:                return size * sizeof(GLuint);
+      case GL_INT_2_10_10_10_REV:          return 4;
+      case GL_UNSIGNED_INT_2_10_10_10_REV: return 4;
+      case GL_FIXED:                       return size * sizeof(GLfixed);
+      case GL_HALF_FLOAT:                  return size * sizeof(GLhalf);
+      case GL_FLOAT:                       return size * sizeof(GLfloat);
+      default: UNREACHABLE();              return size * sizeof(GLfloat);
+    }
+}
+
+size_t ComputeVertexAttributeStride(const VertexAttribute& attrib)
+{
+    if (!attrib.enabled)
+    {
+        return 16;
+    }
+    return attrib.stride ? attrib.stride : ComputeVertexAttributeTypeSize(attrib);
+}
+
+}
\ No newline at end of file
diff --git a/src/libGLESv2/VertexAttribute.h b/src/libGLESv2/VertexAttribute.h
index e9364d6..e9757b6 100644
--- a/src/libGLESv2/VertexAttribute.h
+++ b/src/libGLESv2/VertexAttribute.h
@@ -14,95 +14,58 @@
 namespace gl
 {
 
-class VertexAttribute
+struct VertexAttribute
 {
-  public:
-    VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mPureInteger(false),
-                        mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0)
-    {
-    }
+    bool enabled; // From glEnable/DisableVertexAttribArray
 
-    int typeSize() const
-    {
-        switch (mType)
-        {
-          case GL_BYTE:                        return mSize * sizeof(GLbyte);
-          case GL_UNSIGNED_BYTE:               return mSize * sizeof(GLubyte);
-          case GL_SHORT:                       return mSize * sizeof(GLshort);
-          case GL_UNSIGNED_SHORT:              return mSize * sizeof(GLushort);
-          case GL_INT:                         return mSize * sizeof(GLint);
-          case GL_UNSIGNED_INT:                return mSize * sizeof(GLuint);
-          case GL_INT_2_10_10_10_REV:          return 4;
-          case GL_UNSIGNED_INT_2_10_10_10_REV: return 4;
-          case GL_FIXED:                       return mSize * sizeof(GLfixed);
-          case GL_HALF_FLOAT:                  return mSize * sizeof(GLhalf);
-          case GL_FLOAT:                       return mSize * sizeof(GLfloat);
-          default: UNREACHABLE();              return mSize * sizeof(GLfloat);
-        }
-    }
-
-    GLsizei stride() const
-    {
-        return (mArrayEnabled ? (mStride ? mStride : typeSize()) : 16);
-    }
-
-    void setState(gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
-                  bool pureInteger, GLsizei stride, const void *pointer)
-    {
-        mBoundBuffer.set(boundBuffer);
-        mSize = size;
-        mType = type;
-        mNormalized = normalized;
-        mPureInteger = pureInteger;
-        mStride = stride;
-        mPointer = pointer;
-    }
-
-    template <typename T>
-    T querySingleParameter(GLenum pname) const
-    {
-        switch (pname)
-        {
-          case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
-            return static_cast<T>(mArrayEnabled ? GL_TRUE : GL_FALSE);
-          case GL_VERTEX_ATTRIB_ARRAY_SIZE:
-            return static_cast<T>(mSize);
-          case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
-            return static_cast<T>(mStride);
-          case GL_VERTEX_ATTRIB_ARRAY_TYPE:
-            return static_cast<T>(mType);
-          case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
-            return static_cast<T>(mNormalized ? GL_TRUE : GL_FALSE);
-          case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
-            return static_cast<T>(mBoundBuffer.id());
-          case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
-            return static_cast<T>(mDivisor);
-          case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
-            return static_cast<T>(mPureInteger ? GL_TRUE : GL_FALSE);
-          default:
-            UNREACHABLE();
-            return static_cast<T>(0);
-        }
-    }
-
-    // From glVertexAttribPointer
-    GLenum mType;
-    GLint mSize;
-    bool mNormalized;
-    bool mPureInteger;
-    GLsizei mStride;   // 0 means natural stride
+    GLenum type;
+    GLuint size;
+    bool normalized;
+    bool pureInteger;
+    GLuint stride; // 0 means natural stride
 
     union
     {
-        const void *mPointer;
-        intptr_t mOffset;
+        const GLvoid *pointer;
+        GLintptr offset;
     };
+    BindingPointer<Buffer> buffer; // Captured when glVertexAttribPointer is called.
 
-    BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
-    bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
-    unsigned int mDivisor;
+    GLuint divisor;
+
+    VertexAttribute();
 };
 
+template <typename T>
+T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname)
+{
+  switch (pname)
+  {
+    case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+      return static_cast<T>(attrib.enabled ? GL_TRUE : GL_FALSE);
+    case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+      return static_cast<T>(attrib.size);
+    case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+      return static_cast<T>(attrib.stride);
+    case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+      return static_cast<T>(attrib.type);
+    case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+      return static_cast<T>(attrib.normalized ? GL_TRUE : GL_FALSE);
+    case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+      return static_cast<T>(attrib.buffer.id());
+    case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+      return static_cast<T>(attrib.divisor);
+    case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+      return static_cast<T>(attrib.pureInteger ? GL_TRUE : GL_FALSE);
+    default:
+      UNREACHABLE();
+      return static_cast<T>(0);
+  }
+}
+
+size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib);
+size_t ComputeVertexAttributeStride(const VertexAttribute& attrib);
+
 struct VertexAttribCurrentValueData
 {
     union
diff --git a/src/libGLESv2/angletypes.cpp b/src/libGLESv2/angletypes.cpp
index acb3da8..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
@@ -14,6 +13,25 @@
 namespace gl
 {
 
+SamplerState::SamplerState()
+    : minFilter(GL_NEAREST_MIPMAP_LINEAR),
+      magFilter(GL_LINEAR),
+      wrapS(GL_REPEAT),
+      wrapT(GL_REPEAT),
+      wrapR(GL_REPEAT),
+      maxAnisotropy(1.0f),
+      baseLevel(0),
+      maxLevel(1000),
+      minLod(-1000.0f),
+      maxLod(1000.0f),
+      compareMode(GL_NONE),
+      compareFunc(GL_LEQUAL),
+      swizzleRed(GL_RED),
+      swizzleGreen(GL_GREEN),
+      swizzleBlue(GL_BLUE),
+      swizzleAlpha(GL_ALPHA)
+{}
+
 bool SamplerState::swizzleRequired() const
 {
     return swizzleRed != GL_RED || swizzleGreen != GL_GREEN ||
@@ -90,15 +108,15 @@
     }
 }
 
-VertexFormat::VertexFormat(const VertexAttribute &attribute)
-    : mType(attribute.mType),
-      mNormalized(attribute.mNormalized ? GL_TRUE : GL_FALSE),
-      mComponents(attribute.mSize),
-      mPureInteger(attribute.mPureInteger)
+VertexFormat::VertexFormat(const VertexAttribute &attrib)
+    : mType(attrib.type),
+      mNormalized(attrib.normalized ? GL_TRUE : GL_FALSE),
+      mComponents(attrib.size),
+      mPureInteger(attrib.pureInteger)
 {
     // Ensure we aren't initializing a vertex format which should be using
     // the current-value type
-    ASSERT(attribute.mArrayEnabled);
+    ASSERT(attrib.enabled);
 
     // Float data can not be normalized, so ignore the user setting
     if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED)
@@ -107,13 +125,13 @@
     }
 }
 
-VertexFormat::VertexFormat(const VertexAttribute &attribute, GLenum currentValueType)
-    : mType(attribute.mType),
-      mNormalized(attribute.mNormalized ? GL_TRUE : GL_FALSE),
-      mComponents(attribute.mSize),
-      mPureInteger(attribute.mPureInteger)
+VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueType)
+    : mType(attrib.type),
+      mNormalized(attrib.normalized ? GL_TRUE : GL_FALSE),
+      mComponents(attrib.size),
+      mPureInteger(attrib.pureInteger)
 {
-    if (!attribute.mArrayEnabled)
+    if (!attrib.enabled)
     {
         mType = currentValueType;
         mNormalized = GL_FALSE;
diff --git a/src/libGLESv2/angletypes.h b/src/libGLESv2/angletypes.h
index 0e91279..922053e 100644
--- a/src/libGLESv2/angletypes.h
+++ b/src/libGLESv2/angletypes.h
@@ -16,20 +16,9 @@
 {
 class Buffer;
 class ProgramBinary;
-class VertexAttribute;
+struct VertexAttribute;
 struct VertexAttribCurrentValueData;
 
-enum TextureType
-{
-    TEXTURE_2D,
-    TEXTURE_CUBE,
-    TEXTURE_3D,
-    TEXTURE_2D_ARRAY,
-
-    TEXTURE_TYPE_COUNT,
-    TEXTURE_UNKNOWN
-};
-
 enum SamplerType
 {
     SAMPLER_PIXEL,
@@ -147,6 +136,8 @@
 
 struct SamplerState
 {
+    SamplerState();
+
     GLenum minFilter;
     GLenum magFilter;
     GLenum wrapS;
diff --git a/src/libGLESv2/constants.h b/src/libGLESv2/constants.h
index 0c1c0ef..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
@@ -31,11 +27,17 @@
                                                          IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS,
 
     IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS = 4,
-};
 
-const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
-const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
-const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f;
+    // These are the maximums the implementation can support
+    // The actual GL caps are limited by the device caps
+    // and should be queried from the Context
+    IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384,
+    IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
+    IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048,
+    IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048,
+
+    IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15   // 1+log2 of MAX_TEXTURE_SIZE
+};
 
 }
 
diff --git a/src/libGLESv2/formatutils.cpp b/src/libGLESv2/formatutils.cpp
index 3aac25e..9d98829 100644
--- a/src/libGLESv2/formatutils.cpp
+++ b/src/libGLESv2/formatutils.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// 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.
 //
@@ -22,82 +21,26 @@
 // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
 // format and type combinations.
 
-struct FormatTypeInfo
+FormatType::FormatType()
+    : internalFormat(GL_NONE),
+      colorWriteFunction(NULL)
 {
-    GLenum mInternalFormat;
-    ColorWriteFunction mColorWriteFunction;
-
-    FormatTypeInfo(GLenum internalFormat, ColorWriteFunction writeFunc)
-        : mInternalFormat(internalFormat), mColorWriteFunction(writeFunc)
-    { }
-};
+}
 
 typedef std::pair<GLenum, GLenum> FormatTypePair;
-typedef std::pair<FormatTypePair, FormatTypeInfo> FormatPair;
-typedef std::map<FormatTypePair, FormatTypeInfo> FormatMap;
+typedef std::pair<FormatTypePair, FormatType> FormatPair;
+typedef std::map<FormatTypePair, FormatType> FormatMap;
 
 // A helper function to insert data into the format map with fewer characters.
 static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc)
 {
-    map->insert(FormatPair(FormatTypePair(format, type), FormatTypeInfo(internalFormat, writeFunc)));
+    FormatType info;
+    info.internalFormat = internalFormat;
+    info.colorWriteFunction = writeFunc;
+    map->insert(FormatPair(FormatTypePair(format, type), info));
 }
 
-FormatMap BuildES2FormatMap()
-{
-    FormatMap map;
-
-    using namespace rx;
-
-    //                       | Format                            | Type                             | Internal format                   | Color write function             |
-    InsertFormatMapping(&map, GL_ALPHA,                           GL_UNSIGNED_BYTE,                  GL_ALPHA8_EXT,                      WriteColor<A8, GLfloat>           );
-    InsertFormatMapping(&map, GL_ALPHA,                           GL_FLOAT,                          GL_ALPHA32F_EXT,                    WriteColor<A32F, GLfloat>         );
-    InsertFormatMapping(&map, GL_ALPHA,                           GL_HALF_FLOAT_OES,                 GL_ALPHA16F_EXT,                    WriteColor<A16F, GLfloat>         );
-
-    InsertFormatMapping(&map, GL_LUMINANCE,                       GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_EXT,                  WriteColor<L8, GLfloat>           );
-    InsertFormatMapping(&map, GL_LUMINANCE,                       GL_FLOAT,                          GL_LUMINANCE32F_EXT,                WriteColor<L32F, GLfloat>         );
-    InsertFormatMapping(&map, GL_LUMINANCE,                       GL_HALF_FLOAT_OES,                 GL_LUMINANCE16F_EXT,                WriteColor<L16F, GLfloat>         );
-
-    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_ALPHA8_EXT,           WriteColor<L8A8, GLfloat>         );
-    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_FLOAT,                          GL_LUMINANCE_ALPHA32F_EXT,          WriteColor<L32A32F, GLfloat>      );
-    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_HALF_FLOAT_OES,                 GL_LUMINANCE_ALPHA16F_EXT,          WriteColor<L16A16F, GLfloat>      );
-
-    InsertFormatMapping(&map, GL_RED,                             GL_UNSIGNED_BYTE,                  GL_R8_EXT,                          WriteColor<R8, GLfloat>           );
-    InsertFormatMapping(&map, GL_RED,                             GL_FLOAT,                          GL_R32F_EXT,                        WriteColor<R32F, GLfloat>         );
-    InsertFormatMapping(&map, GL_RED,                             GL_HALF_FLOAT_OES,                 GL_R16F_EXT,                        WriteColor<R16F, GLfloat>         );
-
-    InsertFormatMapping(&map, GL_RG,                              GL_UNSIGNED_BYTE,                  GL_RG8_EXT,                         WriteColor<R8G8, GLfloat>         );
-    InsertFormatMapping(&map, GL_RG,                              GL_FLOAT,                          GL_RG32F_EXT,                       WriteColor<R32G32F, GLfloat>      );
-    InsertFormatMapping(&map, GL_RG,                              GL_HALF_FLOAT_OES,                 GL_RG16F_EXT,                       WriteColor<R16G16F, GLfloat>      );
-
-    InsertFormatMapping(&map, GL_RGB,                             GL_UNSIGNED_BYTE,                  GL_RGB8_OES,                        WriteColor<R8G8B8, GLfloat>       );
-    InsertFormatMapping(&map, GL_RGB,                             GL_UNSIGNED_SHORT_5_6_5,           GL_RGB565,                          WriteColor<R5G6B5, GLfloat>       );
-    InsertFormatMapping(&map, GL_RGB,                             GL_FLOAT,                          GL_RGB32F_EXT,                      WriteColor<R32G32B32F, GLfloat>   );
-    InsertFormatMapping(&map, GL_RGB,                             GL_HALF_FLOAT_OES,                 GL_RGB16F_EXT,                      WriteColor<R16G16B16F, GLfloat>   );
-
-    InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_BYTE,                  GL_RGBA8_OES,                       WriteColor<R8G8B8A8, GLfloat>     );
-    InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_SHORT_4_4_4_4,         GL_RGBA4,                           WriteColor<R4G4B4A4, GLfloat>     );
-    InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_SHORT_5_5_5_1,         GL_RGB5_A1,                         WriteColor<R5G5B5A1, GLfloat>     );
-    InsertFormatMapping(&map, GL_RGBA,                            GL_FLOAT,                          GL_RGBA32F_EXT,                     WriteColor<R32G32B32A32F, GLfloat>);
-    InsertFormatMapping(&map, GL_RGBA,                            GL_HALF_FLOAT_OES,                 GL_RGBA16F_EXT,                     WriteColor<R16G16B16A16F, GLfloat>);
-
-    InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_BYTE,                  GL_BGRA8_EXT,                       WriteColor<B8G8R8A8, GLfloat>     );
-    InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX,                    WriteColor<B4G4R4A4, GLfloat>     );
-    InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX,                  WriteColor<B5G5R5A1, GLfloat>     );
-
-    InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    NULL                              );
-    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   NULL                              );
-    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL                              );
-    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL                              );
-
-    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,                 GL_UNSIGNED_SHORT,                 GL_DEPTH_COMPONENT16,               NULL                              );
-    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,                 GL_UNSIGNED_INT,                   GL_DEPTH_COMPONENT32_OES,           NULL                              );
-
-    InsertFormatMapping(&map, GL_DEPTH_STENCIL_OES,               GL_UNSIGNED_INT_24_8_OES,          GL_DEPTH24_STENCIL8_OES,            NULL                              );
-
-    return map;
-}
-
-FormatMap BuildES3FormatMap()
+FormatMap BuildFormatMap()
 {
     FormatMap map;
 
@@ -111,6 +54,7 @@
     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_INT_2_10_10_10_REV,    GL_RGB10_A2,               WriteColor<R10G10B10A2, GLfloat>  );
     InsertFormatMapping(&map, GL_RGBA,               GL_FLOAT,                          GL_RGBA32F,                WriteColor<R32G32B32A32F, GLfloat>);
     InsertFormatMapping(&map, GL_RGBA,               GL_HALF_FLOAT,                     GL_RGBA16F,                WriteColor<R16G16B16A16F, GLfloat>);
+    InsertFormatMapping(&map, GL_RGBA,               GL_HALF_FLOAT_OES,                 GL_RGBA16F,                WriteColor<R16G16B16A16F, GLfloat>);
 
     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_BYTE,                  GL_RGBA8UI,                WriteColor<R8G8B8A8, GLuint>      );
     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_BYTE,                           GL_RGBA8I,                 WriteColor<R8G8B8A8S, GLint>      );
@@ -127,6 +71,7 @@
     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_INT_5_9_9_9_REV,       GL_RGB9_E5,                WriteColor<R9G9B9E5, GLfloat>     );
     InsertFormatMapping(&map, GL_RGB,                GL_FLOAT,                          GL_RGB32F,                 WriteColor<R32G32B32F, GLfloat>   );
     InsertFormatMapping(&map, GL_RGB,                GL_HALF_FLOAT,                     GL_RGB16F,                 WriteColor<R16G16B16F, GLfloat>   );
+    InsertFormatMapping(&map, GL_RGB,                GL_HALF_FLOAT_OES,                 GL_RGB16F,                 WriteColor<R16G16B16F, GLfloat>   );
 
     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_BYTE,                  GL_RGB8UI,                 WriteColor<R8G8B8, GLuint>        );
     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_BYTE,                           GL_RGB8I,                  WriteColor<R8G8B8S, GLint>        );
@@ -139,6 +84,7 @@
     InsertFormatMapping(&map, GL_RG,                 GL_BYTE,                           GL_RG8_SNORM,              WriteColor<R8G8S, GLfloat>        );
     InsertFormatMapping(&map, GL_RG,                 GL_FLOAT,                          GL_RG32F,                  WriteColor<R32G32F, GLfloat>      );
     InsertFormatMapping(&map, GL_RG,                 GL_HALF_FLOAT,                     GL_RG16F,                  WriteColor<R16G16F, GLfloat>      );
+    InsertFormatMapping(&map, GL_RG,                 GL_HALF_FLOAT_OES,                 GL_RG16F,                  WriteColor<R16G16F, GLfloat>      );
 
     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_BYTE,                  GL_RG8UI,                  WriteColor<R8G8, GLuint>          );
     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_BYTE,                           GL_RG8I,                   WriteColor<R8G8S, GLint>          );
@@ -151,6 +97,7 @@
     InsertFormatMapping(&map, GL_RED,                GL_BYTE,                           GL_R8_SNORM,               WriteColor<R8S, GLfloat>          );
     InsertFormatMapping(&map, GL_RED,                GL_FLOAT,                          GL_R32F,                   WriteColor<R32F, GLfloat>         );
     InsertFormatMapping(&map, GL_RED,                GL_HALF_FLOAT,                     GL_R16F,                   WriteColor<R16F, GLfloat>         );
+    InsertFormatMapping(&map, GL_RED,                GL_HALF_FLOAT_OES,                 GL_R16F,                   WriteColor<R16F, GLfloat>         );
 
     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_BYTE,                  GL_R8UI,                   WriteColor<R8, GLuint>            );
     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_BYTE,                           GL_R8I,                    WriteColor<R8S, GLint>            );
@@ -166,1647 +113,510 @@
     InsertFormatMapping(&map, GL_LUMINANCE,          GL_FLOAT,                          GL_LUMINANCE32F_EXT,       WriteColor<L32F, GLfloat>         );
     InsertFormatMapping(&map, GL_ALPHA,              GL_FLOAT,                          GL_ALPHA32F_EXT,           WriteColor<A32F, GLfloat>         );
     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT,                     GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat>      );
+    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT_OES,                 GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat>      );
     InsertFormatMapping(&map, GL_LUMINANCE,          GL_HALF_FLOAT,                     GL_LUMINANCE16F_EXT,       WriteColor<L16F, GLfloat>         );
+    InsertFormatMapping(&map, GL_LUMINANCE,          GL_HALF_FLOAT_OES,                 GL_LUMINANCE16F_EXT,       WriteColor<L16F, GLfloat>         );
     InsertFormatMapping(&map, GL_ALPHA,              GL_HALF_FLOAT,                     GL_ALPHA16F_EXT,           WriteColor<A16F, GLfloat>         );
+    InsertFormatMapping(&map, GL_ALPHA,              GL_HALF_FLOAT_OES,                 GL_ALPHA16F_EXT,           WriteColor<A16F, GLfloat>         );
 
     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_BYTE,                  GL_BGRA8_EXT,              WriteColor<B8G8R8A8, GLfloat>     );
     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX,           WriteColor<B4G4R4A4, GLfloat>     );
     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX,         WriteColor<B5G5R5A1, GLfloat>     );
 
+    InsertFormatMapping(&map, GL_SRGB_EXT,           GL_UNSIGNED_BYTE,                  GL_SRGB8,                  WriteColor<R8G8B8, GLfloat>       );
+    InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT,     GL_UNSIGNED_BYTE,                  GL_SRGB8_ALPHA8,           WriteColor<R8G8B8A8, GLfloat>     );
+
+    InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE,     GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    NULL                     );
+    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE,     GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   NULL                     );
+    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE,     GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL                     );
+    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE,     GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL                     );
+
     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_SHORT,                 GL_DEPTH_COMPONENT16,      NULL                              );
-    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_INT,                   GL_DEPTH_COMPONENT24,      NULL                              );
+    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_INT,                   GL_DEPTH_COMPONENT32_OES,  NULL                              );
     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_FLOAT,                          GL_DEPTH_COMPONENT32F,     NULL                              );
 
+    InsertFormatMapping(&map, GL_STENCIL,            GL_UNSIGNED_BYTE,                  GL_STENCIL_INDEX8,         NULL                              );
+
     InsertFormatMapping(&map, GL_DEPTH_STENCIL,      GL_UNSIGNED_INT_24_8,              GL_DEPTH24_STENCIL8,       NULL                              );
     InsertFormatMapping(&map, GL_DEPTH_STENCIL,      GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8,      NULL                              );
 
     return map;
 }
 
-static const FormatMap &GetFormatMap(GLuint clientVersion)
+Type::Type()
+    : bytes(0),
+      specialInterpretation(false)
 {
-    if (clientVersion == 2)
-    {
-        static const FormatMap formats = BuildES2FormatMap();
-        return formats;
-    }
-    else if (clientVersion == 3)
-    {
-        static const FormatMap formats = BuildES3FormatMap();
-        return formats;
-    }
-    else
-    {
-        UNREACHABLE();
-        static FormatMap emptyMap;
-        return emptyMap;
-    }
-}
-
-struct FormatInfo
-{
-    GLenum mInternalformat;
-    GLenum mFormat;
-    GLenum mType;
-
-    FormatInfo(GLenum internalformat, GLenum format, GLenum type)
-        : mInternalformat(internalformat), mFormat(format), mType(type) { }
-
-    bool operator<(const FormatInfo& other) const
-    {
-        return memcmp(this, &other, sizeof(FormatInfo)) < 0;
-    }
-};
-
-// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
-typedef std::set<FormatInfo> ES3FormatSet;
-
-ES3FormatSet BuildES3FormatSet()
-{
-    ES3FormatSet set;
-
-    // Format combinations from ES 3.0.1 spec, table 3.2
-
-    //                   | Internal format      | Format            | Type                            |
-    //                   |                      |                   |                                 |
-    set.insert(FormatInfo(GL_RGBA8,              GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_SRGB8_ALPHA8,       GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGBA8_SNORM,        GL_RGBA,            GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        ));
-    set.insert(FormatInfo(GL_RGB10_A2,           GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   ));
-    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   ));
-    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        ));
-    set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_RGBA32F,            GL_RGBA,            GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGBA8UI,            GL_RGBA_INTEGER,    GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGBA8I,             GL_RGBA_INTEGER,    GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RGBA16UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_RGBA16I,            GL_RGBA_INTEGER,    GL_SHORT                         ));
-    set.insert(FormatInfo(GL_RGBA32UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_RGBA32I,            GL_RGBA_INTEGER,    GL_INT                           ));
-    set.insert(FormatInfo(GL_RGB10_A2UI,         GL_RGBA_INTEGER,    GL_UNSIGNED_INT_2_10_10_10_REV   ));
-    set.insert(FormatInfo(GL_RGB8,               GL_RGB,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB565,             GL_RGB,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_SRGB8,              GL_RGB,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB8_SNORM,         GL_RGB,             GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RGB565,             GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          ));
-    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_UNSIGNED_INT_10F_11F_11F_REV  ));
-    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_UNSIGNED_INT_5_9_9_9_REV      ));
-    set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_RGB32F,             GL_RGB,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGB8UI,             GL_RGB_INTEGER,     GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB8I,              GL_RGB_INTEGER,     GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RGB16UI,            GL_RGB_INTEGER,     GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_RGB16I,             GL_RGB_INTEGER,     GL_SHORT                         ));
-    set.insert(FormatInfo(GL_RGB32UI,            GL_RGB_INTEGER,     GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_RGB32I,             GL_RGB_INTEGER,     GL_INT                           ));
-    set.insert(FormatInfo(GL_RG8,                GL_RG,              GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RG8_SNORM,          GL_RG,              GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_RG32F,              GL_RG,              GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RG8UI,              GL_RG_INTEGER,      GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RG8I,               GL_RG_INTEGER,      GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RG16UI,             GL_RG_INTEGER,      GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_RG16I,              GL_RG_INTEGER,      GL_SHORT                         ));
-    set.insert(FormatInfo(GL_RG32UI,             GL_RG_INTEGER,      GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_RG32I,              GL_RG_INTEGER,      GL_INT                           ));
-    set.insert(FormatInfo(GL_R8,                 GL_RED,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_R8_SNORM,           GL_RED,             GL_BYTE                          ));
-    set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_R32F,               GL_RED,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_R8UI,               GL_RED_INTEGER,     GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_R8I,                GL_RED_INTEGER,     GL_BYTE                          ));
-    set.insert(FormatInfo(GL_R16UI,              GL_RED_INTEGER,     GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_R16I,               GL_RED_INTEGER,     GL_SHORT                         ));
-    set.insert(FormatInfo(GL_R32UI,              GL_RED_INTEGER,     GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_R32I,               GL_RED_INTEGER,     GL_INT                           ));
-
-    // Unsized formats
-    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        ));
-    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        ));
-    set.insert(FormatInfo(GL_RGB,                GL_RGB,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB,                GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          ));
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_UNSIGNED_BYTE                 ));
-
-    // Depth stencil formats
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT24,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_DEPTH24_STENCIL8,   GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8             ));
-    set.insert(FormatInfo(GL_DEPTH32F_STENCIL8,  GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV));
-
-    // From GL_OES_texture_float
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_FLOAT                         ));
-
-    // From GL_OES_texture_half_float
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_HALF_FLOAT                    ));
-
-    // From GL_EXT_texture_format_BGRA8888
-    set.insert(FormatInfo(GL_BGRA_EXT,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
-
-    // From GL_EXT_texture_storage
-    //                   | Internal format          | Format            | Type                            |
-    //                   |                          |                   |                                 |
-    set.insert(FormatInfo(GL_ALPHA8_EXT,             GL_ALPHA,           GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_LUMINANCE8_EXT,         GL_LUMINANCE,       GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_LUMINANCE8_ALPHA8_EXT,  GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_ALPHA32F_EXT,           GL_ALPHA,           GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_LUMINANCE32F_EXT,       GL_LUMINANCE,       GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_ALPHA16F_EXT,           GL_ALPHA,           GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_LUMINANCE16F_EXT,       GL_LUMINANCE,       GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    ));
-
-    // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888
-    set.insert(FormatInfo(GL_BGRA8_EXT,              GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT));
-    set.insert(FormatInfo(GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT));
-    set.insert(FormatInfo(GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
-
-    // From GL_ANGLE_depth_texture
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT32_OES,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES         ));
-
-    // Compressed formats
-    // From ES 3.0.1 spec, table 3.16
-    //                   | Internal format                             | Format                                      | Type           |
-    //                   |                                             |                                             |                |
-    set.insert(FormatInfo(GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SIGNED_R11_EAC,                 GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RG11_EAC,                       GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SIGNED_RG11_EAC,                GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RGB8_ETC2,                      GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ETC2,                     GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE));
-
-
-    // From GL_EXT_texture_compression_dxt1
-    set.insert(FormatInfo(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_UNSIGNED_BYTE));
-
-    // From GL_ANGLE_texture_compression_dxt3
-    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_UNSIGNED_BYTE));
-
-    // From GL_ANGLE_texture_compression_dxt5
-    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_UNSIGNED_BYTE));
-
-    return set;
-}
-
-static const ES3FormatSet &GetES3FormatSet()
-{
-    static const ES3FormatSet es3FormatSet = BuildES3FormatSet();
-    return es3FormatSet;
 }
 
 // Map of sizes of input types
-struct TypeInfo
+typedef std::pair<GLenum, Type> TypeInfoPair;
+typedef std::map<GLenum, Type> TypeInfoMap;
+
+static inline void InsertTypeInfo(TypeInfoMap *map, GLenum type, GLuint bytes, bool specialInterpretation)
 {
-    GLuint mTypeBytes;
-    bool mSpecialInterpretation;
+    Type info;
+    info.bytes = bytes;
+    info.specialInterpretation = specialInterpretation;
 
-    TypeInfo()
-        : mTypeBytes(0), mSpecialInterpretation(false) { }
+    map->insert(std::make_pair(type, info));
+}
 
-    TypeInfo(GLuint typeBytes, bool specialInterpretation)
-        : mTypeBytes(typeBytes), mSpecialInterpretation(specialInterpretation) { }
-
-    bool operator<(const TypeInfo& other) const
-    {
-        return memcmp(this, &other, sizeof(TypeInfo)) < 0;
-    }
-};
-
-typedef std::pair<GLenum, TypeInfo> TypeInfoPair;
-typedef std::map<GLenum, TypeInfo> TypeInfoMap;
+bool operator<(const Type& a, const Type& b)
+{
+    return memcmp(&a, &b, sizeof(Type)) < 0;
+}
 
 static TypeInfoMap BuildTypeInfoMap()
 {
     TypeInfoMap map;
 
-    map.insert(TypeInfoPair(GL_UNSIGNED_BYTE,                  TypeInfo( 1, false)));
-    map.insert(TypeInfoPair(GL_BYTE,                           TypeInfo( 1, false)));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT,                 TypeInfo( 2, false)));
-    map.insert(TypeInfoPair(GL_SHORT,                          TypeInfo( 2, false)));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT,                   TypeInfo( 4, false)));
-    map.insert(TypeInfoPair(GL_INT,                            TypeInfo( 4, false)));
-    map.insert(TypeInfoPair(GL_HALF_FLOAT,                     TypeInfo( 2, false)));
-    map.insert(TypeInfoPair(GL_HALF_FLOAT_OES,                 TypeInfo( 2, false)));
-    map.insert(TypeInfoPair(GL_FLOAT,                          TypeInfo( 4, false)));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_6_5,           TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4,         TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_5_5_1,         TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_2_10_10_10_REV,    TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8,              TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_10F_11F_11F_REV,   TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_5_9_9_9_REV,       TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8_OES,          TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_FLOAT_32_UNSIGNED_INT_24_8_REV, TypeInfo( 8, true )));
+    InsertTypeInfo(&map, GL_UNSIGNED_BYTE,                  1, false);
+    InsertTypeInfo(&map, GL_BYTE,                           1, false);
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT,                 2, false);
+    InsertTypeInfo(&map, GL_SHORT,                          2, false);
+    InsertTypeInfo(&map, GL_UNSIGNED_INT,                   4, false);
+    InsertTypeInfo(&map, GL_INT,                            4, false);
+    InsertTypeInfo(&map, GL_HALF_FLOAT,                     2, false);
+    InsertTypeInfo(&map, GL_HALF_FLOAT_OES,                 2, false);
+    InsertTypeInfo(&map, GL_FLOAT,                          4, false);
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_6_5,           2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4,         2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_5_5_1,         2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, 2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, 2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV,    4, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8,              4, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_10F_11F_11F_REV,   4, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_5_9_9_9_REV,       4, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8_OES,          4, true );
+    InsertTypeInfo(&map, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, true );
 
     return map;
 }
 
-static bool GetTypeInfo(GLenum type, TypeInfo *outTypeInfo)
+// Information about internal formats
+static bool AlwaysSupported(GLuint, const Extensions &)
+{
+    return true;
+}
+
+static bool UnimplementedSupport(GLuint, const Extensions &)
+{
+    return false;
+}
+
+static bool NeverSupported(GLuint, const Extensions &)
+{
+    return false;
+}
+
+template <GLuint minCoreGLVersion>
+static bool RequireESVersion(GLuint clientVersion, const Extensions &)
+{
+    return clientVersion >= minCoreGLVersion;
+}
+
+// Pointer to a boolean memeber of the Extensions struct
+typedef bool(Extensions::*ExtensionBool);
+
+// Check support for a single extension
+template <ExtensionBool bool1>
+static bool RequireExtension(GLuint, const Extensions & extensions)
+{
+    return extensions.*bool1;
+}
+
+// Check for a minimum client version or a single extension
+template <GLuint minCoreGLVersion, ExtensionBool bool1>
+static bool RequireESVersionOrExtension(GLuint clientVersion, const Extensions &extensions)
+{
+    return clientVersion >= minCoreGLVersion || extensions.*bool1;
+}
+
+// Check for a minimum client version or two extensions
+template <GLuint minCoreGLVersion, ExtensionBool bool1, ExtensionBool bool2>
+static bool RequireESVersionOrExtensions(GLuint clientVersion, const Extensions &extensions)
+{
+    return clientVersion >= minCoreGLVersion || (extensions.*bool1 || extensions.*bool2);
+}
+
+// Check support for two extensions
+template <ExtensionBool bool1, ExtensionBool bool2>
+static bool RequireExtensions(GLuint, const Extensions &extensions)
+{
+    return extensions.*bool1 || extensions.*bool2;
+}
+
+InternalFormat::InternalFormat()
+    : redBits(0),
+      greenBits(0),
+      blueBits(0),
+      luminanceBits(0),
+      alphaBits(0),
+      sharedBits(0),
+      depthBits(0),
+      stencilBits(0),
+      pixelBytes(0),
+      componentCount(0),
+      compressedBlockWidth(0),
+      compressedBlockHeight(0),
+      format(GL_NONE),
+      type(GL_NONE),
+      componentType(GL_NONE),
+      colorEncoding(GL_NONE),
+      compressed(false),
+      textureSupport(NeverSupported),
+      renderSupport(NeverSupported),
+      filterSupport(NeverSupported)
+{
+}
+
+static InternalFormat UnsizedFormat(GLenum format, InternalFormat::SupportCheckFunction textureSupport,
+                                    InternalFormat::SupportCheckFunction renderSupport,
+                                    InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.format = format;
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
+
+static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
+                                 GLenum format, GLenum type, GLenum componentType, bool srgb,
+                                 InternalFormat::SupportCheckFunction textureSupport,
+                                 InternalFormat::SupportCheckFunction renderSupport,
+                                 InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.redBits = red;
+    formatInfo.greenBits = green;
+    formatInfo.blueBits = blue;
+    formatInfo.alphaBits = alpha;
+    formatInfo.sharedBits = shared;
+    formatInfo.pixelBytes = (red + green + blue + alpha + shared) / 8;
+    formatInfo.componentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
+    formatInfo.format = format;
+    formatInfo.type = type;
+    formatInfo.componentType = componentType;
+    formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
+
+static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
+                                 InternalFormat::SupportCheckFunction textureSupport,
+                                 InternalFormat::SupportCheckFunction renderSupport,
+                                 InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.luminanceBits = luminance;
+    formatInfo.alphaBits = alpha;
+    formatInfo.pixelBytes = (luminance + alpha) / 8;
+    formatInfo.componentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
+    formatInfo.format = format;
+    formatInfo.type = type;
+    formatInfo.componentType = componentType;
+    formatInfo.colorEncoding = GL_LINEAR;
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
+
+static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
+                                         GLenum type, GLenum componentType, InternalFormat::SupportCheckFunction textureSupport,
+                                         InternalFormat::SupportCheckFunction renderSupport,
+                                         InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.depthBits = depthBits;
+    formatInfo.stencilBits = stencilBits;
+    formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8;
+    formatInfo.componentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
+    formatInfo.format = format;
+    formatInfo.type = type;
+    formatInfo.componentType = componentType;
+    formatInfo.colorEncoding = GL_LINEAR;
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
+
+static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
+                                       GLuint componentCount, GLenum format, GLenum type, bool srgb,
+                                       InternalFormat::SupportCheckFunction textureSupport,
+                                       InternalFormat::SupportCheckFunction renderSupport,
+                                       InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.compressedBlockWidth = compressedBlockWidth;
+    formatInfo.compressedBlockHeight = compressedBlockHeight;
+    formatInfo.pixelBytes = compressedBlockSize / 8;
+    formatInfo.componentCount = componentCount;
+    formatInfo.format = format;
+    formatInfo.type = type;
+    formatInfo.componentType = GL_UNSIGNED_NORMALIZED;
+    formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+    formatInfo.compressed = true;
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
+
+typedef std::pair<GLenum, InternalFormat> InternalFormatInfoPair;
+typedef std::map<GLenum, InternalFormat> InternalFormatInfoMap;
+
+static InternalFormatInfoMap BuildInternalFormatInfoMap()
+{
+    InternalFormatInfoMap map;
+
+    // From ES 3.0.1 spec, table 3.12
+    map.insert(InternalFormatInfoPair(GL_NONE,              InternalFormat()));
+
+    //                               | Internal format     |          | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Texture supported                                    | Renderable      | Filterable    |
+    map.insert(InternalFormatInfoPair(GL_R8,                RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_R8_SNORM,          RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG8,               RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG8_SNORM,         RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB8,              RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB8_SNORM,        RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB565,            RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA4,             RGBAFormat( 4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB5_A1,           RGBAFormat( 5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA8,             RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM,       RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB10_A2,          RGBAFormat(10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, RequireESVersion<3>,                                    AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB10_A2UI,        RGBAFormat(10, 10, 10,  2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_SRGB8,             RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireESVersionOrExtension<3, &Extensions::sRGB>,      NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8,      RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireESVersionOrExtension<3, &Extensions::sRGB>,      AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F,    RGBAFormat(11, 11, 10,  0, 0, GL_RGB,          GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT,               false, RequireESVersion<3>,                                    RequireExtension<&Extensions::colorBufferFloat>, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB9_E5,           RGBAFormat( 9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT,               false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_R8I,               RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R8UI,              RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R16I,              RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R16UI,             RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R32I,              RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R32UI,             RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG8I,              RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG8UI,             RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG16I,             RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG16UI,            RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG32I,             RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG32UI,            RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB8I,             RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB8UI,            RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB16I,            RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB16UI,           RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB32I,            RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB32UI,           RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA8I,            RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA8UI,           RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA16I,           RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA16UI,          RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA32I,           RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA32UI,          RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+
+    map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,         RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX,      RGBAFormat( 4,  4,  4,  4, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX,    RGBAFormat( 5,  5,  5,  1, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
+
+    // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
+    //                               | Internal format     |          | D |S | Format             | Type                           | Comp   | SRGB |  Texture supported                                                                     | Renderable     | Filterable                                          |
+    //                               |                     |          |   |  |                    |                                | type   |      |                                                                                        |                |                                                     |
+    map.insert(InternalFormatInfoPair(GL_R16F,              RGBAFormat(16,  0,  0,  0, 0, GL_RED,          GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
+    map.insert(InternalFormatInfoPair(GL_RG16F,             RGBAFormat(16, 16,  0,  0, 0, GL_RG,           GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
+    map.insert(InternalFormatInfoPair(GL_RGB16F,            RGBAFormat(16, 16, 16,  0, 0, GL_RGB,          GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>,                          AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
+    map.insert(InternalFormatInfoPair(GL_RGBA16F,           RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,         GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>,                          AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
+    map.insert(InternalFormatInfoPair(GL_R32F,              RGBAFormat(32,  0,  0,  0, 0, GL_RED,          GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>,     AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
+    map.insert(InternalFormatInfoPair(GL_RG32F,             RGBAFormat(32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>,     AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
+    map.insert(InternalFormatInfoPair(GL_RGB32F,            RGBAFormat(32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>,                              AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
+    map.insert(InternalFormatInfoPair(GL_RGBA32F,           RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>,                              AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
+
+    // Depth stencil formats
+    //                               | Internal format         |                  | D |S | X | Format            | Type                             | Component type        | Supported     |
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,     DepthStencilFormat(16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireESVersion<2>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24,     DepthStencilFormat(24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireESVersion<3>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,    DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireESVersion<3>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::depthTextures>,                           AlwaysSupported, AlwaysSupported                                           )));
+    map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8,      DepthStencilFormat(24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, RequireESVersionOrExtension<2, &Extensions::depthTextures>,             AlwaysSupported, AlwaysSupported                                           )));
+    map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8,     DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               RequireESVersion<3>,                                                    AlwaysSupported, AlwaysSupported                                           )));
+    map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,        DepthStencilFormat( 0, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        RequireESVersion<2>,                                                    AlwaysSupported, NeverSupported                                            )));
+
+    // Luminance alpha formats
+    //                               | Internal format          |          | L | A | Format            | Type            | Component type        | Supported                                                                    | Renderable    | Filterable    |
+    map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             LUMAFormat( 0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         LUMAFormat( 8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           LUMAFormat( 0, 32, GL_ALPHA,           GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       LUMAFormat(32,  0, GL_LUMINANCE,       GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           LUMAFormat( 0, 16, GL_ALPHA,           GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       LUMAFormat(16,  0, GL_LUMINANCE,       GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+
+    // Unsized formats
+    //                               | Internal format   |             | Format            | Supported                                                      | Renderable     | Filterable     |
+    map.insert(InternalFormatInfoPair(GL_ALPHA,           UnsizedFormat(GL_ALPHA,           RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE,       UnsizedFormat(GL_LUMINANCE,       RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, UnsizedFormat(GL_LUMINANCE_ALPHA, RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RED,             UnsizedFormat(GL_RED,             RequireESVersionOrExtension<3, &Extensions::textureRG>,          NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG,              UnsizedFormat(GL_RG,              RequireESVersionOrExtension<3, &Extensions::textureRG>,          NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB,             UnsizedFormat(GL_RGB,             RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA,            UnsizedFormat(GL_RGBA,            RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RED_INTEGER,     UnsizedFormat(GL_RED_INTEGER,     RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
+    map.insert(InternalFormatInfoPair(GL_RG_INTEGER,      UnsizedFormat(GL_RG_INTEGER,      RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
+    map.insert(InternalFormatInfoPair(GL_RGB_INTEGER,     UnsizedFormat(GL_RGB_INTEGER,     RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
+    map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER,    UnsizedFormat(GL_RGBA_INTEGER,    RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
+    map.insert(InternalFormatInfoPair(GL_BGRA_EXT,        UnsizedFormat(GL_BGRA_EXT,        RequireExtension<&Extensions::textureFormatBGRA8888>,            AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, UnsizedFormat(GL_DEPTH_COMPONENT, RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL,   UnsizedFormat(GL_DEPTH_STENCIL,   RequireESVersionOrExtension<3, &Extensions::packedDepthStencil>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_SRGB_EXT,        UnsizedFormat(GL_RGB,             RequireESVersionOrExtension<3, &Extensions::sRGB>,               NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT,  UnsizedFormat(GL_RGBA,            RequireESVersionOrExtension<3, &Extensions::sRGB>,               AlwaysSupported, AlwaysSupported)));
+
+    // Compressed formats, From ES 3.0.1 spec, table 3.16
+    //                               | Internal format                             |                |W |H | BS |CC| Format                                      | Type            | SRGB | Supported          | Renderable           | Filterable         |
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC,                        CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC,                 CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC,                       CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC,                CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2,                      CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2,                     CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC,                 CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+
+    // From GL_EXT_texture_compression_dxt1
+    //                               | Internal format                   |                |W |H | BS |CC| Format                            | Type            | SRGB | Supported                                           | Renderable           | Filterable         |
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported,       AlwaysSupported     )));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   CompressedFormat(4, 4,  64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported,       AlwaysSupported     )));
+
+    // From GL_ANGLE_texture_compression_dxt3
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported,       AlwaysSupported     )));
+
+    // From GL_ANGLE_texture_compression_dxt5
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported,       AlwaysSupported     )));
+
+    return map;
+}
+
+static const InternalFormatInfoMap &GetInternalFormatMap()
+{
+    static const InternalFormatInfoMap formatMap = BuildInternalFormatInfoMap();
+    return formatMap;
+}
+
+static FormatSet BuildAllSizedInternalFormatSet()
+{
+    FormatSet result;
+
+    const InternalFormatInfoMap &formats = GetInternalFormatMap();
+    for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++)
+    {
+        if (i->second.pixelBytes > 0)
+        {
+            result.insert(i->first);
+        }
+    }
+
+    return result;
+}
+
+const FormatType &GetFormatTypeInfo(GLenum format, GLenum type)
+{
+    static const FormatMap formatMap = BuildFormatMap();
+    FormatMap::const_iterator iter = formatMap.find(FormatTypePair(format, type));
+    if (iter != formatMap.end())
+    {
+        return iter->second;
+    }
+    else
+    {
+        static const FormatType defaultInfo;
+        return defaultInfo;
+    }
+}
+
+const Type &GetTypeInfo(GLenum type)
 {
     static const TypeInfoMap infoMap = BuildTypeInfoMap();
     TypeInfoMap::const_iterator iter = infoMap.find(type);
     if (iter != infoMap.end())
     {
-        if (outTypeInfo)
-        {
-            *outTypeInfo = iter->second;
-        }
-        return true;
+        return iter->second;
     }
     else
     {
-        return false;
+        static const Type defaultInfo;
+        return defaultInfo;
     }
 }
 
-// Information about internal formats
-typedef bool ((Context::*ContextSupportCheckMemberFunction)(void) const);
-typedef bool (*ContextSupportCheckFunction)(const Context *context);
-
-typedef bool ((rx::Renderer::*RendererSupportCheckMemberFunction)(void) const);
-typedef bool (*ContextRendererSupportCheckFunction)(const Context *context, const rx::Renderer *renderer);
-
-template <ContextSupportCheckMemberFunction func>
-bool CheckSupport(const Context *context)
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat)
 {
-    return (context->*func)();
-}
-
-template <ContextSupportCheckMemberFunction contextFunc, RendererSupportCheckMemberFunction rendererFunc>
-bool CheckSupport(const Context *context, const rx::Renderer *renderer)
-{
-    if (context)
+    const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
+    InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat);
+    if (iter != formatMap.end())
     {
-        return (context->*contextFunc)();
-    }
-    else if (renderer)
-    {
-        return (renderer->*rendererFunc)();
+        return iter->second;
     }
     else
     {
-        UNREACHABLE();
-        return false;
+        static const InternalFormat defaultInternalFormat;
+        return defaultInternalFormat;
     }
 }
 
-template <typename objectType>
-bool AlwaysSupported(const objectType*)
-{
-    return true;
-}
-
-template <typename objectTypeA, typename objectTypeB>
-bool AlwaysSupported(const objectTypeA*, const objectTypeB*)
-{
-    return true;
-}
-
-template <typename objectType>
-bool NeverSupported(const objectType*)
-{
-    return false;
-}
-
-template <typename objectTypeA, typename objectTypeB>
-bool NeverSupported(const objectTypeA *, const objectTypeB *)
-{
-    return false;
-}
-
-template <typename objectType>
-bool UnimplementedSupport(const objectType*)
-{
-    UNIMPLEMENTED();
-    return false;
-}
-
-template <typename objectTypeA, typename objectTypeB>
-bool UnimplementedSupport(const objectTypeA*, const objectTypeB*)
-{
-    UNIMPLEMENTED();
-    return false;
-}
-
-struct InternalFormatInfo
-{
-    GLuint mRedBits;
-    GLuint mGreenBits;
-    GLuint mBlueBits;
-
-    GLuint mLuminanceBits;
-
-    GLuint mAlphaBits;
-    GLuint mSharedBits;
-
-    GLuint mDepthBits;
-    GLuint mStencilBits;
-
-    GLuint mPixelBits;
-
-    GLuint mComponentCount;
-
-    GLuint mCompressedBlockWidth;
-    GLuint mCompressedBlockHeight;
-
-    GLenum mFormat;
-    GLenum mType;
-
-    GLenum mComponentType;
-    GLenum mColorEncoding;
-
-    bool mIsCompressed;
-
-    ContextRendererSupportCheckFunction mIsColorRenderable;
-    ContextRendererSupportCheckFunction mIsDepthRenderable;
-    ContextRendererSupportCheckFunction mIsStencilRenderable;
-    ContextRendererSupportCheckFunction mIsTextureFilterable;
-
-    ContextSupportCheckFunction mSupportFunction;
-
-    InternalFormatInfo() : mRedBits(0), mGreenBits(0), mBlueBits(0), mLuminanceBits(0), mAlphaBits(0), mSharedBits(0), mDepthBits(0), mStencilBits(0),
-                           mPixelBits(0), mComponentCount(0), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE),
-                           mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mIsColorRenderable(NeverSupported),
-                           mIsDepthRenderable(NeverSupported), mIsStencilRenderable(NeverSupported), mIsTextureFilterable(NeverSupported),
-                           mSupportFunction(NeverSupported)
-    {
-    }
-
-    static InternalFormatInfo UnsizedFormat(GLenum format, ContextSupportCheckFunction supportFunction)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mFormat = format;
-        formatInfo.mSupportFunction = supportFunction;
-
-        if (format == GL_RGB || format == GL_RGBA)
-            formatInfo.mIsColorRenderable = AlwaysSupported;
-
-        return formatInfo;
-    }
-
-    static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
-                                         GLenum format, GLenum type, GLenum componentType, bool srgb,
-                                         ContextRendererSupportCheckFunction colorRenderable,
-                                         ContextRendererSupportCheckFunction textureFilterable,
-                                         ContextSupportCheckFunction supportFunction)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mRedBits = red;
-        formatInfo.mGreenBits = green;
-        formatInfo.mBlueBits = blue;
-        formatInfo.mAlphaBits = alpha;
-        formatInfo.mSharedBits = shared;
-        formatInfo.mPixelBits = red + green + blue + alpha + shared;
-        formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
-        formatInfo.mFormat = format;
-        formatInfo.mType = type;
-        formatInfo.mComponentType = componentType;
-        formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
-        formatInfo.mIsColorRenderable = colorRenderable;
-        formatInfo.mIsTextureFilterable = textureFilterable;
-        formatInfo.mSupportFunction = supportFunction;
-        return formatInfo;
-    }
-
-    static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
-                                         ContextSupportCheckFunction supportFunction)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mLuminanceBits = luminance;
-        formatInfo.mAlphaBits = alpha;
-        formatInfo.mPixelBits = luminance + alpha;
-        formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
-        formatInfo.mFormat = format;
-        formatInfo.mType = type;
-        formatInfo.mComponentType = componentType;
-        formatInfo.mColorEncoding = GL_LINEAR;
-        formatInfo.mIsTextureFilterable = AlwaysSupported;
-        formatInfo.mSupportFunction = supportFunction;
-        return formatInfo;
-    }
-
-    static InternalFormatInfo DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
-                                                 GLenum type, GLenum componentType,
-                                                 ContextRendererSupportCheckFunction depthRenderable,
-                                                 ContextRendererSupportCheckFunction stencilRenderable,
-                                                 ContextSupportCheckFunction supportFunction)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mDepthBits = depthBits;
-        formatInfo.mStencilBits = stencilBits;
-        formatInfo.mPixelBits = depthBits + stencilBits + unusedBits;
-        formatInfo.mComponentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
-        formatInfo.mFormat = format;
-        formatInfo.mType = type;
-        formatInfo.mComponentType = componentType;
-        formatInfo.mColorEncoding = GL_LINEAR;
-        formatInfo.mIsDepthRenderable = depthRenderable;
-        formatInfo.mIsStencilRenderable = stencilRenderable;
-        formatInfo.mIsTextureFilterable = AlwaysSupported;
-        formatInfo.mSupportFunction = supportFunction;
-        return formatInfo;
-    }
-
-    static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
-                                               GLuint componentCount, GLenum format, GLenum type, bool srgb,
-                                               ContextSupportCheckFunction supportFunction)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mCompressedBlockWidth = compressedBlockWidth;
-        formatInfo.mCompressedBlockHeight = compressedBlockHeight;
-        formatInfo.mPixelBits = compressedBlockSize;
-        formatInfo.mComponentCount = componentCount;
-        formatInfo.mFormat = format;
-        formatInfo.mType = type;
-        formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED;
-        formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
-        formatInfo.mIsCompressed = true;
-        formatInfo.mIsTextureFilterable = AlwaysSupported;
-        formatInfo.mSupportFunction = supportFunction;
-        return formatInfo;
-    }
-};
-
-typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
-typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
-
-static InternalFormatInfoMap BuildES3InternalFormatInfoMap()
-{
-    InternalFormatInfoMap map;
-
-    // From ES 3.0.1 spec, table 3.12
-    map.insert(InternalFormatInfoPair(GL_NONE,              InternalFormatInfo()));
-
-    //                               | Internal format     |                              | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Color          | Texture        | Supported          |
-    //                               |                     |                              |   |   |   |   |  |                |                                |                       |      | renderable     | filterable     |                    |
-    map.insert(InternalFormatInfoPair(GL_R8,                InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R8_SNORM,          InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG8,               InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG8_SNORM,         InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB8,              InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB8_SNORM,        InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB565,            InternalFormatInfo::RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA4,             InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB5_A1,           InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA8,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM,       InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB10_A2,          InternalFormatInfo::RGBAFormat(10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB10_A2UI,        InternalFormatInfo::RGBAFormat(10, 10, 10,  2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_SRGB8,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  NeverSupported,  AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8,      InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F,    InternalFormatInfo::RGBAFormat(11, 11, 10,  0, 0, GL_RGB,          GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT,               false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB9_E5,           InternalFormatInfo::RGBAFormat( 9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT,               false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R8I,               InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R8UI,              InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R16I,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R16UI,             InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R32I,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R32UI,             InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG8I,              InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG8UI,             InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG16I,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG16UI,            InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG32I,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG32UI,            InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB8I,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                         GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB8UI,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB16I,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                        GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB16UI,           InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB32I,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                          GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB32UI,           InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA8I,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA8UI,           InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA16I,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA16UI,          InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA32I,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA32UI,          InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
-
-    map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,         InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX,      InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX,    InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
-
-    // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
-    //                               | Internal format        |                                   | D |S | Format             | Type                           | Comp   | SRGB | Color renderable                                                                                           | Texture filterable                                                                                    | Supported          |
-    //                               |                        |                                   |   |  |                    |                                | type   |      |                                                                                                            |                                                                                                       |                    |
-    map.insert(InternalFormatInfoPair(GL_R16F,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED,          GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG16F,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG,           GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB16F,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB,          GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA16F,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,         GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_R32F,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED,          GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RG32F,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGB32F,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_RGBA32F,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
-
-    // Depth stencil formats
-    //                               | Internal format         |                                      | D |S | X | Format            | Type                             | Component type        | Depth          | Stencil        | Supported     |
-    //                               |                         |                                      |   |  |   |                   |                                  |                       | renderable     | renderable     |               |
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,     InternalFormatInfo::DepthStencilFormat(16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24,     InternalFormatInfo::DepthStencilFormat(24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,    InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               AlwaysSupported, NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8,      InternalFormatInfo::DepthStencilFormat(24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8,     InternalFormatInfo::DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               AlwaysSupported, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,        InternalFormatInfo::DepthStencilFormat( 0, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        NeverSupported,  AlwaysSupported, AlwaysSupported)));
-
-    // Luminance alpha formats
-    //                               | Internal format          |                              | L | A | Format            | Type            | Component type        | Supported     |
-    map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             InternalFormatInfo::LUMAFormat( 0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         InternalFormatInfo::LUMAFormat( 8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA,           GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       InternalFormatInfo::LUMAFormat(32,  0, GL_LUMINANCE,       GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA,           GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       InternalFormatInfo::LUMAFormat(16,  0, GL_LUMINANCE,       GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  InternalFormatInfo::LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
-
-    // Unsized formats
-    //                               | Internal format   |                                 | Format            | Supported     |
-    map.insert(InternalFormatInfoPair(GL_ALPHA,           InternalFormatInfo::UnsizedFormat(GL_ALPHA,           AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE,       InternalFormatInfo::UnsizedFormat(GL_LUMINANCE,       AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RED,             InternalFormatInfo::UnsizedFormat(GL_RED,             AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG,              InternalFormatInfo::UnsizedFormat(GL_RG,              AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB,             InternalFormatInfo::UnsizedFormat(GL_RGB,             AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA,            InternalFormatInfo::UnsizedFormat(GL_RGBA,            AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RED_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER,     AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG_INTEGER,      InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER,      AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER,     AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER,    InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER,    AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_BGRA_EXT,        InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT,        AlwaysSupported)));
-
-    // Compressed formats, From ES 3.0.1 spec, table 3.16
-    //                               | Internal format                             |                                    |W |H | BS |CC| Format                                      | Type            | SRGB | Supported          |
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC,                        InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC,                 InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC,                       InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC,                InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2,                      InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2,                     InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, true,  UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true,  UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC,                 InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE, true,  UnimplementedSupport)));
-
-    // From GL_EXT_texture_compression_dxt1
-    //                               | Internal format                   |                                    |W |H | BS |CC| Format                            | Type            | SRGB | Supported     |
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE, false, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   InternalFormatInfo::CompressedFormat(4, 4,  64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE, false, AlwaysSupported)));
-
-    // From GL_ANGLE_texture_compression_dxt3
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, AlwaysSupported)));
-
-    // From GL_ANGLE_texture_compression_dxt5
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, AlwaysSupported)));
-
-    return map;
-}
-
-static InternalFormatInfoMap BuildES2InternalFormatInfoMap()
-{
-    InternalFormatInfoMap map;
-
-    // From ES 2.0.25 table 4.5
-    map.insert(InternalFormatInfoPair(GL_NONE,                 InternalFormatInfo()));
-
-    //                               | Internal format        |                              | R | G | B | A |S | Format          | Type                     | Component type        | SRGB | Color         | Texture        | Supported      |
-    //                               |                        |                              |   |   |   |   |  |                 |                          |                       |      | renderable    | filterable     |                |
-    map.insert(InternalFormatInfoPair(GL_RGBA4,                InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_RGBA,          GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB5_A1,              InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_RGBA,          GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB565,               InternalFormatInfo::RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,           GL_UNSIGNED_SHORT_5_6_5,   GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
-
-    // Extension formats
-    map.insert(InternalFormatInfoPair(GL_R8_EXT,               InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_EXT,       GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures>)));
-    map.insert(InternalFormatInfoPair(GL_RG8_EXT,              InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_EXT,        GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures>)));
-    map.insert(InternalFormatInfoPair(GL_RGB8_OES,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,           GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA8_OES,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,          GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,      GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX,         InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_BGRA_EXT,      GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, NeverSupported,  AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX,       InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_BGRA_EXT,      GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, NeverSupported,  AlwaysSupported, AlwaysSupported)));
-
-    // Floating point formats have to query the renderer for support
-    //                               | Internal format        |                              | R | G | B | A |S | Format          | Type                     | Comp    | SRGB | Color renderable                                                                                           | Texture filterable                                                                                   | Supported                                     |
-    //                               |                        |                              |   |   |   |   |  |                 |                          | type    |      |                                                                                                            |                                                                                                      |                                               |
-    map.insert(InternalFormatInfoPair(GL_R16F_EXT,             InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED,           GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
-    map.insert(InternalFormatInfoPair(GL_R32F_EXT,             InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED,           GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
-    map.insert(InternalFormatInfoPair(GL_RG16F_EXT,            InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG,            GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
-    map.insert(InternalFormatInfoPair(GL_RG32F_EXT,            InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG,            GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
-    map.insert(InternalFormatInfoPair(GL_RGB16F_EXT,           InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB,           GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>)));
-    map.insert(InternalFormatInfoPair(GL_RGB32F_EXT,           InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB,           GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>)));
-    map.insert(InternalFormatInfoPair(GL_RGBA16F_EXT,          InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,          GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>)));
-    map.insert(InternalFormatInfoPair(GL_RGBA32F_EXT,          InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,          GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>)));
-
-    // Depth and stencil formats
-    //                               | Internal format        |                                      | D |S |X | Format              | Type                     | Internal format     | Depth          | Stencil         | Supported                                  |
-    //                               |                        |                                      |   |  |  |                     |                          | type                | renderable     | renderable      |                                            |
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES,InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT,   GL_UNSIGNED_INT,           GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  CheckSupport<&Context::supportsDepthTextures>)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8_OES, InternalFormatInfo::DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES,  GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, CheckSupport<&Context::supportsDepthTextures>)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,    InternalFormatInfo::DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT,   GL_UNSIGNED_SHORT,         GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,       InternalFormatInfo::DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, NeverSupported,  AlwaysSupported, AlwaysSupported)));
-
-    // Unsized formats
-    //                               | Internal format        |                                 | Format              | Supported     |
-    map.insert(InternalFormatInfoPair(GL_ALPHA,                InternalFormatInfo::UnsizedFormat(GL_ALPHA,             AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE,            InternalFormatInfo::UnsizedFormat(GL_LUMINANCE,         AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA,      InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA,   AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RED_EXT,              InternalFormatInfo::UnsizedFormat(GL_RED_EXT,           CheckSupport<&Context::supportsRGTextures>)));
-    map.insert(InternalFormatInfoPair(GL_RG_EXT,               InternalFormatInfo::UnsizedFormat(GL_RG_EXT,            CheckSupport<&Context::supportsRGTextures>)));
-    map.insert(InternalFormatInfoPair(GL_RGB,                  InternalFormatInfo::UnsizedFormat(GL_RGB,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA,                 InternalFormatInfo::UnsizedFormat(GL_RGBA,              AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_BGRA_EXT,             InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT,          AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT,      InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT,   AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL_OES,    InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL_OES, AlwaysSupported)));
-
-    // Luminance alpha formats from GL_EXT_texture_storage
-    //                               | Internal format          |                              | L | A | Format                   | Type                     | Component type        | Supported     |
-    map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             InternalFormatInfo::LUMAFormat( 0,  8, GL_ALPHA,                  GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         InternalFormatInfo::LUMAFormat( 8,  0, GL_LUMINANCE,              GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA,                  GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       InternalFormatInfo::LUMAFormat(32,  0, GL_LUMINANCE,              GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA,                  GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       InternalFormatInfo::LUMAFormat(16,  0, GL_LUMINANCE,              GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  InternalFormatInfo::LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA,        GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA,        GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA,        GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
-
-    // From GL_EXT_texture_compression_dxt1
-    //                               | Internal format                   |                                    |W |H | BS |CC|Format                             | Type            | SRGB | Supported                                  |
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT1Textures>)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   InternalFormatInfo::CompressedFormat(4, 4,  64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT1Textures>)));
-
-    // From GL_ANGLE_texture_compression_dxt3
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT3Textures>)));
-
-    // From GL_ANGLE_texture_compression_dxt5
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT5Textures>)));
-
-    return map;
-}
-
-static bool GetInternalFormatInfo(GLenum internalFormat, GLuint clientVersion, InternalFormatInfo *outFormatInfo)
-{
-    const InternalFormatInfoMap* map = NULL;
-
-    if (clientVersion == 2)
-    {
-        static const InternalFormatInfoMap formatMap = BuildES2InternalFormatInfoMap();
-        map = &formatMap;
-    }
-    else if (clientVersion == 3)
-    {
-        static const InternalFormatInfoMap formatMap = BuildES3InternalFormatInfoMap();
-        map = &formatMap;
-    }
-    else
-    {
-        UNREACHABLE();
-    }
-
-    InternalFormatInfoMap::const_iterator iter = map->find(internalFormat);
-    if (iter != map->end())
-    {
-        if (outFormatInfo)
-        {
-            *outFormatInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-typedef std::set<GLenum> FormatSet;
-
-static FormatSet BuildES2ValidFormatSet()
-{
-    static const FormatMap &formatMap = GetFormatMap(2);
-
-    FormatSet set;
-
-    for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++)
-    {
-        const FormatTypePair& formatPair = i->first;
-        set.insert(formatPair.first);
-    }
-
-    return set;
-}
-
-static FormatSet BuildES3ValidFormatSet()
-{
-    static const ES3FormatSet &formatSet = GetES3FormatSet();
-
-    FormatSet set;
-
-    for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++)
-    {
-        const FormatInfo& formatInfo = *i;
-        set.insert(formatInfo.mFormat);
-    }
-
-    return set;
-}
-
-typedef std::set<GLenum> TypeSet;
-
-static TypeSet BuildES2ValidTypeSet()
-{
-    static const FormatMap &formatMap = GetFormatMap(2);
-
-    TypeSet set;
-
-    for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++)
-    {
-        const FormatTypePair& formatPair = i->first;
-        set.insert(formatPair.second);
-    }
-
-    return set;
-}
-
-static TypeSet BuildES3ValidTypeSet()
-{
-    static const ES3FormatSet &formatSet = GetES3FormatSet();
-
-    TypeSet set;
-
-    for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++)
-    {
-        const FormatInfo& formatInfo = *i;
-        set.insert(formatInfo.mType);
-    }
-
-    return set;
-}
-
-struct EffectiveInternalFormatInfo
-{
-    GLenum mEffectiveFormat;
-    GLenum mDestFormat;
-    GLuint mMinRedBits;
-    GLuint mMaxRedBits;
-    GLuint mMinGreenBits;
-    GLuint mMaxGreenBits;
-    GLuint mMinBlueBits;
-    GLuint mMaxBlueBits;
-    GLuint mMinAlphaBits;
-    GLuint mMaxAlphaBits;
-
-    EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
-                                GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
-                                GLuint minAlphaBits, GLuint maxAlphaBits)
-        : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
-          mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
-          mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
-          mMaxAlphaBits(maxAlphaBits) {};
-};
-
-typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
-
-static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
-{
-    EffectiveInternalFormatList list;
-
-    // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
-    //                                                    linear source buffer component sizes.
-    //                                                                            | Source channel min/max sizes |
-    //                                         Effective Internal Format |  N/A   |  R   |  G   |  B   |  A      |
-    list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_NONE, 0,  0, 0,  0, 0,  0, 1, 8));
-    list.push_back(EffectiveInternalFormatInfo(GL_R8,                      GL_NONE, 1,  8, 0,  0, 0,  0, 0, 0));
-    list.push_back(EffectiveInternalFormatInfo(GL_RG8,                     GL_NONE, 1,  8, 1,  8, 0,  0, 0, 0));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_NONE, 1,  5, 1,  6, 1,  5, 0, 0));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_NONE, 6,  8, 7,  8, 6,  8, 0, 0));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_NONE, 1,  4, 1,  4, 1,  4, 1, 4));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_NONE, 5,  5, 5,  5, 5,  5, 1, 1));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_NONE, 5,  8, 5,  8, 5,  8, 2, 8));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2,                GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
-
-    return list;
-}
-
-
-static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
-{
-    EffectiveInternalFormatList list;
-
-    // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
-    //                                                    linear source buffer component sizes.
-    //                                                                                        |          Source channel min/max sizes            |
-    //                                         Effective Internal Format |    Dest Format     |     R     |      G     |      B     |      A     |
-    list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_ALPHA,           0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
-    list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT,          GL_LUMINANCE,       1,        8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
-    list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT,   GL_LUMINANCE_ALPHA, 1,        8, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_RGB,             1,        5, 1,        6, 1,        5, 0, UINT_MAX));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_RGB,             6,        8, 7,        8, 6,        8, 0, UINT_MAX));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_RGBA,            1,        4, 1,        4, 1,        4, 1,        4));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_RGBA,            5,        5, 5,        5, 5,        5, 1,        1));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_RGBA,            5,        8, 5,        8, 5,        8, 5,        8));
-
-    return list;
-}
-
-static bool GetEffectiveInternalFormat(const InternalFormatInfo &srcFormat, const InternalFormatInfo &destFormat,
-                                       GLuint clientVersion, GLenum *outEffectiveFormat)
-{
-    const EffectiveInternalFormatList *list = NULL;
-    GLenum targetFormat = GL_NONE;
-
-    if (gl::IsSizedInternalFormat(destFormat.mFormat, clientVersion))
-    {
-        static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
-        list = &sizedList;
-    }
-    else
-    {
-        static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
-        list = &unsizedList;
-        targetFormat = destFormat.mFormat;
-    }
-
-    for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
-    {
-        const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
-        if ((formatInfo.mDestFormat == targetFormat) &&
-            (formatInfo.mMinRedBits   <= srcFormat.mRedBits   && formatInfo.mMaxRedBits   >= srcFormat.mRedBits)   &&
-            (formatInfo.mMinGreenBits <= srcFormat.mGreenBits && formatInfo.mMaxGreenBits >= srcFormat.mGreenBits) &&
-            (formatInfo.mMinBlueBits  <= srcFormat.mBlueBits  && formatInfo.mMaxBlueBits  >= srcFormat.mBlueBits)  &&
-            (formatInfo.mMinAlphaBits <= srcFormat.mAlphaBits && formatInfo.mMaxAlphaBits >= srcFormat.mAlphaBits))
-        {
-            *outEffectiveFormat = formatInfo.mEffectiveFormat;
-            return true;
-        }
-    }
-
-    return false;
-}
-
-struct CopyConversion
-{
-    GLenum mTextureFormat;
-    GLenum mFramebufferFormat;
-
-    CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
-        : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
-
-    bool operator<(const CopyConversion& other) const
-    {
-        return memcmp(this, &other, sizeof(CopyConversion)) < 0;
-    }
-};
-
-typedef std::set<CopyConversion> CopyConversionSet;
-
-static CopyConversionSet BuildValidES3CopyTexImageCombinations()
-{
-    CopyConversionSet set;
-
-    // From ES 3.0.1 spec, table 3.15
-    set.insert(CopyConversion(GL_ALPHA,           GL_RGBA));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_RED));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_RG));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_RGB));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_RGBA));
-    set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
-    set.insert(CopyConversion(GL_RED,             GL_RED));
-    set.insert(CopyConversion(GL_RED,             GL_RG));
-    set.insert(CopyConversion(GL_RED,             GL_RGB));
-    set.insert(CopyConversion(GL_RED,             GL_RGBA));
-    set.insert(CopyConversion(GL_RG,              GL_RG));
-    set.insert(CopyConversion(GL_RG,              GL_RGB));
-    set.insert(CopyConversion(GL_RG,              GL_RGBA));
-    set.insert(CopyConversion(GL_RGB,             GL_RGB));
-    set.insert(CopyConversion(GL_RGB,             GL_RGBA));
-    set.insert(CopyConversion(GL_RGBA,            GL_RGBA));
-
-    // Necessary for ANGLE back-buffers
-    set.insert(CopyConversion(GL_ALPHA,           GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_RED,             GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_RG,              GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_RGB,             GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_RGBA,            GL_BGRA_EXT));
-
-    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RED_INTEGER));
-    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RG_INTEGER));
-    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RGB_INTEGER));
-    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RGBA_INTEGER));
-    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RG_INTEGER));
-    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RGB_INTEGER));
-    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RGBA_INTEGER));
-    set.insert(CopyConversion(GL_RGB_INTEGER,     GL_RGB_INTEGER));
-    set.insert(CopyConversion(GL_RGB_INTEGER,     GL_RGBA_INTEGER));
-    set.insert(CopyConversion(GL_RGBA_INTEGER,    GL_RGBA_INTEGER));
-
-    return set;
-}
-
-bool IsValidInternalFormat(GLenum internalFormat, const Context *context)
-{
-    if (!context)
-    {
-        return false;
-    }
-
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
-    {
-        ASSERT(internalFormatInfo.mSupportFunction != NULL);
-        return internalFormatInfo.mSupportFunction(context);
-    }
-    else
-    {
-        return false;
-    }
-}
-
-bool IsValidFormat(GLenum format, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        static const FormatSet formatSet = BuildES2ValidFormatSet();
-        return formatSet.find(format) != formatSet.end();
-    }
-    else if (clientVersion == 3)
-    {
-        static const FormatSet formatSet = BuildES3ValidFormatSet();
-        return formatSet.find(format) != formatSet.end();
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsValidType(GLenum type, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        static const TypeSet typeSet = BuildES2ValidTypeSet();
-        return typeSet.find(type) != typeSet.end();
-    }
-    else if (clientVersion == 3)
-    {
-        static const TypeSet typeSet = BuildES3ValidTypeSet();
-        return typeSet.find(type) != typeSet.end();
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        static const FormatMap &formats = GetFormatMap(clientVersion);
-        FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
-
-        return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second.mInternalFormat));
-    }
-    else if (clientVersion == 3)
-    {
-        static const ES3FormatSet &formats = GetES3FormatSet();
-        return formats.find(FormatInfo(internalFormat, format, type)) != formats.end();
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion)
-{
-    InternalFormatInfo textureInternalFormatInfo;
-    InternalFormatInfo framebufferInternalFormatInfo;
-    if (GetInternalFormatInfo(textureInternalFormat, clientVersion, &textureInternalFormatInfo) &&
-        GetInternalFormatInfo(frameBufferInternalFormat, clientVersion, &framebufferInternalFormatInfo))
-    {
-        if (clientVersion == 2)
-        {
-            UNIMPLEMENTED();
-            return false;
-        }
-        else if (clientVersion == 3)
-        {
-            static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
-            const CopyConversion conversion = CopyConversion(textureInternalFormatInfo.mFormat,
-                                                             framebufferInternalFormatInfo.mFormat);
-            if (conversionSet.find(conversion) != conversionSet.end())
-            {
-                // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
-                // must both be signed, unsigned, or fixed point and both source and destinations
-                // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
-                // conversion between fixed and floating point.
-
-                if ((textureInternalFormatInfo.mColorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB))
-                {
-                    return false;
-                }
-
-                if (((textureInternalFormatInfo.mComponentType == GL_INT) != (framebufferInternalFormatInfo.mComponentType == GL_INT)) ||
-                    ((textureInternalFormatInfo.mComponentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.mComponentType == GL_UNSIGNED_INT)))
-                {
-                    return false;
-                }
-
-                if (gl::IsFloatOrFixedComponentType(textureInternalFormatInfo.mComponentType) &&
-                    !gl::IsFloatOrFixedComponentType(framebufferInternalFormatInfo.mComponentType))
-                {
-                    return false;
-                }
-
-                // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
-                // The effective internal format of the source buffer is determined with the following rules applied in order:
-                //    * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
-                //      effective internal format is the source buffer's sized internal format.
-                //    * If the source buffer is a texture that was created with an unsized base internal format, then the
-                //      effective internal format is the source image array's effective internal format, as specified by table
-                //      3.12, which is determined from the <format> and <type> that were used when the source image array was
-                //      specified by TexImage*.
-                //    * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
-                //      Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
-                //      with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
-                //      FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
-                //      is SRGB.
-                InternalFormatInfo sourceEffectiveFormat;
-                if (readBufferHandle != 0)
-                {
-                    // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
-                    if (gl::IsSizedInternalFormat(framebufferInternalFormatInfo.mFormat, clientVersion))
-                    {
-                        sourceEffectiveFormat = framebufferInternalFormatInfo;
-                    }
-                    else
-                    {
-                        // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
-                        // texture. We can use the same table we use when creating textures to get its effective sized format.
-                        GLenum effectiveFormat = gl::GetSizedInternalFormat(framebufferInternalFormatInfo.mFormat,
-                                                                            framebufferInternalFormatInfo.mType, clientVersion);
-                        gl::GetInternalFormatInfo(effectiveFormat, clientVersion, &sourceEffectiveFormat);
-                    }
-                }
-                else
-                {
-                    // The effective internal format must be derived from the source framebuffer's channel sizes.
-                    // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
-                    if (framebufferInternalFormatInfo.mColorEncoding == GL_LINEAR)
-                    {
-                        GLenum effectiveFormat;
-                        if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, clientVersion, &effectiveFormat))
-                        {
-                            gl::GetInternalFormatInfo(effectiveFormat, clientVersion, &sourceEffectiveFormat);
-                        }
-                        else
-                        {
-                            return false;
-                        }
-                    }
-                    else if (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB)
-                    {
-                        // SRGB buffers can only be copied to sized format destinations according to table 3.18
-                        if (gl::IsSizedInternalFormat(textureInternalFormat, clientVersion) &&
-                            (framebufferInternalFormatInfo.mRedBits   >= 1 && framebufferInternalFormatInfo.mRedBits   <= 8) &&
-                            (framebufferInternalFormatInfo.mGreenBits >= 1 && framebufferInternalFormatInfo.mGreenBits <= 8) &&
-                            (framebufferInternalFormatInfo.mBlueBits  >= 1 && framebufferInternalFormatInfo.mBlueBits  <= 8) &&
-                            (framebufferInternalFormatInfo.mAlphaBits >= 1 && framebufferInternalFormatInfo.mAlphaBits <= 8))
-                        {
-                            gl::GetInternalFormatInfo(GL_SRGB8_ALPHA8, clientVersion, &sourceEffectiveFormat);
-                        }
-                        else
-                        {
-                            return false;
-                        }
-                    }
-                    else
-                    {
-                        UNREACHABLE();
-                    }
-                }
-
-                if (gl::IsSizedInternalFormat(textureInternalFormatInfo.mFormat, clientVersion))
-                {
-                    // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
-                    // component sizes of the source and destination formats must exactly match
-                    if (textureInternalFormatInfo.mRedBits != sourceEffectiveFormat.mRedBits ||
-                        textureInternalFormatInfo.mGreenBits != sourceEffectiveFormat.mGreenBits ||
-                        textureInternalFormatInfo.mBlueBits != sourceEffectiveFormat.mBlueBits ||
-                        textureInternalFormatInfo.mAlphaBits != sourceEffectiveFormat.mAlphaBits)
-                    {
-                        return false;
-                    }
-                }
-
-
-                return true; // A conversion function exists, and no rule in the specification has precluded conversion
-                             // between these formats.
-            }
-
-            return false;
-        }
-        else
-        {
-            UNREACHABLE();
-            return false;
-        }
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsSizedInternalFormat(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mPixelBits > 0;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-GLenum GetSizedInternalFormat(GLenum format, GLenum type, GLuint clientVersion)
-{
-    const FormatMap &formats = GetFormatMap(clientVersion);
-    FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
-    return (iter != formats.end()) ? iter->second.mInternalFormat : GL_NONE;
-}
-
-GLuint GetPixelBytes(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mPixelBits / 8;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetAlphaBits(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mAlphaBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetRedBits(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mRedBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetGreenBits(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mGreenBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetBlueBits(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mBlueBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetLuminanceBits(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mLuminanceBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetDepthBits(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mDepthBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetStencilBits(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mStencilBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetTypeBytes(GLenum type)
-{
-    TypeInfo typeInfo;
-    if (GetTypeInfo(type, &typeInfo))
-    {
-        return typeInfo.mTypeBytes;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-bool IsSpecialInterpretationType(GLenum type)
-{
-    TypeInfo typeInfo;
-    if (GetTypeInfo(type, &typeInfo))
-    {
-        return typeInfo.mSpecialInterpretation;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsFloatOrFixedComponentType(GLenum type)
-{
-    if (type == GL_UNSIGNED_NORMALIZED ||
-        type == GL_SIGNED_NORMALIZED ||
-        type == GL_FLOAT)
-    {
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-GLenum GetFormat(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mFormat;
-    }
-    else
-    {
-        UNREACHABLE();
-        return GL_NONE;
-    }
-}
-
-GLenum GetType(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mType;
-    }
-    else
-    {
-        UNREACHABLE();
-        return GL_NONE;
-    }
-}
-
-GLenum GetComponentType(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mComponentType;
-    }
-    else
-    {
-        UNREACHABLE();
-        return GL_NONE;
-    }
-}
-
-GLuint GetComponentCount(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mComponentCount;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-GLenum GetColorEncoding(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mColorEncoding;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsColorRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsColorRenderable(NULL, renderer);
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsColorRenderingSupported(GLenum internalFormat, const Context *context)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsColorRenderable(context, NULL);
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsTextureFilteringSupported(GLenum internalFormat, const rx::Renderer *renderer)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsTextureFilterable(NULL, renderer);
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsTextureFilteringSupported(GLenum internalFormat, const Context *context)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsTextureFilterable(context, NULL);
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsDepthRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsDepthRenderable(NULL, renderer);
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsDepthRenderingSupported(GLenum internalFormat, const Context *context)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsDepthRenderable(context, NULL);
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsStencilRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsStencilRenderable(NULL, renderer);
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsStencilRenderingSupported(GLenum internalFormat, const Context *context)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsStencilRenderable(context, NULL);
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLint alignment)
+GLuint InternalFormat::computeRowPitch(GLenum type, GLsizei width, GLint alignment) const
 {
     ASSERT(alignment > 0 && isPow2(alignment));
-    return rx::roundUp(GetBlockSize(internalFormat, type, clientVersion, width, 1), static_cast<GLuint>(alignment));
+    return rx::roundUp(computeBlockSize(type, width, 1), static_cast<GLuint>(alignment));
 }
 
-GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height, GLint alignment)
+GLuint InternalFormat::computeDepthPitch(GLenum type, GLsizei width, GLsizei height, GLint alignment) const
 {
-    return GetRowPitch(internalFormat, type, clientVersion, width, alignment) * height;
+    return computeRowPitch(type, width, alignment) * height;
 }
 
-GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height)
+GLuint InternalFormat::computeBlockSize(GLenum type, GLsizei width, GLsizei height) const
 {
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
+    if (compressed)
     {
-        if (internalFormatInfo.mIsCompressed)
+        GLsizei numBlocksWide = (width + compressedBlockWidth - 1) / compressedBlockWidth;
+        GLsizei numBlocksHight = (height + compressedBlockHeight - 1) / compressedBlockHeight;
+        return (pixelBytes * numBlocksWide * numBlocksHight);
+    }
+    else
+    {
+        const Type &typeInfo = GetTypeInfo(type);
+        if (typeInfo.specialInterpretation)
         {
-            GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth;
-            GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight;
-
-            return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
+            return typeInfo.bytes * width * height;
         }
         else
         {
-            TypeInfo typeInfo;
-            if (GetTypeInfo(type, &typeInfo))
-            {
-                if (typeInfo.mSpecialInterpretation)
-                {
-                    return typeInfo.mTypeBytes * width * height;
-                }
-                else
-                {
-                    return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height;
-                }
-            }
-            else
-            {
-                UNREACHABLE();
-                return 0;
-            }
+            return componentCount * typeInfo.bytes * width * height;
         }
     }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
 }
 
-bool IsFormatCompressed(GLenum internalFormat, GLuint clientVersion)
+GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
 {
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsCompressed;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
+    const InternalFormat& formatInfo = GetInternalFormatInfo(internalFormat);
+    return (formatInfo.pixelBytes > 0) ? internalFormat : GetFormatTypeInfo(internalFormat, type).internalFormat;
 }
 
-GLuint GetCompressedBlockWidth(GLenum internalFormat, GLuint clientVersion)
+const FormatSet &GetAllSizedInternalFormats()
 {
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mCompressedBlockWidth;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetCompressedBlockHeight(GLenum internalFormat, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
-    {
-        return internalFormatInfo.mCompressedBlockHeight;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type, GLuint clientVersion)
-{
-    static const FormatMap &formats = GetFormatMap(clientVersion);
-    FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
-    return (iter != formats.end()) ? iter->second.mColorWriteFunction : NULL;
+    static FormatSet formatSet = BuildAllSizedInternalFormatSet();
+    return formatSet;
 }
 
 }
diff --git a/src/libGLESv2/formatutils.h b/src/libGLESv2/formatutils.h
index 004c8ed..25106a5 100644
--- a/src/libGLESv2/formatutils.h
+++ b/src/libGLESv2/formatutils.h
@@ -9,90 +9,98 @@
 #ifndef LIBGLESV2_FORMATUTILS_H_
 #define LIBGLESV2_FORMATUTILS_H_
 
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
+#include "libGLESv2/Caps.h"
 #include "libGLESv2/angletypes.h"
 
-typedef void (*MipGenerationFunction)(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                                      const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                                      unsigned char *destData, int destRowPitch, int destDepthPitch);
+#include "angle_gl.h"
 
-typedef void (*LoadImageFunction)(int width, int height, int depth,
-                                  const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                  void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
+#include <cstddef>
+#include <cstdint>
 
-typedef void (*InitializeTextureDataFunction)(int width, int height, int depth,
-                                              void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
+typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                                      const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                                      uint8_t *destData, size_t destRowPitch, size_t destDepthPitch);
 
-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 (*LoadImageFunction)(size_t width, size_t height, size_t depth,
+                                  const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                                  uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
 
-typedef void (*VertexCopyFunction)(const void *input, size_t stride, size_t count, void *output);
+typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth,
+                                              uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
 
-namespace rx
-{
+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);
 
-class Renderer;
-
-}
+typedef void (*VertexCopyFunction)(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
 
 namespace gl
 {
 
-class Context;
+struct FormatType
+{
+    FormatType();
 
-bool IsValidInternalFormat(GLenum internalFormat, const Context *context);
-bool IsValidFormat(GLenum format, GLuint clientVersion);
-bool IsValidType(GLenum type, GLuint clientVersion);
+    GLenum internalFormat;
+    ColorWriteFunction colorWriteFunction;
+};
+const FormatType &GetFormatTypeInfo(GLenum format, GLenum type);
 
-bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, GLuint clientVersion);
-bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion);
+struct Type
+{
+    Type();
 
-bool IsSizedInternalFormat(GLenum internalFormat, GLuint clientVersion);
-GLenum GetSizedInternalFormat(GLenum format, GLenum type, GLuint clientVersion);
+    GLuint bytes;
+    bool specialInterpretation;
+};
+const Type &GetTypeInfo(GLenum type);
 
-GLuint GetPixelBytes(GLenum internalFormat, GLuint clientVersion);
-GLuint GetAlphaBits(GLenum internalFormat, GLuint clientVersion);
-GLuint GetRedBits(GLenum internalFormat, GLuint clientVersion);
-GLuint GetGreenBits(GLenum internalFormat, GLuint clientVersion);
-GLuint GetBlueBits(GLenum internalFormat, GLuint clientVersion);
-GLuint GetLuminanceBits(GLenum internalFormat, GLuint clientVersion);
-GLuint GetDepthBits(GLenum internalFormat, GLuint clientVersion);
-GLuint GetStencilBits(GLenum internalFormat, GLuint clientVersion);
+struct InternalFormat
+{
+    InternalFormat();
 
-GLuint GetTypeBytes(GLenum type);
-bool IsSpecialInterpretationType(GLenum type);
-bool IsFloatOrFixedComponentType(GLenum type);
+    GLuint redBits;
+    GLuint greenBits;
+    GLuint blueBits;
 
-GLenum GetFormat(GLenum internalFormat, GLuint clientVersion);
-GLenum GetType(GLenum internalFormat, GLuint clientVersion);
+    GLuint luminanceBits;
 
-GLenum GetComponentType(GLenum internalFormat, GLuint clientVersion);
-GLuint GetComponentCount(GLenum internalFormat, GLuint clientVersion);
-GLenum GetColorEncoding(GLenum internalFormat, GLuint clientVersion);
+    GLuint alphaBits;
+    GLuint sharedBits;
 
-bool IsColorRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer);
-bool IsColorRenderingSupported(GLenum internalFormat, const Context *context);
-bool IsTextureFilteringSupported(GLenum internalFormat, const rx::Renderer *renderer);
-bool IsTextureFilteringSupported(GLenum internalFormat, const Context *context);
-bool IsDepthRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer);
-bool IsDepthRenderingSupported(GLenum internalFormat, const Context *context);
-bool IsStencilRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer);
-bool IsStencilRenderingSupported(GLenum internalFormat, const Context *context);
+    GLuint depthBits;
+    GLuint stencilBits;
 
-GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLint alignment);
-GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height, GLint alignment);
-GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height);
+    GLuint pixelBytes;
 
-bool IsFormatCompressed(GLenum internalFormat, GLuint clientVersion);
-GLuint GetCompressedBlockWidth(GLenum internalFormat, GLuint clientVersion);
-GLuint GetCompressedBlockHeight(GLenum internalFormat, GLuint clientVersion);
+    GLuint componentCount;
 
-ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type, GLuint clientVersion);
+    bool compressed;
+    GLuint compressedBlockWidth;
+    GLuint compressedBlockHeight;
+
+    GLenum format;
+    GLenum type;
+
+    GLenum componentType;
+    GLenum colorEncoding;
+
+    typedef bool (*SupportCheckFunction)(GLuint, const Extensions &);
+    SupportCheckFunction textureSupport;
+    SupportCheckFunction renderSupport;
+    SupportCheckFunction filterSupport;
+
+    GLuint computeRowPitch(GLenum type, GLsizei width, GLint alignment) const;
+    GLuint computeDepthPitch(GLenum type, GLsizei width, GLsizei height, GLint alignment) const;
+    GLuint computeBlockSize(GLenum type, GLsizei width, GLsizei height) const;
+};
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat);
+
+GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
+
+typedef std::set<GLenum> FormatSet;
+const FormatSet &GetAllSizedInternalFormats();
 
 }
 
-#endif LIBGLESV2_FORMATUTILS_H_
+#endif // LIBGLESV2_FORMATUTILS_H_
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index bf3cd0f..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"
@@ -22,7 +21,9 @@
 #include "libGLESv2/Query.h"
 #include "libGLESv2/Context.h"
 #include "libGLESv2/VertexArray.h"
+#include "libGLESv2/VertexAttribute.h"
 #include "libGLESv2/TransformFeedback.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "libGLESv2/validationES.h"
 #include "libGLESv2/validationES2.h"
@@ -38,23 +39,16 @@
 {
     EVENT("(GLenum texture = 0x%X)", texture);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
         {
-            if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            context->setActiveSampler(texture - GL_TEXTURE0);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->getState().setActiveSampler(texture - GL_TEXTURE0);
     }
 }
 
@@ -62,48 +56,45 @@
 {
     EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-            gl::Shader *shaderObject = context->getShader(shader);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            if (!shaderObject)
+            else
             {
-                if (context->getProgram(shader))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-            }
-
-            if (!programObject->attachShader(shaderObject))
-            {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!shaderObject)
+        {
+            if (context->getProgram(shader))
+            {
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
+            }
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+        }
+
+        if (!programObject->attachShader(shaderObject))
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
     }
 }
 
@@ -111,23 +102,20 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateBeginQuery(context, target, id))
         {
-            if (!ValidateBeginQuery(context, target, id))
-            {
-                return;
-            }
-
-            context->beginQuery(target, id);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Error error = context->beginQuery(target, id);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -135,42 +123,38 @@
 {
     EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            if (strncmp(name, "gl_", 3) == 0)
+            else
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
-
-            programObject->bindAttributeLocation(index, name);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (strncmp(name, "gl_", 3) == 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        programObject->bindAttributeLocation(index, name);
     }
 }
 
@@ -178,51 +162,46 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidBufferTarget(context, target))
         {
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            switch (target)
-            {
-              case GL_ARRAY_BUFFER:
-                context->bindArrayBuffer(buffer);
-                return;
-              case GL_ELEMENT_ARRAY_BUFFER:
-                context->bindElementArrayBuffer(buffer);
-                return;
-              case GL_COPY_READ_BUFFER:
-                context->bindCopyReadBuffer(buffer);
-                return;
-              case GL_COPY_WRITE_BUFFER:
-                context->bindCopyWriteBuffer(buffer);
-                return;
-              case GL_PIXEL_PACK_BUFFER:
-                context->bindPixelPackBuffer(buffer);
-                return;
-              case GL_PIXEL_UNPACK_BUFFER:
-                context->bindPixelUnpackBuffer(buffer);
-                return;
-              case GL_UNIFORM_BUFFER:
-                context->bindGenericUniformBuffer(buffer);
-                return;
-              case GL_TRANSFORM_FEEDBACK_BUFFER:
-                context->bindGenericTransformFeedbackBuffer(buffer);
-                return;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (target)
+        {
+          case GL_ARRAY_BUFFER:
+            context->bindArrayBuffer(buffer);
+            return;
+          case GL_ELEMENT_ARRAY_BUFFER:
+            context->bindElementArrayBuffer(buffer);
+            return;
+          case GL_COPY_READ_BUFFER:
+            context->bindCopyReadBuffer(buffer);
+            return;
+          case GL_COPY_WRITE_BUFFER:
+            context->bindCopyWriteBuffer(buffer);
+            return;
+          case GL_PIXEL_PACK_BUFFER:
+            context->bindPixelPackBuffer(buffer);
+            return;
+          case GL_PIXEL_UNPACK_BUFFER:
+            context->bindPixelUnpackBuffer(buffer);
+            return;
+          case GL_UNIFORM_BUFFER:
+            context->bindGenericUniformBuffer(buffer);
+            return;
+          case GL_TRANSFORM_FEEDBACK_BUFFER:
+            context->bindGenericTransformFeedbackBuffer(buffer);
+            return;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -230,31 +209,24 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
         {
-            if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
-            {
-                context->bindReadFramebuffer(framebuffer);
-            }
-            
-            if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
-            {
-                context->bindDrawFramebuffer(framebuffer);
-            }
+            context->bindReadFramebuffer(framebuffer);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+        {
+            context->bindDrawFramebuffer(framebuffer);
+        }
     }
 }
 
@@ -262,23 +234,16 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->bindRenderbuffer(renderbuffer);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->bindRenderbuffer(renderbuffer);
     }
 }
 
@@ -286,49 +251,38 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Texture *textureObject = context->getTexture(texture);
 
-        if (context)
+        if (textureObject && textureObject->getTarget() != target && texture != 0)
         {
-            gl::Texture *textureObject = context->getTexture(texture);
-
-            if (textureObject && textureObject->getTarget() != target && texture != 0)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                context->bindTexture2D(texture);
-                return;
-              case GL_TEXTURE_CUBE_MAP:
-                context->bindTextureCubeMap(texture);
-                return;
-              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->bindTexture2DArray(texture);
-                return;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+          case GL_TEXTURE_CUBE_MAP:
+            break;
+
+          case GL_TEXTURE_3D:
+          case GL_TEXTURE_2D_ARRAY:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        context->bindTexture(target, texture);
     }
 }
 
@@ -337,18 +291,11 @@
     EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
           red, green, blue, alpha);
 
-    try
-    {
-        gl::Context* context = gl::getNonLostContext();
+    gl::Context* context = gl::getNonLostContext();
 
-        if (context)
-        {
-            context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
-        }
-    }
-    catch (...)
+    if (context)
     {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
     }
 }
 
@@ -361,10 +308,9 @@
 {
     EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
         switch (modeRGB)
         {
           case GL_FUNC_ADD:
@@ -375,7 +321,8 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (modeAlpha)
@@ -388,17 +335,11 @@
             break;
 
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        if (context)
-        {
-            context->setBlendEquation(modeRGB, modeAlpha);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setBlendEquation(modeRGB, modeAlpha);
     }
 }
 
@@ -412,10 +353,9 @@
     EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
           srcRGB, dstRGB, srcAlpha, dstAlpha);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
         switch (srcRGB)
         {
           case GL_ZERO:
@@ -434,8 +374,10 @@
           case GL_ONE_MINUS_CONSTANT_ALPHA:
           case GL_SRC_ALPHA_SATURATE:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+              context->recordError(gl::Error(GL_INVALID_ENUM));
+              return;
         }
 
         switch (dstRGB)
@@ -457,14 +399,16 @@
             break;
 
           case GL_SRC_ALPHA_SATURATE:
-            if (!context || context->getClientVersion() < 3)
+            if (context->getClientVersion() < 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;
         }
 
         switch (srcAlpha)
@@ -485,8 +429,10 @@
           case GL_ONE_MINUS_CONSTANT_ALPHA:
           case GL_SRC_ALPHA_SATURATE:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+              context->recordError(gl::Error(GL_INVALID_ENUM));
+              return;
         }
 
         switch (dstAlpha)
@@ -508,14 +454,16 @@
             break;
 
           case GL_SRC_ALPHA_SATURATE:
-            if (!context || context->getClientVersion() < 3)
+            if (context->getClientVersion() < 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;
         }
 
         bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
@@ -527,17 +475,11 @@
         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);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (context)
-        {
-            context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
     }
 }
 
@@ -546,15 +488,15 @@
     EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
           target, size, data, usage);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (size < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
         switch (usage)
         {
           case GL_STREAM_DRAW:
@@ -568,36 +510,38 @@
           case GL_STATIC_COPY:
           case GL_DYNAMIC_READ:
           case GL_DYNAMIC_COPY:
-            if (context && context->getClientVersion() < 3)
+            if (context->getClientVersion() < 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;
         }
 
-        if (context)
+        if (!gl::ValidBufferTarget(context, target))
         {
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (!buffer)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            buffer->bufferData(data, size, usage);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (!buffer)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        gl::Error error = buffer->bufferData(data, size, usage);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -606,11 +550,13 @@
     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
           target, offset, size, data);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (size < 0 || offset < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         if (data == NULL)
@@ -618,44 +564,45 @@
             return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidBufferTarget(context, target))
         {
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (!buffer)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (buffer->mapped())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // Check for possible overflow of size + offset
-            if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset))
-            {
-                return gl::error(GL_OUT_OF_MEMORY);
-            }
-
-            if (size + offset > buffer->size())
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            buffer->bufferSubData(data, size, offset);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (!buffer)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (buffer->isMapped())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        // Check for possible overflow of size + offset
+        if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset))
+        {
+            context->recordError(gl::Error(GL_OUT_OF_MEMORY));
+            return;
+        }
+
+        if (size + offset > buffer->getSize())
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        gl::Error error = buffer->bufferSubData(data, size, offset);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -663,25 +610,18 @@
 {
     EVENT("(GLenum target = 0x%X)", target);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (!gl::ValidFramebufferTarget(target))
         {
-            return gl::error(GL_INVALID_ENUM, 0);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return 0;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
-            ASSERT(framebuffer);
-            return framebuffer->completeness();
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, 0);
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+        ASSERT(framebuffer);
+        return framebuffer->completeness();
     }
 
     return 0;
@@ -691,30 +631,29 @@
 {
     EVENT("(GLbitfield mask = 0x%X)", mask);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
 
-        if (context)
+        if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
         {
-            gl::Framebuffer *framebufferObject = context->getDrawFramebuffer();
-
-            if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
-            {
-                return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
-            }
-
-            if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            context->clear(mask);
+            context->recordError(gl::Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        gl::Error error = context->clear(mask);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -723,18 +662,10 @@
     EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
           red, green, blue, alpha);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setClearColor(red, green, blue, alpha);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setClearColor(red, green, blue, alpha);
     }
 }
 
@@ -742,18 +673,10 @@
 {
     EVENT("(GLclampf depth = %f)", depth);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setClearDepth(depth);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setClearDepth(depth);
     }
 }
 
@@ -761,18 +684,10 @@
 {
     EVENT("(GLint s = %d)", s);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setClearStencil(s);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setClearStencil(s);
     }
 }
 
@@ -781,18 +696,10 @@
     EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)",
           red, green, blue, alpha);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
     }
 }
 
@@ -800,96 +707,85 @@
 {
     EVENT("(GLuint shader = %d)", shader);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context)
+        if (!shaderObject)
         {
-            gl::Shader *shaderObject = context->getShader(shader);
-
-            if (!shaderObject)
+            if (context->getProgram(shader))
             {
-                if (context->getProgram(shader))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            shaderObject->compile();
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        shaderObject->compile();
     }
 }
 
-void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, 
+void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
                                       GLint border, GLsizei imageSize, const GLvoid* data)
 {
-    EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 
+    EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
           "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
           target, level, internalformat, width, height, border, imageSize, data);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3 &&
+            !ValidateES2TexImageParameters(context, target, level, internalformat, true, false,
+                                           0, 0, width, height, border, GL_NONE, GL_NONE, data))
         {
-            if (context->getClientVersion() < 3 &&
-                !ValidateES2TexImageParameters(context, target, level, internalformat, true, false,
-                                               0, 0, width, height, border, GL_NONE, GL_NONE, data))
-            {
-                return;
-            }
-
-            if (context->getClientVersion() >= 3 &&
-                !ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
-                                               0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data))
-            {
-                return;
-            }
-
-            if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height))
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                {
-                    gl::Texture2D *texture = context->getTexture2D();
-                    texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
-                }
-                break;
-
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (context->getClientVersion() >= 3 &&
+            !ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
+                                           0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data))
+        {
+            return;
+        }
+
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+        if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+            {
+                gl::Texture2D *texture = context->getTexture2D();
+                texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+            }
+            break;
+
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -901,60 +797,55 @@
           "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
           target, level, xoffset, yoffset, width, height, format, imageSize, data);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3 &&
+            !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true,
+                                           xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data))
         {
-            if (context->getClientVersion() < 3 &&
-                !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true,
-                                               xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data))
-            {
-                return;
-            }
-
-            if (context->getClientVersion() >= 3 &&
-                !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
-                                               xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data))
-            {
-                return;
-            }
-
-            if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height))
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                {
-                    gl::Texture2D *texture = context->getTexture2D();
-                    texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
-                }
-                break;
-
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (context->getClientVersion() >= 3 &&
+            !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
+                                           xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data))
+        {
+            return;
+        }
+
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
+        if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+            {
+                gl::Texture2D *texture = context->getTexture2D();
+                texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+            }
+            break;
+
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -964,57 +855,50 @@
           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
           target, level, internalformat, x, y, width, height, border);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3 &&
+            !ValidateES2CopyTexImageParameters(context, target, level, internalformat, false,
+                                               0, 0, x, y, width, height, border))
         {
-            if (context->getClientVersion() < 3 &&
-                !ValidateES2CopyTexImageParameters(context, target, level, internalformat, false,
-                                                   0, 0, x, y, width, height, border))
-            {
-                return;
-            }
-
-            if (context->getClientVersion() >= 3 &&
-                !ValidateES3CopyTexImageParameters(context, target, level, internalformat, false,
-                                                   0, 0, 0, x, y, width, height, border))
-            {
-                return;
-            }
-
-            gl::Framebuffer *framebuffer = context->getReadFramebuffer();
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                {
-                    gl::Texture2D *texture = context->getTexture2D();
-                    texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
-                }
-                break;
-
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
-                }
-                break;
-
-             default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (context->getClientVersion() >= 3 &&
+            !ValidateES3CopyTexImageParameters(context, target, level, internalformat, false,
+                                               0, 0, 0, x, y, width, height, border))
+        {
+            return;
+        }
+
+        gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+            {
+                gl::Texture2D *texture = context->getTexture2D();
+                texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+            }
+            break;
+
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -1024,58 +908,50 @@
           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
           target, level, xoffset, yoffset, x, y, width, height);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3 &&
+            !ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true,
+                                               xoffset, yoffset, x, y, width, height, 0))
         {
-            if (context->getClientVersion() < 3 &&
-                !ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true,
-                                                   xoffset, yoffset, x, y, width, height, 0))
-            {
-                return;
-            }
-
-            if (context->getClientVersion() >= 3 &&
-                !ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true,
-                                                   xoffset, yoffset, 0, x, y, width, height, 0))
-            {
-                return;
-            }
-
-            gl::Framebuffer *framebuffer = context->getReadFramebuffer();
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                {
-                    gl::Texture2D *texture = context->getTexture2D();
-                    texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
-                }
-                break;
-
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            return;
         }
-    }
 
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        if (context->getClientVersion() >= 3 &&
+            !ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true,
+                                               xoffset, yoffset, 0, x, y, width, height, 0))
+        {
+            return;
+        }
+
+        gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+            {
+                gl::Texture2D *texture = context->getTexture2D();
+                texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
+            }
+            break;
+
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -1083,18 +959,10 @@
 {
     EVENT("()");
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            return context->createProgram();
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, 0);
+        return context->createProgram();
     }
 
     return 0;
@@ -1104,26 +972,20 @@
 {
     EVENT("(GLenum type = 0x%X)", type);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        switch (type)
         {
-            switch (type)
-            {
-              case GL_FRAGMENT_SHADER:
-              case GL_VERTEX_SHADER:
-                return context->createShader(type);
-              default:
-                return gl::error(GL_INVALID_ENUM, 0);
-            }
+          case GL_FRAGMENT_SHADER:
+          case GL_VERTEX_SHADER:
+            return context->createShader(type);
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return 0;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, 0);
-    }
 
     return 0;
 }
@@ -1132,29 +994,22 @@
 {
     EVENT("(GLenum mode = 0x%X)", mode);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         switch (mode)
         {
           case GL_FRONT:
           case GL_BACK:
           case GL_FRONT_AND_BACK:
-            {
-                gl::Context *context = gl::getNonLostContext();
-
-                if (context)
-                {
-                    context->setCullMode(mode);
-                }
-            }
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->getState().setCullMode(mode);
     }
 }
 
@@ -1162,119 +1017,92 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                context->deleteBuffer(buffers[i]);
-            }
+            context->deleteBuffer(buffers[i]);
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
 {
     EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                context->deleteFenceNV(fences[i]);
-            }
+            context->deleteFenceNV(fences[i]);
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
 {
     EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
+            if (framebuffers[i] != 0)
             {
-                if (framebuffers[i] != 0)
-                {
-                    context->deleteFramebuffer(framebuffers[i]);
-                }
+                context->deleteFramebuffer(framebuffers[i]);
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glDeleteProgram(GLuint program)
 {
     EVENT("(GLuint program = %d)", program);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (program == 0)
         {
             return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!context->getProgram(program))
         {
-            if (!context->getProgram(program))
+            if(context->getShader(program))
             {
-                if(context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            context->deleteProgram(program);
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->deleteProgram(program);
     }
 }
 
@@ -1282,89 +1110,69 @@
 {
     EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                context->deleteQuery(ids[i]);
-            }
+            context->deleteQuery(ids[i]);
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
 {
     EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                context->deleteRenderbuffer(renderbuffers[i]);
-            }
+            context->deleteRenderbuffer(renderbuffers[i]);
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glDeleteShader(GLuint shader)
 {
     EVENT("(GLuint shader = %d)", shader);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (shader == 0)
         {
             return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!context->getShader(shader))
         {
-            if (!context->getShader(shader))
+            if(context->getProgram(shader))
             {
-                if(context->getProgram(shader))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            context->deleteShader(shader);
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->deleteShader(shader);
     }
 }
 
@@ -1372,37 +1180,31 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
+            if (textures[i] != 0)
             {
-                if (textures[i] != 0)
-                {
-                    context->deleteTexture(textures[i]);
-                }
+                context->deleteTexture(textures[i]);
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glDepthFunc(GLenum func)
 {
     EVENT("(GLenum func = 0x%X)", func);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         switch (func)
         {
@@ -1414,21 +1216,13 @@
           case GL_GREATER:
           case GL_GEQUAL:
           case GL_NOTEQUAL:
+            context->getState().setDepthFunc(func);
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setDepthFunc(func);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
     }
 }
 
@@ -1436,18 +1230,10 @@
 {
     EVENT("(GLboolean flag = %u)", flag);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setDepthMask(flag != GL_FALSE);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setDepthMask(flag != GL_FALSE);
     }
 }
 
@@ -1455,18 +1241,10 @@
 {
     EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setDepthRange(zNear, zFar);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setDepthRange(zNear, zFar);
     }
 }
 
@@ -1474,52 +1252,48 @@
 {
     EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context)
+        if (!programObject)
         {
-
-            gl::Program *programObject = context->getProgram(program);
-            gl::Shader *shaderObject = context->getShader(shader);
-            
-            if (!programObject)
+            gl::Shader *shaderByProgramHandle;
+            shaderByProgramHandle = context->getShader(program);
+            if (!shaderByProgramHandle)
             {
-                gl::Shader *shaderByProgramHandle;
-                shaderByProgramHandle = context->getShader(program);
-                if (!shaderByProgramHandle)
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
-
-            if (!shaderObject)
+            else
             {
-                gl::Program *programByShaderHandle = context->getProgram(shader);
-                if (!programByShaderHandle)
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-            }
-
-            if (!programObject->detachShader(shaderObject))
-            {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!shaderObject)
+        {
+            gl::Program *programByShaderHandle = context->getProgram(shader);
+            if (!programByShaderHandle)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
+            }
+        }
+
+        if (!programObject->detachShader(shaderObject))
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
     }
 }
 
@@ -1527,23 +1301,16 @@
 {
     EVENT("(GLenum cap = 0x%X)", cap);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidCap(context, cap))
         {
-            if (!ValidCap(context, cap))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            context->setCap(cap, false);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->getState().setEnableFeature(cap, false);
     }
 }
 
@@ -1551,23 +1318,16 @@
 {
     EVENT("(GLuint index = %d)", index);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setEnableVertexAttribArray(index, false);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setEnableVertexAttribArray(index, false);
     }
 }
 
@@ -1575,39 +1335,15 @@
 {
     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        if (count < 0 || first < 0)
+        if (!ValidateDrawArrays(context, mode, first, count, 0))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        // Check for mapped buffers
-        if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
-        {
-            return gl::error(GL_INVALID_OPERATION);
-        }
-
-        if (context)
-        {
-            gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
-            if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
-                curTransformFeedback->getDrawMode() != mode)
-            {
-                // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
-                // that does not match the current transform feedback object's draw mode (if transform feedback
-                // is active), (3.0.2, section 2.14, pg 86)
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->drawArrays(mode, first, count, 0);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->drawArrays(mode, first, count, 0);
     }
 }
 
@@ -1615,42 +1351,15 @@
 {
     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        if (count < 0 || first < 0 || primcount < 0)
+        if (!ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
-        if (primcount > 0)
-        {
-            gl::Context *context = gl::getNonLostContext();
-
-            // Check for mapped buffers
-            if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (context)
-            {
-                gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
-                if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
-                    curTransformFeedback->getDrawMode() != mode)
-                {
-                    // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
-                    // that does not match the current transform feedback object's draw mode (if transform feedback
-                    // is active), (3.0.2, section 2.14, pg 86)
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-
-                context->drawArrays(mode, first, count, primcount);
-            }
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->drawArrays(mode, first, count, primcount);
     }
 }
 
@@ -1659,52 +1368,16 @@
     EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
           mode, count, type, indices);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        if (count < 0)
+        rx::RangeUI indexRange;
+        if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            switch (type)
-            {
-              case GL_UNSIGNED_BYTE:
-              case GL_UNSIGNED_SHORT:
-                break;
-              case GL_UNSIGNED_INT:
-                if (!context->supports32bitIndices())
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
-            if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
-            {
-                // 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);
-            }
-
-            // Check for mapped buffers
-            if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->drawElements(mode, count, type, indices, 0);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->drawElements(mode, count, type, indices, 0, indexRange);
     }
 }
 
@@ -1713,55 +1386,16 @@
     EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
           mode, count, type, indices, primcount);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        if (count < 0 || primcount < 0)
+        rx::RangeUI indexRange;
+        if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, &indexRange))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
-        if (primcount > 0)
-        {
-            gl::Context *context = gl::getNonLostContext();
-
-            if (context)
-            {
-                switch (type)
-                {
-                  case GL_UNSIGNED_BYTE:
-                  case GL_UNSIGNED_SHORT:
-                    break;
-                  case GL_UNSIGNED_INT:
-                    if (!context->supports32bitIndices())
-                    {
-                        return gl::error(GL_INVALID_ENUM);
-                    }
-                    break;
-                  default:
-                    return gl::error(GL_INVALID_ENUM);
-                }
-
-                gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
-                if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
-                {
-                    // 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);
-                }
-
-                // Check for mapped buffers
-                if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-
-                context->drawElements(mode, count, type, indices, primcount);
-            }
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->drawElements(mode, count, type, indices, primcount, indexRange);
     }
 }
 
@@ -1769,23 +1403,16 @@
 {
     EVENT("(GLenum cap = 0x%X)", cap);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidCap(context, cap))
         {
-            if (!ValidCap(context, cap))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            context->setCap(cap, true);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->getState().setEnableFeature(cap, true);
     }
 }
 
@@ -1793,23 +1420,16 @@
 {
     EVENT("(GLuint index = %d)", index);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setEnableVertexAttribArray(index, true);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setEnableVertexAttribArray(index, true);
     }
 }
 
@@ -1817,23 +1437,20 @@
 {
     EVENT("GLenum target = 0x%X)", target);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateEndQuery(context, target))
         {
-            if (!ValidateEndQuery(context, target))
-            {
-                return;
-            }
-
-            context->endQuery(target);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Error error = context->endQuery(target);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -1841,30 +1458,24 @@
 {
     EVENT("(GLuint fence = %d)", fence);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
-        if (context)
+        if (fenceObject == NULL)
         {
-            gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
-            if (fenceObject == NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (fenceObject->isFence() != GL_TRUE)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            fenceObject->finishFence();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (fenceObject->isFence() != GL_TRUE)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        fenceObject->finishFence();
     }
 }
 
@@ -1872,18 +1483,10 @@
 {
     EVENT("()");
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->sync(true);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->sync(true);
     }
 }
 
@@ -1891,18 +1494,10 @@
 {
     EVENT("()");
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->sync(false);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->sync(false);
     }
 }
 
@@ -1911,54 +1506,47 @@
     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
           "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer))
         {
-            if (!gl::ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer))
-            {
-                return;
-            }
+            return;
+        }
 
-            gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
-            ASSERT(framebuffer);
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+        ASSERT(framebuffer);
 
-            if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+        if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+        {
+            unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+            framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0);
+        }
+        else
+        {
+            switch (attachment)
             {
-                unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
-                framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0);
-            }
-            else
-            {
-                switch (attachment)
-                {
-                  case GL_DEPTH_ATTACHMENT:
-                    framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
-                    break;
-                  case GL_STENCIL_ATTACHMENT:
-                    framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
-                    break;
-                  case GL_DEPTH_STENCIL_ATTACHMENT:
-                    framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
-                    break;
-                  default:
-                    UNREACHABLE();
-                    break;
-                }
+              case GL_DEPTH_ATTACHMENT:
+                framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
+                break;
+              case GL_STENCIL_ATTACHMENT:
+                framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
+                break;
+              case GL_DEPTH_STENCIL_ATTACHMENT:
+                framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
+                break;
+              default:
+                UNREACHABLE();
+                break;
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
@@ -1966,169 +1554,149 @@
     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
           "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-        if (context)
+        if (!ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level))
         {
-            if (context->getClientVersion() < 3 &&
-                !ValidateES2FramebufferTextureParameters(context, target, attachment, textarget, texture, level))
-            {
-                return;
-            }
+            return;
+        }
 
-            if (context->getClientVersion() >= 3 &&
-                !ValidateES3FramebufferTextureParameters(context, target, attachment, textarget, texture, level, 0, false))
-            {
-                return;
-            }
+        if (texture == 0)
+        {
+            textarget = GL_NONE;
+        }
 
-            if (texture == 0)
-            {
-                textarget = GL_NONE;
-            }
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
 
-            gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
-
-            if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+        if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+        {
+            const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+            framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0);
+        }
+        else
+        {
+            switch (attachment)
             {
-                const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
-                framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0);
-            }
-            else
-            {
-                switch (attachment)
-                {
-                  case GL_DEPTH_ATTACHMENT:         framebuffer->setDepthbuffer(textarget, texture, level, 0);        break;
-                  case GL_STENCIL_ATTACHMENT:       framebuffer->setStencilbuffer(textarget, texture, level, 0);      break;
-                  case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break;
-                }
+              case GL_DEPTH_ATTACHMENT:         framebuffer->setDepthbuffer(textarget, texture, level, 0);        break;
+              case GL_STENCIL_ATTACHMENT:       framebuffer->setStencilbuffer(textarget, texture, level, 0);      break;
+              case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break;
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glFrontFace(GLenum mode)
 {
     EVENT("(GLenum mode = 0x%X)", mode);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         switch (mode)
         {
           case GL_CW:
           case GL_CCW:
-            {
-                gl::Context *context = gl::getNonLostContext();
-
-                if (context)
-                {
-                    context->setFrontFace(mode);
-                }
-            }
+            context->getState().setFrontFace(mode);
             break;
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
 {
     EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                buffers[i] = context->createBuffer();
-            }
+            buffers[i] = context->createBuffer();
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGenerateMipmap(GLenum target)
 {
     EVENT("(GLenum target = 0x%X)", target);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidTextureTarget(context, target))
         {
-            if (!ValidTextureTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Texture *texture = context->getTargetTexture(target);
-
-            if (texture == NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            GLenum internalFormat = texture->getBaseLevelInternalFormat();
-
-            // Internally, all texture formats are sized so checking if the format
-            // is color renderable and filterable will not fail.
-
-            bool validRenderable = (gl::IsColorRenderingSupported(internalFormat, context) ||
-                                    gl::IsSizedInternalFormat(internalFormat, context->getClientVersion()));
-
-            if (gl::IsDepthRenderingSupported(internalFormat, context) ||
-                gl::IsFormatCompressed(internalFormat, context->getClientVersion()) ||
-                !gl::IsTextureFilteringSupported(internalFormat, context) ||
-                !validRenderable)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // Non-power of 2 ES2 check
-            if (!context->supportsNonPower2Texture() && (!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);
-            }
-
-            // Cube completeness check
-            if (target == GL_TEXTURE_CUBE_MAP)
-            {
-                gl::TextureCubeMap *textureCube = static_cast<gl::TextureCubeMap *>(texture);
-                if (!textureCube->isCubeComplete())
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-            }
-
-            texture->generateMipmaps();
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Texture *texture = context->getTargetTexture(target);
+
+        if (texture == NULL)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        GLenum internalFormat = texture->getBaseLevelInternalFormat();
+        const gl::TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+
+        // GenerateMipmap should not generate an INVALID_OPERATION for textures created with
+        // unsized formats or that are color renderable and filterable.  Since we do not track if
+        // the texture was created with sized or unsized format (only sized formats are stored),
+        // it is not possible to make sure the the LUMA formats can generate mipmaps (they should
+        // be able to) because they aren't color renderable.  Simply do a special case for LUMA
+        // textures since they're the only texture format that can be created with unsized formats
+        // that is not color renderable.  New unsized formats are unlikely to be added, since ES2
+        // was the last version to use add them.
+        bool isLUMA = internalFormat == GL_LUMINANCE8_EXT ||
+                      internalFormat == GL_LUMINANCE8_ALPHA8_EXT ||
+                      internalFormat == GL_ALPHA8_EXT;
+
+        if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0 || !formatCaps.filterable ||
+            (!formatCaps.renderable && !isLUMA) || formatInfo.compressed)
+        {
+            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)
+        {
+            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));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        // Cube completeness check
+        if (target == GL_TEXTURE_CUBE_MAP)
+        {
+            gl::TextureCubeMap *textureCube = static_cast<gl::TextureCubeMap *>(texture);
+            if (!textureCube->isCubeComplete())
+            {
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
+            }
+        }
+
+        texture->generateMipmaps();
     }
 }
 
@@ -2136,80 +1704,59 @@
 {
     EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                fences[i] = context->createFenceNV();
-            }
+            fences[i] = context->createFenceNV();
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
 {
     EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                framebuffers[i] = context->createFramebuffer();
-            }
+            framebuffers[i] = context->createFramebuffer();
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
 {
     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (n < 0)
         {
-            if (n < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            for (GLsizei i = 0; i < n; i++)
-            {
-                ids[i] = context->createQuery();
-            }
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        for (GLsizei i = 0; i < n; i++)
+        {
+            ids[i] = context->createQuery();
+        }
     }
 }
 
@@ -2217,54 +1764,40 @@
 {
     EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                renderbuffers[i] = context->createRenderbuffer();
-            }
+            renderbuffers[i] = context->createRenderbuffer();
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGenTextures(GLsizei n, GLuint* textures)
 {
     EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (n < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        for (int i = 0; i < n; i++)
         {
-            for (int i = 0; i < n; i++)
-            {
-                textures[i] = context->createTexture();
-            }
+            textures[i] = context->createTexture();
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
@@ -2273,42 +1806,38 @@
           "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
           program, index, bufsize, length, size, type, name);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (bufsize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            if (index >= (GLuint)programObject->getActiveAttributeCount())
+            else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
-
-            programObject->getActiveAttribute(index, bufsize, length, size, type, name);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (index >= (GLuint)programObject->getActiveAttributeCount())
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        programObject->getActiveAttribute(index, bufsize, length, size, type, name);
     }
 }
 
@@ -2318,42 +1847,39 @@
           "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);
 
-    try
+
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (bufsize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            if (index >= (GLuint)programObject->getActiveUniformCount())
+            else
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
-
-            programObject->getActiveUniform(index, bufsize, length, size, type, name);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (index >= (GLuint)programObject->getActiveUniformCount())
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        programObject->getActiveUniform(index, bufsize, length, size, type, name);
     }
 }
 
@@ -2362,77 +1888,66 @@
     EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
           program, maxcount, count, shaders);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (maxcount < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            return programObject->getAttachedShaders(maxcount, count, shaders);
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        return programObject->getAttachedShaders(maxcount, count, shaders);
     }
 }
 
-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);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION, -1);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE, -1);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return -1;
             }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programObject->isLinked() || !programBinary)
+            else
             {
-                return gl::error(GL_INVALID_OPERATION, -1);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return -1;
             }
-
-            return programBinary->getAttributeLocation(name);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, -1);
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        if (!programObject->isLinked() || !programBinary)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
+        }
+
+        return programBinary->getAttributeLocation(name);
     }
 
     return -1;
@@ -2442,32 +1957,24 @@
 {
     EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)",  pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        GLenum nativeType;
+        unsigned int numParams = 0;
+        if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
         {
-            GLenum nativeType;
-            unsigned int numParams = 0;
-            if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
-            {
-                return;
-            }
-
-            if (nativeType == GL_BOOL)
-            {
-                context->getBooleanv(pname, params);
-            }
-            else
-            {
-                CastStateValues(context, nativeType, pname, numParams, params);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (nativeType == GL_BOOL)
+        {
+            context->getBooleanv(pname, params);
+        }
+        else
+        {
+            CastStateValues(context, nativeType, pname, numParams, params);
+        }
     }
 }
 
@@ -2475,57 +1982,52 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidBufferTarget(context, target))
         {
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            if (!gl::ValidBufferParameter(context, pname))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (!buffer)
-            {
-                // A null buffer means that "0" is bound to the requested buffer target
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (pname)
-            {
-              case GL_BUFFER_USAGE:
-                *params = static_cast<GLint>(buffer->usage());
-                break;
-              case GL_BUFFER_SIZE:
-                *params = gl::clampCast<GLint>(buffer->size());
-                break;
-              case GL_BUFFER_ACCESS_FLAGS:
-                *params = buffer->accessFlags();
-                break;
-              case GL_BUFFER_MAPPED:
-                *params = static_cast<GLint>(buffer->mapped());
-                break;
-              case GL_BUFFER_MAP_OFFSET:
-                *params = gl::clampCast<GLint>(buffer->mapOffset());
-                break;
-              case GL_BUFFER_MAP_LENGTH:
-                *params = gl::clampCast<GLint>(buffer->mapLength());
-                break;
-              default: UNREACHABLE(); break;
-            }
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!gl::ValidBufferParameter(context, pname))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (!buffer)
+        {
+            // A null buffer means that "0" is bound to the requested buffer target
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_BUFFER_USAGE:
+            *params = static_cast<GLint>(buffer->getUsage());
+            break;
+          case GL_BUFFER_SIZE:
+            *params = gl::clampCast<GLint>(buffer->getSize());
+            break;
+          case GL_BUFFER_ACCESS_FLAGS:
+            *params = buffer->getAccessFlags();
+            break;
+          case GL_BUFFER_MAPPED:
+            *params = static_cast<GLint>(buffer->isMapped());
+            break;
+          case GL_BUFFER_MAP_OFFSET:
+            *params = gl::clampCast<GLint>(buffer->getMapOffset());
+            break;
+          case GL_BUFFER_MAP_LENGTH:
+            *params = gl::clampCast<GLint>(buffer->getMapLength());
+            break;
+          default: UNREACHABLE(); break;
+        }
     }
 }
 
@@ -2547,40 +2049,35 @@
 {
     EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-    
-        gl::Context *context = gl::getNonLostContext();
+        gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
-        if (context)
+        if (fenceObject == NULL)
         {
-            gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
-            if (fenceObject == NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (fenceObject->isFence() != GL_TRUE)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (pname)
-            {
-              case GL_FENCE_STATUS_NV:
-              case GL_FENCE_CONDITION_NV:
-                break;
-
-              default: return gl::error(GL_INVALID_ENUM);
-            }
-
-            params[0] = fenceObject->getFencei(pname);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (fenceObject->isFence() != GL_TRUE)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_FENCE_STATUS_NV:
+          case GL_FENCE_CONDITION_NV:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        params[0] = fenceObject->getFencei(pname);
     }
 }
 
@@ -2588,32 +2085,24 @@
 {
     EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        GLenum nativeType;
+        unsigned int numParams = 0;
+        if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
         {
-            GLenum nativeType;
-            unsigned int numParams = 0;
-            if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
-            {
-                return;
-            }
-
-            if (nativeType == GL_FLOAT)
-            {
-                context->getFloatv(pname, params);
-            }
-            else
-            {
-                CastStateValues(context, nativeType, pname, numParams, params);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (nativeType == GL_FLOAT)
+        {
+            context->getFloatv(pname, params);
+        }
+        else
+        {
+            CastStateValues(context, nativeType, pname, numParams, params);
+        }
     }
 }
 
@@ -2622,301 +2111,295 @@
     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
           target, attachment, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidFramebufferTarget(target))
         {
-            if (!gl::ValidFramebufferTarget(target))
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        int clientVersion = context->getClientVersion();
+
+        switch (pname)
+        {
+          case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+          case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+          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:
+          case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+          case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+          case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+          case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+          case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+            if (clientVersion < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        // Determine if the attachment is a valid enum
+        switch (attachment)
+        {
+          case GL_BACK:
+          case GL_FRONT:
+          case GL_DEPTH:
+          case GL_STENCIL:
+          case GL_DEPTH_STENCIL_ATTACHMENT:
+            if (clientVersion < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            break;
+
+          case GL_DEPTH_ATTACHMENT:
+          case GL_STENCIL_ATTACHMENT:
+            break;
+
+          default:
+            if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
+                (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            break;
+        }
+
+        GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id();
+        gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle);
+
+        if (framebufferHandle == 0)
+        {
+            if (clientVersion < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
+            }
+
+            switch (attachment)
+            {
+              case GL_BACK:
+              case GL_DEPTH:
+              case GL_STENCIL:
+                break;
+
+              default:
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
+            }
+        }
+        else
+        {
+            if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+            {
+                // Valid attachment query
+            }
+            else
+            {
+                switch (attachment)
+                {
+                  case GL_DEPTH_ATTACHMENT:
+                  case GL_STENCIL_ATTACHMENT:
+                    break;
+
+                  case GL_DEPTH_STENCIL_ATTACHMENT:
+                    if (framebuffer->hasValidDepthStencil())
+                    {
+                        context->recordError(gl::Error(GL_INVALID_OPERATION));
+                        return;
+                    }
+                    break;
+
+                  default:
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
+                }
+            }
+        }
+
+        GLenum attachmentType = GL_NONE;
+        GLuint attachmentHandle = 0;
+        GLuint attachmentLevel = 0;
+        GLuint attachmentLayer = 0;
+
+        const gl::FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
+
+        if (attachmentObject)
+        {
+            attachmentType = attachmentObject->type();
+            attachmentHandle = attachmentObject->id();
+            attachmentLevel = attachmentObject->mipLevel();
+            attachmentLayer = attachmentObject->layer();
+        }
+
+        GLenum attachmentObjectType;   // Type category
+        if (framebufferHandle == 0)
+        {
+            attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
+        }
+        else if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
+        {
+            attachmentObjectType = attachmentType;
+        }
+        else if (gl::ValidTexture2DDestinationTarget(context, attachmentType))
+        {
+            attachmentObjectType = GL_TEXTURE;
+        }
+        else
+        {
+            UNREACHABLE();
+            return;
+        }
+
+        if (attachmentObjectType == GL_NONE)
+        {
+            // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
+            // is NONE, then querying any other pname will generate INVALID_ENUM.
+
+            // ES 3.0.2 spec pg 235 states that if the attachment type is none,
+            // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
+            // INVALID_OPERATION for all other pnames
 
             switch (pname)
             {
               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+                *params = attachmentObjectType;
+                break;
+
               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-              case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
-              case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
-                break;
-              case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
-              case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
-              case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
-              case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
-              case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
-              case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
-              case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
-              case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
-              case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
-                if (context->getClientVersion() >= 3)
+                if (clientVersion < 3)
                 {
-                    break;
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
                 }
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            // Determine if the attachment is a valid enum
-            switch (attachment)
-            {
-              case GL_BACK:
-              case GL_FRONT:
-              case GL_DEPTH:
-              case GL_STENCIL:
-              case GL_DEPTH_STENCIL_ATTACHMENT:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                break;
-
-              case GL_DEPTH_ATTACHMENT:
-              case GL_STENCIL_ATTACHMENT:
+                *params = 0;
                 break;
 
               default:
-                if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
-                    (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getMaximumRenderTargets())
+                if (clientVersion < 3)
                 {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                break;
-            }
-
-            GLuint framebufferHandle = context->getTargetFramebufferHandle(target);
-            ASSERT(framebufferHandle != GL_INVALID_INDEX);
-            gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle);
-
-            GLenum attachmentType;
-            GLuint attachmentHandle;
-            GLuint attachmentLevel;
-            GLuint attachmentLayer;
-            gl::FramebufferAttachment *attachmentObject;
-
-            if (framebufferHandle == 0)
-            {
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-
-                switch (attachment)
-                {
-                  case GL_BACK:
-                    attachmentType = framebuffer->getColorbufferType(0);
-                    attachmentHandle = framebuffer->getColorbufferHandle(0);
-                    attachmentLevel = framebuffer->getColorbufferMipLevel(0);
-                    attachmentLayer = framebuffer->getColorbufferLayer(0);
-                    attachmentObject = framebuffer->getColorbuffer(0);
-                    break;
-                  case GL_DEPTH:
-                    attachmentType = framebuffer->getDepthbufferType();
-                    attachmentHandle = framebuffer->getDepthbufferHandle();
-                    attachmentLevel = framebuffer->getDepthbufferMipLevel();
-                    attachmentLayer = framebuffer->getDepthbufferLayer();
-                    attachmentObject = framebuffer->getDepthbuffer();
-                    break;
-                  case GL_STENCIL:
-                    attachmentType = framebuffer->getStencilbufferType();
-                    attachmentHandle = framebuffer->getStencilbufferHandle();
-                    attachmentLevel = framebuffer->getStencilbufferMipLevel();
-                    attachmentLayer = framebuffer->getStencilbufferLayer();
-                    attachmentObject = framebuffer->getStencilbuffer();
-                    break;
-                  default:
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-            }
-            else
-            {
-                if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
-                {
-                    const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
-                    attachmentType = framebuffer->getColorbufferType(colorAttachment);
-                    attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment);
-                    attachmentLevel = framebuffer->getColorbufferMipLevel(colorAttachment);
-                    attachmentLayer = framebuffer->getColorbufferLayer(colorAttachment);
-                    attachmentObject = framebuffer->getColorbuffer(colorAttachment);
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
                 }
                 else
                 {
-                    switch (attachment)
-                    {
-                      case GL_DEPTH_ATTACHMENT:
-                        attachmentType = framebuffer->getDepthbufferType();
-                        attachmentHandle = framebuffer->getDepthbufferHandle();
-                        attachmentLevel = framebuffer->getDepthbufferMipLevel();
-                        attachmentLayer = framebuffer->getDepthbufferLayer();
-                        attachmentObject = framebuffer->getDepthbuffer();
-                        break;
-                      case GL_STENCIL_ATTACHMENT:
-                        attachmentType = framebuffer->getStencilbufferType();
-                        attachmentHandle = framebuffer->getStencilbufferHandle();
-                        attachmentLevel = framebuffer->getStencilbufferMipLevel();
-                        attachmentLayer = framebuffer->getStencilbufferLayer();
-                        attachmentObject = framebuffer->getStencilbuffer();
-                        break;
-                      case GL_DEPTH_STENCIL_ATTACHMENT:
-                        if (framebuffer->getDepthbufferHandle() != framebuffer->getStencilbufferHandle())
-                        {
-                            return gl::error(GL_INVALID_OPERATION);
-                        }
-                        attachmentType = framebuffer->getDepthStencilbufferType();
-                        attachmentHandle = framebuffer->getDepthStencilbufferHandle();
-                        attachmentLevel = framebuffer->getDepthStencilbufferMipLevel();
-                        attachmentLayer = framebuffer->getDepthStencilbufferLayer();
-                        attachmentObject = framebuffer->getDepthStencilBuffer();
-                        break;
-                      default:
-                        return gl::error(GL_INVALID_OPERATION);
-                    }
-                }
-            }
-
-            GLenum attachmentObjectType;   // Type category
-            if (framebufferHandle == 0)
-            {
-                attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
-            }
-            else if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
-            {
-                attachmentObjectType = attachmentType;
-            }
-            else if (gl::IsInternalTextureTarget(attachmentType, context->getClientVersion()))
-            {
-                attachmentObjectType = GL_TEXTURE;
-            }
-            else
-            {
-                UNREACHABLE();
-                return;
-            }
-
-            if (attachmentObjectType == GL_NONE)
-            {
-                // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
-                // is NONE, then querying any other pname will generate INVALID_ENUM.
-
-                // ES 3.0.2 spec pg 235 states that if the attachment type is none,
-                // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
-                // INVALID_OPERATION for all other pnames
-
-                switch (pname)
-                {
-                  case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-                    *params = attachmentObjectType;
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-                    if (context->getClientVersion() < 3)
-                    {
-                        return gl::error(GL_INVALID_ENUM);
-                    }
-                    *params = 0;
-                    break;
-
-                  default:
-                    if (context->getClientVersion() < 3)
-                    {
-                        return gl::error(GL_INVALID_ENUM);
-                    }
-                    else
-                    {
-                        gl::error(GL_INVALID_OPERATION);
-                    }
-                }
-            }
-            else
-            {
-                ASSERT(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE ||
-                       attachmentObjectType == GL_FRAMEBUFFER_DEFAULT);
-                ASSERT(attachmentObject != NULL);
-
-                switch (pname)
-                {
-                  case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-                    *params = attachmentObjectType;
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-                    if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE)
-                    {
-                        return gl::error(GL_INVALID_ENUM);
-                    }
-                    *params = attachmentHandle;
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
-                    if (attachmentObjectType != GL_TEXTURE)
-                    {
-                        return gl::error(GL_INVALID_ENUM);
-                    }
-                    *params = attachmentLevel;
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
-                    if (attachmentObjectType != GL_TEXTURE)
-                    {
-                        return gl::error(GL_INVALID_ENUM);
-                    }
-                    *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0;
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
-                    *params = attachmentObject->getRedSize();
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
-                    *params = attachmentObject->getGreenSize();
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
-                    *params = attachmentObject->getBlueSize();
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
-                    *params = attachmentObject->getAlphaSize();
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
-                    *params = attachmentObject->getDepthSize();
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
-                    *params = attachmentObject->getStencilSize();
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
-                    if (attachment == GL_DEPTH_STENCIL)
-                    {
-                        gl::error(GL_INVALID_OPERATION);
-                    }
-                    *params = attachmentObject->getComponentType();
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
-                    *params = attachmentObject->getColorEncoding();
-                    break;
-
-                  case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
-                    if (attachmentObjectType != GL_TEXTURE)
-                    {
-                        return gl::error(GL_INVALID_ENUM);
-                    }
-                    *params = attachmentLayer;
-                    break;
-
-                  default:
-                    UNREACHABLE();
-                    break;
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
                 }
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        else
+        {
+            ASSERT(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE ||
+                   attachmentObjectType == GL_FRAMEBUFFER_DEFAULT);
+            ASSERT(attachmentObject != NULL);
+
+            switch (pname)
+            {
+              case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+                *params = attachmentObjectType;
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+                if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE)
+                {
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
+                }
+                *params = attachmentHandle;
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+                if (attachmentObjectType != GL_TEXTURE)
+                {
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
+                }
+                *params = attachmentLevel;
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+                if (attachmentObjectType != GL_TEXTURE)
+                {
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
+                }
+                *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0;
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+                *params = attachmentObject->getRedSize();
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+                *params = attachmentObject->getGreenSize();
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
+                *params = attachmentObject->getBlueSize();
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+                *params = attachmentObject->getAlphaSize();
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+                *params = attachmentObject->getDepthSize();
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+                *params = attachmentObject->getStencilSize();
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+                if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+                {
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
+                }
+                *params = attachmentObject->getComponentType();
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
+                *params = attachmentObject->getColorEncoding();
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+                if (attachmentObjectType != GL_TEXTURE)
+                {
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
+                }
+                *params = attachmentLayer;
+                break;
+
+              default:
+                UNREACHABLE();
+                break;
+            }
+        }
     }
 }
 
@@ -2924,54 +2407,39 @@
 {
     EVENT("()");
 
-    try
-    {
-        gl::Context *context = gl::getContext();
+    gl::Context *context = gl::getContext();
 
-        if (context)
-        {
-            return context->getResetStatus();
-        }
-
-        return GL_NO_ERROR;
-    }
-    catch (...)
+    if (context)
     {
-        return GL_OUT_OF_MEMORY;
+        return context->getResetStatus();
     }
+
+    return GL_NO_ERROR;
 }
 
 void __stdcall glGetIntegerv(GLenum pname, GLint* params)
 {
     EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        GLenum nativeType;
+        unsigned int numParams = 0;
 
-        if (context)
+        if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
         {
-            GLenum nativeType;
-            unsigned int numParams = 0;
-
-            if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
-            {
-                return;
-            }
-
-            if (nativeType == GL_INT)
-            {
-                context->getIntegerv(pname, params);
-            }
-            else
-            {
-                CastStateValues(context, nativeType, pname, numParams, params);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (nativeType == GL_INT)
+        {
+            context->getIntegerv(pname, params);
+        }
+        else
+        {
+            CastStateValues(context, nativeType, pname, numParams, params);
+        }
     }
 }
 
@@ -2979,87 +2447,83 @@
 {
     EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
 
-            if (!programObject)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            if (context->getClientVersion() < 3)
-            {
-                switch (pname)
-                {
-                  case GL_ACTIVE_UNIFORM_BLOCKS:
-                  case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
-                  case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
-                  case GL_TRANSFORM_FEEDBACK_VARYINGS:
-                  case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
-                    return gl::error(GL_INVALID_ENUM);
-                }
-            }
-
+        if (context->getClientVersion() < 3)
+        {
             switch (pname)
             {
-              case GL_DELETE_STATUS:
-                *params = programObject->isFlaggedForDeletion();
-                return;
-              case GL_LINK_STATUS:
-                *params = programObject->isLinked();
-                return;
-              case GL_VALIDATE_STATUS:
-                *params = programObject->isValidated();
-                return;
-              case GL_INFO_LOG_LENGTH:
-                *params = programObject->getInfoLogLength();
-                return;
-              case GL_ATTACHED_SHADERS:
-                *params = programObject->getAttachedShadersCount();
-                return;
-              case GL_ACTIVE_ATTRIBUTES:
-                *params = programObject->getActiveAttributeCount();
-                return;
-              case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
-                *params = programObject->getActiveAttributeMaxLength();
-                return;
-              case GL_ACTIVE_UNIFORMS:
-                *params = programObject->getActiveUniformCount();
-                return;
-              case GL_ACTIVE_UNIFORM_MAX_LENGTH:
-                *params = programObject->getActiveUniformMaxLength();
-                return;
-              case GL_PROGRAM_BINARY_LENGTH_OES:
-                *params = programObject->getProgramBinaryLength();
-                return;
               case GL_ACTIVE_UNIFORM_BLOCKS:
-                *params = programObject->getActiveUniformBlockCount();
-                return;
               case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
-                *params = programObject->getActiveUniformBlockMaxLength();
-                break;
               case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
-                *params = programObject->getTransformFeedbackBufferMode();
-                break;
               case GL_TRANSFORM_FEEDBACK_VARYINGS:
-                *params = programObject->getTransformFeedbackVaryingCount();
-                break;
               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;
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (pname)
+        {
+          case GL_DELETE_STATUS:
+            *params = programObject->isFlaggedForDeletion();
+            return;
+          case GL_LINK_STATUS:
+            *params = programObject->isLinked();
+            return;
+          case GL_VALIDATE_STATUS:
+            *params = programObject->isValidated();
+            return;
+          case GL_INFO_LOG_LENGTH:
+            *params = programObject->getInfoLogLength();
+            return;
+          case GL_ATTACHED_SHADERS:
+            *params = programObject->getAttachedShadersCount();
+            return;
+          case GL_ACTIVE_ATTRIBUTES:
+            *params = programObject->getActiveAttributeCount();
+            return;
+          case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+            *params = programObject->getActiveAttributeMaxLength();
+            return;
+          case GL_ACTIVE_UNIFORMS:
+            *params = programObject->getActiveUniformCount();
+            return;
+          case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+            *params = programObject->getActiveUniformMaxLength();
+            return;
+          case GL_PROGRAM_BINARY_LENGTH_OES:
+            *params = programObject->getProgramBinaryLength();
+            return;
+          case GL_ACTIVE_UNIFORM_BLOCKS:
+            *params = programObject->getActiveUniformBlockCount();
+            return;
+          case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
+            *params = programObject->getActiveUniformBlockMaxLength();
+            break;
+          case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+            *params = programObject->getTransformFeedbackBufferMode();
+            break;
+          case GL_TRANSFORM_FEEDBACK_VARYINGS:
+            *params = programObject->getTransformFeedbackVaryingCount();
+            break;
+          case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+            *params = programObject->getTransformFeedbackVaryingMaxLength();
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -3068,30 +2532,24 @@
     EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
           program, bufsize, length, infolog);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (bufsize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            programObject->getInfoLog(bufsize, length, infolog);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        programObject->getInfoLog(bufsize, length, infolog);
     }
 }
 
@@ -3099,31 +2557,25 @@
 {
     EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidQueryType(context, target))
         {
-            if (!ValidQueryType(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            switch (pname)
-            {
-              case GL_CURRENT_QUERY_EXT:
-                params[0] = context->getActiveQueryId(target);
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (pname)
+        {
+          case GL_CURRENT_QUERY_EXT:
+            params[0] = context->getState().getActiveQueryId(target);
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -3131,40 +2583,51 @@
 {
     EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
 
-        if (context)
+        if (!queryObject)
         {
-            gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
-
-            if (!queryObject)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (context->getActiveQueryId(queryObject->getType()) == id)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch(pname)
-            {
-              case GL_QUERY_RESULT_EXT:
-                params[0] = queryObject->getResult();
-                break;
-              case GL_QUERY_RESULT_AVAILABLE_EXT:
-                params[0] = queryObject->isResultAvailable();
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (context->getState().getActiveQueryId(queryObject->getType()) == id)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        switch(pname)
+        {
+          case GL_QUERY_RESULT_EXT:
+            {
+                gl::Error error = queryObject->getResult(params);
+                if (error.isError())
+                {
+                    context->recordError(error);
+                    return;
+                }
+            }
+            break;
+
+          case GL_QUERY_RESULT_AVAILABLE_EXT:
+            {
+                gl::Error error = queryObject->isResultAvailable(params);
+                if (error.isError())
+                {
+                    context->recordError(error);
+                    return;
+                }
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -3172,53 +2635,48 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (target != GL_RENDERBUFFER)
         {
-            if (target != GL_RENDERBUFFER)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            if (context->getRenderbufferHandle() == 0)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::FramebufferAttachment *attachment = context->getRenderbuffer(context->getRenderbufferHandle());
-
-            switch (pname)
-            {
-              case GL_RENDERBUFFER_WIDTH:           *params = attachment->getWidth();          break;
-              case GL_RENDERBUFFER_HEIGHT:          *params = attachment->getHeight();         break;
-              case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = attachment->getInternalFormat(); break;
-              case GL_RENDERBUFFER_RED_SIZE:        *params = attachment->getRedSize();        break;
-              case GL_RENDERBUFFER_GREEN_SIZE:      *params = attachment->getGreenSize();      break;
-              case GL_RENDERBUFFER_BLUE_SIZE:       *params = attachment->getBlueSize();       break;
-              case GL_RENDERBUFFER_ALPHA_SIZE:      *params = attachment->getAlphaSize();      break;
-              case GL_RENDERBUFFER_DEPTH_SIZE:      *params = attachment->getDepthSize();      break;
-              case GL_RENDERBUFFER_STENCIL_SIZE:    *params = attachment->getStencilSize();    break;
-              case GL_RENDERBUFFER_SAMPLES_ANGLE:
-                if (context->getMaxSupportedSamples() != 0)
-                {
-                    *params = attachment->getSamples();
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (context->getState().getRenderbufferId() == 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getState().getRenderbufferId());
+
+        switch (pname)
+        {
+          case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();          break;
+          case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();         break;
+          case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
+          case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();        break;
+          case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();      break;
+          case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();       break;
+          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)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = renderbuffer->getSamples();
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -3226,47 +2684,42 @@
 {
     EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context)
+        if (!shaderObject)
         {
-            gl::Shader *shaderObject = context->getShader(shader);
-
-            if (!shaderObject)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            switch (pname)
-            {
-              case GL_SHADER_TYPE:
-                *params = shaderObject->getType();
-                return;
-              case GL_DELETE_STATUS:
-                *params = shaderObject->isFlaggedForDeletion();
-                return;
-              case GL_COMPILE_STATUS:
-                *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
-                return;
-              case GL_INFO_LOG_LENGTH:
-                *params = shaderObject->getInfoLogLength();
-                return;
-              case GL_SHADER_SOURCE_LENGTH:
-                *params = shaderObject->getSourceLength();
-                return;
-              case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
-                *params = shaderObject->getTranslatedSourceLength();
-                return;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (pname)
+        {
+          case GL_SHADER_TYPE:
+            *params = shaderObject->getType();
+            return;
+          case GL_DELETE_STATUS:
+            *params = shaderObject->isFlaggedForDeletion();
+            return;
+          case GL_COMPILE_STATUS:
+            *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
+            return;
+          case GL_INFO_LOG_LENGTH:
+            *params = shaderObject->getInfoLogLength();
+            return;
+          case GL_SHADER_SOURCE_LENGTH:
+            *params = shaderObject->getSourceLength();
+            return;
+          case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
+            *params = shaderObject->getTranslatedSourceLength();
+            return;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -3275,30 +2728,24 @@
     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
           shader, bufsize, length, infolog);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (bufsize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context)
+        if (!shaderObject)
         {
-            gl::Shader *shaderObject = context->getShader(shader);
-
-            if (!shaderObject)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            shaderObject->getInfoLog(bufsize, length, infolog);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        shaderObject->getInfoLog(bufsize, length, infolog);
     }
 }
 
@@ -3307,15 +2754,18 @@
     EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
           shadertype, precisiontype, range, precision);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         switch (shadertype)
         {
           case GL_VERTEX_SHADER:
           case GL_FRAGMENT_SHADER:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (precisiontype)
@@ -3328,6 +2778,7 @@
             range[1] = 127;
             *precision = 23;
             break;
+
           case GL_LOW_INT:
           case GL_MEDIUM_INT:
           case GL_HIGH_INT:
@@ -3337,14 +2788,12 @@
             range[1] = 24;
             *precision = 0;
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
@@ -3352,30 +2801,24 @@
     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
           shader, bufsize, length, source);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (bufsize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context)
+        if (!shaderObject)
         {
-            gl::Shader *shaderObject = context->getShader(shader);
-
-            if (!shaderObject)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            shaderObject->getSource(bufsize, length, source);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        shaderObject->getSource(bufsize, length, source);
     }
 }
 
@@ -3384,30 +2827,24 @@
     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
           shader, bufsize, length, source);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (bufsize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context)
+        if (!shaderObject)
         {
-            gl::Shader *shaderObject = context->getShader(shader);
-
-            if (!shaderObject)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            shaderObject->getTranslatedSource(bufsize, length, source);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        shaderObject->getTranslatedSource(bufsize, length, source);
     }
 }
 
@@ -3415,43 +2852,45 @@
 {
     EVENT("(GLenum name = 0x%X)", name);
 
-    try
-    {
-        gl::Context *context = gl::getNonLostContext();
+    gl::Context *context = gl::getNonLostContext();
 
-        switch (name)
-        {
-          case GL_VENDOR:
-            return (GLubyte*)"Google Inc.";
-          case GL_RENDERER:
-            return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
-          case GL_VERSION:
-            if (context->getClientVersion() == 2)
-            {
-                return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")";
-            }
-            else
-            {
-                return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")";
-            }
-          case GL_SHADING_LANGUAGE_VERSION:
-            if (context->getClientVersion() == 2)
-            {
-                return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")";
-            }
-            else
-            {
-                return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")";
-            }
-          case GL_EXTENSIONS:
-            return (GLubyte*)((context != NULL) ? context->getCombinedExtensionsString() : "");
-          default:
-            return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL);
-        }
-    }
-    catch (...)
+    switch (name)
     {
-        return gl::error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
+      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)
+        {
+            return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")";
+        }
+        else
+        {
+            return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")";
+        }
+
+      case GL_SHADING_LANGUAGE_VERSION:
+        if (context->getClientVersion() == 2)
+        {
+            return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")";
+        }
+        else
+        {
+            return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")";
+        }
+
+      case GL_EXTENSIONS:
+        return (GLubyte*)((context != NULL) ? context->getExtensionString().c_str() : "");
+
+      default:
+        if (context)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+        }
+        return NULL;
     }
 }
 
@@ -3459,125 +2898,131 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Texture *texture = context->getTargetTexture(target);
 
-        if (context)
+        if (!texture)
         {
-            gl::Texture *texture = context->getTargetTexture(target);
-
-            if (!texture)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            switch (pname)
-            {
-              case GL_TEXTURE_MAG_FILTER:
-                *params = (GLfloat)texture->getMagFilter();
-                break;
-              case GL_TEXTURE_MIN_FILTER:
-                *params = (GLfloat)texture->getMinFilter();
-                break;
-              case GL_TEXTURE_WRAP_S:
-                *params = (GLfloat)texture->getWrapS();
-                break;
-              case GL_TEXTURE_WRAP_T:
-                *params = (GLfloat)texture->getWrapT();
-                break;
-              case GL_TEXTURE_WRAP_R:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->getWrapR();
-                break;
-              case GL_TEXTURE_IMMUTABLE_FORMAT:
-                // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
-                *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
-                break;
-              case GL_TEXTURE_IMMUTABLE_LEVELS:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->immutableLevelCount();
-                break;
-              case GL_TEXTURE_USAGE_ANGLE:
-                *params = (GLfloat)texture->getUsage();
-                break;
-              case GL_TEXTURE_MAX_ANISOTROPY_EXT:
-                if (!context->supportsTextureFilterAnisotropy())
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->getMaxAnisotropy();
-                break;
-              case GL_TEXTURE_SWIZZLE_R:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->getSwizzleRed();
-                break;
-              case GL_TEXTURE_SWIZZLE_G:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->getSwizzleGreen();
-                break;
-              case GL_TEXTURE_SWIZZLE_B:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->getSwizzleBlue();
-                break;
-              case GL_TEXTURE_SWIZZLE_A:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->getSwizzleAlpha();
-                break;
-              case GL_TEXTURE_BASE_LEVEL:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->getBaseLevel();
-                break;
-              case GL_TEXTURE_MAX_LEVEL:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLfloat)texture->getMaxLevel();
-                break;
-              case GL_TEXTURE_MIN_LOD:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getMinLod();
-                break;
-              case GL_TEXTURE_MAX_LOD:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getMaxLod();
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (pname)
+        {
+          case GL_TEXTURE_MAG_FILTER:
+            *params = (GLfloat)texture->getSamplerState().magFilter;
+            break;
+          case GL_TEXTURE_MIN_FILTER:
+            *params = (GLfloat)texture->getSamplerState().minFilter;
+            break;
+          case GL_TEXTURE_WRAP_S:
+            *params = (GLfloat)texture->getSamplerState().wrapS;
+            break;
+          case GL_TEXTURE_WRAP_T:
+            *params = (GLfloat)texture->getSamplerState().wrapT;
+            break;
+          case GL_TEXTURE_WRAP_R:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->getSamplerState().wrapR;
+            break;
+          case GL_TEXTURE_IMMUTABLE_FORMAT:
+            // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
+            *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
+            break;
+          case GL_TEXTURE_IMMUTABLE_LEVELS:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->immutableLevelCount();
+            break;
+          case GL_TEXTURE_USAGE_ANGLE:
+            *params = (GLfloat)texture->getUsage();
+            break;
+          case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+            if (!context->getExtensions().textureFilterAnisotropic)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->getSamplerState().maxAnisotropy;
+            break;
+          case GL_TEXTURE_SWIZZLE_R:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->getSamplerState().swizzleRed;
+            break;
+          case GL_TEXTURE_SWIZZLE_G:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->getSamplerState().swizzleGreen;
+            break;
+          case GL_TEXTURE_SWIZZLE_B:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->getSamplerState().swizzleBlue;
+            break;
+          case GL_TEXTURE_SWIZZLE_A:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->getSamplerState().swizzleAlpha;
+            break;
+          case GL_TEXTURE_BASE_LEVEL:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->getSamplerState().baseLevel;
+            break;
+          case GL_TEXTURE_MAX_LEVEL:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLfloat)texture->getSamplerState().maxLevel;
+            break;
+          case GL_TEXTURE_MIN_LOD:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().minLod;
+            break;
+          case GL_TEXTURE_MAX_LOD:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().maxLod;
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -3585,125 +3030,131 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Texture *texture = context->getTargetTexture(target);
 
-        if (context)
+        if (!texture)
         {
-            gl::Texture *texture = context->getTargetTexture(target);
-
-            if (!texture)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            switch (pname)
-            {
-              case GL_TEXTURE_MAG_FILTER:
-                *params = texture->getMagFilter();
-                break;
-              case GL_TEXTURE_MIN_FILTER:
-                *params = texture->getMinFilter();
-                break;
-              case GL_TEXTURE_WRAP_S:
-                *params = texture->getWrapS();
-                break;
-              case GL_TEXTURE_WRAP_T:
-                *params = texture->getWrapT();
-                break;
-              case GL_TEXTURE_WRAP_R:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getWrapR();
-                break;
-              case GL_TEXTURE_IMMUTABLE_FORMAT:
-                // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
-                *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
-                break;
-              case GL_TEXTURE_IMMUTABLE_LEVELS:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->immutableLevelCount();
-                break;
-              case GL_TEXTURE_USAGE_ANGLE:
-                *params = texture->getUsage();
-                break;
-              case GL_TEXTURE_MAX_ANISOTROPY_EXT:
-                if (!context->supportsTextureFilterAnisotropy())
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLint)texture->getMaxAnisotropy();
-                break;
-              case GL_TEXTURE_SWIZZLE_R:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getSwizzleRed();
-                break;
-              case GL_TEXTURE_SWIZZLE_G:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getSwizzleGreen();
-                break;
-              case GL_TEXTURE_SWIZZLE_B:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getSwizzleBlue();
-                break;
-              case GL_TEXTURE_SWIZZLE_A:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getSwizzleAlpha();
-                break;
-              case GL_TEXTURE_BASE_LEVEL:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getBaseLevel();
-                break;
-              case GL_TEXTURE_MAX_LEVEL:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = texture->getMaxLevel();
-                break;
-              case GL_TEXTURE_MIN_LOD:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLint)texture->getMinLod();
-                break;
-              case GL_TEXTURE_MAX_LOD:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                *params = (GLint)texture->getMaxLod();
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (pname)
+        {
+          case GL_TEXTURE_MAG_FILTER:
+            *params = texture->getSamplerState().magFilter;
+            break;
+          case GL_TEXTURE_MIN_FILTER:
+            *params = texture->getSamplerState().minFilter;
+            break;
+          case GL_TEXTURE_WRAP_S:
+            *params = texture->getSamplerState().wrapS;
+            break;
+          case GL_TEXTURE_WRAP_T:
+            *params = texture->getSamplerState().wrapT;
+            break;
+          case GL_TEXTURE_WRAP_R:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().wrapR;
+            break;
+          case GL_TEXTURE_IMMUTABLE_FORMAT:
+            // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
+            *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
+            break;
+          case GL_TEXTURE_IMMUTABLE_LEVELS:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->immutableLevelCount();
+            break;
+          case GL_TEXTURE_USAGE_ANGLE:
+            *params = texture->getUsage();
+            break;
+          case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+            if (!context->getExtensions().textureFilterAnisotropic)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLint)texture->getSamplerState().maxAnisotropy;
+            break;
+          case GL_TEXTURE_SWIZZLE_R:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().swizzleRed;
+            break;
+          case GL_TEXTURE_SWIZZLE_G:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().swizzleGreen;
+            break;
+          case GL_TEXTURE_SWIZZLE_B:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().swizzleBlue;
+            break;
+          case GL_TEXTURE_SWIZZLE_A:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().swizzleAlpha;
+            break;
+          case GL_TEXTURE_BASE_LEVEL:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().baseLevel;
+            break;
+          case GL_TEXTURE_MAX_LEVEL:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = texture->getSamplerState().maxLevel;
+            break;
+          case GL_TEXTURE_MIN_LOD:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLint)texture->getSamplerState().minLod;
+            break;
+          case GL_TEXTURE_MAX_LOD:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            *params = (GLint)texture->getSamplerState().maxLod;
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -3712,44 +3163,20 @@
     EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
           program, location, bufSize, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        if (bufSize < 0)
+        if (!ValidateGetnUniformfvEXT(context, program, location, bufSize, params))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
+        ASSERT(programObject);
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        ASSERT(programBinary);
 
-        if (context)
-        {
-            if (program == 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject || !programObject->isLinked())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programBinary)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!programBinary->getUniformfv(location, &bufSize, params))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        programBinary->getUniformfv(location, params);
     }
 }
 
@@ -3757,85 +3184,42 @@
 {
     EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateGetUniformfv(context, program, location, params))
         {
-            if (program == 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject || !programObject->isLinked())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programBinary)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!programBinary->getUniformfv(location, NULL, params))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Program *programObject = context->getProgram(program);
+        ASSERT(programObject);
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        ASSERT(programBinary);
+
+        programBinary->getUniformfv(location, params);
     }
 }
 
 void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
 {
-    EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", 
+    EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
           program, location, bufSize, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        if (bufSize < 0)
+        if (!ValidateGetnUniformivEXT(context, program, location, bufSize, params))
         {
-            return gl::error(GL_INVALID_VALUE);
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
+        ASSERT(programObject);
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        ASSERT(programBinary);
 
-        if (context)
-        {
-            if (program == 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject || !programObject->isLinked())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programBinary)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!programBinary->getUniformiv(location, &bufSize, params))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        programBinary->getUniformiv(location, params);
     }
 }
 
@@ -3843,83 +3227,59 @@
 {
     EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateGetUniformiv(context, program, location, params))
         {
-            if (program == 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject || !programObject->isLinked())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programBinary)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!programBinary->getUniformiv(location, NULL, params))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Program *programObject = context->getProgram(program);
+        ASSERT(programObject);
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        ASSERT(programBinary);
+
+        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);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
         if (strstr(name, "gl_") == name)
         {
             return -1;
         }
 
-        if (context)
+        gl::Program *programObject = context->getProgram(program);
+
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION, -1);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE, -1);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return -1;
             }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programObject->isLinked() || !programBinary)
+            else
             {
-                return gl::error(GL_INVALID_OPERATION, -1);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return -1;
             }
-
-            return programBinary->getUniformLocation(name);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, -1);
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        if (!programObject->isLinked() || !programBinary)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
+        }
+
+        return programBinary->getUniformLocation(name);
     }
 
     return -1;
@@ -3929,41 +3289,33 @@
 {
     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            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->getVertexAttribState(index);
+        const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
+        if (!gl::ValidateGetVertexAttribParameters(context, pname))
+        {
+            return;
+        }
 
-            if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+        if (pname == GL_CURRENT_VERTEX_ATTRIB)
+        {
+            const gl::VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
+            for (int i = 0; i < 4; ++i)
             {
-                return;
-            }
-
-            if (pname == GL_CURRENT_VERTEX_ATTRIB)
-            {
-                const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
-                for (int i = 0; i < 4; ++i)
-                {
-                    params[i] = currentValueData.FloatValues[i];
-                }
-            }
-            else
-            {
-                *params = attribState.querySingleParameter<GLfloat>(pname);
+                params[i] = currentValueData.FloatValues[i];
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        else
+        {
+            *params = gl::QuerySingleVertexAttributeParameter<GLfloat>(attribState, pname);
+        }
     }
 }
 
@@ -3971,42 +3323,35 @@
 {
     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            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->getVertexAttribState(index);
+        const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
 
-            if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
-            {
-                return;
-            }
+        if (!gl::ValidateGetVertexAttribParameters(context, pname))
+        {
+            return;
+        }
 
-            if (pname == GL_CURRENT_VERTEX_ATTRIB)
+        if (pname == GL_CURRENT_VERTEX_ATTRIB)
+        {
+            const gl::VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
+            for (int i = 0; i < 4; ++i)
             {
-                const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
-                for (int i = 0; i < 4; ++i)
-                {
-                    float currentValue = currentValueData.FloatValues[i];
-                    params[i] = gl::iround<GLint>(currentValue);
-                }
-            }
-            else
-            {
-                *params = attribState.querySingleParameter<GLint>(pname);
+                float currentValue = currentValueData.FloatValues[i];
+                params[i] = gl::iround<GLint>(currentValue);
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        else
+        {
+            *params = gl::QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
+        }
     }
 }
 
@@ -4014,28 +3359,22 @@
 {
     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
         {
-            if (index >= gl::MAX_VERTEX_ATTRIBS)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        *pointer = const_cast<GLvoid*>(context->getState().getVertexAttribPointer(index));
     }
 }
 
@@ -4043,7 +3382,8 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         switch (mode)
         {
@@ -4051,51 +3391,43 @@
           case GL_NICEST:
           case GL_DONT_CARE:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM); 
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
         switch (target)
         {
           case GL_GENERATE_MIPMAP_HINT:
-            if (context) context->setGenerateMipmapHint(mode);
+            context->getState().setGenerateMipmapHint(mode);
             break;
+
           case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
-            if (context) context->setFragmentShaderDerivativeHint(mode);
+            context->getState().setFragmentShaderDerivativeHint(mode);
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 GLboolean __stdcall glIsBuffer(GLuint buffer)
 {
     EVENT("(GLuint buffer = %d)", buffer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context && buffer)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Buffer *bufferObject = context->getBuffer(buffer);
 
-        if (context && buffer)
+        if (bufferObject)
         {
-            gl::Buffer *bufferObject = context->getBuffer(buffer);
-
-            if (bufferObject)
-            {
-                return GL_TRUE;
-            }
+            return GL_TRUE;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
-    }
 
     return GL_FALSE;
 }
@@ -4104,23 +3436,16 @@
 {
     EVENT("(GLenum cap = 0x%X)", cap);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidCap(context, cap))
         {
-            if (!ValidCap(context, cap))
-            {
-                return gl::error(GL_INVALID_ENUM, false);
-            }
-
-            return context->getCap(cap);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, false);
+
+        return context->getState().getEnableFeature(cap);
     }
 
     return false;
@@ -4130,25 +3455,17 @@
 {
     EVENT("(GLuint fence = %d)", fence);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
-        if (context)
+        if (fenceObject == NULL)
         {
-            gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
-            if (fenceObject == NULL)
-            {
-                return GL_FALSE;
-            }
-
-            return fenceObject->isFence();
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        return fenceObject->isFence();
     }
 
     return GL_FALSE;
@@ -4158,24 +3475,16 @@
 {
     EVENT("(GLuint framebuffer = %d)", framebuffer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context && framebuffer)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
 
-        if (context && framebuffer)
+        if (framebufferObject)
         {
-            gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
-
-            if (framebufferObject)
-            {
-                return GL_TRUE;
-            }
+            return GL_TRUE;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
-    }
 
     return GL_FALSE;
 }
@@ -4184,24 +3493,16 @@
 {
     EVENT("(GLuint program = %d)", program);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context && program)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context && program)
+        if (programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (programObject)
-            {
-                return GL_TRUE;
-            }
+            return GL_TRUE;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
-    }
 
     return GL_FALSE;
 }
@@ -4210,18 +3511,10 @@
 {
     EVENT("(GLuint id = %d)", id);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+        return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
     }
 
     return GL_FALSE;
@@ -4231,24 +3524,16 @@
 {
     EVENT("(GLuint renderbuffer = %d)", renderbuffer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context && renderbuffer)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
 
-        if (context && renderbuffer)
+        if (renderbufferObject)
         {
-            gl::FramebufferAttachment *renderbufferObject = context->getRenderbuffer(renderbuffer);
-
-            if (renderbufferObject)
-            {
-                return GL_TRUE;
-            }
+            return GL_TRUE;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
-    }
 
     return GL_FALSE;
 }
@@ -4257,24 +3542,16 @@
 {
     EVENT("(GLuint shader = %d)", shader);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context && shader)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context && shader)
+        if (shaderObject)
         {
-            gl::Shader *shaderObject = context->getShader(shader);
-
-            if (shaderObject)
-            {
-                return GL_TRUE;
-            }
+            return GL_TRUE;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
-    }
 
     return GL_FALSE;
 }
@@ -4283,24 +3560,16 @@
 {
     EVENT("(GLuint texture = %d)", texture);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context && texture)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Texture *textureObject = context->getTexture(texture);
 
-        if (context && texture)
+        if (textureObject)
         {
-            gl::Texture *textureObject = context->getTexture(texture);
-
-            if (textureObject)
-            {
-                return GL_TRUE;
-            }
+            return GL_TRUE;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
-    }
 
     return GL_FALSE;
 }
@@ -4309,23 +3578,16 @@
 {
     EVENT("(GLfloat width = %f)", width);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (width <= 0.0f)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setLineWidth(width);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setLineWidth(width);
     }
 }
 
@@ -4333,32 +3595,26 @@
 {
     EVENT("(GLuint program = %d)", program);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            context->linkProgram(program);
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->linkProgram(program);
     }
 }
 
@@ -4366,78 +3622,66 @@
 {
     EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        switch (pname)
         {
-            switch (pname)
+          case GL_UNPACK_ALIGNMENT:
+            if (param != 1 && param != 2 && param != 4 && param != 8)
             {
-              case GL_UNPACK_ALIGNMENT:
-                if (param != 1 && param != 2 && param != 4 && param != 8)
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-
-                context->setUnpackAlignment(param);
-                break;
-
-              case GL_PACK_ALIGNMENT:
-                if (param != 1 && param != 2 && param != 4 && param != 8)
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-
-                context->setPackAlignment(param);
-                break;
-
-              case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
-                context->setPackReverseRowOrder(param != 0);
-                break;
-
-              case GL_UNPACK_IMAGE_HEIGHT:
-              case GL_UNPACK_SKIP_IMAGES:
-              case GL_UNPACK_ROW_LENGTH:
-              case GL_UNPACK_SKIP_ROWS:
-              case GL_UNPACK_SKIP_PIXELS:
-              case GL_PACK_ROW_LENGTH:
-              case GL_PACK_SKIP_ROWS:
-              case GL_PACK_SKIP_PIXELS:
-                if (context->getClientVersion() < 3)
-                {
-                    return gl::error(GL_INVALID_ENUM);
-                }
-                UNIMPLEMENTED();
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
+
+            context->getState().setUnpackAlignment(param);
+            break;
+
+          case GL_PACK_ALIGNMENT:
+            if (param != 1 && param != 2 && param != 4 && param != 8)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+
+            context->getState().setPackAlignment(param);
+            break;
+
+          case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+            context->getState().setPackReverseRowOrder(param != 0);
+            break;
+
+          case GL_UNPACK_IMAGE_HEIGHT:
+          case GL_UNPACK_SKIP_IMAGES:
+          case GL_UNPACK_ROW_LENGTH:
+          case GL_UNPACK_SKIP_ROWS:
+          case GL_UNPACK_SKIP_PIXELS:
+          case GL_PACK_ROW_LENGTH:
+          case GL_PACK_SKIP_ROWS:
+          case GL_PACK_SKIP_PIXELS:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
+            }
+            UNIMPLEMENTED();
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
 {
     EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setPolygonOffsetParams(factor, units);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setPolygonOffsetParams(factor, units);
     }
 }
 
@@ -4449,29 +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);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (width < 0 || height < 0 || bufSize < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
+                                              format, type, &bufSize, data))
         {
-            if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
-                                                  format, type, &bufSize, data))
-            {
-                return;
-            }
-
-            context->readPixels(x, y, width, height, format, type, &bufSize, data);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Error error = context->readPixels(x, y, width, height, format, type, &bufSize, data);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -4482,29 +3724,27 @@
           "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
           x, y, width, height, format, type,  pixels);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (width < 0 || height < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
+                                              format, type, NULL, pixels))
         {
-            if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
-                                                  format, type, NULL, pixels))
-            {
-                return;
-            }
-
-            context->readPixels(x, y, width, height, format, type, NULL, pixels);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Error error = context->readPixels(x, y, width, height, format, type, NULL, pixels);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -4512,13 +3752,11 @@
 {
     EVENT("()");
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+
+    if (context)
     {
-        gl::Shader::releaseCompiler();
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->releaseShaderCompiler();
     }
 }
 
@@ -4527,24 +3765,16 @@
     EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
           target, samples, internalformat, width, height);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
+                                                   width, height, true))
         {
-            if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
-                                                       width, height, true))
-            {
-                return;
-            }
-
-            context->setRenderbufferStorage(width, height, internalformat, samples);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->setRenderbufferStorage(width, height, internalformat, samples);
     }
 }
 
@@ -4557,18 +3787,11 @@
 {
     EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert);
 
-    try
-    {
-        gl::Context* context = gl::getNonLostContext();
+    gl::Context* context = gl::getNonLostContext();
 
-        if (context)
-        {
-            context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
-        }
-    }
-    catch (...)
+    if (context)
     {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
     }
 }
 
@@ -4576,30 +3799,24 @@
 {
     EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (condition != GL_ALL_COMPLETED_NV)
         {
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
-        if (context)
+        if (fenceObject == NULL)
         {
-            gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
-            if (fenceObject == NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            fenceObject->setFence(condition);    
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        fenceObject->setFence(condition);
     }
 }
 
@@ -4607,23 +3824,16 @@
 {
     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
 
-    try
+    gl::Context* context = gl::getNonLostContext();
+    if (context)
     {
         if (width < 0 || height < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context* context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setScissorParams(x, y, width, height);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setScissorParams(x, y, width, height);
     }
 }
 
@@ -4633,14 +3843,18 @@
           "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
           n, shaders, binaryformat, binary, length);
 
-    try
+    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.
-        return gl::error(GL_INVALID_ENUM);
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        UNIMPLEMENTED();
     }
 }
 
@@ -4649,37 +3863,32 @@
     EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
           shader, count, string, length);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (count < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
+        gl::Shader *shaderObject = context->getShader(shader);
 
-        if (context)
+        if (!shaderObject)
         {
-            gl::Shader *shaderObject = context->getShader(shader);
-
-            if (!shaderObject)
+            if (context->getProgram(shader))
             {
-                if (context->getProgram(shader))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            shaderObject->setSource(count, string, length);
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        shaderObject->setSource(count, string, length);
     }
 }
 
@@ -4692,7 +3901,8 @@
 {
     EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         switch (face)
         {
@@ -4700,8 +3910,10 @@
           case GL_BACK:
           case GL_FRONT_AND_BACK:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (func)
@@ -4715,28 +3927,21 @@
           case GL_GREATER:
           case GL_NOTEQUAL:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
         {
-            if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
-            {
-                context->setStencilParams(func, ref, mask);
-            }
-
-            if (face == GL_BACK || face == GL_FRONT_AND_BACK)
-            {
-                context->setStencilBackParams(func, ref, mask);
-            }
+            context->getState().setStencilParams(func, ref, mask);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+        {
+            context->getState().setStencilBackParams(func, ref, mask);
+        }
     }
 }
 
@@ -4749,7 +3954,8 @@
 {
     EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         switch (face)
         {
@@ -4757,28 +3963,21 @@
           case GL_BACK:
           case GL_FRONT_AND_BACK:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
         {
-            if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
-            {
-                context->setStencilWritemask(mask);
-            }
-
-            if (face == GL_BACK || face == GL_FRONT_AND_BACK)
-            {
-                context->setStencilBackWritemask(mask);
-            }
+            context->getState().setStencilWritemask(mask);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+        {
+            context->getState().setStencilBackWritemask(mask);
+        }
     }
 }
 
@@ -4792,7 +3991,8 @@
     EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
           face, fail, zfail, zpass);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         switch (face)
         {
@@ -4800,8 +4000,10 @@
           case GL_BACK:
           case GL_FRONT_AND_BACK:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (fail)
@@ -4815,8 +4017,10 @@
           case GL_INCR_WRAP:
           case GL_DECR_WRAP:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (zfail)
@@ -4830,8 +4034,10 @@
           case GL_INCR_WRAP:
           case GL_DECR_WRAP:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         switch (zpass)
@@ -4845,28 +4051,21 @@
           case GL_INCR_WRAP:
           case GL_DECR_WRAP:
             break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
         {
-            if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
-            {
-                context->setStencilOperations(fail, zfail, zpass);
-            }
-
-            if (face == GL_BACK || face == GL_FRONT_AND_BACK)
-            {
-                context->setStencilBackOperations(fail, zfail, zpass);
-            }
+            context->getState().setStencilOperations(fail, zfail, zpass);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+        {
+            context->getState().setStencilBackOperations(fail, zfail, zpass);
+        }
     }
 }
 
@@ -4874,32 +4073,26 @@
 {
     EVENT("(GLuint fence = %d)", fence);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::FenceNV *fenceObject = context->getFenceNV(fence);
 
-        if (context)
+        if (fenceObject == NULL)
         {
-            gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
-            if (fenceObject == NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_TRUE);
-            }
-
-            if (fenceObject->isFence() != GL_TRUE)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_TRUE);
-            }
-
-            return fenceObject->testFence();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_TRUE;
         }
+
+        if (fenceObject->isFence() != GL_TRUE)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_TRUE;
+        }
+
+        return fenceObject->testFence();
     }
-    catch (...)
-    {
-        gl::error(GL_OUT_OF_MEMORY);
-    }
-    
+
     return GL_TRUE;
 }
 
@@ -4910,77 +4103,69 @@
           "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
           target, level, internalformat, width, height, border, format, type, pixels);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3 &&
+            !ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
+                                           0, 0, width, height, border, format, type, pixels))
         {
-            if (context->getClientVersion() < 3 &&
-                !ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
-                                               0, 0, width, height, border, format, type, pixels))
-            {
-                return;
-            }
-
-            if (context->getClientVersion() >= 3 &&
-                !ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
-                                               0, 0, 0, width, height, 1, border, format, type, pixels))
-            {
-                return;
-            }
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                {
-                    gl::Texture2D *texture = context->getTexture2D();
-                    texture->setImage(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->setImagePosX(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->setImageNegX(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->setImagePosY(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->setImageNegY(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->setImagePosZ(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->setImageNegZ(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-              default: UNREACHABLE();
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (context->getClientVersion() >= 3 &&
+            !ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
+                                           0, 0, 0, width, height, 1, border, format, type, pixels))
+        {
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+            {
+                gl::Texture2D *texture = context->getTexture2D();
+                texture->setImage(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->setImagePosX(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->setImageNegX(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->setImagePosY(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->setImageNegY(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->setImagePosZ(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->setImageNegZ(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+          default: UNREACHABLE();
+        }
     }
 }
 
@@ -4988,50 +4173,43 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
         {
-            if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
-            {
-                return;
-            }
-
-            gl::Texture *texture = context->getTargetTexture(target);
-
-            if (!texture)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            switch (pname)
-            {
-              case GL_TEXTURE_WRAP_S:               texture->setWrapS(gl::uiround<GLenum>(param));       break;
-              case GL_TEXTURE_WRAP_T:               texture->setWrapT(gl::uiround<GLenum>(param));       break;
-              case GL_TEXTURE_WRAP_R:               texture->setWrapR(gl::uiround<GLenum>(param));       break;
-              case GL_TEXTURE_MIN_FILTER:           texture->setMinFilter(gl::uiround<GLenum>(param));   break;
-              case GL_TEXTURE_MAG_FILTER:           texture->setMagFilter(gl::uiround<GLenum>(param));   break;
-              case GL_TEXTURE_USAGE_ANGLE:          texture->setUsage(gl::uiround<GLenum>(param));       break;
-              case GL_TEXTURE_MAX_ANISOTROPY_EXT:   texture->setMaxAnisotropy(param, context->getTextureMaxAnisotropy()); break;
-              case GL_TEXTURE_COMPARE_MODE:         texture->setCompareMode(gl::uiround<GLenum>(param)); break;
-              case GL_TEXTURE_COMPARE_FUNC:         texture->setCompareFunc(gl::uiround<GLenum>(param)); break;
-              case GL_TEXTURE_SWIZZLE_R:            texture->setSwizzleRed(gl::uiround<GLenum>(param));   break;
-              case GL_TEXTURE_SWIZZLE_G:            texture->setSwizzleGreen(gl::uiround<GLenum>(param)); break;
-              case GL_TEXTURE_SWIZZLE_B:            texture->setSwizzleBlue(gl::uiround<GLenum>(param));  break;
-              case GL_TEXTURE_SWIZZLE_A:            texture->setSwizzleAlpha(gl::uiround<GLenum>(param)); break;
-              case GL_TEXTURE_BASE_LEVEL:           texture->setBaseLevel(gl::iround<GLint>(param));      break;
-              case GL_TEXTURE_MAX_LEVEL:            texture->setMaxLevel(gl::iround<GLint>(param));       break;
-              case GL_TEXTURE_MIN_LOD:              texture->setMinLod(param);                            break;
-              case GL_TEXTURE_MAX_LOD:              texture->setMaxLod(param);                            break;
-              default: UNREACHABLE(); break;
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Texture *texture = context->getTargetTexture(target);
+
+        if (!texture)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_TEXTURE_WRAP_S:               texture->getSamplerState().wrapS = gl::uiround<GLenum>(param);        break;
+          case GL_TEXTURE_WRAP_T:               texture->getSamplerState().wrapT = gl::uiround<GLenum>(param);        break;
+          case GL_TEXTURE_WRAP_R:               texture->getSamplerState().wrapR = gl::uiround<GLenum>(param);        break;
+          case GL_TEXTURE_MIN_FILTER:           texture->getSamplerState().minFilter = gl::uiround<GLenum>(param);    break;
+          case GL_TEXTURE_MAG_FILTER:           texture->getSamplerState().magFilter = gl::uiround<GLenum>(param);    break;
+          case GL_TEXTURE_USAGE_ANGLE:          texture->setUsage(gl::uiround<GLenum>(param));                        break;
+          case GL_TEXTURE_MAX_ANISOTROPY_EXT:   texture->getSamplerState().maxAnisotropy = std::min(param, context->getExtensions().maxTextureAnisotropy); break;
+          case GL_TEXTURE_COMPARE_MODE:         texture->getSamplerState().compareMode = gl::uiround<GLenum>(param);  break;
+          case GL_TEXTURE_COMPARE_FUNC:         texture->getSamplerState().compareFunc = gl::uiround<GLenum>(param);  break;
+          case GL_TEXTURE_SWIZZLE_R:            texture->getSamplerState().swizzleRed = gl::uiround<GLenum>(param);   break;
+          case GL_TEXTURE_SWIZZLE_G:            texture->getSamplerState().swizzleGreen = gl::uiround<GLenum>(param); break;
+          case GL_TEXTURE_SWIZZLE_B:            texture->getSamplerState().swizzleBlue = gl::uiround<GLenum>(param);  break;
+          case GL_TEXTURE_SWIZZLE_A:            texture->getSamplerState().swizzleAlpha = gl::uiround<GLenum>(param); break;
+          case GL_TEXTURE_BASE_LEVEL:           texture->getSamplerState().baseLevel = gl::iround<GLint>(param);      break;
+          case GL_TEXTURE_MAX_LEVEL:            texture->getSamplerState().maxLevel = gl::iround<GLint>(param);       break;
+          case GL_TEXTURE_MIN_LOD:              texture->getSamplerState().minLod = param;                            break;
+          case GL_TEXTURE_MAX_LOD:              texture->getSamplerState().maxLod = param;                            break;
+          default: UNREACHABLE(); break;
+        }
     }
 }
 
@@ -5044,50 +4222,43 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateTexParamParameters(context, pname, param))
         {
-            if (!ValidateTexParamParameters(context, pname, param))
-            {
-                return;
-            }
-
-            gl::Texture *texture = context->getTargetTexture(target);
-
-            if (!texture)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            switch (pname)
-            {
-              case GL_TEXTURE_WRAP_S:               texture->setWrapS((GLenum)param);       break;
-              case GL_TEXTURE_WRAP_T:               texture->setWrapT((GLenum)param);       break;
-              case GL_TEXTURE_WRAP_R:               texture->setWrapR((GLenum)param);       break;
-              case GL_TEXTURE_MIN_FILTER:           texture->setMinFilter((GLenum)param);   break;
-              case GL_TEXTURE_MAG_FILTER:           texture->setMagFilter((GLenum)param);   break;
-              case GL_TEXTURE_USAGE_ANGLE:          texture->setUsage((GLenum)param);       break;
-              case GL_TEXTURE_MAX_ANISOTROPY_EXT:   texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()); break;
-              case GL_TEXTURE_COMPARE_MODE:         texture->setCompareMode((GLenum)param); break;
-              case GL_TEXTURE_COMPARE_FUNC:         texture->setCompareFunc((GLenum)param); break;
-              case GL_TEXTURE_SWIZZLE_R:            texture->setSwizzleRed((GLenum)param);   break;
-              case GL_TEXTURE_SWIZZLE_G:            texture->setSwizzleGreen((GLenum)param); break;
-              case GL_TEXTURE_SWIZZLE_B:            texture->setSwizzleBlue((GLenum)param);  break;
-              case GL_TEXTURE_SWIZZLE_A:            texture->setSwizzleAlpha((GLenum)param); break;
-              case GL_TEXTURE_BASE_LEVEL:           texture->setBaseLevel(param);            break;
-              case GL_TEXTURE_MAX_LEVEL:            texture->setMaxLevel(param);             break;
-              case GL_TEXTURE_MIN_LOD:              texture->setMinLod((GLfloat)param);      break;
-              case GL_TEXTURE_MAX_LOD:              texture->setMaxLod((GLfloat)param);      break;
-              default: UNREACHABLE(); break;
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Texture *texture = context->getTargetTexture(target);
+
+        if (!texture)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_TEXTURE_WRAP_S:               texture->getSamplerState().wrapS = (GLenum)param;        break;
+          case GL_TEXTURE_WRAP_T:               texture->getSamplerState().wrapT = (GLenum)param;        break;
+          case GL_TEXTURE_WRAP_R:               texture->getSamplerState().wrapR = (GLenum)param;        break;
+          case GL_TEXTURE_MIN_FILTER:           texture->getSamplerState().minFilter = (GLenum)param;    break;
+          case GL_TEXTURE_MAG_FILTER:           texture->getSamplerState().magFilter = (GLenum)param;    break;
+          case GL_TEXTURE_USAGE_ANGLE:          texture->setUsage((GLenum)param);                        break;
+          case GL_TEXTURE_MAX_ANISOTROPY_EXT:   texture->getSamplerState().maxAnisotropy = std::min((float)param, context->getExtensions().maxTextureAnisotropy); break;
+          case GL_TEXTURE_COMPARE_MODE:         texture->getSamplerState().compareMode = (GLenum)param;  break;
+          case GL_TEXTURE_COMPARE_FUNC:         texture->getSamplerState().compareFunc = (GLenum)param;  break;
+          case GL_TEXTURE_SWIZZLE_R:            texture->getSamplerState().swizzleRed = (GLenum)param;   break;
+          case GL_TEXTURE_SWIZZLE_G:            texture->getSamplerState().swizzleGreen = (GLenum)param; break;
+          case GL_TEXTURE_SWIZZLE_B:            texture->getSamplerState().swizzleBlue = (GLenum)param;  break;
+          case GL_TEXTURE_SWIZZLE_A:            texture->getSamplerState().swizzleAlpha = (GLenum)param; break;
+          case GL_TEXTURE_BASE_LEVEL:           texture->getSamplerState().baseLevel = param;            break;
+          case GL_TEXTURE_MAX_LEVEL:            texture->getSamplerState().maxLevel = param;             break;
+          case GL_TEXTURE_MIN_LOD:              texture->getSamplerState().minLod = (GLfloat)param;      break;
+          case GL_TEXTURE_MAX_LOD:              texture->getSamplerState().maxLod = (GLfloat)param;      break;
+          default: UNREACHABLE(); break;
+        }
     }
 }
 
@@ -5101,48 +4272,47 @@
     EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
            target, levels, internalformat, width, height);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!context->getExtensions().textureStorage)
         {
-            if (context->getClientVersion() < 3 &&
-                !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height))
-            {
-                return;
-            }
-
-            if (context->getClientVersion() >= 3 &&
-                !ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
-            {
-                return;
-            }
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                {
-                    gl::Texture2D *texture2d = context->getTexture2D();
-                    texture2d->storage(levels, internalformat, width, height);
-                }
-                break;
-
-              case GL_TEXTURE_CUBE_MAP:
-                {
-                    gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
-                    textureCube->storage(levels, internalformat, width);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (context->getClientVersion() < 3 &&
+            !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height))
+        {
+            return;
+        }
+
+        if (context->getClientVersion() >= 3 &&
+            !ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
+        {
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+            {
+                gl::Texture2D *texture2d = context->getTexture2D();
+                texture2d->storage(levels, internalformat, width, height);
+            }
+            break;
+
+          case GL_TEXTURE_CUBE_MAP:
+            {
+                gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
+                textureCube->storage(levels, internalformat, width);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -5154,61 +4324,53 @@
           "const GLvoid* pixels = 0x%0.8p)",
            target, level, xoffset, yoffset, width, height, format, type, pixels);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3 &&
+            !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true,
+                                           xoffset, yoffset, width, height, 0, format, type, pixels))
         {
-            if (context->getClientVersion() < 3 &&
-                !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true,
-                                               xoffset, yoffset, width, height, 0, format, type, pixels))
-            {
-                return;
-            }
-
-            if (context->getClientVersion() >= 3 &&
-                !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
-                                               xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels))
-            {
-                return;
-            }
-
-            // Zero sized uploads are valid but no-ops
-            if (width == 0 || height == 0)
-            {
-                return;
-            }
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                {
-                    gl::Texture2D *texture = context->getTexture2D();
-                    texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-                {
-                    gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                    texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-
-              default:
-                UNREACHABLE();
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (context->getClientVersion() >= 3 &&
+            !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
+                                           xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels))
+        {
+            return;
+        }
+
+        // Zero sized uploads are valid but no-ops
+        if (width == 0 || height == 0)
+        {
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+            {
+                gl::Texture2D *texture = context->getTexture2D();
+                texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            {
+                gl::TextureCubeMap *texture = context->getTextureCubeMap();
+                texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+
+          default:
+            UNREACHABLE();
+        }
     }
 }
 
@@ -5221,24 +4383,16 @@
 {
     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_FLOAT, location, count))
         {
-            if (!ValidateUniform(context, GL_FLOAT, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform1fv(location, count, v);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform1fv(location, count, v);
     }
 }
 
@@ -5251,24 +4405,16 @@
 {
     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_INT, location, count))
         {
-            if (!ValidateUniform(context, GL_INT, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform1iv(location, count, v);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform1iv(location, count, v);
     }
 }
 
@@ -5283,24 +4429,16 @@
 {
     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count))
         {
-            if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform2fv(location, count, v);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform2fv(location, count, v);
     }
 }
 
@@ -5315,24 +4453,16 @@
 {
     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_INT_VEC2, location, count))
         {
-            if (!ValidateUniform(context, GL_INT_VEC2, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform2iv(location, count, v);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform2iv(location, count, v);
     }
 }
 
@@ -5347,24 +4477,16 @@
 {
     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count))
         {
-            if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform3fv(location, count, v);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform3fv(location, count, v);
     }
 }
 
@@ -5379,24 +4501,16 @@
 {
     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_INT_VEC3, location, count))
         {
-            if (!ValidateUniform(context, GL_INT_VEC3, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform3iv(location, count, v);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform3iv(location, count, v);
     }
 }
 
@@ -5411,24 +4525,16 @@
 {
     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count))
         {
-            if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform4fv(location, count, v);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform4fv(location, count, v);
     }
 }
 
@@ -5443,24 +4549,16 @@
 {
     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_INT_VEC4, location, count))
         {
-            if (!ValidateUniform(context, GL_INT_VEC4, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform4iv(location, count, v);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform4iv(location, count, v);
     }
 }
 
@@ -5469,24 +4567,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix2fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix2fv(location, count, transpose, value);
     }
 }
 
@@ -5495,24 +4585,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix3fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix3fv(location, count, transpose, value);
     }
 }
 
@@ -5521,24 +4603,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix4fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix4fv(location, count, transpose, value);
     }
 }
 
@@ -5546,37 +4620,32 @@
 {
     EVENT("(GLuint program = %d)", program);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject && program != 0)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject && program != 0)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            if (program != 0 && !programObject->isLinked())
+            else
             {
-                return gl::error(GL_INVALID_OPERATION);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
-
-            context->useProgram(program);
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (program != 0 && !programObject->isLinked())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        context->useProgram(program);
     }
 }
 
@@ -5584,32 +4653,26 @@
 {
     EVENT("(GLuint program = %d)", program);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject)
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
-
-            programObject->validate();
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        programObject->validate(context->getCaps());
     }
 }
 
@@ -5617,24 +4680,17 @@
 {
     EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            GLfloat vals[4] = { x, 0, 0, 1 };
-            context->setVertexAttribf(index, vals);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        GLfloat vals[4] = { x, 0, 0, 1 };
+        context->getState().setVertexAttribf(index, vals);
     }
 }
 
@@ -5642,24 +4698,17 @@
 {
     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            GLfloat vals[4] = { values[0], 0, 0, 1 };
-            context->setVertexAttribf(index, vals);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        GLfloat vals[4] = { values[0], 0, 0, 1 };
+        context->getState().setVertexAttribf(index, vals);
     }
 }
 
@@ -5667,24 +4716,17 @@
 {
     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            GLfloat vals[4] = { x, y, 0, 1 };
-            context->setVertexAttribf(index, vals);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        GLfloat vals[4] = { x, y, 0, 1 };
+        context->getState().setVertexAttribf(index, vals);
     }
 }
 
@@ -5692,24 +4734,17 @@
 {
     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            GLfloat vals[4] = { values[0], values[1], 0, 1 };
-            context->setVertexAttribf(index, vals);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        GLfloat vals[4] = { values[0], values[1], 0, 1 };
+        context->getState().setVertexAttribf(index, vals);
     }
 }
 
@@ -5717,24 +4752,17 @@
 {
     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            GLfloat vals[4] = { x, y, z, 1 };
-            context->setVertexAttribf(index, vals);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        GLfloat vals[4] = { x, y, z, 1 };
+        context->getState().setVertexAttribf(index, vals);
     }
 }
 
@@ -5742,24 +4770,17 @@
 {
     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            GLfloat vals[4] = { values[0], values[1], values[2], 1 };
-            context->setVertexAttribf(index, vals);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        GLfloat vals[4] = { values[0], values[1], values[2], 1 };
+        context->getState().setVertexAttribf(index, vals);
     }
 }
 
@@ -5767,24 +4788,17 @@
 {
     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            GLfloat vals[4] = { x, y, z, w };
-            context->setVertexAttribf(index, vals);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        GLfloat vals[4] = { x, y, z, w };
+        context->getState().setVertexAttribf(index, vals);
     }
 }
 
@@ -5792,23 +4806,16 @@
 {
     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setVertexAttribf(index, values);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setVertexAttribf(index, values);
     }
 }
 
@@ -5816,23 +4823,16 @@
 {
     EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
 
-    try
+    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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setVertexAttribDivisor(index, divisor);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->setVertexAttribDivisor(index, divisor);
     }
 }
 
@@ -5842,20 +4842,21 @@
           "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
           index, size, type, normalized, stride, ptr);
 
-    try
+    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 (size < 1 || size > 4)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
         switch (type)
         {
           case GL_BYTE:
@@ -5865,51 +4866,48 @@
           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)
+            if (context->getClientVersion() < 3)
             {
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
-            else
-            {
-                break;
-            }
+            break;
+
           default:
-            return gl::error(GL_INVALID_ENUM);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (stride < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            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)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (context)
+        // [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)
         {
-            // [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->getVertexArrayHandle() != 0 && context->getArrayBufferHandle() == 0 && ptr != NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->setVertexAttribState(index, context->getArrayBuffer(), size, type,
-                                          normalized == GL_TRUE, false, stride, ptr);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type,
+                                                 normalized == GL_TRUE, false, stride, ptr);
     }
 }
 
@@ -5917,23 +4915,16 @@
 {
     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
         if (width < 0 || height < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            context->setViewportParams(x, y, width, height);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->getState().setViewportParams(x, y, width, height);
     }
 }
 
@@ -5943,24 +4934,17 @@
 {
     EVENT("(GLenum mode = 0x%X)", mode);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // glReadBuffer
-            UNIMPLEMENTED();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // glReadBuffer
+        UNIMPLEMENTED();
     }
 }
 
@@ -5969,24 +4953,17 @@
     EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, "
           "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // glDrawRangeElements
-            UNIMPLEMENTED();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // glDrawRangeElements
+        UNIMPLEMENTED();
     }
 }
 
@@ -5997,48 +4974,42 @@
           "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
           target, level, internalformat, width, height, depth, border, format, type, pixels);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // validateES3TexImageFormat sets the error code if there is an error
-            if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
-                                               0, 0, 0, width, height, depth, border, format, type, pixels))
-            {
-                return;
-            }
-
-            switch(target)
-            {
-              case GL_TEXTURE_3D:
-                {
-                    gl::Texture3D *texture = context->getTexture3D();
-                    texture->setImage(level, width, height, depth, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-
-              case GL_TEXTURE_2D_ARRAY:
-                {
-                    gl::Texture2DArray *texture = context->getTexture2DArray();
-                    texture->setImage(level, width, height, depth, internalformat, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // validateES3TexImageFormat sets the error code if there is an error
+        if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
+                                           0, 0, 0, width, height, depth, border, format, type, pixels))
+        {
+            return;
+        }
+
+        switch(target)
+        {
+          case GL_TEXTURE_3D:
+            {
+                gl::Texture3D *texture = context->getTexture3D();
+                texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+
+          case GL_TEXTURE_2D_ARRAY:
+            {
+                gl::Texture2DArray *texture = context->getTexture2DArray();
+                texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -6049,55 +5020,49 @@
           "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
           target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // validateES3TexImageFormat sets the error code if there is an error
-            if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
-                                               xoffset, yoffset, zoffset, width, height, depth, 0,
-                                               format, type, pixels))
-            {
-                return;
-            }
-
-            // Zero sized uploads are valid but no-ops
-            if (width == 0 || height == 0 || depth == 0)
-            {
-                return;
-            }
-
-            switch(target)
-            {
-              case GL_TEXTURE_3D:
-                {
-                    gl::Texture3D *texture = context->getTexture3D();
-                    texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-
-              case GL_TEXTURE_2D_ARRAY:
-                {
-                    gl::Texture2DArray *texture = context->getTexture2DArray();
-                    texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackState(), pixels);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // validateES3TexImageFormat sets the error code if there is an error
+        if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
+                                           xoffset, yoffset, zoffset, width, height, depth, 0,
+                                           format, type, pixels))
+        {
+            return;
+        }
+
+        // Zero sized uploads are valid but no-ops
+        if (width == 0 || height == 0 || depth == 0)
+        {
+            return;
+        }
+
+        switch(target)
+        {
+          case GL_TEXTURE_3D:
+            {
+                gl::Texture3D *texture = context->getTexture3D();
+                texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+
+          case GL_TEXTURE_2D_ARRAY:
+            {
+                gl::Texture2DArray *texture = context->getTexture2DArray();
+                texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -6107,45 +5072,39 @@
           "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
           target, level, xoffset, yoffset, zoffset, x, y, width, height);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
-                                                   x, y, width, height, 0))
-            {
-                return;
-            }
-
-            gl::Framebuffer *framebuffer = context->getReadFramebuffer();
-            gl::Texture *texture = NULL;
-            switch (target)
-            {
-              case GL_TEXTURE_3D:
-                texture = context->getTexture3D();
-                break;
-
-              case GL_TEXTURE_2D_ARRAY:
-                texture = context->getTexture2DArray();
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
+                                               x, y, width, height, 0))
+        {
+            return;
+        }
+
+        gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
+        gl::Texture *texture = NULL;
+        switch (target)
+        {
+          case GL_TEXTURE_3D:
+            texture = context->getTexture3D();
+            break;
+
+          case GL_TEXTURE_2D_ARRAY:
+            texture = context->getTexture2DArray();
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
     }
 }
 
@@ -6156,53 +5115,49 @@
           "const GLvoid* data = 0x%0.8p)",
           target, level, internalformat, width, height, depth, border, imageSize, data);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height))
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            // validateES3TexImageFormat sets the error code if there is an error
-            if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
-                                               0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data))
-            {
-                return;
-            }
-
-            switch(target)
-            {
-              case GL_TEXTURE_3D:
-                {
-                    gl::Texture3D *texture = context->getTexture3D();
-                    texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
-                }
-                break;
-
-              case GL_TEXTURE_2D_ARRAY:
-                {
-                    gl::Texture2DArray *texture = context->getTexture2DArray();
-                    texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+        if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        // validateES3TexImageFormat sets the error code if there is an error
+        if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
+                                           0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data))
+        {
+            return;
+        }
+
+        switch(target)
+        {
+          case GL_TEXTURE_3D:
+            {
+                gl::Texture3D *texture = context->getTexture3D();
+                texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
+            }
+            break;
+
+          case GL_TEXTURE_2D_ARRAY:
+            {
+                gl::Texture2DArray *texture = context->getTexture2DArray();
+                texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -6213,66 +5168,63 @@
         "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
         target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height))
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            if (!data)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            // validateES3TexImageFormat sets the error code if there is an error
-            if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
-                                               0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data))
-            {
-                return;
-            }
-
-            // Zero sized uploads are valid but no-ops
-            if (width == 0 || height == 0)
-            {
-                return;
-            }
-
-            switch(target)
-            {
-              case GL_TEXTURE_3D:
-                {
-                    gl::Texture3D *texture = context->getTexture3D();
-                    texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
-                                                format, imageSize, data);
-                }
-                break;
-
-              case GL_TEXTURE_2D_ARRAY:
-                {
-                    gl::Texture2DArray *texture = context->getTexture2DArray();
-                    texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
-                                                format, imageSize, data);
-                }
-                break;
-
-            default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
+        if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        if (!data)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        // validateES3TexImageFormat sets the error code if there is an error
+        if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
+                                           0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data))
+        {
+            return;
+        }
+
+        // Zero sized uploads are valid but no-ops
+        if (width == 0 || height == 0)
+        {
+            return;
+        }
+
+        switch(target)
+        {
+          case GL_TEXTURE_3D:
+            {
+                gl::Texture3D *texture = context->getTexture3D();
+                texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
+                                            format, imageSize, data);
+            }
+            break;
+
+          case GL_TEXTURE_2D_ARRAY:
+            {
+                gl::Texture2DArray *texture = context->getTexture2DArray();
+                texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
+                                            format, imageSize, data);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -6280,31 +5232,25 @@
 {
     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (n < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            for (GLsizei i = 0; i < n; i++)
-            {
-                ids[i] = context->createQuery();
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        for (GLsizei i = 0; i < n; i++)
+        {
+            ids[i] = context->createQuery();
+        }
     }
 }
 
@@ -6312,31 +5258,25 @@
 {
     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (n < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            for (GLsizei i = 0; i < n; i++)
-            {
-                context->deleteQuery(ids[i]);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        for (GLsizei i = 0; i < n; i++)
+        {
+            context->deleteQuery(ids[i]);
+        }
     }
 }
 
@@ -6344,23 +5284,16 @@
 {
     EVENT("(GLuint id = %u)", id);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_FALSE);
-            }
-
-            return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
     }
 
     return GL_FALSE;
@@ -6370,27 +5303,26 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateBeginQuery(context, target, id))
-            {
-                return;
-            }
-            context->beginQuery(target, id);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateBeginQuery(context, target, id))
+        {
+            return;
+        }
+
+        gl::Error error = context->beginQuery(target, id);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -6398,28 +5330,26 @@
 {
     EVENT("(GLenum target = 0x%X)", target);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateEndQuery(context, target))
-            {
-                return;
-            }
-
-            context->endQuery(target);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateEndQuery(context, target))
+        {
+            return;
+        }
+
+        gl::Error error = context->endQuery(target);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -6427,36 +5357,31 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidQueryType(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            switch (pname)
-            {
-              case GL_CURRENT_QUERY:
-                params[0] = static_cast<GLint>(context->getActiveQueryId(target));
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidQueryType(context, target))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_CURRENT_QUERY:
+            params[0] = static_cast<GLint>(context->getState().getActiveQueryId(target));
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -6464,45 +5389,57 @@
 {
     EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
-
-            if (!queryObject)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (context->getActiveQueryId(queryObject->getType()) == id)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch(pname)
-            {
-              case GL_QUERY_RESULT:
-                params[0] = queryObject->getResult();
-                break;
-              case GL_QUERY_RESULT_AVAILABLE:
-                params[0] = queryObject->isResultAvailable();
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
+
+        if (!queryObject)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (context->getState().getActiveQueryId(queryObject->getType()) == id)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        switch(pname)
+        {
+          case GL_QUERY_RESULT_EXT:
+            {
+                gl::Error error = queryObject->getResult(params);
+                if (error.isError())
+                {
+                    context->recordError(error);
+                    return;
+                }
+            }
+            break;
+
+          case GL_QUERY_RESULT_AVAILABLE_EXT:
+            {
+                gl::Error error = queryObject->isResultAvailable(params);
+                if (error.isError())
+                {
+                    context->recordError(error);
+                    return;
+                }
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -6510,23 +5447,16 @@
 {
     EVENT("(GLenum target = 0x%X)", target);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_FALSE);
-            }
-
-            return glUnmapBufferOES(target);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        return glUnmapBufferOES(target);
     }
 
     return GL_FALSE;
@@ -6536,45 +5466,31 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            glGetBufferPointervOES(target, pname, params);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        glGetBufferPointervOES(target, pname, params);
     }
 }
 
 void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs)
 {
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            glDrawBuffersEXT(n, bufs);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        glDrawBuffersEXT(n, bufs);
     }
 }
 
@@ -6583,24 +5499,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix2x3fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix2x3fv(location, count, transpose, value);
     }
 }
 
@@ -6609,24 +5517,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix3x2fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix3x2fv(location, count, transpose, value);
     }
 }
 
@@ -6635,24 +5535,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix2x4fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix2x4fv(location, count, transpose, value);
     }
 }
 
@@ -6661,24 +5553,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix4x2fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix4x2fv(location, count, transpose, value);
     }
 }
 
@@ -6687,24 +5571,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix3x4fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix3x4fv(location, count, transpose, value);
     }
 }
 
@@ -6713,24 +5589,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
           location, count, transpose, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
         {
-            if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniformMatrix4x3fv(location, count, transpose, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniformMatrix4x3fv(location, count, transpose, value);
     }
 }
 
@@ -6740,30 +5608,24 @@
           "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
           srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
-                                                   dstX0, dstY0, dstX1, dstY1, mask, filter,
-                                                   false))
-            {
-                return;
-            }
-
-            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
-                                     mask, filter);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
+                                               dstX0, dstY0, dstX1, dstY1, mask, filter,
+                                               false))
+        {
+            return;
+        }
+
+        context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+                                 mask, filter);
     }
 }
 
@@ -6772,29 +5634,22 @@
     EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
         target, samples, internalformat, width, height);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
-                                                       width, height, false))
-            {
-                return;
-            }
-
-            context->setRenderbufferStorage(width, height, internalformat, samples);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
+                                                   width, height, false))
+        {
+            return;
+        }
+
+        context->setRenderbufferStorage(width, height, internalformat, samples);
     }
 }
 
@@ -6803,48 +5658,36 @@
     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)",
         target, attachment, texture, level, layer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateFramebufferTextureLayer(context, target, attachment, texture,
+                                             level, layer))
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
+            return;
+        }
 
-            if (!ValidateES3FramebufferTextureParameters(context, target, attachment, GL_NONE, texture, level, layer, true))
-            {
-                return;
-            }
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+        ASSERT(framebuffer);
 
-            gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
-            ASSERT(framebuffer);
+        gl::Texture *textureObject = context->getTexture(texture);
+        GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE;
 
-            gl::Texture *textureObject = context->getTexture(texture);
-            GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE;
-
-            if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+        if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+        {
+            const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+            framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer);
+        }
+        else
+        {
+            switch (attachment)
             {
-                const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
-                framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer);
-            }
-            else
-            {
-                switch (attachment)
-                {
-                case GL_DEPTH_ATTACHMENT:         framebuffer->setDepthbuffer(textarget, texture, level, layer);        break;
-                case GL_STENCIL_ATTACHMENT:       framebuffer->setStencilbuffer(textarget, texture, level, layer);      break;
-                case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break;
-                }
+              case GL_DEPTH_ATTACHMENT:         framebuffer->setDepthbuffer(textarget, texture, level, layer);        break;
+              case GL_STENCIL_ATTACHMENT:       framebuffer->setStencilbuffer(textarget, texture, level, layer);      break;
+              case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break;
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
@@ -6852,23 +5695,16 @@
     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
           target, offset, length, access);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            return glMapBufferRangeEXT(target, offset, length, access);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL));
+
+        return glMapBufferRangeEXT(target, offset, length, access);
     }
 
     return NULL;
@@ -6878,23 +5714,16 @@
 {
     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            glFlushMappedBufferRangeEXT(target, offset, length);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        glFlushMappedBufferRangeEXT(target, offset, length);
     }
 }
 
@@ -6902,32 +5731,26 @@
 {
     EVENT("(GLuint array = %u)", array);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::VertexArray *vao = context->getVertexArray(array);
-
-            if (!vao)
-            {
-                // The default VAO should always exist
-                ASSERT(array != 0);
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->bindVertexArray(array);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::VertexArray *vao = context->getVertexArray(array);
+
+        if (!vao)
+        {
+            // The default VAO should always exist
+            ASSERT(array != 0);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        context->bindVertexArray(array);
     }
 }
 
@@ -6935,66 +5758,54 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            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);
-            }
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
 
-            for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+        for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+        {
+            if (arrays[arrayIndex] != 0)
             {
-                if (arrays[arrayIndex] != 0)
-                {
-                    context->deleteVertexArray(arrays[arrayIndex]);
-                }
+                context->deleteVertexArray(arrays[arrayIndex]);
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays)
 {
     EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (n < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
-            {
-                arrays[arrayIndex] = context->createVertexArray();
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (n < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+        {
+            arrays[arrayIndex] = context->createVertexArray();
+        }
     }
 }
 
@@ -7002,30 +5813,23 @@
 {
     EVENT("(GLuint array = %u)", array);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_FALSE);
-            }
-
-            if (array == 0)
-            {
-                return GL_FALSE;
-            }
-
-            gl::VertexArray *vao = context->getVertexArray(array);
-
-            return (vao != NULL ? GL_TRUE : GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        if (array == 0)
+        {
+            return GL_FALSE;
+        }
+
+        gl::VertexArray *vao = context->getVertexArray(array);
+
+        return (vao != NULL ? GL_TRUE : GL_FALSE);
     }
 
     return GL_FALSE;
@@ -7036,120 +5840,124 @@
     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)",
           target, index, data);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
+            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 >= caps.maxTransformFeedbackSeparateAttributes)
             {
-                return gl::error(GL_INVALID_OPERATION);
+                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 >= caps.maxCombinedUniformBlocks)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        if (!(context->getIndexedIntegerv(target, index, data)))
+        {
+            GLenum nativeType;
+            unsigned int numParams = 0;
+            if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
 
-            switch (target)
+            if (numParams == 0)
             {
-              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);
-                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);
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
+                return; // it is known that pname is valid, but there are no parameters to return
             }
 
-            if (!(context->getIndexedIntegerv(target, index, data)))
+            if (nativeType == GL_INT_64_ANGLEX)
             {
-                GLenum nativeType;
-                unsigned int numParams = 0;
-                if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
-                    return gl::error(GL_INVALID_ENUM);
+                GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min());
+                GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max());
+                GLint64 *int64Params = new GLint64[numParams];
 
-                if (numParams == 0)
-                    return; // it is known that pname is valid, but there are no parameters to return
+                context->getIndexedInteger64v(target, index, int64Params);
 
-                if (nativeType == GL_INT_64_ANGLEX)
+                for (unsigned int i = 0; i < numParams; ++i)
                 {
-                    GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min());
-                    GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max());
-                    GLint64 *int64Params = new GLint64[numParams];
-
-                    context->getIndexedInteger64v(target, index, int64Params);
-
-                    for (unsigned int i = 0; i < numParams; ++i)
-                    {
-                        GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue);
-                        data[i] = static_cast<GLint>(clampedValue);
-                    }
-
-                    delete [] int64Params;
+                    GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue);
+                    data[i] = static_cast<GLint>(clampedValue);
                 }
-                else
-                {
-                    UNREACHABLE();
-                }
+
+                delete [] int64Params;
+            }
+            else
+            {
+                UNREACHABLE();
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
 {
     EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (primitiveMode)
-            {
-              case GL_TRIANGLES:
-              case GL_LINES:
-              case GL_POINTS:
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
-            ASSERT(transformFeedback != NULL);
-
-            if (transformFeedback->isStarted())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (transformFeedback->isPaused())
-            {
-                transformFeedback->resume();
-            }
-            else
-            {
-                transformFeedback->start(primitiveMode);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (primitiveMode)
+        {
+          case GL_TRIANGLES:
+          case GL_LINES:
+          case GL_POINTS:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+        ASSERT(transformFeedback != NULL);
+
+        if (transformFeedback->isStarted())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (transformFeedback->isPaused())
+        {
+            transformFeedback->resume();
+        }
+        else
+        {
+            transformFeedback->start(primitiveMode);
+        }
     }
 }
 
@@ -7157,31 +5965,25 @@
 {
     EVENT("(void)");
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
-            ASSERT(transformFeedback != NULL);
-
-            if (!transformFeedback->isStarted())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            transformFeedback->stop();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+        ASSERT(transformFeedback != NULL);
+
+        if (!transformFeedback->isStarted())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        transformFeedback->stop();
     }
 }
 
@@ -7190,76 +5992,76 @@
     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)",
           target, index, buffer, offset, size);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (target)
-            {
-              case GL_TRANSFORM_FEEDBACK_BUFFER:
-                if (index >= context->getMaxTransformFeedbackBufferBindings())
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-
-              case GL_UNIFORM_BUFFER:
-                if (index >= context->getMaximumCombinedUniformBufferBindings())
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            if (buffer != 0 && size <= 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            switch (target)
-            {
-              case GL_TRANSFORM_FEEDBACK_BUFFER:
-
-                // 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->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
-                context->bindGenericTransformFeedbackBuffer(buffer);
-                break;
-
-              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)
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-
-                context->bindIndexedUniformBuffer(buffer, index, offset, size);
-                context->bindGenericUniformBuffer(buffer);
-                break;
-
-              default:
-                UNREACHABLE();
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        const gl::Caps &caps = context->getCaps();
+        switch (target)
+        {
+          case GL_TRANSFORM_FEEDBACK_BUFFER:
+            if (index >= caps.maxTransformFeedbackSeparateAttributes)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          case GL_UNIFORM_BUFFER:
+            if (index >= caps.maxUniformBufferBindings)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        if (buffer != 0 && size <= 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TRANSFORM_FEEDBACK_BUFFER:
+
+            // size and offset must be a multiple of 4
+            if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+
+            context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
+            context->bindGenericTransformFeedbackBuffer(buffer);
+            break;
+
+          case GL_UNIFORM_BUFFER:
+
+            // it is an error to bind an offset not a multiple of the alignment
+            if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+
+            context->bindIndexedUniformBuffer(buffer, index, offset, size);
+            context->bindGenericUniformBuffer(buffer);
+            break;
+
+          default:
+            UNREACHABLE();
+        }
     }
 }
 
@@ -7268,57 +6070,54 @@
     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)",
           target, index, buffer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (target)
-            {
-              case GL_TRANSFORM_FEEDBACK_BUFFER:
-                if (index >= context->getMaxTransformFeedbackBufferBindings())
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-
-              case GL_UNIFORM_BUFFER:
-                if (index >= context->getMaximumCombinedUniformBufferBindings())
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            switch (target)
-            {
-              case GL_TRANSFORM_FEEDBACK_BUFFER:
-                context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
-                context->bindGenericTransformFeedbackBuffer(buffer);
-                break;
-
-              case GL_UNIFORM_BUFFER:
-                context->bindIndexedUniformBuffer(buffer, index, 0, 0);
-                context->bindGenericUniformBuffer(buffer);
-                break;
-
-              default:
-                UNREACHABLE();
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        const gl::Caps &caps = context->getCaps();
+        switch (target)
+        {
+          case GL_TRANSFORM_FEEDBACK_BUFFER:
+            if (index >= caps.maxTransformFeedbackSeparateAttributes)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          case GL_UNIFORM_BUFFER:
+            if (index >= caps.maxUniformBufferBindings)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TRANSFORM_FEEDBACK_BUFFER:
+            context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
+            context->bindGenericTransformFeedbackBuffer(buffer);
+            break;
+
+          case GL_UNIFORM_BUFFER:
+            context->bindIndexedUniformBuffer(buffer, index, 0, 0);
+            context->bindGenericUniformBuffer(buffer);
+            break;
+
+          default:
+            UNREACHABLE();
+        }
     }
 }
 
@@ -7327,50 +6126,47 @@
     EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)",
           program, count, varyings, bufferMode);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            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);
-            }
+        if (count < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
 
-            switch (bufferMode)
+        const gl::Caps &caps = context->getCaps();
+        switch (bufferMode)
+        {
+          case GL_INTERLEAVED_ATTRIBS:
+            break;
+          case GL_SEPARATE_ATTRIBS:
+            if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
             {
-              case GL_INTERLEAVED_ATTRIBS:
-                break;
-              case GL_SEPARATE_ATTRIBS:
-                if (static_cast<GLuint>(count) > context->getMaxTransformFeedbackBufferBindings())
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            if (!gl::ValidProgram(context, program))
-            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
                 return;
             }
-
-            gl::Program *programObject = context->getProgram(program);
-            ASSERT(programObject);
-
-            programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
+            break;
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!gl::ValidProgram(context, program))
+        {
+            return;
+        }
+
+        gl::Program *programObject = context->getProgram(program);
+        ASSERT(programObject);
+
+        programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
     }
 }
 
@@ -7380,41 +6176,36 @@
           "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
           program, index, bufSize, length, size, type, name);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (bufSize < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            if (!gl::ValidProgram(context, program))
-            {
-                return;
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-            ASSERT(programObject);
-
-            if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (bufSize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        if (!gl::ValidProgram(context, program))
+        {
+            return;
+        }
+
+        gl::Program *programObject = context->getProgram(program);
+        ASSERT(programObject);
+
+        if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
     }
 }
 
@@ -7423,26 +6214,25 @@
     EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)",
           index, size, type, stride, pointer);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            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;
         }
 
         if (size < 1 || size > 4)
         {
-            return gl::error(GL_INVALID_VALUE);
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
 
         switch (type)
@@ -7456,38 +6246,36 @@
           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);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
 
         if (stride < 0)
         {
-            return gl::error(GL_INVALID_VALUE);
+            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)
         {
-            return gl::error(GL_INVALID_OPERATION);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
 
-        if (context)
+        // [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)
         {
-            // [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->getVertexArrayHandle() != 0 && context->getArrayBufferHandle() == 0 && pointer != NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, true,
-                                          stride, pointer);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type, false, true,
+                                                 stride, pointer);
     }
 }
 
@@ -7496,46 +6284,40 @@
     EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
           index, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            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;
+        }
 
-            const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
+        const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
 
-            if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
-            {
-                return;
-            }
+        if (!gl::ValidateGetVertexAttribParameters(context, pname))
+        {
+            return;
+        }
 
-            if (pname == GL_CURRENT_VERTEX_ATTRIB)
+        if (pname == GL_CURRENT_VERTEX_ATTRIB)
+        {
+            const gl::VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
+            for (int i = 0; i < 4; ++i)
             {
-                const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
-                for (int i = 0; i < 4; ++i)
-                {
-                    params[i] = currentValueData.IntValues[i];
-                }
-            }
-            else
-            {
-                *params = attribState.querySingleParameter<GLint>(pname);
+                params[i] = currentValueData.IntValues[i];
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        else
+        {
+            *params = gl::QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
+        }
     }
 }
 
@@ -7544,46 +6326,40 @@
     EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)",
           index, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            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;
+        }
 
-            const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
+        const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
 
-            if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
-            {
-                return;
-            }
+        if (!gl::ValidateGetVertexAttribParameters(context, pname))
+        {
+            return;
+        }
 
-            if (pname == GL_CURRENT_VERTEX_ATTRIB)
+        if (pname == GL_CURRENT_VERTEX_ATTRIB)
+        {
+            const gl::VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
+            for (int i = 0; i < 4; ++i)
             {
-                const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
-                for (int i = 0; i < 4; ++i)
-                {
-                    params[i] = currentValueData.UnsignedIntValues[i];
-                }
-            }
-            else
-            {
-                *params = attribState.querySingleParameter<GLuint>(pname);
+                params[i] = currentValueData.UnsignedIntValues[i];
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        else
+        {
+            *params = gl::QuerySingleVertexAttributeParameter<GLuint>(attribState, pname);
+        }
     }
 }
 
@@ -7592,29 +6368,23 @@
     EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
           index, x, y, z, w);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (index >= gl::MAX_VERTEX_ATTRIBS)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            GLint vals[4] = { x, y, z, w };
-            context->setVertexAttribi(index, vals);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        GLint vals[4] = { x, y, z, w };
+        context->getState().setVertexAttribi(index, vals);
     }
 }
 
@@ -7623,29 +6393,23 @@
     EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)",
           index, x, y, z, w);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (index >= gl::MAX_VERTEX_ATTRIBS)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            GLuint vals[4] = { x, y, z, w };
-            context->setVertexAttribu(index, vals);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        GLuint vals[4] = { x, y, z, w };
+        context->getState().setVertexAttribu(index, vals);
     }
 }
 
@@ -7653,28 +6417,22 @@
 {
     EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (index >= gl::MAX_VERTEX_ATTRIBS)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            context->setVertexAttribi(index, v);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        context->getState().setVertexAttribi(index, v);
     }
 }
 
@@ -7682,28 +6440,22 @@
 {
     EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (index >= gl::MAX_VERTEX_ATTRIBS)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            context->setVertexAttribu(index, v);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (index >= gl::MAX_VERTEX_ATTRIBS)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        context->getState().setVertexAttribu(index, v);
     }
 }
 
@@ -7712,44 +6464,20 @@
     EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)",
           program, location, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateGetUniformuiv(context, program, location, params))
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (program == 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject || !programObject->isLinked())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programBinary)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!programBinary->getUniformuiv(location, NULL, params))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Program *programObject = context->getProgram(program);
+        ASSERT(programObject);
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        ASSERT(programBinary);
+
+        programBinary->getUniformuiv(location, params);
     }
 }
 
@@ -7758,41 +6486,37 @@
     EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)",
           program, name);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, -1);
-            }
-
-            if (program == 0)
-            {
-                return gl::error(GL_INVALID_VALUE, -1);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject || !programObject->isLinked())
-            {
-                return gl::error(GL_INVALID_OPERATION, -1);
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programBinary)
-            {
-                return gl::error(GL_INVALID_OPERATION, -1);
-            }
-
-            return programBinary->getFragDataLocation(name);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, 0);
+
+        if (program == 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return -1;
+        }
+
+        gl::Program *programObject = context->getProgram(program);
+
+        if (!programObject || !programObject->isLinked())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
+        }
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        if (!programBinary)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return -1;
+        }
+
+        return programBinary->getFragDataLocation(name);
     }
 
     return 0;
@@ -7826,24 +6550,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
           location, count, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
         {
-            if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform1uiv(location, count, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform1uiv(location, count, value);
     }
 }
 
@@ -7852,24 +6568,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
           location, count, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
         {
-            if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform2uiv(location, count, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform2uiv(location, count, value);
     }
 }
 
@@ -7878,24 +6586,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)",
           location, count, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
         {
-            if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform3uiv(location, count, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform3uiv(location, count, value);
     }
 }
 
@@ -7904,24 +6604,16 @@
     EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
           location, count, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count))
         {
-            if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count))
-            {
-                return;
-            }
-
-            gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
-            programBinary->setUniform4uiv(location, count, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
+        programBinary->setUniform4uiv(location, count, value);
     }
 }
 
@@ -7930,41 +6622,43 @@
     EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)",
           buffer, drawbuffer, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateClearBuffer(context))
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (buffer)
-            {
-              case GL_COLOR:
-                if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets()))
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-              case GL_STENCIL:
-                if (drawbuffer != 0)
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            context->clearBufferiv(buffer, drawbuffer, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (buffer)
+        {
+          case GL_COLOR:
+            if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          case GL_STENCIL:
+            if (drawbuffer != 0)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Error error = context->clearBufferiv(buffer, drawbuffer, value);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -7973,35 +6667,35 @@
     EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)",
           buffer, drawbuffer, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateClearBuffer(context))
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (buffer)
-            {
-              case GL_COLOR:
-                if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets()))
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            context->clearBufferuiv(buffer, drawbuffer, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (buffer)
+        {
+          case GL_COLOR:
+            if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Error error = context->clearBufferuiv(buffer, drawbuffer, value);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -8010,41 +6704,43 @@
     EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)",
           buffer, drawbuffer, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateClearBuffer(context))
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (buffer)
-            {
-              case GL_COLOR:
-                if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets()))
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-              case GL_DEPTH:
-                if (drawbuffer != 0)
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            context->clearBufferfv(buffer, drawbuffer, value);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (buffer)
+        {
+          case GL_COLOR:
+            if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          case GL_DEPTH:
+            if (drawbuffer != 0)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Error error = context->clearBufferfv(buffer, drawbuffer, value);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -8053,35 +6749,35 @@
     EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)",
           buffer, drawbuffer, depth, stencil);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateClearBuffer(context))
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (buffer)
-            {
-              case GL_DEPTH_STENCIL:
-                if (drawbuffer != 0)
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (buffer)
+        {
+          case GL_DEPTH_STENCIL:
+            if (drawbuffer != 0)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Error error = context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return;
+        }
     }
 }
 
@@ -8089,33 +6785,28 @@
 {
     EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLubyte*>(NULL));
-            }
-
-            if (name != GL_EXTENSIONS)
-            {
-                return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLubyte*>(NULL));
-            }
-
-            if (index >= context->getNumExtensions())
-            {
-                return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLubyte*>(NULL));
-            }
-            
-            return reinterpret_cast<const GLubyte*>(context->getExtensionString(index));
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLubyte*>(NULL));
+
+        if (name != GL_EXTENSIONS)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return NULL;
+        }
+
+        if (index >= context->getExtensionStringCount())
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return NULL;
+        }
+
+        return reinterpret_cast<const GLubyte*>(context->getExtensionString(index).c_str());
     }
 
     return NULL;
@@ -8126,60 +6817,62 @@
     EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",
           readTarget, writeTarget, readOffset, writeOffset, size);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Buffer *readBuffer = context->getState().getTargetBuffer(readTarget);
+        gl::Buffer *writeBuffer = context->getState().getTargetBuffer(writeTarget);
+
+        if (!readBuffer || !writeBuffer)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        // Verify that readBuffer and writeBuffer are not currently mapped
+        if (readBuffer->isMapped() || writeBuffer->isMapped())
+        {
+            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())
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        // if size is zero, the copy is a successful no-op
+        if (size > 0)
+        {
+            gl::Error error = writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
+            if (error.isError())
             {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Buffer *readBuffer = context->getTargetBuffer(readTarget);
-            gl::Buffer *writeBuffer = context->getTargetBuffer(writeTarget);
-
-            if (!readBuffer || !writeBuffer)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (readBuffer->mapped() || writeBuffer->mapped())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (readOffset < 0 || writeOffset < 0 || size < 0 ||
-                static_cast<unsigned int>(readOffset + size) > readBuffer->size() ||
-                static_cast<unsigned int>(writeOffset + size) > writeBuffer->size())
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            // TODO: Verify that readBuffer and writeBuffer are not currently mapped (GL_INVALID_OPERATION)
-
-            // if size is zero, the copy is a successful no-op
-            if (size > 0)
-            {
-                writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
+                context->recordError(error);
+                return;
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices)
@@ -8187,56 +6880,52 @@
     EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)",
           program, uniformCount, uniformNames, uniformIndices);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            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);
-            }
+        if (uniformCount < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
 
-            gl::Program *programObject = context->getProgram(program);
+        gl::Program *programObject = context->getProgram(program);
 
-            if (!programObject)
+        if (!programObject)
+        {
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programObject->isLinked() || !programBinary)
-            {
-                for (int uniformId = 0; uniformId < uniformCount; uniformId++)
-                {
-                    uniformIndices[uniformId] = GL_INVALID_INDEX;
-                }
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
             else
             {
-                for (int uniformId = 0; uniformId < uniformCount; uniformId++)
-                {
-                    uniformIndices[uniformId] = programBinary->getUniformIndex(uniformNames[uniformId]);
-                }
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        if (!programObject->isLinked() || !programBinary)
+        {
+            for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+            {
+                uniformIndices[uniformId] = GL_INVALID_INDEX;
+            }
+        }
+        else
+        {
+            for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+            {
+                uniformIndices[uniformId] = programBinary->getUniformIndex(uniformNames[uniformId]);
+            }
+        }
     }
 }
 
@@ -8245,78 +6934,78 @@
     EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
           program, uniformCount, uniformIndices, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (uniformCount < 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;
             }
-
-            if (uniformCount < 0)
+            else
             {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
-            {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-            }
-
-            switch (pname)
-            {
-              case GL_UNIFORM_TYPE:
-              case GL_UNIFORM_SIZE:
-              case GL_UNIFORM_NAME_LENGTH:
-              case GL_UNIFORM_BLOCK_INDEX:
-              case GL_UNIFORM_OFFSET:
-              case GL_UNIFORM_ARRAY_STRIDE:
-              case GL_UNIFORM_MATRIX_STRIDE:
-              case GL_UNIFORM_IS_ROW_MAJOR:
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
-            if (!programBinary && uniformCount > 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            for (int uniformId = 0; uniformId < uniformCount; uniformId++)
-            {
-                const GLuint index = uniformIndices[uniformId];
-
-                if (index >= (GLuint)programBinary->getActiveUniformCount())
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-            }
-
-            for (int uniformId = 0; uniformId < uniformCount; uniformId++)
-            {
-                const GLuint index = uniformIndices[uniformId];
-                params[uniformId] = programBinary->getActiveUniformi(index, pname);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (pname)
+        {
+          case GL_UNIFORM_TYPE:
+          case GL_UNIFORM_SIZE:
+          case GL_UNIFORM_NAME_LENGTH:
+          case GL_UNIFORM_BLOCK_INDEX:
+          case GL_UNIFORM_OFFSET:
+          case GL_UNIFORM_ARRAY_STRIDE:
+          case GL_UNIFORM_MATRIX_STRIDE:
+          case GL_UNIFORM_IS_ROW_MAJOR:
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+        if (!programBinary && uniformCount > 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+        {
+            const GLuint index = uniformIndices[uniformId];
+
+            if (index >= (GLuint)programBinary->getActiveUniformCount())
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+        }
+
+        for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+        {
+            const GLuint index = uniformIndices[uniformId];
+            params[uniformId] = programBinary->getActiveUniformi(index, pname);
+        }
     }
 }
 
@@ -8324,43 +7013,38 @@
 {
     EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            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);
+        gl::Program *programObject = context->getProgram(program);
 
-            if (!programObject)
+        if (!programObject)
+        {
+            if (context->getShader(program))
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE, GL_INVALID_INDEX);
-                }
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-            if (!programBinary)
-            {
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
                 return GL_INVALID_INDEX;
             }
-
-            return programBinary->getUniformBlockIndex(uniformBlockName);
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return GL_INVALID_INDEX;
+            }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, 0);
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+        if (!programBinary)
+        {
+            return GL_INVALID_INDEX;
+        }
+
+        return programBinary->getUniformBlockIndex(uniformBlockName);
     }
 
     return 0;
@@ -8371,60 +7055,57 @@
     EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
           program, uniformBlockIndex, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            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;
             }
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
+            else
             {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
-            if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            switch (pname)
-            {
-              case GL_UNIFORM_BLOCK_BINDING:
-                *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));
-                break;
-
-              case GL_UNIFORM_BLOCK_DATA_SIZE:
-              case GL_UNIFORM_BLOCK_NAME_LENGTH:
-              case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
-              case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
-              case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
-              case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
-                programBinary->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+        if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_UNIFORM_BLOCK_BINDING:
+            *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));
+            break;
+
+          case GL_UNIFORM_BLOCK_DATA_SIZE:
+          case GL_UNIFORM_BLOCK_NAME_LENGTH:
+          case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+          case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+          case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+          case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+            programBinary->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -8433,44 +7114,40 @@
     EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)",
           program, uniformBlockIndex, bufSize, length, uniformBlockName);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
-            {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
-            if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Program *programObject = context->getProgram(program);
+
+        if (!programObject)
+        {
+            if (context->getShader(program))
+            {
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
+            }
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+        }
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+        if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
     }
 }
 
@@ -8479,50 +7156,47 @@
     EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)",
           program, uniformBlockIndex, uniformBlockBinding);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (uniformBlockBinding >= context->getMaximumCombinedUniformBufferBindings())
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
-            {
-                if (context->getShader(program))
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-                else
-                {
-                    return gl::error(GL_INVALID_VALUE);
-                }
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
-            // if never linked, there won't be any uniform blocks
-            if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        gl::Program *programObject = context->getProgram(program);
+
+        if (!programObject)
+        {
+            if (context->getShader(program))
+            {
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
+            }
+            else
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+        }
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+        // if never linked, there won't be any uniform blocks
+        if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
     }
 }
 
@@ -8531,24 +7205,17 @@
     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
           mode, first, count, instanceCount);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // glDrawArraysInstanced
-            UNIMPLEMENTED();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // glDrawArraysInstanced
+        UNIMPLEMENTED();
     }
 }
 
@@ -8557,24 +7224,17 @@
     EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)",
           mode, count, type, indices, instanceCount);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // glDrawElementsInstanced
-            UNIMPLEMENTED();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // glDrawElementsInstanced
+        UNIMPLEMENTED();
     }
 }
 
@@ -8582,33 +7242,28 @@
 {
     EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLsync>(0));
-            }
-
-            if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
-            {
-                return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLsync>(0));
-            }
-
-            if (flags != 0)
-            {
-                return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLsync>(0));
-            }
-
-            return context->createFenceSync(condition);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return 0;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLsync>(NULL));
+
+        if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return 0;
+        }
+
+        if (flags != 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return 0;
+        }
+
+        return context->createFenceSync(condition);
     }
 
     return NULL;
@@ -8618,23 +7273,16 @@
 {
     EVENT("(GLsync sync = 0x%0.8p)", sync);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_FALSE);
-            }
-
-            return (context->getFenceSync(sync) != NULL);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        return (context->getFenceSync(sync) != NULL);
     }
 
     return GL_FALSE;
@@ -8644,28 +7292,22 @@
 {
     EVENT("(GLsync sync = 0x%0.8p)", sync);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync))
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            context->deleteFenceSync(sync);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        context->deleteFenceSync(sync);
     }
 }
 
@@ -8674,35 +7316,30 @@
     EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
           sync, flags, timeout);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_WAIT_FAILED);
-            }
-
-            if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
-            {
-                return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED);
-            }
-
-            gl::FenceSync *fenceSync = context->getFenceSync(sync);
-
-            if (!fenceSync)
-            {
-                return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED);
-            }
-
-            return fenceSync->clientWait(flags, timeout);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_WAIT_FAILED;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return GL_WAIT_FAILED;
+        }
+
+        gl::FenceSync *fenceSync = context->getFenceSync(sync);
+
+        if (!fenceSync)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return GL_WAIT_FAILED;
+        }
+
+        return fenceSync->clientWait(flags, timeout);
     }
 
     return GL_FALSE;
@@ -8713,40 +7350,36 @@
     EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
           sync, flags, timeout);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (flags != 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            if (timeout != GL_TIMEOUT_IGNORED)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::FenceSync *fenceSync = context->getFenceSync(sync);
-
-            if (!fenceSync)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            fenceSync->serverWait();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (flags != 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        if (timeout != GL_TIMEOUT_IGNORED)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        gl::FenceSync *fenceSync = context->getFenceSync(sync);
+
+        if (!fenceSync)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        fenceSync->serverWait();
     }
 }
 
@@ -8755,37 +7388,30 @@
     EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
           pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            GLenum nativeType;
-            unsigned int numParams = 0;
-            if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
-            {
-                return;
-            }
-
-            if (nativeType == GL_INT_64_ANGLEX)
-            {
-                context->getInteger64v(pname, params);
-            }
-            else
-            {
-                CastStateValues(context, nativeType, pname, numParams, params);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        GLenum nativeType;
+        unsigned int numParams = 0;
+        if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
+        {
+            return;
+        }
+
+        if (nativeType == GL_INT_64_ANGLEX)
+        {
+            context->getInteger64v(pname, params);
+        }
+        else
+        {
+            CastStateValues(context, nativeType, pname, numParams, params);
+        }
     }
 }
 
@@ -8794,44 +7420,40 @@
     EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)",
           sync, pname, bufSize, length, values);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (bufSize < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            gl::FenceSync *fenceSync = context->getFenceSync(sync);
-
-            if (!fenceSync)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            switch (pname)
-            {
-              case GL_OBJECT_TYPE:     values[0] = static_cast<GLint>(GL_SYNC_FENCE);              break;
-              case GL_SYNC_STATUS:     values[0] = static_cast<GLint>(fenceSync->getStatus());     break;
-              case GL_SYNC_CONDITION:  values[0] = static_cast<GLint>(fenceSync->getCondition());  break;
-              case GL_SYNC_FLAGS:      values[0] = 0;                                              break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (bufSize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        gl::FenceSync *fenceSync = context->getFenceSync(sync);
+
+        if (!fenceSync)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_OBJECT_TYPE:     values[0] = static_cast<GLint>(GL_SYNC_FENCE);              break;
+          case GL_SYNC_STATUS:     values[0] = static_cast<GLint>(fenceSync->getStatus());     break;
+          case GL_SYNC_CONDITION:  values[0] = static_cast<GLint>(fenceSync->getCondition());  break;
+          case GL_SYNC_FLAGS:      values[0] = 0;                                              break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -8840,69 +7462,75 @@
     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)",
           target, index, data);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
+            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 >= caps.maxTransformFeedbackSeparateAttributes)
             {
-                return gl::error(GL_INVALID_OPERATION);
+                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 >= caps.maxUniformBufferBindings)
+            {
+                context->recordError(gl::Error(GL_INVALID_VALUE));
+                return;
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        if (!(context->getIndexedInteger64v(target, index, data)))
+        {
+            GLenum nativeType;
+            unsigned int numParams = 0;
+            if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
+            {
+                context->recordError(gl::Error(GL_INVALID_ENUM));
+                return;
             }
 
-            switch (target)
+            if (numParams == 0)
+                return; // it is known that pname is valid, but there are no parameters to return
+
+            if (nativeType == GL_INT)
             {
-              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);
-                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);
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
+                GLint *intParams = new GLint[numParams];
+
+                context->getIndexedIntegerv(target, index, intParams);
+
+                for (unsigned int i = 0; i < numParams; ++i)
+                {
+                    data[i] = static_cast<GLint64>(intParams[i]);
+                }
+
+                delete [] intParams;
             }
-
-            if (!(context->getIndexedInteger64v(target, index, data)))
+            else
             {
-                GLenum nativeType;
-                unsigned int numParams = 0;
-                if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
-                    return gl::error(GL_INVALID_ENUM);
-
-                if (numParams == 0)
-                    return; // it is known that pname is valid, but there are no parameters to return
-
-                if (nativeType == GL_INT)
-                {
-                    GLint *intParams = new GLint[numParams];
-
-                    context->getIndexedIntegerv(target, index, intParams);
-
-                    for (unsigned int i = 0; i < numParams; ++i)
-                    {
-                        data[i] = static_cast<GLint64>(intParams[i]);
-                    }
-
-                    delete [] intParams;
-                }
-                else
-                {
-                    UNREACHABLE();
-                }
+                UNREACHABLE();
             }
         }
     }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
 }
 
 void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
@@ -8910,62 +7538,58 @@
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
           target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            if (!gl::ValidBufferParameter(context, pname))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (!buffer)
-            {
-                // A null buffer means that "0" is bound to the requested buffer target
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (pname)
-            {
-              case GL_BUFFER_USAGE:
-                *params = static_cast<GLint64>(buffer->usage());
-                break;
-              case GL_BUFFER_SIZE:
-                *params = buffer->size();
-                break;
-              case GL_BUFFER_ACCESS_FLAGS:
-                *params = static_cast<GLint64>(buffer->accessFlags());
-                break;
-              case GL_BUFFER_MAPPED:
-                *params = static_cast<GLint64>(buffer->mapped());
-                break;
-              case GL_BUFFER_MAP_OFFSET:
-                *params = buffer->mapOffset();
-                break;
-              case GL_BUFFER_MAP_LENGTH:
-                *params = buffer->mapLength();
-                break;
-              default: UNREACHABLE(); break;
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!gl::ValidBufferTarget(context, target))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        if (!gl::ValidBufferParameter(context, pname))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (!buffer)
+        {
+            // A null buffer means that "0" is bound to the requested buffer target
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_BUFFER_USAGE:
+            *params = static_cast<GLint64>(buffer->getUsage());
+            break;
+          case GL_BUFFER_SIZE:
+            *params = buffer->getSize();
+            break;
+          case GL_BUFFER_ACCESS_FLAGS:
+            *params = static_cast<GLint64>(buffer->getAccessFlags());
+            break;
+          case GL_BUFFER_MAPPED:
+            *params = static_cast<GLint64>(buffer->isMapped());
+            break;
+          case GL_BUFFER_MAP_OFFSET:
+            *params = buffer->getMapOffset();
+            break;
+          case GL_BUFFER_MAP_LENGTH:
+            *params = buffer->getMapLength();
+            break;
+          default: UNREACHABLE(); break;
+        }
     }
 }
 
@@ -8973,31 +7597,25 @@
 {
     EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (count < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            for (int i = 0; i < count; i++)
-            {
-                samplers[i] = context->createSampler();
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (count < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        for (int i = 0; i < count; i++)
+        {
+            samplers[i] = context->createSampler();
+        }
     }
 }
 
@@ -9005,31 +7623,25 @@
 {
     EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (count < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            for (int i = 0; i < count; i++)
-            {
-                context->deleteSampler(samplers[i]);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (count < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        for (int i = 0; i < count; i++)
+        {
+            context->deleteSampler(samplers[i]);
+        }
     }
 }
 
@@ -9037,23 +7649,16 @@
 {
     EVENT("(GLuint sampler = %u)", sampler);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_FALSE);
-            }
-
-            return context->isSampler(sampler);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        return context->isSampler(sampler);
     }
 
     return GL_FALSE;
@@ -9063,33 +7668,28 @@
 {
     EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (sampler != 0 && !context->isSampler(sampler))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (unit >= context->getMaximumCombinedTextureImageUnits())
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            context->bindSampler(unit, sampler);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (sampler != 0 && !context->isSampler(sampler))
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (unit >= context->getCaps().maxCombinedTextureImageUnits)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        context->bindSampler(unit, sampler);
     }
 }
 
@@ -9097,38 +7697,32 @@
 {
     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!gl::ValidateSamplerObjectParameter(pname))
-            {
-                return;
-            }
-
-            if (!gl::ValidateTexParamParameters(context, pname, param))
-            {
-                return;
-            }
-
-            if (!context->isSampler(sampler))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->samplerParameteri(sampler, pname, param);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!gl::ValidateSamplerObjectParameter(context, pname))
+        {
+            return;
+        }
+
+        if (!gl::ValidateTexParamParameters(context, pname, param))
+        {
+            return;
+        }
+
+        if (!context->isSampler(sampler))
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        context->samplerParameteri(sampler, pname, param);
     }
 }
 
@@ -9141,38 +7735,32 @@
 {
     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!gl::ValidateSamplerObjectParameter(pname))
-            {
-                return;
-            }
-
-            if (!gl::ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
-            {
-                return;
-            }
-
-            if (!context->isSampler(sampler))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->samplerParameterf(sampler, pname, param);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!gl::ValidateSamplerObjectParameter(context, pname))
+        {
+            return;
+        }
+
+        if (!gl::ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
+        {
+            return;
+        }
+
+        if (!context->isSampler(sampler))
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        context->samplerParameterf(sampler, pname, param);
     }
 }
 
@@ -9185,33 +7773,27 @@
 {
     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!gl::ValidateSamplerObjectParameter(pname))
-            {
-                return;
-            }
-
-            if (!context->isSampler(sampler))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            *params = context->getSamplerParameteri(sampler, pname);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!gl::ValidateSamplerObjectParameter(context, pname))
+        {
+            return;
+        }
+
+        if (!context->isSampler(sampler))
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        *params = context->getSamplerParameteri(sampler, pname);
     }
 }
 
@@ -9219,33 +7801,27 @@
 {
     EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!gl::ValidateSamplerObjectParameter(pname))
-            {
-                return;
-            }
-
-            if (!context->isSampler(sampler))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            *params = context->getSamplerParameterf(sampler, pname);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!gl::ValidateSamplerObjectParameter(context, pname))
+        {
+            return;
+        }
+
+        if (!context->isSampler(sampler))
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        *params = context->getSamplerParameterf(sampler, pname);
     }
 }
 
@@ -9253,28 +7829,22 @@
 {
     EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
+        if (context->getClientVersion() < 3)
+        {
+            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;
         }
 
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
-        {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->setVertexAttribDivisor(index, divisor);
-        }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        context->setVertexAttribDivisor(index, divisor);
     }
 }
 
@@ -9282,46 +7852,42 @@
 {
     EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            switch (target)
-            {
-              case GL_TRANSFORM_FEEDBACK:
-                {
-                    // Cannot bind a transform feedback object if the current one is started and not paused (3.0.2 pg 85 section 2.14.1)
-                    gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
-                    if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
-                    {
-                        return gl::error(GL_INVALID_OPERATION);
-                    }
-
-                    // 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->bindTransformFeedback(id);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        switch (target)
+        {
+          case GL_TRANSFORM_FEEDBACK:
+            {
+                // Cannot bind a transform feedback object if the current one is started and not paused (3.0.2 pg 85 section 2.14.1)
+                gl::TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
+                if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
+                {
+                    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)
+                {
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
+                }
+
+                context->bindTransformFeedback(id);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -9329,26 +7895,19 @@
 {
     EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            for (int i = 0; i < n; i++)
-            {
-                context->deleteTransformFeedback(ids[i]);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        for (int i = 0; i < n; i++)
+        {
+            context->deleteTransformFeedback(ids[i]);
+        }
     }
 }
 
@@ -9356,26 +7915,19 @@
 {
     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            for (int i = 0; i < n; i++)
-            {
-                ids[i] = context->createTransformFeedback();
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        for (int i = 0; i < n; i++)
+        {
+            ids[i] = context->createTransformFeedback();
+        }
     }
 }
 
@@ -9383,23 +7935,16 @@
 {
     EVENT("(GLuint id = %u)", id);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_FALSE);
-            }
-
-            return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
     }
 
     return GL_FALSE;
@@ -9409,32 +7954,26 @@
 {
     EVENT("(void)");
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
-            ASSERT(transformFeedback != NULL);
-
-            // 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);
-            }
-
-            transformFeedback->pause();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+        ASSERT(transformFeedback != NULL);
+
+        // Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86)
+        if (!transformFeedback->isStarted() || transformFeedback->isPaused())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        transformFeedback->pause();
     }
 }
 
@@ -9442,32 +7981,26 @@
 {
     EVENT("(void)");
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
-            ASSERT(transformFeedback != NULL);
-
-            // 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);
-            }
-
-            transformFeedback->resume();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+        ASSERT(transformFeedback != NULL);
+
+        // Current transform feedback must be started and paused in order to resume (3.0.2 pg 86)
+        if (!transformFeedback->isStarted() || !transformFeedback->isPaused())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        transformFeedback->resume();
     }
 }
 
@@ -9476,24 +8009,17 @@
     EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)",
           program, bufSize, length, binaryFormat, binary);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // glGetProgramBinary
-            UNIMPLEMENTED();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // glGetProgramBinary
+        UNIMPLEMENTED();
     }
 }
 
@@ -9502,24 +8028,17 @@
     EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
           program, binaryFormat, binary, length);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // glProgramBinary
-            UNIMPLEMENTED();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // glProgramBinary
+        UNIMPLEMENTED();
     }
 }
 
@@ -9528,24 +8047,17 @@
     EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)",
           program, pname, value);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // glProgramParameteri
-            UNIMPLEMENTED();
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        // glProgramParameteri
+        UNIMPLEMENTED();
     }
 }
 
@@ -9554,29 +8066,25 @@
     EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)",
           target, numAttachments, attachments);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
-            {
-                return;
-            }
-
-            int maxDimension = context->getMaximumRenderbufferDimension();
-            context->invalidateFrameBuffer(target, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
+        {
+            return;
+        }
+
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+        if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+        {
+            framebuffer->invalidate(context->getCaps(), numAttachments, attachments);
+        }
     }
 }
 
@@ -9586,28 +8094,25 @@
           "GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
           target, numAttachments, attachments, x, y, width, height);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
-            {
-                return;
-            }
-
-            context->invalidateFrameBuffer(target, numAttachments, attachments, x, y, width, height);
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
+        {
+            return;
+        }
+
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+        if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+        {
+            framebuffer->invalidateSub(context->getCaps(), numAttachments, attachments, x, y, width, height);
+        }
     }
 }
 
@@ -9616,46 +8121,40 @@
     EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
           target, levels, internalformat, width, height);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
-            {
-                return;
-            }
-
-            switch (target)
-            {
-              case GL_TEXTURE_2D:
-                {
-                    gl::Texture2D *texture2d = context->getTexture2D();
-                    texture2d->storage(levels, internalformat, width, height);
-                }
-                break;
-
-              case GL_TEXTURE_CUBE_MAP:
-                {
-                    gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
-                    textureCube->storage(levels, internalformat, width);
-                }
-                break;
-
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
+        {
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TEXTURE_2D:
+            {
+                gl::Texture2D *texture2d = context->getTexture2D();
+                texture2d->storage(levels, internalformat, width, height);
+            }
+            break;
+
+          case GL_TEXTURE_CUBE_MAP:
+            {
+                gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
+                textureCube->storage(levels, internalformat, width);
+            }
+            break;
+
+          default:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -9665,46 +8164,39 @@
           "GLsizei height = %d, GLsizei depth = %d)",
           target, levels, internalformat, width, height, depth);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth))
-            {
-                return;
-            }
-
-            switch (target)
-            {
-              case GL_TEXTURE_3D:
-                {
-                    gl::Texture3D *texture3d = context->getTexture3D();
-                    texture3d->storage(levels, internalformat, width, height, depth);
-                }
-                break;
-
-              case GL_TEXTURE_2D_ARRAY:
-                {
-                    gl::Texture2DArray *texture2darray = context->getTexture2DArray();
-                    texture2darray->storage(levels, internalformat, width, height, depth);
-                }
-                break;
-
-              default:
-                UNREACHABLE();
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth))
+        {
+            return;
+        }
+
+        switch (target)
+        {
+          case GL_TEXTURE_3D:
+            {
+                gl::Texture3D *texture3d = context->getTexture3D();
+                texture3d->storage(levels, internalformat, width, height, depth);
+            }
+            break;
+
+          case GL_TEXTURE_2D_ARRAY:
+            {
+                gl::Texture2DArray *texture2darray = context->getTexture2DArray();
+                texture2darray->storage(levels, internalformat, width, height, depth);
+            }
+            break;
+
+          default:
+            UNREACHABLE();
+        }
     }
 }
 
@@ -9714,51 +8206,51 @@
           "GLint* params = 0x%0.8p)",
           target, internalformat, pname, bufSize, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (context->getClientVersion() < 3)
         {
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!gl::IsColorRenderingSupported(internalformat, context) &&
-                !gl::IsDepthRenderingSupported(internalformat, context) &&
-                !gl::IsStencilRenderingSupported(internalformat, context))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            if (target != GL_RENDERBUFFER)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            if (bufSize < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            switch (pname)
-            {
-              case GL_NUM_SAMPLE_COUNTS:
-                if (bufSize != 0)
-                    *params = context->getNumSampleCounts(internalformat);
-                break;
-              case GL_SAMPLES:
-                context->getSampleCounts(internalformat, bufSize, params);
-                break;
-              default:
-                return gl::error(GL_INVALID_ENUM);
-            }
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        const gl::TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+        if (!formatCaps.renderable)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        if (target != GL_RENDERBUFFER)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        if (bufSize < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        switch (pname)
+        {
+          case GL_NUM_SAMPLE_COUNTS:
+            if (bufSize != 0)
+            {
+                *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:
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
     }
 }
 
@@ -9772,26 +8264,18 @@
           "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
           srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
+                                               dstX0, dstY0, dstX1, dstY1, mask, filter,
+                                               true))
         {
-            if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
-                                                   dstX0, dstY0, dstX1, dstY1, mask, filter,
-                                                   true))
-            {
-                return;
-            }
-
-            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
-                                     mask, filter);
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+                                 mask, filter);
     }
 }
 
@@ -9803,53 +8287,39 @@
           "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
           target, level, internalformat, width, height, depth, border, format, type, pixels);
 
-    try
-    {
-        UNIMPLEMENTED();   // FIXME
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
-    }
+    UNIMPLEMENTED();   // FIXME
 }
 
-void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, 
+void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length,
                                      GLenum *binaryFormat, void *binary)
 {
     EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)",
           program, bufSize, length, binaryFormat, binary);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Program *programObject = context->getProgram(program);
 
-        if (context)
+        if (!programObject || !programObject->isLinked())
         {
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject || !programObject->isLinked())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
-            if (!programBinary)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!programBinary->save(binary, bufSize, length))
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+        if (!programBinary)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (!programBinary->save(binaryFormat, binary, bufSize, length))
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
     }
 }
 
@@ -9859,30 +8329,24 @@
     EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
           program, binaryFormat, binary, length);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
+        if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == programBinaryFormats.end())
         {
-            if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Program *programObject = context->getProgram(program);
-
-            if (!programObject)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            context->setProgramBinary(program, binary, length);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        gl::Program *programObject = context->getProgram(program);
+        if (!programObject)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        context->setProgramBinary(program, binaryFormat, binary, length);
     }
 }
 
@@ -9890,57 +8354,53 @@
 {
     EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
         {
-            if (n < 0 || (unsigned int)n > context->getMaximumRenderTargets())
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        if (context->getState().getDrawFramebuffer()->id() == 0)
+        {
+            if (n != 1)
             {
-                return gl::error(GL_INVALID_VALUE);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
 
-            if (context->getDrawFramebufferHandle() == 0)
+            if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
             {
-                if (n != 1)
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-
-                if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
-                {
-                    return gl::error(GL_INVALID_OPERATION);
-                }
-            }
-            else
-            {
-                for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
-                {
-                    const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
-                    if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
-                    {
-                        return gl::error(GL_INVALID_OPERATION);
-                    }
-                }
-            }
-
-            gl::Framebuffer *framebuffer = context->getDrawFramebuffer();
-
-            for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
-            {
-                framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]);
-            }
-
-            for (int colorAttachment = n; colorAttachment < (int)context->getMaximumRenderTargets(); colorAttachment++)
-            {
-                framebuffer->setDrawBufferState(colorAttachment, GL_NONE);
+                context->recordError(gl::Error(GL_INVALID_OPERATION));
+                return;
             }
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+        else
+        {
+            for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
+            {
+                const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
+                if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
+                {
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
+                }
+            }
+        }
+
+        gl::Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
+
+        for (unsigned int colorAttachment = 0; colorAttachment < static_cast<unsigned int>(n); colorAttachment++)
+        {
+            framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]);
+        }
+
+        for (unsigned int colorAttachment = n; colorAttachment < context->getCaps().maxDrawBuffers; colorAttachment++)
+        {
+            framebuffer->setDrawBufferState(colorAttachment, GL_NONE);
+        }
     }
 }
 
@@ -9948,40 +8408,31 @@
 {
     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidBufferTarget(context, target))
         {
-            if (!context->supportsPBOs())
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            if (pname != GL_BUFFER_MAP_POINTER)
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (!buffer || !buffer->mapped())
-            {
-                *params = NULL;
-            }
-
-            *params = buffer->mapPointer();
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (pname != GL_BUFFER_MAP_POINTER)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (!buffer || !buffer->isMapped())
+        {
+            *params = NULL;
+        }
+        else
+        {
+            *params = buffer->getMapPointer();
+        }
     }
 }
 
@@ -9989,40 +8440,43 @@
 {
     EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidBufferTarget(context, target))
         {
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (buffer == NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            if (access != GL_WRITE_ONLY_OES)
-            {
-                return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            if (buffer->mapped())
-            {
-                return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            return buffer->mapRange(0, buffer->size(), GL_MAP_WRITE_BIT);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return NULL;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL));
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (buffer == NULL)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
+        }
+
+        if (access != GL_WRITE_ONLY_OES)
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return NULL;
+        }
+
+        if (buffer->isMapped())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
+        }
+
+        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;
@@ -10032,34 +8486,33 @@
 {
     EVENT("(GLenum target = 0x%X)", target);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidBufferTarget(context, target))
         {
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM, GL_FALSE);
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (buffer == NULL || !buffer->mapped())
-            {
-                return gl::error(GL_INVALID_OPERATION, GL_FALSE);
-            }
-
-            // TODO: detect if we had corruption. if so, throw an error and return false.
-
-            buffer->unmap();
-
-            return GL_TRUE;
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return GL_FALSE;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (buffer == NULL || !buffer->isMapped())
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return GL_FALSE;
+        }
+
+        // TODO: detect if we had corruption. if so, throw an error and return false.
+
+        gl::Error error = buffer->unmap();
+        if (error.isError())
+        {
+            context->recordError(error);
+            return GL_FALSE;
+        }
+
+        return GL_TRUE;
     }
 
     return GL_FALSE;
@@ -10070,83 +8523,91 @@
     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
           target, offset, length, access);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (!gl::ValidBufferTarget(context, target))
         {
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            if (offset < 0 || length < 0)
-            {
-                return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (buffer == NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            // Check for buffer overflow
-            size_t offsetSize = static_cast<size_t>(offset);
-            size_t lengthSize = static_cast<size_t>(length);
-
-            if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
-                offsetSize + lengthSize > static_cast<size_t>(buffer->size()))
-            {
-                return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            // Check for invalid bits in the mask
-            GLbitfield allAccessBits = GL_MAP_READ_BIT |
-                                       GL_MAP_WRITE_BIT |
-                                       GL_MAP_INVALIDATE_RANGE_BIT |
-                                       GL_MAP_INVALIDATE_BUFFER_BIT |
-                                       GL_MAP_FLUSH_EXPLICIT_BIT |
-                                       GL_MAP_UNSYNCHRONIZED_BIT;
-
-            if (access & ~(allAccessBits))
-            {
-                return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
-            }
-
-            if (length == 0 || buffer->mapped())
-            {
-                return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(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));
-            }
-
-            GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT |
-                                       GL_MAP_INVALIDATE_BUFFER_BIT |
-                                       GL_MAP_UNSYNCHRONIZED_BIT;
-
-            if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
-            {
-                return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(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));
-            }
-
-            return buffer->mapRange(offset, length, access);
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return NULL;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL));
+
+        if (offset < 0 || length < 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return NULL;
+        }
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (buffer == NULL)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
+        }
+
+        // Check for buffer overflow
+        size_t offsetSize = static_cast<size_t>(offset);
+        size_t lengthSize = static_cast<size_t>(length);
+
+        if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
+            offsetSize + lengthSize > static_cast<size_t>(buffer->getSize()))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return NULL;
+        }
+
+        // Check for invalid bits in the mask
+        GLbitfield allAccessBits = GL_MAP_READ_BIT |
+                                   GL_MAP_WRITE_BIT |
+                                   GL_MAP_INVALIDATE_RANGE_BIT |
+                                   GL_MAP_INVALIDATE_BUFFER_BIT |
+                                   GL_MAP_FLUSH_EXPLICIT_BIT |
+                                   GL_MAP_UNSYNCHRONIZED_BIT;
+
+        if (access & ~(allAccessBits))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return NULL;
+        }
+
+        if (length == 0 || buffer->isMapped())
+        {
+            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)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
+        }
+
+        GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT |
+                                   GL_MAP_INVALIDATE_BUFFER_BIT |
+                                   GL_MAP_UNSYNCHRONIZED_BIT;
+
+        if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
+        }
+
+        if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return NULL;
+        }
+
+        gl::Error error = buffer->mapRange(offset, length, access);
+        if (error.isError())
+        {
+            context->recordError(error);
+            return NULL;
+        }
+
+        return buffer->getMapPointer();
     }
 
     return NULL;
@@ -10156,50 +8617,47 @@
 {
     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
-
-        if (context)
+        if (offset < 0 || length < 0)
         {
-            if (offset < 0 || length < 0)
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            if (!gl::ValidBufferTarget(context, target))
-            {
-                return gl::error(GL_INVALID_ENUM);
-            }
-
-            gl::Buffer *buffer = context->getTargetBuffer(target);
-
-            if (buffer == NULL)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            if (!buffer->mapped() || (buffer->accessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
-            {
-                return gl::error(GL_INVALID_OPERATION);
-            }
-
-            // Check for buffer overflow
-            size_t offsetSize = static_cast<size_t>(offset);
-            size_t lengthSize = static_cast<size_t>(length);
-
-            if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
-                offsetSize + lengthSize > static_cast<size_t>(buffer->mapLength()))
-            {
-                return gl::error(GL_INVALID_VALUE);
-            }
-
-            // We do not currently support a non-trivial implementation of FlushMappedBufferRange
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY);
+
+        if (!gl::ValidBufferTarget(context, target))
+        {
+            context->recordError(gl::Error(GL_INVALID_ENUM));
+            return;
+        }
+
+        gl::Buffer *buffer = context->getState().getTargetBuffer(target);
+
+        if (buffer == NULL)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
+        {
+            context->recordError(gl::Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        // Check for buffer overflow
+        size_t offsetSize = static_cast<size_t>(offset);
+        size_t lengthSize = static_cast<size_t>(length);
+
+        if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
+            offsetSize + lengthSize > static_cast<size_t>(buffer->getMapLength()))
+        {
+            context->recordError(gl::Error(GL_INVALID_VALUE));
+            return;
+        }
+
+        // We do not currently support a non-trivial implementation of FlushMappedBufferRange
     }
 }
 
@@ -10266,26 +8724,18 @@
     EVENT("(egl::Surface* surface = 0x%0.8p)",
           surface);
 
-    try
+    gl::Context *context = gl::getNonLostContext();
+    if (context)
     {
-        gl::Context *context = gl::getNonLostContext();
+        gl::Texture2D *textureObject = context->getTexture2D();
+        ASSERT(textureObject != NULL);
 
-        if (context)
+        if (textureObject->isImmutable())
         {
-            gl::Texture2D *textureObject = context->getTexture2D();
-            ASSERT(textureObject != NULL);
-
-            if (textureObject->isImmutable())
-            {
-                return false;
-            }
-
-            textureObject->bindTexImage(surface);
+            return false;
         }
-    }
-    catch (...)
-    {
-        return gl::error(GL_OUT_OF_MEMORY, false);
+
+        textureObject->bindTexImage(surface);
     }
 
     return true;
diff --git a/src/libGLESv2/main.cpp b/src/libGLESv2/main.cpp
index 50e2593..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
@@ -8,41 +7,41 @@
 // main.cpp: DLL entry point and management of thread-local data.
 
 #include "libGLESv2/main.h"
-
 #include "libGLESv2/Context.h"
 
-static DWORD currentTLS = TLS_OUT_OF_INDEXES;
+#include "common/tls.h"
+
+static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
 
 namespace gl
 {
 
 Current *AllocateCurrent()
 {
-    Current *current = (Current*)LocalAlloc(LPTR, sizeof(Current));
-
-    if (!current)
+    ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
+    if (currentTLS == TLS_OUT_OF_INDEXES)
     {
-        ERR("Could not allocate thread local storage.");
         return NULL;
     }
 
-    ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
-    TlsSetValue(currentTLS, current);
-
+    Current *current = new Current();
     current->context = NULL;
     current->display = NULL;
 
+    if (!SetTLSValue(currentTLS, current))
+    {
+        ERR("Could not set thread local storage.");
+        return NULL;
+    }
+
     return current;
 }
 
 void DeallocateCurrent()
 {
-    void *current = TlsGetValue(currentTLS);
-
-    if (current)
-    {
-        LocalFree((HLOCAL)current);
-    }
+    Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
+    SafeDelete(current);
+    SetTLSValue(currentTLS, NULL);
 }
 
 }
@@ -53,14 +52,13 @@
     {
       case DLL_PROCESS_ATTACH:
         {
-            currentTLS = TlsAlloc();
-
+            currentTLS = CreateTLSIndex();
             if (currentTLS == TLS_OUT_OF_INDEXES)
             {
                 return FALSE;
             }
         }
-        // Fall throught to initialize index
+        // Fall through to initialize index
       case DLL_THREAD_ATTACH:
         {
             gl::AllocateCurrent();
@@ -74,7 +72,7 @@
       case DLL_PROCESS_DETACH:
         {
             gl::DeallocateCurrent();
-            TlsFree(currentTLS);
+            DestroyTLSIndex(currentTLS);
         }
         break;
       default:
@@ -89,7 +87,7 @@
 
 Current *GetCurrentData()
 {
-    Current *current = (Current*)TlsGetValue(currentTLS);
+    Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
 
     // ANGLE issue 488: when the dll is loaded after thread initialization,
     // thread local storage (current) might not exist yet.
@@ -119,7 +117,7 @@
 Context *getNonLostContext()
 {
     Context *context = getContext();
-    
+
     if (context)
     {
         if (context->isContextLost())
@@ -146,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 d17facf..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;
@@ -57,7 +60,7 @@
 void glDestroyContext(gl::Context *context);
 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
 gl::Context *glGetCurrentContext();
-rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId);
+rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType);
 void glDestroyRenderer(rx::Renderer *renderer);
 
 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname);
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 3bc66a1..0000000
--- a/src/libGLESv2/precompiled.h
+++ /dev/null
@@ -1,48 +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 <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <GLES2/gl2.h>
-
-#include <GLES2/gl2ext.h>
-
-#include <EGL/egl.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>
-
-#if defined(ANGLE_ENABLE_D3D9)
-#include <d3d9.h>
-#include <d3dcompiler.h>
-#endif // ANGLE_ENABLE_D3D9
-
-#if defined(ANGLE_ENABLE_D3D11)
-#include <d3d10_1.h>
-#include <d3d11.h>
-#include <dxgi.h>
-#include <dxgi1_2.h>
-#include <d3dcompiler.h>
-#endif // ANGLE_ENABLE_D3D11
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
new file mode 100644
index 0000000..f0b5f02
--- /dev/null
+++ b/src/libGLESv2/renderer/BufferImpl.h
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+// BufferImpl.h: Defines the abstract rx::BufferImpl class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERIMPL_H_
+#define LIBGLESV2_RENDERER_BUFFERIMPL_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/Buffer.h"
+
+namespace rx
+{
+
+class BufferImpl
+{
+  public:
+    virtual ~BufferImpl() { }
+
+    virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0;
+    virtual void *getData() = 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;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERIMPL_H_
diff --git a/src/libGLESv2/renderer/BufferStorage.cpp b/src/libGLESv2/renderer/BufferStorage.cpp
deleted file mode 100644
index 4d245f8..0000000
--- a/src/libGLESv2/renderer/BufferStorage.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// BufferStorage.cpp Defines the abstract BufferStorage class.
-
-#include "libGLESv2/renderer/BufferStorage.h"
-
-namespace rx
-{
-
-unsigned int BufferStorage::mNextSerial = 1;
-
-BufferStorage::BufferStorage()
-{
-    updateSerial();
-}
-
-BufferStorage::~BufferStorage()
-{
-}
-
-unsigned int BufferStorage::getSerial() const
-{
-    return mSerial;
-}
-
-void BufferStorage::updateSerial()
-{
-    mSerial = mNextSerial++;
-}
-
-}
diff --git a/src/libGLESv2/renderer/BufferStorage.h b/src/libGLESv2/renderer/BufferStorage.h
deleted file mode 100644
index a5f95d1..0000000
--- a/src/libGLESv2/renderer/BufferStorage.h
+++ /dev/null
@@ -1,49 +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.
-//
-
-// BufferStorage.h Defines the abstract BufferStorage class.
-
-#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
-#define LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
-
-#include "common/angleutils.h"
-
-namespace rx
-{
-
-class BufferStorage
-{
-  public:
-    BufferStorage();
-    virtual ~BufferStorage();
-
-    // The data returned is only guaranteed valid until next non-const method.
-    virtual void *getData() = 0;
-    virtual void setData(const void* data, size_t size, size_t offset) = 0;
-    virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset) = 0;
-    virtual void clear() = 0;
-    virtual void markTransformFeedbackUsage() = 0;
-    virtual size_t getSize() const = 0;
-    virtual bool supportsDirectBinding() const = 0;
-    unsigned int getSerial() const;
-
-    virtual bool isMapped() const = 0;
-    virtual void *map(GLbitfield access) = 0;
-    virtual void unmap() = 0;
-
-  protected:
-    void updateSerial();
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(BufferStorage);
-
-    unsigned int mSerial;
-    static unsigned int mNextSerial;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
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 73e4e84..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;
@@ -20,11 +22,8 @@
 
 namespace rx
 {
+
 class Renderer;
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
-class TextureStorageInterface3D;
-class TextureStorageInterface2DArray;
 
 class Image
 {
@@ -44,15 +43,6 @@
     void markClean() {mDirty = false;}
     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 bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0;
 
     virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
diff --git a/src/libGLESv2/renderer/IndexDataManager.cpp b/src/libGLESv2/renderer/IndexDataManager.cpp
deleted file mode 100644
index fdd7989..0000000
--- a/src/libGLESv2/renderer/IndexDataManager.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// IndexDataManager.cpp: Defines the IndexDataManager, a class that
-// runs the Buffer translation process for index buffers.
-
-#include "libGLESv2/renderer/IndexDataManager.h"
-#include "libGLESv2/renderer/BufferStorage.h"
-
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/renderer/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)
-{
-    if (sourceType == GL_UNSIGNED_BYTE)
-    {
-        ASSERT(destinationType == GL_UNSIGNED_SHORT);
-        const GLubyte *in = static_cast<const GLubyte*>(input);
-        GLushort *out = static_cast<GLushort*>(output);
-
-        for (GLsizei i = 0; i < count; i++)
-        {
-            out[i] = in[i];
-        }
-    }
-    else if (sourceType == GL_UNSIGNED_INT)
-    {
-        ASSERT(destinationType == GL_UNSIGNED_INT);
-        memcpy(output, input, count * sizeof(GLuint));
-    }
-    else if (sourceType == GL_UNSIGNED_SHORT)
-    {
-        if (destinationType == GL_UNSIGNED_SHORT)
-        {
-            memcpy(output, input, count * sizeof(GLushort));
-        }
-        else if (destinationType == GL_UNSIGNED_INT)
-        {
-            const GLushort *in = static_cast<const GLushort*>(input);
-            GLuint *out = static_cast<GLuint*>(output);
-
-            for (GLsizei i = 0; i < count; i++)
-            {
-                out[i] = in[i];
-            }
-        }
-        else UNREACHABLE();
-    }
-    else UNREACHABLE();
-}
-
-template <class IndexType>
-static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
-{
-    *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)
-{
-    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();
-}
-
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
-{
-    if (!mStreamingBufferShort)
-    {
-        return GL_OUT_OF_MEMORY;
-    }
-
-    GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
-    unsigned int offset = 0;
-    bool alignedOffset = false;
-
-    BufferStorage *storage = NULL;
-
-    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 = buffer->getStorage();
-
-        switch (type)
-        {
-          case GL_UNSIGNED_BYTE:  alignedOffset = (offset % sizeof(GLubyte) == 0);  break;
-          case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
-          case GL_UNSIGNED_INT:   alignedOffset = (offset % sizeof(GLuint) == 0);   break;
-          default: UNREACHABLE(); alignedOffset = false;
-        }
-
-        unsigned int typeSize = gl::GetTypeBytes(type);
-
-        // check for integer overflows
-        if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeSize) ||
-            typeSize * static_cast<unsigned int>(count) + offset < offset)
-        {
-            return GL_OUT_OF_MEMORY;
-        }
-
-        if (typeSize * static_cast<unsigned int>(count) + offset > storage->getSize())
-        {
-            return GL_INVALID_OPERATION;
-        }
-
-        indices = static_cast<const GLubyte*>(storage->getData()) + offset;
-    }
-
-    StaticIndexBufferInterface *staticBuffer = buffer ? buffer->getStaticIndexBuffer() : NULL;
-    IndexBufferInterface *indexBuffer = NULL;
-    bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() &&
-                         destinationIndexType == type;
-    unsigned int streamOffset = 0;
-
-    if (directStorage)
-    {
-        streamOffset = offset;
-
-        if (!buffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
-            &translated->maxIndex, NULL))
-        {
-            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            buffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                   translated->maxIndex, 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))
-        {
-            streamOffset = (offset / gl::GetTypeBytes(type)) * gl::GetTypeBytes(destinationIndexType);
-            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                         translated->maxIndex, 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)
-    {
-        destinationIndexType = GL_UNSIGNED_INT;
-        directStorage = false;
-        indexBuffer = NULL;
-    }
-
-    if (!directStorage && !indexBuffer)
-    {
-        indexBuffer = (destinationIndexType == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
-
-        unsigned int convertCount = count;
-
-        if (staticBuffer)
-        {
-            if (staticBuffer->getBufferSize() == 0 && alignedOffset)
-            {
-                indexBuffer = staticBuffer;
-                convertCount = storage->getSize() / gl::GetTypeBytes(type);
-            }
-            else
-            {
-                buffer->invalidateStaticData();
-                staticBuffer = NULL;
-            }
-        }
-
-        if (!indexBuffer)
-        {
-            ERR("No valid index buffer.");
-            return GL_INVALID_OPERATION;
-        }
-
-        unsigned int indexTypeSize = gl::GetTypeBytes(destinationIndexType);
-        if (convertCount > std::numeric_limits<unsigned int>::max() / indexTypeSize)
-        {
-            ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, indexTypeSize);
-            return GL_OUT_OF_MEMORY;
-        }
-
-        unsigned int bufferSizeRequired = convertCount * indexTypeSize;
-        if (!indexBuffer->reserveBufferSpace(bufferSizeRequired, type))
-        {
-            ERR("Failed to reserve %u bytes in an index buffer.", bufferSizeRequired);
-            return GL_OUT_OF_MEMORY;
-        }
-
-        void* output = NULL;
-        if (!indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset))
-        {
-            ERR("Failed to map index buffer.");
-            return GL_OUT_OF_MEMORY;
-        }
-
-        convertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
-
-        if (!indexBuffer->unmapBuffer())
-        {
-            ERR("Failed to unmap index buffer.");
-            return GL_OUT_OF_MEMORY;
-        }
-
-        if (staticBuffer)
-        {
-            streamOffset = (offset / gl::GetTypeBytes(type)) * gl::GetTypeBytes(destinationIndexType);
-            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                         translated->maxIndex, streamOffset);
-        }
-    }
-
-    translated->storage = directStorage ? storage : NULL;
-    translated->indexBuffer = indexBuffer ? indexBuffer->getIndexBuffer() : NULL;
-    translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial();
-    translated->startIndex = streamOffset / gl::GetTypeBytes(destinationIndexType);
-    translated->startOffset = streamOffset;
-    translated->indexType = destinationIndexType;
-
-    if (buffer)
-    {
-        buffer->promoteStaticUsage(count * gl::GetTypeBytes(type));
-    }
-
-    return GL_NO_ERROR;
-}
-
-StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count)
-{
-    if (count <= 65536)   // 16-bit indices
-    {
-        const unsigned int spaceNeeded = count * sizeof(unsigned short);
-
-        if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
-        {
-            delete mCountingBuffer;
-            mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
-            mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
-
-            void* mappedMemory = NULL;
-            if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
-            {
-                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;
-            }
-        }
-    }
-    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;
-            }
-        }
-    }
-    else
-    {
-        return NULL;
-    }
-
-    return mCountingBuffer;
-}
-
-}
diff --git a/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/libGLESv2/renderer/IndexRangeCache.cpp
index 14410d0..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)
@@ -31,7 +63,7 @@
     while (i != mIndexRangeCache.end())
     {
         unsigned int rangeStart = i->second.streamOffset;
-        unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeBytes(i->first.type) * i->first.count);
+        unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeInfo(i->first.type).bytes * i->first.count);
 
         if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
         {
@@ -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 92594a4..a0682e9 100644
--- a/src/libGLESv2/renderer/Renderer.cpp
+++ b/src/libGLESv2/renderer/Renderer.cpp
@@ -1,13 +1,11 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// 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
 // found in the LICENSE file.
 //
 
 // 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"
@@ -16,11 +14,11 @@
 #include "libGLESv2/Shader.h"
 
 #if defined (ANGLE_ENABLE_D3D9)
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #endif // ANGLE_ENABLE_D3D9
 
 #if defined (ANGLE_ENABLE_D3D11)
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #endif // ANGLE_ENABLE_D3D11
 
 #if !defined(ANGLE_DEFAULT_D3D11)
@@ -28,17 +26,61 @@
 #define ANGLE_DEFAULT_D3D11 0
 #endif
 
+#include <EGL/eglext.h>
+
 namespace rx
 {
 
-Renderer::Renderer(egl::Display *display) : mDisplay(display)
+Renderer::Renderer(egl::Display *display)
+    : mDisplay(display),
+      mCapsInitialized(false),
+      mCurrentClientVersion(2)
 {
-    mCurrentClientVersion = 2;
 }
 
 Renderer::~Renderer()
 {
-    gl::Shader::releaseCompiler();
+}
+
+const gl::Caps &Renderer::getRendererCaps() const
+{
+    if (!mCapsInitialized)
+    {
+        generateCaps(&mCaps, &mTextureCaps, &mExtensions);
+        mCapsInitialized = true;
+    }
+
+    return mCaps;
+}
+
+const gl::TextureCapsMap &Renderer::getRendererTextureCaps() const
+{
+    if (!mCapsInitialized)
+    {
+        generateCaps(&mCaps, &mTextureCaps, &mExtensions);
+        mCapsInitialized = true;
+    }
+
+    return mTextureCaps;
+}
+
+const gl::Extensions &Renderer::getRendererExtensions() const
+{
+    if (!mCapsInitialized)
+    {
+        generateCaps(&mCaps, &mTextureCaps, &mExtensions);
+        mCapsInitialized = true;
+    }
+
+    return mExtensions;
+}
+
+typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, EGLint);
+
+template <typename RendererType>
+Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType)
+{
+    return new RendererType(display, nativeDisplay, requestedDisplayType);
 }
 
 }
@@ -46,40 +88,64 @@
 extern "C"
 {
 
-rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId)
+rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType)
 {
-#if defined(ANGLE_ENABLE_D3D11)
-    if (ANGLE_DEFAULT_D3D11 ||
-        displayId == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
-        displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE)
-    {
-        rx::Renderer11 *renderer = new rx::Renderer11(display, hDc);
-        if (renderer->initialize() == EGL_SUCCESS)
-        {
-            return renderer;
-        }
-        else
-        {
-            // Failed to create a D3D11 renderer, try D3D9
-            SafeDelete(renderer);
-        }
-    }
-#endif
+    std::vector<rx::CreateRendererFunction> rendererCreationFunctions;
 
-#if defined(ANGLE_ENABLE_D3D9)
-    if (displayId != EGL_D3D11_ONLY_DISPLAY_ANGLE)
+#   if defined(ANGLE_ENABLE_D3D11)
+        if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+            nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
+            requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
+            requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE)
+        {
+            rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
+        }
+#   endif
+
+#   if defined(ANGLE_ENABLE_D3D9)
+        if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+            requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
+        {
+            rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
+        }
+#   endif
+
+    if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE &&
+        nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE &&
+        requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
     {
-        rx::Renderer9 *renderer = new rx::Renderer9(display, hDc);
+        // The default display is requested, try the D3D9 and D3D11 renderers, order them using
+        // the definition of ANGLE_DEFAULT_D3D11
+#       if ANGLE_DEFAULT_D3D11
+#           if defined(ANGLE_ENABLE_D3D11)
+                rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
+#           endif
+#           if defined(ANGLE_ENABLE_D3D9)
+                rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
+#           endif
+#       else
+#           if defined(ANGLE_ENABLE_D3D9)
+                rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
+#           endif
+#           if defined(ANGLE_ENABLE_D3D11)
+                rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
+#           endif
+#       endif
+    }
+
+    for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
+    {
+        rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, requestedDisplayType);
         if (renderer->initialize() == EGL_SUCCESS)
         {
             return renderer;
         }
         else
         {
+            // Failed to create the renderer, try the next
             SafeDelete(renderer);
         }
     }
-#endif
 
     return NULL;
 }
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index b2a05d9..f104a95 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -12,6 +12,12 @@
 
 #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.
@@ -29,7 +35,7 @@
 class InfoLog;
 class ProgramBinary;
 struct LinkedVarying;
-class VertexAttribute;
+struct VertexAttribute;
 class Buffer;
 class Texture;
 class Framebuffer;
@@ -38,22 +44,25 @@
 
 namespace rx
 {
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
-class TextureStorageInterface3D;
-class TextureStorageInterface2DArray;
+class TextureStorage;
 class VertexBuffer;
 class IndexBuffer;
 class QueryImpl;
 class FenceImpl;
+class BufferImpl;
+class VertexArrayImpl;
 class BufferStorage;
 struct TranslatedIndexData;
+class ShaderImpl;
+class ProgramImpl;
 class ShaderExecutable;
 class SwapChain;
 class RenderTarget;
 class Image;
 class TextureStorage;
 class UniformStorage;
+class TextureImpl;
+class TransformFeedbackImpl;
 
 struct ConfigDesc
 {
@@ -113,23 +122,24 @@
                                       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;
-    virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]) = 0;
+    virtual void applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+                              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[], 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;
 
@@ -139,98 +149,57 @@
     virtual bool testDeviceLost(bool notify) = 0;
     virtual bool testDeviceResettable() = 0;
 
-    // Renderer capabilities
+    // Renderer capabilities (virtual because it is used by egl::Display, do not override)
+    virtual const gl::Caps &getRendererCaps() const;
+    virtual const gl::TextureCapsMap &getRendererTextureCaps() const;
+    virtual const gl::Extensions &getRendererExtensions() const;
+
     virtual DWORD getAdapterVendor() const = 0;
     virtual std::string getRendererDescription() const = 0;
     virtual GUID getAdapterIdentifier() const = 0;
 
-    virtual bool getBGRATextureSupport() const = 0;
-    virtual bool getDXT1TextureSupport() const = 0;
-    virtual bool getDXT3TextureSupport() const = 0;
-    virtual bool getDXT5TextureSupport() const = 0;
-    virtual bool getEventQuerySupport() const = 0;
-    virtual bool getFloat32TextureSupport() const = 0;
-    virtual bool getFloat32TextureFilteringSupport() const= 0;
-    virtual bool getFloat32TextureRenderingSupport() const= 0;
-    virtual bool getFloat16TextureSupport()  const= 0;
-    virtual bool getFloat16TextureFilteringSupport() const= 0;
-    virtual bool getFloat16TextureRenderingSupport() const = 0;
-    virtual bool getRGB565TextureSupport() const = 0;
-    virtual bool getLuminanceTextureSupport() const = 0;
-    virtual bool getLuminanceAlphaTextureSupport() const = 0;
-    virtual bool getRGTextureSupport() 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 getNonPower2TextureSupport() const = 0;
-    virtual bool getDepthTextureSupport() const = 0;
-    virtual bool getOcclusionQuerySupport() const = 0;
-    virtual bool getInstancingSupport() const = 0;
-    virtual bool getTextureFilterAnisotropySupport() const = 0;
-    virtual bool getPBOSupport() const = 0;
-    virtual float getTextureMaxAnisotropy() const = 0;
     virtual bool getShareHandleSupport() const = 0;
-    virtual bool getDerivativeInstructionSupport() const = 0;
     virtual bool getPostSubBufferSupport() const = 0;
-    virtual int getMaxRecommendedElementsIndices() const = 0;
-    virtual int getMaxRecommendedElementsVertices() const = 0;
 
     virtual int getMajorShaderModel() const = 0;
-    virtual float getMaxPointSize() const = 0;
-    virtual int getMaxViewportDimension() const = 0;
-    virtual int getMaxTextureWidth() const = 0;
-    virtual int getMaxTextureHeight() const = 0;
-    virtual int getMaxTextureDepth() const = 0;
-    virtual int getMaxTextureArrayLayers() const = 0;
-    virtual bool get32BitIndexSupport() const = 0;
     virtual int getMinSwapInterval() const = 0;
     virtual int getMaxSwapInterval() const = 0;
 
-    virtual GLsizei getMaxSupportedSamples() const = 0;
-    virtual GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const = 0;
-    virtual GLsizei getNumSampleCounts(GLenum internalFormat) const = 0;
-    virtual void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const = 0;
-
-    virtual unsigned int getMaxRenderTargets() 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;
@@ -248,15 +217,24 @@
     virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
 
+    // Texture creation
+    virtual TextureImpl *createTexture(GLenum target) = 0;
+
     // Buffer creation
+    virtual BufferImpl *createBuffer() = 0;
     virtual VertexBuffer *createVertexBuffer() = 0;
     virtual IndexBuffer *createIndexBuffer() = 0;
-    virtual BufferStorage *createBufferStorage() = 0;
+
+    // Vertex Array creation
+    virtual VertexArrayImpl *createVertexArray() = 0;
 
     // Query and Fence creation
     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; }
@@ -267,7 +245,6 @@
                                          GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0;
 
     virtual bool getLUID(LUID *adapterLuid) const = 0;
-    virtual GLenum getNativeTextureFormat(GLenum internalFormat) const = 0;
     virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0;
     virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0;
 
@@ -277,6 +254,13 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Renderer);
 
+    virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const = 0;
+
+    mutable bool mCapsInitialized;
+    mutable gl::Caps mCaps;
+    mutable gl::TextureCapsMap mTextureCaps;
+    mutable gl::Extensions mExtensions;
+
     int mCurrentClientVersion;
 };
 
diff --git a/src/libGLESv2/renderer/ShaderExecutable.h b/src/libGLESv2/renderer/ShaderExecutable.h
index 5e229d7..f171956 100644
--- a/src/libGLESv2/renderer/ShaderExecutable.h
+++ b/src/libGLESv2/renderer/ShaderExecutable.h
@@ -13,38 +13,37 @@
 #include "common/angleutils.h"
 #include "common/debug.h"
 
+#include <vector>
+#include <cstdint>
+
 namespace rx
 {
 
 class ShaderExecutable
 {
   public:
-    ShaderExecutable(const void *function, size_t length) : mLength(length)
+    ShaderExecutable(const void *function, size_t length)
+        : mFunctionBuffer(length)
     {
-        mFunction = new char[length];
-        memcpy(mFunction, function, length);
-    }
-    
-    virtual ~ShaderExecutable()
-    {
-        delete[] mFunction;
+        memcpy(mFunctionBuffer.data(), function, length);
     }
 
-    void *getFunction() const
+    virtual ~ShaderExecutable() {}
+
+    const uint8_t *getFunction() const
     {
-        return mFunction;
+        return mFunctionBuffer.data();
     }
 
     size_t getLength() const
     {
-        return mLength;
+        return mFunctionBuffer.size();
     }
 
   private:
     DISALLOW_COPY_AND_ASSIGN(ShaderExecutable);
 
-    void *mFunction;
-    const size_t mLength;
+    std::vector<uint8_t> mFunctionBuffer;
 };
 
 class UniformStorage
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
new file mode 100644
index 0000000..e3cc50d
--- /dev/null
+++ b/src/libGLESv2/renderer/TextureImpl.h
@@ -0,0 +1,70 @@
+//
+// 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.
+//
+
+// TextureImpl.h: Defines the abstract rx::TextureImpl classes.
+
+#ifndef LIBGLESV2_RENDERER_TEXTUREIMPL_H_
+#define LIBGLESV2_RENDERER_TEXTUREIMPL_H_
+
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+#include "libGLESv2/ImageIndex.h"
+
+namespace egl
+{
+class Surface;
+}
+
+namespace gl
+{
+class Framebuffer;
+struct PixelUnpackState;
+struct SamplerState;
+}
+
+namespace rx
+{
+
+class Image;
+class Renderer;
+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 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 void setUsage(GLenum usage) = 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;
+    virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0;
+    virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
+    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
+    virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0;
+
+    virtual void generateMipmaps() = 0;
+
+    virtual void bindTexImage(egl::Surface *surface) = 0;
+    virtual void releaseTexImage() = 0;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTUREIMPL_H_
diff --git a/src/libGLESv2/renderer/TextureStorage.cpp b/src/libGLESv2/renderer/TextureStorage.cpp
deleted file mode 100644
index 650f368..0000000
--- a/src/libGLESv2/renderer/TextureStorage.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-#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.
-
-#include "libGLESv2/renderer/TextureStorage.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Texture.h"
-
-#include "common/debug.h"
-#include "common/mathutil.h"
-
-namespace rx
-{
-unsigned int TextureStorageInterface::mCurrentTextureSerial = 1;
-
-TextureStorageInterface::TextureStorageInterface()
-    : mTextureSerial(issueTextureSerial()),
-      mInstance(NULL)
-{
-}
-
-TextureStorageInterface::~TextureStorageInterface()
-{
-    delete mInstance;
-}
-
-bool TextureStorageInterface::isRenderTarget() const
-{
-    return mInstance->isRenderTarget();
-}
-
-bool TextureStorageInterface::isManaged() const
-{
-    return mInstance->isManaged();
-}
-
-unsigned int TextureStorageInterface::getTextureSerial() const
-{
-    return mTextureSerial;
-}
-
-unsigned int TextureStorageInterface::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::targetToIndex(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/TextureStorage.h b/src/libGLESv2/renderer/TextureStorage.h
deleted file mode 100644
index 0a212e1..0000000
--- a/src/libGLESv2/renderer/TextureStorage.h
+++ /dev/null
@@ -1,145 +0,0 @@
-//
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// 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.
-
-#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
-#define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
-
-#include "common/debug.h"
-
-namespace rx
-{
-class Renderer;
-class SwapChain;
-class RenderTarget;
-
-class TextureStorage
-{
-  public:
-    TextureStorage() {};
-    virtual ~TextureStorage() {};
-
-    virtual int getTopLevel() const = 0;
-    virtual bool isRenderTarget() const = 0;
-    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;
-
-  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;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE_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/VertexArrayImpl.h b/src/libGLESv2/renderer/VertexArrayImpl.h
new file mode 100644
index 0000000..b013f9c
--- /dev/null
+++ b/src/libGLESv2/renderer/VertexArrayImpl.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.
+//
+
+// VertexAttribImpl.h: Defines the abstract rx::VertexAttribImpl class.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
+#define LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/VertexAttribute.h"
+
+namespace rx
+{
+
+class VertexArrayImpl
+{
+  public:
+    virtual ~VertexArrayImpl() { }
+
+    virtual void setElementArrayBuffer(const gl::Buffer *buffer) = 0;
+    virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) = 0;
+    virtual void setAttributeDivisor(size_t idx, GLuint divisor) = 0;
+    virtual void enableAttribute(size_t idx, bool enabledState) = 0;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
diff --git a/src/libGLESv2/renderer/VertexBuffer.cpp b/src/libGLESv2/renderer/VertexBuffer.cpp
deleted file mode 100644
index 8adfb5b..0000000
--- a/src/libGLESv2/renderer/VertexBuffer.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
-// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
-
-#include "libGLESv2/renderer/VertexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/BufferStorage.h"
-#include "common/mathutil.h"
-
-namespace rx
-{
-
-unsigned int VertexBuffer::mNextSerial = 1;
-
-VertexBuffer::VertexBuffer()
-{
-    updateSerial();
-}
-
-VertexBuffer::~VertexBuffer()
-{
-}
-
-void VertexBuffer::updateSerial()
-{
-    mSerial = mNextSerial++;
-}
-
-unsigned int VertexBuffer::getSerial() const
-{
-    return mSerial;
-}
-
-VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
-{
-    mDynamic = dynamic;
-    mWritePosition = 0;
-    mReservedSpace = 0;
-
-    mVertexBuffer = renderer->createVertexBuffer();
-}
-
-VertexBufferInterface::~VertexBufferInterface()
-{
-    delete mVertexBuffer;
-}
-
-unsigned int VertexBufferInterface::getSerial() const
-{
-    return mVertexBuffer->getSerial();
-}
-
-unsigned int VertexBufferInterface::getBufferSize() const
-{
-    return mVertexBuffer->getBufferSize();
-}
-
-bool VertexBufferInterface::setBufferSize(unsigned int size)
-{
-    if (mVertexBuffer->getBufferSize() == 0)
-    {
-        return mVertexBuffer->initialize(size, mDynamic);
-    }
-    else
-    {
-        return mVertexBuffer->setBufferSize(size);
-    }
-}
-
-unsigned int VertexBufferInterface::getWritePosition() const
-{
-    return mWritePosition;
-}
-
-void VertexBufferInterface::setWritePosition(unsigned int writePosition)
-{
-    mWritePosition = writePosition;
-}
-
-bool 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)
-{
-    unsigned int spaceRequired;
-    if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired))
-    {
-        return false;
-    }
-
-    if (mWritePosition + spaceRequired < mWritePosition)
-    {
-        return false;
-    }
-
-    if (!reserveSpace(mReservedSpace))
-    {
-        return false;
-    }
-    mReservedSpace = 0;
-
-    if (!mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition))
-    {
-        return false;
-    }
-
-    if (outStreamOffset)
-    {
-        *outStreamOffset = mWritePosition;
-    }
-
-    mWritePosition += spaceRequired;
-
-    // Align to 16-byte boundary
-    mWritePosition = rx::roundUp(mWritePosition, 16u);
-
-    return true;
-}
-
-bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
-{
-    unsigned int requiredSpace;
-    if (!mVertexBuffer->getSpaceRequired(attribute, count, instances, &requiredSpace))
-    {
-        return false;
-    }
-
-    // Protect against integer overflow
-    if (mReservedSpace + requiredSpace < mReservedSpace)
-    {
-         return false;
-    }
-
-    mReservedSpace += requiredSpace;
-
-    // Align to 16-byte boundary
-    mReservedSpace = rx::roundUp(mReservedSpace, 16u);
-
-    return true;
-}
-
-VertexBuffer* VertexBufferInterface::getVertexBuffer() const
-{
-    return mVertexBuffer;
-}
-
-bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &attrib,
-                                                  const gl::VertexAttribCurrentValueData &currentValue) const
-{
-    gl::Buffer *buffer = attrib.mBoundBuffer.get();
-    BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
-
-    if (!storage || !storage->supportsDirectBinding())
-    {
-        return false;
-    }
-
-    // Alignment restrictions: In D3D, vertex data must be aligned to
-    //  the format stride, or to a 4-byte boundary, whichever is smaller.
-    //  (Undocumented, and experimentally confirmed)
-    size_t alignment = 4;
-    bool requiresConversion = false;
-
-    if (attrib.mType != GL_FLOAT)
-    {
-        gl::VertexFormat vertexFormat(attrib, currentValue.Type);
-
-        unsigned int outputElementSize;
-        getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
-        alignment = std::min<size_t>(outputElementSize, 4);
-
-        requiresConversion = (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0;
-    }
-
-    bool isAligned = (static_cast<size_t>(attrib.stride()) % alignment == 0) &&
-                     (static_cast<size_t>(attrib.mOffset) % alignment == 0);
-
-    return !requiresConversion && isAligned;
-}
-
-StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
-{
-    setBufferSize(initialSize);
-}
-
-StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
-{
-}
-
-bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
-{
-    bool result = true;
-    unsigned int curBufferSize = getBufferSize();
-    if (size > curBufferSize)
-    {
-        result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
-        setWritePosition(0);
-    }
-    else if (getWritePosition() + size > curBufferSize)
-    {
-        if (!discard())
-        {
-            return false;
-        }
-        setWritePosition(0);
-    }
-
-    return result;
-}
-
-StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
-{
-}
-
-StaticVertexBufferInterface::~StaticVertexBufferInterface()
-{
-}
-
-bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute, unsigned int *outStreamOffset)
-{
-    for (unsigned int element = 0; element < mCache.size(); element++)
-    {
-        if (mCache[element].type == attribute.mType &&
-            mCache[element].size == attribute.mSize &&
-            mCache[element].stride == attribute.stride() &&
-            mCache[element].normalized == attribute.mNormalized &&
-            mCache[element].pureInteger == attribute.mPureInteger)
-        {
-            if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
-            {
-                if (outStreamOffset)
-                {
-                    *outStreamOffset = mCache[element].streamOffset;
-                }
-                return true;
-            }
-        }
-    }
-
-    return false;
-}
-
-bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
-{
-    unsigned int curSize = getBufferSize();
-    if (curSize == 0)
-    {
-        setBufferSize(size);
-        return true;
-    }
-    else if (curSize >= size)
-    {
-        return true;
-    }
-    else
-    {
-        UNREACHABLE();   // Static vertex buffers can't be resized
-        return false;
-    }
-}
-
-bool 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))
-    {
-        int attributeOffset = attrib.mOffset % attrib.stride();
-        VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attrib.mPureInteger, attributeOffset, streamOffset };
-        mCache.push_back(element);
-
-        if (outStreamOffset)
-        {
-            *outStreamOffset = streamOffset;
-        }
-
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-}
diff --git a/src/libGLESv2/renderer/VertexDataManager.cpp b/src/libGLESv2/renderer/VertexDataManager.cpp
deleted file mode 100644
index 6aad5eb..0000000
--- a/src/libGLESv2/renderer/VertexDataManager.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// VertexDataManager.h: Defines the VertexDataManager, a class that
-// runs the Buffer translation process.
-
-#include "libGLESv2/renderer/VertexDataManager.h"
-#include "libGLESv2/renderer/BufferStorage.h"
-
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/VertexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
-
-namespace
-{
-    enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 };
-    // This has to be at least 4k or else it fails on ATI cards.
-    enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 };
-}
-
-namespace rx
-{
-
-static int ElementsInBuffer(const gl::VertexAttribute &attribute, unsigned int size)
-{
-    // Size cannot be larger than a GLsizei
-    if (size > static_cast<unsigned int>(std::numeric_limits<int>::max()))
-    {
-        size = static_cast<unsigned int>(std::numeric_limits<int>::max());
-    }
-
-    GLsizei stride = attribute.stride();
-    return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
-}
-
-static int StreamingBufferElementCount(const gl::VertexAttribute &attribute, int vertexDrawCount, int instanceDrawCount)
-{
-    // For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices.
-    //
-    // A vertex attribute with a positive divisor loads one instanced vertex for every set of
-    // non-instanced vertices, and the instanced vertex index advances once every "mDivisor" instances.
-    if (instanceDrawCount > 0 && attribute.mDivisor > 0)
-    {
-        return instanceDrawCount / attribute.mDivisor;
-    }
-
-    return vertexDrawCount;
-}
-
-VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
-{
-    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
-    {
-        mCurrentValue[i].FloatValues[0] = std::numeric_limits<float>::quiet_NaN();
-        mCurrentValue[i].FloatValues[1] = std::numeric_limits<float>::quiet_NaN();
-        mCurrentValue[i].FloatValues[2] = std::numeric_limits<float>::quiet_NaN();
-        mCurrentValue[i].FloatValues[3] = std::numeric_limits<float>::quiet_NaN();
-        mCurrentValue[i].Type = GL_FLOAT;
-        mCurrentValueBuffer[i] = NULL;
-        mCurrentValueOffsets[i] = 0;
-    }
-
-    mStreamingBuffer = new StreamingVertexBufferInterface(renderer, INITIAL_STREAM_BUFFER_SIZE);
-
-    if (!mStreamingBuffer)
-    {
-        ERR("Failed to allocate the streaming vertex buffer.");
-    }
-}
-
-VertexDataManager::~VertexDataManager()
-{
-    delete mStreamingBuffer;
-
-    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
-    {
-        delete mCurrentValueBuffer[i];
-    }
-}
-
-GLenum 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);
-    }
-
-    // Invalidate static buffers that don't contain matching attributes
-    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (translated[i].active && attribs[i].mArrayEnabled)
-        {
-            gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
-            StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
-
-            if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) &&
-                !staticBuffer->directStoragePossible(attribs[i], currentValues[i]))
-            {
-                buffer->invalidateStaticData();
-            }
-        }
-    }
-
-    // Reserve the required space in the buffers
-    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (translated[i].active && attribs[i].mArrayEnabled)
-        {
-            gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
-            StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
-            VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
-
-            if (!vertexBuffer->directStoragePossible(attribs[i], currentValues[i]))
-            {
-                if (staticBuffer)
-                {
-                    if (staticBuffer->getBufferSize() == 0)
-                    {
-                        int totalCount = ElementsInBuffer(attribs[i], buffer->size());
-                        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 (buffer && ElementsInBuffer(attribs[i], buffer->size()) < totalCount)
-                    {
-                        return GL_INVALID_OPERATION;
-                    }
-
-                    if (!mStreamingBuffer->reserveVertexSpace(attribs[i], totalCount, instances))
-                    {
-                        return GL_OUT_OF_MEMORY;
-                    }
-                }
-            }
-        }
-    }
-
-    // Perform the vertex data translations
-    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (translated[i].active)
-        {
-            if (attribs[i].mArrayEnabled)
-            {
-                gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
-
-                if (!buffer && attribs[i].mPointer == NULL)
-                {
-                    // 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;
-                }
-
-                StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
-                VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
-
-                BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
-                bool directStorage = vertexBuffer->directStoragePossible(attribs[i], currentValues[i]);
-
-                unsigned int streamOffset = 0;
-                unsigned int outputElementSize = 0;
-
-                if (directStorage)
-                {
-                    outputElementSize = attribs[i].stride();
-                    streamOffset = attribs[i].mOffset + 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].mOffset / attribs[i].stride();
-
-                        if (!staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount,
-                                                                 0, &streamOffset))
-                        {
-                            return GL_OUT_OF_MEMORY;
-                        }
-                    }
-
-                    unsigned int firstElementOffset = (attribs[i].mOffset / attribs[i].stride()) * outputElementSize;
-                    unsigned int startOffset = (instances == 0 || attribs[i].mDivisor == 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].mDivisor;
-
-                translated[i].attribute = &attribs[i];
-                translated[i].currentValueType = currentValues[i].Type;
-                translated[i].stride = outputElementSize;
-                translated[i].offset = streamOffset;
-            }
-            else
-            {
-                if (!mCurrentValueBuffer[i])
-                {
-                    mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE);
-                }
-
-                StreamingVertexBufferInterface *buffer = mCurrentValueBuffer[i];
-
-                if (mCurrentValue[i] != currentValues[i])
-                {
-                    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;
-                }
-
-                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];
-            }
-        }
-    }
-
-    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (translated[i].active && attribs[i].mArrayEnabled)
-        {
-            gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
-
-            if (buffer)
-            {
-                buffer->promoteStaticUsage(count * attribs[i].typeSize());
-            }
-        }
-    }
-
-    return GL_NO_ERROR;
-}
-
-}
diff --git a/src/libGLESv2/renderer/VertexDataManager.h b/src/libGLESv2/renderer/VertexDataManager.h
deleted file mode 100644
index 1a69245..0000000
--- a/src/libGLESv2/renderer/VertexDataManager.h
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// VertexDataManager.h: Defines the VertexDataManager, a class that
-// runs the Buffer translation process.
-
-#ifndef LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
-#define LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
-
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "common/angleutils.h"
-
-namespace gl
-{
-class VertexAttribute;
-class ProgramBinary;
-struct VertexAttribCurrentValueData;
-}
-
-namespace rx
-{
-class BufferStorage;
-class StreamingVertexBufferInterface;
-class VertexBuffer;
-class Renderer;
-
-struct TranslatedAttribute
-{
-    bool active;
-
-    const gl::VertexAttribute *attribute;
-    GLenum currentValueType;
-    unsigned int offset;
-    unsigned int stride;   // 0 means not to advance the read pointer at all
-
-    VertexBuffer *vertexBuffer;
-    BufferStorage *storage;
-    unsigned int serial;
-    unsigned int divisor;
-};
-
-class VertexDataManager
-{
-  public:
-    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);
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
-
-    rx::Renderer *const mRenderer;
-
-    StreamingVertexBufferInterface *mStreamingBuffer;
-
-    gl::VertexAttribCurrentValueData mCurrentValue[gl::MAX_VERTEX_ATTRIBS];
-
-    StreamingVertexBufferInterface *mCurrentValueBuffer[gl::MAX_VERTEX_ATTRIBS];
-    std::size_t mCurrentValueOffsets[gl::MAX_VERTEX_ATTRIBS];
-};
-
-}
-
-#endif   // LIBGLESV2_RENDERER_VERTEXDATAMANAGER_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
new file mode 100644
index 0000000..a34ef03
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/BufferD3D.cpp
@@ -0,0 +1,82 @@
+//
+// 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.
+//
+
+// BufferD3D.cpp Defines common functionality between the Buffer9 and Buffer11 classes.
+
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+#include "libGLESv2/renderer/d3d/VertexBuffer.h"
+#include "libGLESv2/renderer/d3d/IndexBuffer.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+unsigned int BufferD3D::mNextSerial = 1;
+
+BufferD3D::BufferD3D()
+    : BufferImpl(),
+      mStaticVertexBuffer(NULL),
+      mStaticIndexBuffer(NULL)
+{
+    updateSerial();
+}
+
+BufferD3D::~BufferD3D()
+{
+    SafeDelete(mStaticVertexBuffer);
+    SafeDelete(mStaticIndexBuffer);
+}
+
+BufferD3D *BufferD3D::makeBufferD3D(BufferImpl *buffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(BufferD3D*, buffer));
+    return static_cast<BufferD3D*>(buffer);
+}
+
+void BufferD3D::updateSerial()
+{
+    mSerial = mNextSerial++;
+}
+
+void BufferD3D::initializeStaticData()
+{
+    if (!mStaticVertexBuffer)
+    {
+        mStaticVertexBuffer = new rx::StaticVertexBufferInterface(getRenderer());
+    }
+    if (!mStaticIndexBuffer)
+    {
+        mStaticIndexBuffer = new rx::StaticIndexBufferInterface(getRenderer());
+    }
+}
+
+void BufferD3D::invalidateStaticData()
+{
+    if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
+    {
+        SafeDelete(mStaticVertexBuffer);
+        SafeDelete(mStaticIndexBuffer);
+    }
+
+    mUnmodifiedDataUse = 0;
+}
+
+// Creates static buffers if sufficient used data has been left unmodified
+void BufferD3D::promoteStaticUsage(int dataSize)
+{
+    if (!mStaticVertexBuffer && !mStaticIndexBuffer)
+    {
+        mUnmodifiedDataUse += dataSize;
+
+        if (mUnmodifiedDataUse > 3 * getSize())
+        {
+            initializeStaticData();
+        }
+    }
+}
+
+}
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/libGLESv2/renderer/d3d/BufferD3D.h
new file mode 100644
index 0000000..44f14ce
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/BufferD3D.h
@@ -0,0 +1,56 @@
+//
+// 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.
+//
+
+// BufferImpl.h: Defines the abstract rx::BufferImpl class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERD3D_H_
+#define LIBGLESV2_RENDERER_BUFFERD3D_H_
+
+#include "libGLESv2/renderer/BufferImpl.h"
+#include "libGLESv2/angletypes.h"
+
+namespace rx
+{
+
+class Renderer;
+class StaticIndexBufferInterface;
+class StaticVertexBufferInterface;
+
+class BufferD3D : public BufferImpl
+{
+  public:
+    BufferD3D();
+    virtual ~BufferD3D();
+
+    static BufferD3D *makeBufferD3D(BufferImpl *buffer);
+
+    unsigned int getSerial() const { return mSerial; }
+
+    virtual size_t getSize() const = 0;
+    virtual bool supportsDirectBinding() const = 0;
+    virtual Renderer* getRenderer() = 0;
+
+    rx::StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; }
+    rx::StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; }
+
+    void initializeStaticData();
+    void invalidateStaticData();
+    void promoteStaticUsage(int dataSize);
+
+  protected:
+    unsigned int mSerial;
+    static unsigned int mNextSerial;
+
+    void updateSerial();
+
+    rx::StaticVertexBufferInterface *mStaticVertexBuffer;
+    rx::StaticIndexBufferInterface *mStaticIndexBuffer;
+    unsigned int mUnmodifiedDataUse;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERIMPLD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
new file mode 100644
index 0000000..13411eb
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
@@ -0,0 +1,1144 @@
+//
+// 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.cpp: Implementation for link and run-time HLSL generation
+//
+
+#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/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);
+
+using namespace gl;
+
+namespace
+{
+
+std::string HLSLComponentTypeString(GLenum componentType)
+{
+    switch (componentType)
+    {
+      case GL_UNSIGNED_INT:         return "uint";
+      case GL_INT:                  return "int";
+      case GL_UNSIGNED_NORMALIZED:
+      case GL_SIGNED_NORMALIZED:
+      case GL_FLOAT:                return "float";
+      default: UNREACHABLE();       return "not-component-type";
+    }
+}
+
+std::string HLSLComponentTypeString(GLenum componentType, int componentCount)
+{
+    return HLSLComponentTypeString(componentType) + (componentCount > 1 ? Str(componentCount) : "");
+}
+
+std::string HLSLMatrixTypeString(GLenum type)
+{
+    switch (type)
+    {
+      case GL_FLOAT_MAT2:     return "float2x2";
+      case GL_FLOAT_MAT3:     return "float3x3";
+      case GL_FLOAT_MAT4:     return "float4x4";
+      case GL_FLOAT_MAT2x3:   return "float2x3";
+      case GL_FLOAT_MAT3x2:   return "float3x2";
+      case GL_FLOAT_MAT2x4:   return "float2x4";
+      case GL_FLOAT_MAT4x2:   return "float4x2";
+      case GL_FLOAT_MAT3x4:   return "float3x4";
+      case GL_FLOAT_MAT4x3:   return "float4x3";
+      default: UNREACHABLE(); return "not-matrix-type";
+    }
+}
+
+std::string HLSLTypeString(GLenum type)
+{
+    if (gl::IsMatrixType(type))
+    {
+        return HLSLMatrixTypeString(type);
+    }
+
+    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 rx
+{
+
+const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
+const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@";
+
+DynamicHLSL::DynamicHLSL(rx::Renderer *const renderer)
+    : mRenderer(renderer)
+{
+}
+
+static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, VaryingPacking packing)
+{
+    GLenum transposedType = TransposeMatrixType(varying->type);
+
+    // matrices within varying structs are not transposed
+    int registers = (varying->isStruct() ? HLSLVariableRegisterCount(*varying) : VariableRowCount(transposedType)) * varying->elementCount();
+    int elements = (varying->isStruct() ? 4 : VariableColumnCount(transposedType));
+
+    if (elements >= 2 && elements <= 4)
+    {
+        for (int r = 0; r <= maxVaryingVectors - registers; r++)
+        {
+            bool available = true;
+
+            for (int y = 0; y < registers && available; y++)
+            {
+                for (int x = 0; x < elements && available; x++)
+                {
+                    if (packing[r + y][x])
+                    {
+                        available = false;
+                    }
+                }
+            }
+
+            if (available)
+            {
+                varying->registerIndex = r;
+                varying->columnIndex = 0;
+
+                for (int y = 0; y < registers; y++)
+                {
+                    for (int x = 0; x < elements; x++)
+                    {
+                        packing[r + y][x] = &*varying;
+                    }
+                }
+
+                return true;
+            }
+        }
+
+        if (elements == 2)
+        {
+            for (int r = maxVaryingVectors - registers; r >= 0; r--)
+            {
+                bool available = true;
+
+                for (int y = 0; y < registers && available; y++)
+                {
+                    for (int x = 2; x < 4 && available; x++)
+                    {
+                        if (packing[r + y][x])
+                        {
+                            available = false;
+                        }
+                    }
+                }
+
+                if (available)
+                {
+                    varying->registerIndex = r;
+                    varying->columnIndex = 2;
+
+                    for (int y = 0; y < registers; y++)
+                    {
+                        for (int x = 2; x < 4; x++)
+                        {
+                            packing[r + y][x] = &*varying;
+                        }
+                    }
+
+                    return true;
+                }
+            }
+        }
+    }
+    else if (elements == 1)
+    {
+        int space[4] = { 0 };
+
+        for (int y = 0; y < maxVaryingVectors; y++)
+        {
+            for (int x = 0; x < 4; x++)
+            {
+                space[x] += packing[y][x] ? 0 : 1;
+            }
+        }
+
+        int column = 0;
+
+        for (int x = 0; x < 4; x++)
+        {
+            if (space[x] >= registers && (space[column] < registers || space[x] < space[column]))
+            {
+                column = x;
+            }
+        }
+
+        if (space[column] >= registers)
+        {
+            for (int r = 0; r < maxVaryingVectors; r++)
+            {
+                if (!packing[r][column])
+                {
+                    varying->registerIndex = r;
+                    varying->columnIndex = column;
+
+                    for (int y = r; y < r + registers; y++)
+                    {
+                        packing[y][column] = &*varying;
+                    }
+
+                    break;
+                }
+            }
+
+            return true;
+        }
+    }
+    else UNREACHABLE();
+
+    return false;
+}
+
+// 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, rx::ShaderD3D *fragmentShader,
+                              rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
+{
+    // TODO (geofflang):  Use context's caps
+    const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
+
+    vertexShader->resetVaryingsRegisterAssignment();
+    fragmentShader->resetVaryingsRegisterAssignment();
+
+    std::set<std::string> packedVaryings;
+
+    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 = &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);
+        }
+        else
+        {
+            infoLog.append("Could not pack varying %s", varying->name.c_str());
+            return -1;
+        }
+    }
+
+    for (unsigned int feedbackVaryingIndex = 0; feedbackVaryingIndex < transformFeedbackVaryings.size(); feedbackVaryingIndex++)
+    {
+        const std::string &transformFeedbackVarying = transformFeedbackVaryings[feedbackVaryingIndex];
+        if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end())
+        {
+            bool found = false;
+            for (unsigned int varyingIndex = 0; varyingIndex < vertexVaryings.size(); varyingIndex++)
+            {
+                PackedVarying *varying = &vertexVaryings[varyingIndex];
+                if (transformFeedbackVarying == varying->name)
+                {
+                    if (!packVarying(varying, maxVaryingVectors, packing))
+                    {
+                        infoLog.append("Could not pack varying %s", varying->name.c_str());
+                        return -1;
+                    }
+
+                    found = true;
+                    break;
+                }
+            }
+
+            if (!found && transformFeedbackVarying != "gl_Position" && transformFeedbackVarying != "gl_PointSize")
+            {
+                infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str());
+                return -1;
+            }
+        }
+    }
+
+    // Return the number of used registers
+    int registers = 0;
+
+    for (int r = 0; r < maxVaryingVectors; r++)
+    {
+        if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
+        {
+            registers++;
+        }
+    }
+
+    return registers;
+}
+
+std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const
+{
+    std::string varyingSemantic = getVaryingSemantic(shader->mUsesPointSize);
+    std::string varyingHLSL;
+
+    const std::vector<gl::PackedVarying> &varyings = shader->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));
+
+            for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++)
+            {
+                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;
+                      case sh::INTERPOLATION_FLAT:     varyingHLSL += "    nointerpolation "; break;
+                      case sh::INTERPOLATION_CENTROID: varyingHLSL += "    centroid ";        break;
+                      default:  UNREACHABLE();
+                    }
+
+                    unsigned int semanticIndex = elementIndex * variableRows + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + varying.registerIndex + row;
+                    std::string n = Str(semanticIndex);
+
+                    std::string typeString;
+
+                    if (varying.isStruct())
+                    {
+                        // matrices within structs are not transposed, so
+                        // do not use the special struct prefix "rm"
+                        typeString = decorateVariable(varying.structName);
+                    }
+                    else
+                    {
+                        GLenum componentType = VariableComponentType(transposedType);
+                        int columnCount = VariableColumnCount(transposedType);
+                        typeString = HLSLComponentTypeString(componentType, columnCount);
+                    }
+                    varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n";
+                }
+            }
+        }
+    }
+
+    return varyingHLSL;
+}
+
+std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &sourceShader,
+                                                            const VertexFormat inputLayout[],
+                                                            const sh::Attribute shaderAttributes[]) const
+{
+    std::string structHLSL, initHLSL;
+
+    int semanticIndex = 0;
+    unsigned int inputIndex = 0;
+
+    for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+    {
+        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 += "    " + HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
+            }
+            else
+            {
+                GLenum componentType = mRenderer->getVertexComponentType(vertexFormat);
+                structHLSL += "    " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
+            }
+
+            structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
+            semanticIndex += VariableRegisterCount(shaderAttribute.type);
+
+            // HLSL code for initialization
+            initHLSL += "    " + decorateVariable(shaderAttribute.name) + " = ";
+
+            // Mismatched vertex attribute to vertex input may result in an undefined
+            // data reinterpretation (eg for pure integer->float, float->pure integer)
+            // TODO: issue warning with gl debug info extension, when supported
+            if (IsMatrixType(shaderAttribute.type) ||
+                (mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0)
+            {
+                initHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute);
+            }
+            else
+            {
+                initHLSL += "input." + decorateVariable(shaderAttribute.name);
+            }
+
+            initHLSL += ";\n";
+
+            inputIndex += VariableRowCount(TransposeMatrixType(shaderAttribute.type));
+        }
+    }
+
+    std::string replacementHLSL = "struct VS_INPUT\n"
+                                  "{\n" +
+                                  structHLSL +
+                                  "};\n"
+                                  "\n"
+                                  "void initAttributes(VS_INPUT input)\n"
+                                  "{\n" +
+                                  initHLSL +
+                                  "}\n";
+
+    std::string vertexHLSL(sourceShader);
+
+    size_t copyInsertionPos = vertexHLSL.find(VERTEX_ATTRIBUTE_STUB_STRING);
+    vertexHLSL.replace(copyInsertionPos, VERTEX_ATTRIBUTE_STUB_STRING.length(), replacementHLSL);
+
+    return vertexHLSL;
+}
+
+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();
+    std::string targetSemantic = (shaderModel >= 4) ? "SV_TARGET" : "COLOR";
+    std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH";
+
+    std::string declarationHLSL;
+    std::string copyHLSL;
+
+    for (size_t layoutIndex = 0; layoutIndex < outputLayout.size(); ++layoutIndex)
+    {
+        GLenum binding = outputLayout[layoutIndex];
+
+        if (binding != GL_NONE)
+        {
+            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";
+        }
+    }
+
+    if (usesFragDepth)
+    {
+        declarationHLSL += "    float gl_Depth : " + depthSemantic + ";\n";
+        copyHLSL += "    output.gl_Depth = gl_Depth; \n";
+    }
+
+    std::string replacementHLSL = "struct PS_OUTPUT\n"
+                                  "{\n" +
+                                  declarationHLSL +
+                                  "};\n"
+                                  "\n"
+                                  "PS_OUTPUT generateOutput()\n"
+                                  "{\n"
+                                  "    PS_OUTPUT output;\n" +
+                                  copyHLSL +
+                                  "    return output;\n"
+                                  "}\n";
+
+    std::string pixelHLSL(sourceShader);
+
+    size_t outputInsertionPos = pixelHLSL.find(PIXEL_OUTPUT_STUB_STRING);
+    pixelHLSL.replace(outputInsertionPos, PIXEL_OUTPUT_STUB_STRING.length(), replacementHLSL);
+
+    return pixelHLSL;
+}
+
+std::string DynamicHLSL::getVaryingSemantic(bool pointSize) const
+{
+    // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
+    // In D3D11 we manually compute gl_PointCoord in the GS.
+    int shaderModel = mRenderer->getMajorShaderModel();
+    return ((pointSize && shaderModel < 4) ? "COLOR" : "TEXCOORD");
+}
+
+struct DynamicHLSL::SemanticInfo
+{
+    struct BuiltinInfo
+    {
+        BuiltinInfo()
+            : enabled(false),
+              index(0),
+              systemValue(false)
+        {}
+
+        bool enabled;
+        std::string semantic;
+        unsigned int index;
+        bool systemValue;
+
+        std::string str() const
+        {
+            return (systemValue ? semantic : (semantic + Str(index)));
+        }
+
+        void enableSystem(const std::string &systemValueSemantic)
+        {
+            enabled = true;
+            semantic = systemValueSemantic;
+            systemValue = true;
+        }
+
+        void enable(const std::string &semanticVal, unsigned int indexVal)
+        {
+            enabled = true;
+            semantic = semanticVal;
+            index = indexVal;
+        }
+    };
+
+    BuiltinInfo dxPosition;
+    BuiltinInfo glPosition;
+    BuiltinInfo glFragCoord;
+    BuiltinInfo glPointCoord;
+    BuiltinInfo glPointSize;
+};
+
+DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord,
+                                                       bool pointSize, bool pixelShader) const
+{
+    SemanticInfo info;
+    bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4);
+    const std::string &varyingSemantic = getVaryingSemantic(pointSize);
+
+    int reservedRegisterIndex = startRegisters;
+
+    if (hlsl4)
+    {
+        info.dxPosition.enableSystem("SV_Position");
+    }
+    else if (pixelShader)
+    {
+        info.dxPosition.enableSystem("VPOS");
+    }
+    else
+    {
+        info.dxPosition.enableSystem("POSITION");
+    }
+
+    info.glPosition.enable(varyingSemantic, reservedRegisterIndex++);
+
+    if (fragCoord)
+    {
+        info.glFragCoord.enable(varyingSemantic, reservedRegisterIndex++);
+    }
+
+    if (pointCoord)
+    {
+        // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
+        // In D3D11 we manually compute gl_PointCoord in the GS.
+        if (hlsl4)
+        {
+            info.glPointCoord.enable(varyingSemantic, reservedRegisterIndex++);
+        }
+        else
+        {
+            info.glPointCoord.enable("TEXCOORD", 0);
+        }
+    }
+
+    // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders
+    if (pointSize && (!pixelShader || hlsl4))
+    {
+        info.glPointSize.enableSystem("PSIZE");
+    }
+
+    return info;
+}
+
+std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const
+{
+    std::string linkHLSL = "{\n";
+
+    ASSERT(info.dxPosition.enabled && info.glPosition.enabled);
+
+    linkHLSL += "    float4 dx_Position : " + info.dxPosition.str() + ";\n";
+    linkHLSL += "    float4 gl_Position : " + info.glPosition.str() + ";\n";
+
+    if (info.glFragCoord.enabled)
+    {
+        linkHLSL += "    float4 gl_FragCoord : " + info.glFragCoord.str() + ";\n";
+    }
+
+    if (info.glPointCoord.enabled)
+    {
+        linkHLSL += "    float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n";
+    }
+
+    linkHLSL += varyingHLSL;
+
+    if (info.glPointSize.enabled)
+    {
+        linkHLSL += "    float gl_PointSize : " + info.glPointSize.str() + ";\n";
+    }
+
+    linkHLSL += "};\n";
+
+    return linkHLSL;
+}
+
+void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
+                                             std::vector<LinkedVarying> *linkedVaryings) const
+{
+    ASSERT(info.glPosition.enabled);
+
+    linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic,
+                                            info.glPosition.index, 1));
+
+    if (info.glFragCoord.enabled)
+    {
+        linkedVaryings->push_back(LinkedVarying("gl_FragCoord", GL_FLOAT_VEC4, 1, info.glFragCoord.semantic,
+                                                info.glFragCoord.index, 1));
+    }
+
+    if (info.glPointSize.enabled)
+    {
+        linkedVaryings->push_back(LinkedVarying("gl_PointSize", GL_FLOAT, 1, "PSIZE", 0, 1));
+    }
+}
+
+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->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));
+
+            linkedVaryings->push_back(LinkedVarying(varying.name, varying.type, varying.elementCount(),
+                                                    varyingSemantic, varying.registerIndex,
+                                                    variableRows * varying.elementCount()));
+        }
+    }
+}
+
+bool DynamicHLSL::generateShaderLinkHLSL(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<LinkedVarying> *linkedVaryings,
+                                         std::map<int, VariableLocation> *programOutputVars,
+                                         std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
+                                         bool *outUsesFragDepth) const
+{
+    if (pixelHLSL.empty() || vertexHLSL.empty())
+    {
+        return false;
+    }
+
+    bool usesMRT = fragmentShader->mUsesMultipleRenderTargets;
+    bool usesFragColor = fragmentShader->mUsesFragColor;
+    bool usesFragData = fragmentShader->mUsesFragData;
+    bool usesFragCoord = fragmentShader->mUsesFragCoord;
+    bool usesPointCoord = fragmentShader->mUsesPointCoord;
+    bool usesPointSize = vertexShader->mUsesPointSize;
+
+    if (usesFragColor && usesFragData)
+    {
+        infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader.");
+        return false;
+    }
+
+    // Write the HLSL input/output declarations
+    const int shaderModel = mRenderer->getMajorShaderModel();
+
+    // TODO (geofflang):  Use context's caps
+    const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
+
+    const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0);
+
+    // Two cases when writing to gl_FragColor and using ESSL 1.0:
+    // - with a 3.0 context, the output color is copied to channel 0
+    // - with a 2.0 context, the output color is broadcast to all channels
+    const bool broadcast = (fragmentShader->mUsesFragColor && mRenderer->getCurrentClientVersion() < 3);
+    const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getRendererCaps().maxDrawBuffers : 1);
+
+    int shaderVersion = vertexShader->getShaderVersion();
+
+    if (registersNeeded > maxVaryingVectors)
+    {
+        infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
+        return false;
+    }
+
+    const std::string &varyingHLSL = generateVaryingHLSL(vertexShader);
+    const SemanticInfo &vertexSemantics = getSemanticInfo(registers, usesFragCoord,
+                                                          false, usesPointSize, false);
+
+    storeUserLinkedVaryings(vertexShader, linkedVaryings);
+    storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings);
+
+    // Add stub string to be replaced when shader is dynamically defined by its layout
+    vertexHLSL += "\n" + VERTEX_ATTRIBUTE_STUB_STRING + "\n"
+                  "struct VS_OUTPUT\n" + generateVaryingLinkHLSL(vertexSemantics, varyingHLSL) + "\n"
+                  "VS_OUTPUT main(VS_INPUT input)\n"
+                  "{\n"
+                  "    initAttributes(input);\n";
+
+    if (shaderModel >= 4)
+    {
+        vertexHLSL += "\n"
+                      "    gl_main();\n"
+                      "\n"
+                      "    VS_OUTPUT output;\n"
+                      "    output.gl_Position = gl_Position;\n"
+                      "    output.dx_Position.x = gl_Position.x;\n"
+                      "    output.dx_Position.y = -gl_Position.y;\n"
+                      "    output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+                      "    output.dx_Position.w = gl_Position.w;\n";
+    }
+    else
+    {
+        vertexHLSL += "\n"
+                      "    gl_main();\n"
+                      "\n"
+                      "    VS_OUTPUT output;\n"
+                      "    output.gl_Position = gl_Position;\n"
+                      "    output.dx_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n"
+                      "    output.dx_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n"
+                      "    output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+                      "    output.dx_Position.w = gl_Position.w;\n";
+    }
+
+    if (usesPointSize && shaderModel >= 3)
+    {
+        vertexHLSL += "    output.gl_PointSize = gl_PointSize;\n";
+    }
+
+    if (usesFragCoord)
+    {
+        vertexHLSL += "    output.gl_FragCoord = gl_Position;\n";
+    }
+
+    const std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
+    for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
+    {
+        const PackedVarying &varying = vertexVaryings[vertVaryingIndex];
+        if (varying.registerAssigned())
+        {
+            for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++)
+            {
+                int variableRows = (varying.isStruct() ? 1 : VariableRowCount(TransposeMatrixType(varying.type)));
+
+                for (int row = 0; row < variableRows; row++)
+                {
+                    int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row;
+                    vertexHLSL += "    output.v" + Str(r);
+
+                    vertexHLSL += " = _" + varying.name;
+
+                    if (varying.isArray())
+                    {
+                        vertexHLSL += ArrayString(elementIndex);
+                    }
+
+                    if (variableRows > 1)
+                    {
+                        vertexHLSL += ArrayString(row);
+                    }
+
+                    vertexHLSL += ";\n";
+                }
+            }
+        }
+    }
+
+    vertexHLSL += "\n"
+                  "    return output;\n"
+                  "}\n";
+
+    const SemanticInfo &pixelSemantics = getSemanticInfo(registers, usesFragCoord, usesPointCoord,
+                                                         usesPointSize, true);
+
+    pixelHLSL += "struct PS_INPUT\n" + generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) + "\n";
+
+    if (shaderVersion < 300)
+    {
+        for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
+        {
+            PixelShaderOutputVariable outputKeyVariable;
+            outputKeyVariable.type = GL_FLOAT_VEC4;
+            outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex);
+            outputKeyVariable.source = broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]";
+            outputKeyVariable.outputIndex = renderTargetIndex;
+
+            outPixelShaderKey->push_back(outputKeyVariable);
+        }
+
+        *outUsesFragDepth = fragmentShader->mUsesFragDepth;
+    }
+    else
+    {
+        defineOutputVariables(fragmentShader, programOutputVars);
+
+        const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables();
+        for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++)
+        {
+            const VariableLocation &outputLocation = locationIt->second;
+            const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
+            const std::string &variableName = "out_" + outputLocation.name;
+            const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
+
+            ASSERT(outputVariable.staticUse);
+
+            PixelShaderOutputVariable outputKeyVariable;
+            outputKeyVariable.type = outputVariable.type;
+            outputKeyVariable.name = variableName + elementString;
+            outputKeyVariable.source = variableName + ArrayString(outputLocation.element);
+            outputKeyVariable.outputIndex = locationIt->first;
+
+            outPixelShaderKey->push_back(outputKeyVariable);
+        }
+
+        *outUsesFragDepth = false;
+    }
+
+    pixelHLSL += PIXEL_OUTPUT_STUB_STRING + "\n";
+
+    if (fragmentShader->mUsesFrontFacing)
+    {
+        if (shaderModel >= 4)
+        {
+            pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n"
+                         "{\n";
+        }
+        else
+        {
+            pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n"
+                         "{\n";
+        }
+    }
+    else
+    {
+        pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n"
+                     "{\n";
+    }
+
+    if (usesFragCoord)
+    {
+        pixelHLSL += "    float rhw = 1.0 / input.gl_FragCoord.w;\n";
+
+        if (shaderModel >= 4)
+        {
+            pixelHLSL += "    gl_FragCoord.x = input.dx_Position.x;\n"
+                         "    gl_FragCoord.y = input.dx_Position.y;\n";
+        }
+        else if (shaderModel >= 3)
+        {
+            pixelHLSL += "    gl_FragCoord.x = input.dx_Position.x + 0.5;\n"
+                         "    gl_FragCoord.y = input.dx_Position.y + 0.5;\n";
+        }
+        else
+        {
+            // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport()
+            pixelHLSL += "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n"
+                         "    gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n";
+        }
+
+        pixelHLSL += "    gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n"
+                     "    gl_FragCoord.w = rhw;\n";
+    }
+
+    if (usesPointCoord && shaderModel >= 3)
+    {
+        pixelHLSL += "    gl_PointCoord.x = input.gl_PointCoord.x;\n";
+        pixelHLSL += "    gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
+    }
+
+    if (fragmentShader->mUsesFrontFacing)
+    {
+        if (shaderModel <= 3)
+        {
+            pixelHLSL += "    gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n";
+        }
+        else
+        {
+            pixelHLSL += "    gl_FrontFacing = isFrontFace;\n";
+        }
+    }
+
+    const std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
+    for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); 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 + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row);
+                    pixelHLSL += "    _" + varying.name;
+
+                    if (varying.isArray())
+                    {
+                        pixelHLSL += ArrayString(elementIndex);
+                    }
+
+                    if (variableRows > 1)
+                    {
+                        pixelHLSL += ArrayString(row);
+                    }
+
+                    if (varying.isStruct())
+                    {
+                        pixelHLSL += " = input.v" + n + ";\n";   break;
+                    }
+                    else
+                    {
+                        switch (VariableColumnCount(transposedType))
+                        {
+                          case 1: pixelHLSL += " = input.v" + n + ".x;\n";   break;
+                          case 2: pixelHLSL += " = input.v" + n + ".xy;\n";  break;
+                          case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break;
+                          case 4: pixelHLSL += " = input.v" + n + ";\n";     break;
+                          default: UNREACHABLE();
+                        }
+                    }
+                }
+            }
+        }
+        else
+        {
+            ASSERT(varying.isBuiltIn() || !varying.staticUse);
+        }
+    }
+
+    pixelHLSL += "\n"
+                 "    gl_main();\n"
+                 "\n"
+                 "    return generateOutput();\n"
+                 "}\n";
+
+    return true;
+}
+
+void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
+{
+    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++)
+            {
+                const int location = baseLocation + elementIndex;
+                ASSERT(programOutputVars->count(location) == 0);
+                (*programOutputVars)[location] = VariableLocation(outputVariable.name, elementIndex, outputVariableIndex);
+            }
+        }
+        else
+        {
+            ASSERT(programOutputVars->count(baseLocation) == 0);
+            (*programOutputVars)[baseLocation] = VariableLocation(outputVariable.name, GL_INVALID_INDEX, outputVariableIndex);
+        }
+    }
+}
+
+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, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
+{
+    ASSERT(registers >= 0);
+    ASSERT(vertexShader->mUsesPointSize);
+    ASSERT(mRenderer->getMajorShaderModel() >= 4);
+
+    std::string geomHLSL;
+
+    const SemanticInfo &inSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord,
+                                                      false, true, false);
+    const SemanticInfo &outSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord,
+                                                       fragmentShader->mUsesPointCoord, true, false);
+
+    std::string varyingHLSL = generateVaryingHLSL(vertexShader);
+    std::string inLinkHLSL = generateVaryingLinkHLSL(inSemantics, varyingHLSL);
+    std::string outLinkHLSL = generateVaryingLinkHLSL(outSemantics, varyingHLSL);
+
+    // TODO(geofflang): use context's caps
+    geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n"
+                "\n"
+                "struct GS_INPUT\n" + inLinkHLSL + "\n" +
+                "struct GS_OUTPUT\n" + outLinkHLSL + "\n" +
+                "\n"
+                  "static float2 pointSpriteCorners[] = \n"
+                  "{\n"
+                  "    float2( 0.5f, -0.5f),\n"
+                  "    float2( 0.5f,  0.5f),\n"
+                  "    float2(-0.5f, -0.5f),\n"
+                  "    float2(-0.5f,  0.5f)\n"
+                  "};\n"
+                  "\n"
+                  "static float2 pointSpriteTexcoords[] = \n"
+                  "{\n"
+                  "    float2(1.0f, 1.0f),\n"
+                  "    float2(1.0f, 0.0f),\n"
+                  "    float2(0.0f, 1.0f),\n"
+                  "    float2(0.0f, 0.0f)\n"
+                  "};\n"
+                  "\n"
+                  "static float minPointSize = " + Str(mRenderer->getRendererCaps().minAliasedPointSize) + ".0f;\n"
+                  "static float maxPointSize = " + Str(mRenderer->getRendererCaps().maxAliasedPointSize) + ".0f;\n"
+                  "\n"
+                  "[maxvertexcount(4)]\n"
+                  "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
+                  "{\n"
+                  "    GS_OUTPUT output = (GS_OUTPUT)0;\n"
+                  "    output.gl_Position = input[0].gl_Position;\n";
+                  "    output.gl_PointSize = input[0].gl_PointSize;\n";
+
+    for (int r = 0; r < registers; r++)
+    {
+        geomHLSL += "    output.v" + Str(r) + " = input[0].v" + Str(r) + ";\n";
+    }
+
+    if (fragmentShader->mUsesFragCoord)
+    {
+        geomHLSL += "    output.gl_FragCoord = input[0].gl_FragCoord;\n";
+    }
+
+    geomHLSL += "    \n"
+                "    float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n"
+                "    float4 dx_Position = input[0].dx_Position;\n"
+                "    float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * dx_Position.w;\n";
+
+    for (int corner = 0; corner < 4; corner++)
+    {
+        geomHLSL += "    \n"
+                    "    output.dx_Position = dx_Position + float4(pointSpriteCorners[" + Str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
+
+        if (fragmentShader->mUsesPointCoord)
+        {
+            geomHLSL += "    output.gl_PointCoord = pointSpriteTexcoords[" + Str(corner) + "];\n";
+        }
+
+        geomHLSL += "    outStream.Append(output);\n";
+    }
+
+    geomHLSL += "    \n"
+                "    outStream.RestartStrip();\n"
+                "}\n";
+
+    return geomHLSL;
+}
+
+// This method needs to match OutputHLSL::decorate
+std::string DynamicHLSL::decorateVariable(const std::string &name)
+{
+    if (name.compare(0, 3, "gl_") != 0)
+    {
+        return "_" + name;
+    }
+
+    return name;
+}
+
+std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const
+{
+    std::string attribString = "input." + decorateVariable(shaderAttrib.name);
+
+    // Matrix
+    if (IsMatrixType(shaderAttrib.type))
+    {
+        return "transpose(" + attribString + ")";
+    }
+
+    GLenum shaderComponentType = VariableComponentType(shaderAttrib.type);
+    int shaderComponentCount = VariableComponentCount(shaderAttrib.type);
+
+    // Perform integer to float conversion (if necessary)
+    bool requiresTypeConversion = (shaderComponentType == GL_FLOAT && vertexFormat.mType != GL_FLOAT);
+
+    if (requiresTypeConversion)
+    {
+        // TODO: normalization for 32-bit integer formats
+        ASSERT(!vertexFormat.mNormalized && !vertexFormat.mPureInteger);
+        return "float" + Str(shaderComponentCount) + "(" + attribString + ")";
+    }
+
+    // No conversion necessary
+    return attribString;
+}
+
+void DynamicHLSL::getInputLayoutSignature(const VertexFormat inputLayout[], GLenum signature[]) const
+{
+    for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++)
+    {
+        const VertexFormat &vertexFormat = inputLayout[inputIndex];
+
+        if (vertexFormat.mType == GL_NONE)
+        {
+            signature[inputIndex] = GL_NONE;
+        }
+        else
+        {
+            bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0);
+            signature[inputIndex] = (gpuConverted ? GL_TRUE : GL_FALSE);
+        }
+    }
+}
+
+}
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 d3ddd98..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"
@@ -26,11 +31,11 @@
     TRACE_EVENT0("gpu", "initializeCompiler");
 #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
     // Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
-    static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
+    static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
 
     for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i)
     {
-        if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3DCompilerModule))
+        if (GetModuleHandleExA(0, d3dCompilerNames[i], &mD3DCompilerModule))
         {
             break;
         }
@@ -105,14 +110,11 @@
                 return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL);
             }
 
-            infoLog.append("Warning: D3D shader compilation failed with ");
-            infoLog.append(flagNames[i]);
-            infoLog.append(" flags.");
+            infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]);
+
             if (i + 1 < attempts)
             {
-                infoLog.append(" Retrying with ");
-                infoLog.append(flagNames[i + 1]);
-                infoLog.append(".\n");
+                infoLog.append(" Retrying with %s.\n", flagNames[i + 1]);
             }
         }
     }
diff --git a/src/libGLESv2/renderer/d3d/HLSLCompiler.h b/src/libGLESv2/renderer/d3d/HLSLCompiler.h
index ab685f1..0ce9e44 100644
--- a/src/libGLESv2/renderer/d3d/HLSLCompiler.h
+++ b/src/libGLESv2/renderer/d3d/HLSLCompiler.h
@@ -3,8 +3,6 @@
 
 #include "common/angleutils.h"
 
-#include <windows.h>
-
 namespace gl
 {
 class InfoLog;
diff --git a/src/libGLESv2/renderer/d3d/ImageD3D.cpp b/src/libGLESv2/renderer/d3d/ImageD3D.cpp
new file mode 100644
index 0000000..0854b96
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/ImageD3D.cpp
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image.h: Implements the rx::Image class, an abstract base class for the
+// renderer-specific classes which will define the interface to the underlying
+// surfaces or resources.
+
+#include "libGLESv2/renderer/d3d/ImageD3D.h"
+
+namespace rx
+{
+
+ImageD3D::ImageD3D()
+{
+}
+
+ImageD3D *ImageD3D::makeImageD3D(Image *img)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::ImageD3D*, img));
+    return static_cast<rx::ImageD3D*>(img);
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/ImageD3D.h b/src/libGLESv2/renderer/d3d/ImageD3D.h
new file mode 100644
index 0000000..60a6ffd
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/ImageD3D.h
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image.h: Defines the rx::Image class, an abstract base class for the
+// renderer-specific classes which will define the interface to the underlying
+// surfaces or resources.
+
+#ifndef LIBGLESV2_RENDERER_IMAGED3D_H_
+#define LIBGLESV2_RENDERER_IMAGED3D_H_
+
+#include "common/debug.h"
+#include "libGLESv2/renderer/Image.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class TextureStorage;
+
+class ImageD3D : public Image
+{
+  public:
+    ImageD3D();
+    virtual ~ImageD3D() {};
+
+    static ImageD3D *makeImageD3D(Image *img);
+
+    virtual bool isDirty() const = 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);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_IMAGED3D_H_
diff --git a/src/libGLESv2/renderer/IndexBuffer.cpp b/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
similarity index 72%
rename from src/libGLESv2/renderer/IndexBuffer.cpp
rename to src/libGLESv2/renderer/d3d/IndexBuffer.cpp
index 7fe2a3a..1dce127 100644
--- a/src/libGLESv2/renderer/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
@@ -8,7 +7,7 @@
 // IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface
 // class with derivations, classes that perform graphics API agnostic index buffer operations.
 
-#include "libGLESv2/renderer/IndexBuffer.h"
+#include "libGLESv2/renderer/d3d/IndexBuffer.h"
 #include "libGLESv2/renderer/Renderer.h"
 
 namespace rx
@@ -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/IndexBuffer.h b/src/libGLESv2/renderer/d3d/IndexBuffer.h
similarity index 71%
rename from src/libGLESv2/renderer/IndexBuffer.h
rename to src/libGLESv2/renderer/d3d/IndexBuffer.h
index 6fb885a..1bb5ae2 100644
--- a/src/libGLESv2/renderer/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
new file mode 100644
index 0000000..8d455b4
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -0,0 +1,255 @@
+//
+// 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.
+//
+
+// IndexDataManager.cpp: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#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"
+
+namespace rx
+{
+
+static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
+{
+    if (sourceType == GL_UNSIGNED_BYTE)
+    {
+        ASSERT(destinationType == GL_UNSIGNED_SHORT);
+        const GLubyte *in = static_cast<const GLubyte*>(input);
+        GLushort *out = static_cast<GLushort*>(output);
+
+        for (GLsizei i = 0; i < count; i++)
+        {
+            out[i] = in[i];
+        }
+    }
+    else if (sourceType == GL_UNSIGNED_INT)
+    {
+        ASSERT(destinationType == GL_UNSIGNED_INT);
+        memcpy(output, input, count * sizeof(GLuint));
+    }
+    else if (sourceType == GL_UNSIGNED_SHORT)
+    {
+        if (destinationType == GL_UNSIGNED_SHORT)
+        {
+            memcpy(output, input, count * sizeof(GLushort));
+        }
+        else if (destinationType == GL_UNSIGNED_INT)
+        {
+            const GLushort *in = static_cast<const GLushort*>(input);
+            GLuint *out = static_cast<GLuint*>(output);
+
+            for (GLsizei i = 0; i < count; i++)
+            {
+                out[i] = in[i];
+            }
+        }
+        else UNREACHABLE();
+    }
+    else UNREACHABLE();
+}
+
+IndexDataManager::IndexDataManager(Renderer *renderer)
+    : mRenderer(renderer),
+      mStreamingBufferShort(NULL),
+      mStreamingBufferInt(NULL)
+{
+}
+
+IndexDataManager::~IndexDataManager()
+{
+    SafeDelete(mStreamingBufferShort);
+    SafeDelete(mStreamingBufferInt);
+}
+
+gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
+{
+    const gl::Type &typeInfo = gl::GetTypeInfo(type);
+
+    GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+
+    unsigned int offset = 0;
+    bool alignedOffset = false;
+
+    BufferD3D *storage = NULL;
+
+    if (buffer != NULL)
+    {
+        offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
+
+        storage = BufferD3D::makeBufferD3D(buffer->getImplementation());
+
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:  alignedOffset = (offset % sizeof(GLubyte) == 0);  break;
+          case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
+          case GL_UNSIGNED_INT:   alignedOffset = (offset % sizeof(GLuint) == 0);   break;
+          default: UNREACHABLE(); alignedOffset = false;
+        }
+
+        ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize());
+
+        indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+    }
+
+    StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL;
+    IndexBufferInterface *indexBuffer = NULL;
+    bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() &&
+                         destinationIndexType == type;
+    unsigned int streamOffset = 0;
+
+    if (directStorage)
+    {
+        streamOffset = offset;
+
+        if (!buffer->getIndexRangeCache()->findRange(type, offset, count, NULL, NULL))
+        {
+            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, NULL, &streamOffset))
+        {
+            streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes;
+            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
+        }
+    }
+
+    // Avoid D3D11's primitive restart index value
+    // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
+    if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
+    {
+        destinationIndexType = GL_UNSIGNED_INT;
+        directStorage = false;
+        indexBuffer = NULL;
+    }
+
+    const gl::Type &destTypeInfo = gl::GetTypeInfo(destinationIndexType);
+
+    if (!directStorage && !indexBuffer)
+    {
+        gl::Error error = getStreamingIndexBuffer(destinationIndexType, &indexBuffer);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        unsigned int convertCount = count;
+
+        if (staticBuffer)
+        {
+            if (staticBuffer->getBufferSize() == 0 && alignedOffset)
+            {
+                indexBuffer = staticBuffer;
+                convertCount = storage->getSize() / typeInfo.bytes;
+            }
+            else
+            {
+                storage->invalidateStaticData();
+                staticBuffer = NULL;
+            }
+        }
+
+        ASSERT(indexBuffer);
+
+        if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes)
+        {
+            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;
+        error = indexBuffer->reserveBufferSpace(bufferSizeRequired, type);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        void* output = NULL;
+        error = indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
+
+        error = indexBuffer->unmapBuffer();
+        if (error.isError())
+        {
+            return error;
+        }
+
+        if (staticBuffer)
+        {
+            streamOffset = (offset / typeInfo.bytes) * destTypeInfo.bytes;
+            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
+        }
+    }
+
+    translated->storage = directStorage ? storage : NULL;
+    translated->indexBuffer = indexBuffer ? indexBuffer->getIndexBuffer() : NULL;
+    translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial();
+    translated->startIndex = streamOffset / destTypeInfo.bytes;
+    translated->startOffset = streamOffset;
+    translated->indexType = destinationIndexType;
+
+    if (storage)
+    {
+        storage->promoteStaticUsage(count * typeInfo.bytes);
+    }
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer)
+{
+    ASSERT(outBuffer);
+    if (destinationIndexType == GL_UNSIGNED_INT)
+    {
+        if (!mStreamingBufferInt)
+        {
+            mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
+            gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+            if (error.isError())
+            {
+                SafeDelete(mStreamingBufferInt);
+                return error;
+            }
+        }
+
+        *outBuffer = mStreamingBufferInt;
+        return gl::Error(GL_NO_ERROR);
+    }
+    else
+    {
+        ASSERT(destinationIndexType == GL_UNSIGNED_SHORT);
+
+        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/IndexDataManager.h b/src/libGLESv2/renderer/d3d/IndexDataManager.h
similarity index 73%
rename from src/libGLESv2/renderer/IndexDataManager.h
rename to src/libGLESv2/renderer/d3d/IndexDataManager.h
index 70c7bf3..6d0b89e 100644
--- a/src/libGLESv2/renderer/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,21 +28,21 @@
 
 namespace rx
 {
+class IndexBufferInterface;
 class StaticIndexBufferInterface;
 class StreamingIndexBufferInterface;
 class IndexBuffer;
-class BufferStorage;
+class BufferD3D;
 class Renderer;
 
 struct TranslatedIndexData
 {
-    unsigned int minIndex;
-    unsigned int maxIndex;
+    RangeUI indexRange;
     unsigned int startIndex;
     unsigned int startOffset;   // In bytes
 
     IndexBuffer *indexBuffer;
-    BufferStorage *storage;
+    BufferD3D *storage;
     GLenum indexType;
     unsigned int serial;
 };
@@ -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
new file mode 100644
index 0000000..2b5b09a
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp
@@ -0,0 +1,74 @@
+//
+// 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 "libGLESv2/renderer/d3d/MemoryBuffer.h"
+#include "common/debug.h"
+
+#include <algorithm>
+#include <cstdlib>
+
+namespace rx
+{
+
+MemoryBuffer::MemoryBuffer()
+    : mSize(0),
+      mData(NULL)
+{
+}
+
+MemoryBuffer::~MemoryBuffer()
+{
+    free(mData);
+    mData = NULL;
+}
+
+bool MemoryBuffer::resize(size_t size)
+{
+    if (size == 0)
+    {
+        free(mData);
+        mData = NULL;
+        mSize = 0;
+    }
+    else
+    {
+        uint8_t *newMemory = reinterpret_cast<uint8_t*>(malloc(sizeof(uint8_t) * size));
+        if (newMemory == NULL)
+        {
+            return false;
+        }
+
+        if (mData)
+        {
+            // Copy the intersection of the old data and the new data
+            std::copy(mData, mData + std::min(mSize, size), newMemory);
+            free(mData);
+        }
+
+        mData = newMemory;
+        mSize = size;
+    }
+
+    return true;
+}
+
+size_t MemoryBuffer::size() const
+{
+    return mSize;
+}
+
+const uint8_t *MemoryBuffer::data() const
+{
+    return mData;
+}
+
+uint8_t *MemoryBuffer::data()
+{
+    ASSERT(mData);
+    return mData;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/MemoryBuffer.h b/src/libGLESv2/renderer/d3d/MemoryBuffer.h
new file mode 100644
index 0000000..c65f79f
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/MemoryBuffer.h
@@ -0,0 +1,36 @@
+//
+// 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 LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H_
+#define LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+namespace rx
+{
+
+class MemoryBuffer
+{
+  public:
+    MemoryBuffer();
+    ~MemoryBuffer();
+
+    bool resize(size_t size);
+    size_t size() const;
+    bool empty() const { return mSize == 0; }
+
+    const uint8_t *data() const;
+    uint8_t *data();
+
+  private:
+    size_t mSize;
+    uint8_t *mData;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H
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
new file mode 100644
index 0000000..2650913
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -0,0 +1,2260 @@
+//
+// 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.
+//
+
+// TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends.
+
+#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"
+#include "libGLESv2/main.h"
+#include "libGLESv2/formatutils.h"
+#include "libGLESv2/renderer/BufferImpl.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/Renderer.h"
+
+#include "libEGL/Surface.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+namespace rx
+{
+
+bool IsRenderTargetUsage(GLenum usage)
+{
+    return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+}
+
+TextureD3D::TextureD3D(Renderer *renderer)
+    : mRenderer(renderer),
+      mUsage(GL_NONE),
+      mDirtyImages(true),
+      mImmutable(false)
+{
+}
+
+TextureD3D::~TextureD3D()
+{
+}
+
+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();
+    return (baseImage ? baseImage->getWidth() : 0);
+}
+
+GLint TextureD3D::getBaseLevelHeight() const
+{
+    const Image *baseImage = getBaseLevelImage();
+    return (baseImage ? baseImage->getHeight() : 0);
+}
+
+GLint TextureD3D::getBaseLevelDepth() const
+{
+    const Image *baseImage = getBaseLevelImage();
+    return (baseImage ? baseImage->getDepth() : 0);
+}
+
+// Note: "base level image" is loosely defined to be any image from the base level,
+// where in the base of 2D array textures and cube maps there are several. Don't use
+// the base level image for anything except querying texture format and size.
+GLenum TextureD3D::getBaseLevelInternalFormat() const
+{
+    const Image *baseImage = getBaseLevelImage();
+    return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
+}
+
+void TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image)
+{
+    // No-op
+    if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
+    {
+        return;
+    }
+
+    // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
+    // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
+    const void *pixelData = pixels;
+
+    if (unpack.pixelBuffer.id() != 0)
+    {
+        // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
+        gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
+        ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
+        // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
+        // This functionality should be moved into renderer and the getData method of BufferImpl removed.
+        const void *bufferData = pixelBuffer->getImplementation()->getData();
+        pixelData = static_cast<const unsigned char *>(bufferData) + offset;
+    }
+
+    if (pixelData != NULL)
+    {
+        image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
+        mDirtyImages = true;
+    }
+}
+
+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, const gl::ImageIndex &index)
+{
+    const void *pixelData = pixels;
+
+    // CPU readback & copy where direct GPU copy is not supported
+    if (unpack.pixelBuffer.id() != 0)
+    {
+        gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
+        unsigned int offset = reinterpret_cast<unsigned int>(pixels);
+        // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
+        // This functionality should be moved into renderer and the getData method of BufferImpl removed.
+        const void *bufferData = pixelBuffer->getImplementation()->getData();
+        pixelData = static_cast<const unsigned char *>(bufferData) + offset;
+    }
+
+    if (pixelData != NULL)
+    {
+        Image *image = getImage(index);
+        ASSERT(image);
+
+        image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData);
+        mDirtyImages = true;
+    }
+
+    return true;
+}
+
+void TextureD3D::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
+{
+    if (pixels != NULL)
+    {
+        image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels);
+        mDirtyImages = true;
+    }
+}
+
+bool TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+                                 GLenum format, GLsizei imageSize, const void *pixels, Image *image)
+{
+    if (pixels != NULL)
+    {
+        image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels);
+        mDirtyImages = true;
+    }
+
+    return true;
+}
+
+bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat)
+{
+    return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
+}
+
+bool TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
+                               GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget)
+{
+    if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
+    {
+        return true;
+    }
+
+    // In order to perform the fast copy through the shader, we must have the right format, and be able
+    // to create a render target.
+    ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat));
+
+    unsigned int offset = reinterpret_cast<unsigned int>(pixels);
+
+    return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
+}
+
+GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const
+{
+    if ((gl::isPow2(width) && gl::isPow2(height) && gl::isPow2(depth)) || mRenderer->getRendererExtensions().textureNPOT)
+    {
+        // Maximum number of levels
+        return gl::log2(std::max(std::max(width, height), depth)) + 1;
+    }
+    else
+    {
+        // OpenGL ES 2.0 without GL_OES_texture_npot does not permit NPOT mipmaps.
+        return 1;
+    }
+}
+
+int TextureD3D::mipLevels() const
+{
+    return gl::log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
+}
+
+
+TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
+    : TextureD3D(renderer),
+      mTexStorage(NULL)
+{
+    for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
+    {
+        mImageArray[i] = ImageD3D::makeImageD3D(renderer->createImage());
+    }
+}
+
+TextureD3D_2D::~TextureD3D_2D()
+{
+    // 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];
+    }
+
+    SafeDelete(mTexStorage);
+}
+
+Image *TextureD3D_2D::getImage(int level, int layer) const
+{
+    ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(layer == 0);
+    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);
+    return 1;
+}
+
+GLsizei TextureD3D_2D::getWidth(GLint level) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[level]->getWidth();
+    else
+        return 0;
+}
+
+GLsizei TextureD3D_2D::getHeight(GLint level) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[level]->getHeight();
+    else
+        return 0;
+}
+
+GLenum TextureD3D_2D::getInternalFormat(GLint level) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[level]->getInternalFormat();
+    else
+        return GL_NONE;
+}
+
+GLenum TextureD3D_2D::getActualFormat(GLint level) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[level]->getActualFormat();
+    else
+        return GL_NONE;
+}
+
+bool TextureD3D_2D::isDepth(GLint level) const
+{
+    return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
+}
+
+void TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_2D && depth == 1);
+
+    GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
+
+    bool fastUnpacked = false;
+
+    redefineImage(level, sizedInternalFormat, width, height);
+
+    // 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(index);
+        gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
+
+        if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
+        {
+            // Ensure we don't overwrite our newly initialized data
+            mImageArray[level]->markClean();
+
+            fastUnpacked = true;
+        }
+    }
+
+    if (!fastUnpacked)
+    {
+        TextureD3D::setImage(unpack, type, pixels, mImageArray[level]);
+    }
+}
+
+void TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_2D && depth == 1);
+
+    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+    redefineImage(level, format, width, height);
+
+    TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]);
+}
+
+void TextureD3D_2D::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)
+{
+    ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
+
+    bool fastUnpacked = false;
+
+    gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+    if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
+    {
+        RenderTarget *renderTarget = getRenderTarget(index);
+        gl::Box destArea(xoffset, yoffset, 0, width, height, 1);
+
+        if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget))
+        {
+            // Ensure we don't overwrite our newly initialized data
+            mImageArray[level]->markClean();
+
+            fastUnpacked = true;
+        }
+    }
+
+    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
+    {
+        commitRect(level, xoffset, yoffset, width, height);
+    }
+}
+
+void TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
+
+    if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level]))
+    {
+        commitRect(level, xoffset, yoffset, width, height);
+    }
+}
+
+void TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    ASSERT(target == GL_TEXTURE_2D);
+
+    GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+    redefineImage(level, sizedInternalFormat, width, height);
+
+    if (!mImageArray[level]->isRenderableFormat())
+    {
+        mImageArray[level]->copy(0, 0, 0, x, y, width, height, source);
+        mDirtyImages = true;
+    }
+    else
+    {
+        ensureRenderTarget();
+        mImageArray[level]->markClean();
+
+        if (width != 0 && height != 0 && isValidLevel(level))
+        {
+            gl::Rectangle sourceRect;
+            sourceRect.x = x;
+            sourceRect.width = width;
+            sourceRect.y = y;
+            sourceRect.height = height;
+
+            mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level);
+        }
+    }
+}
+
+void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    ASSERT(target == GL_TEXTURE_2D && zoffset == 0);
+
+    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
+    // the current level we're copying to is defined (with appropriate format, width & height)
+    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
+
+    if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+    {
+        mImageArray[level]->copy(xoffset, yoffset, 0, x, y, width, height, source);
+        mDirtyImages = true;
+    }
+    else
+    {
+        ensureRenderTarget();
+
+        if (isValidLevel(level))
+        {
+            updateStorageLevel(level);
+
+            gl::Rectangle sourceRect;
+            sourceRect.x = x;
+            sourceRect.width = width;
+            sourceRect.y = y;
+            sourceRect.height = height;
+
+            mRenderer->copyImage2D(source, sourceRect,
+                                   gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+                                   xoffset, yoffset, mTexStorage, level);
+        }
+    }
+}
+
+void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+    ASSERT(target == GL_TEXTURE_2D && depth == 1);
+
+    for (int level = 0; level < levels; level++)
+    {
+        GLsizei levelWidth = std::max(1, width >> level);
+        GLsizei levelHeight = std::max(1, height >> level);
+        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, levelWidth, levelHeight, 1, true);
+    }
+
+    for (int level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+    {
+        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
+    }
+
+    mImmutable = true;
+
+    bool renderTarget = IsRenderTargetUsage(mUsage);
+    TextureStorage *storage = mRenderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels);
+    setCompleteTexStorage(storage);
+}
+
+void TextureD3D_2D::bindTexImage(egl::Surface *surface)
+{
+    GLenum internalformat = surface->getFormat();
+
+    mImageArray[0]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, surface->getWidth(), surface->getHeight(), 1, true);
+
+    if (mTexStorage)
+    {
+        SafeDelete(mTexStorage);
+    }
+
+    mTexStorage = mRenderer->createTextureStorage2D(surface->getSwapChain());
+
+    mDirtyImages = true;
+}
+
+void TextureD3D_2D::releaseTexImage()
+{
+    if (mTexStorage)
+    {
+        SafeDelete(mTexStorage);
+    }
+
+    for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+    {
+        mImageArray[i]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
+    }
+}
+
+void TextureD3D_2D::generateMipmaps()
+{
+    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
+    int levelCount = mipLevels();
+    for (int level = 1; level < levelCount; level++)
+    {
+        redefineImage(level, getBaseLevelInternalFormat(),
+                      std::max(getBaseLevelWidth() >> level, 1),
+                      std::max(getBaseLevelHeight() >> level, 1));
+    }
+
+    if (mTexStorage && mTexStorage->isRenderTarget())
+    {
+        mTexStorage->generateMipmaps();
+        for (int level = 1; level < levelCount; level++)
+        {
+            mImageArray[level]->markClean();
+        }
+    }
+    else
+    {
+        for (int level = 1; level < levelCount; level++)
+        {
+            mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
+        }
+    }
+}
+
+unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index)
+{
+    ASSERT(!index.hasLayer());
+    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+}
+
+RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index)
+{
+    ASSERT(!index.hasLayer());
+
+    // ensure the underlying texture is created
+    if (!ensureRenderTarget())
+    {
+        return NULL;
+    }
+
+    updateStorageLevel(index.mipIndex);
+    return mTexStorage->getRenderTarget(index);
+}
+
+bool TextureD3D_2D::isValidLevel(int level) const
+{
+    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false);
+}
+
+bool TextureD3D_2D::isLevelComplete(int level) const
+{
+    if (isImmutable())
+    {
+        return true;
+    }
+
+    const 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 <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
+    ImageD3D *image = mImageArray[level];
+
+    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;
+}
+
+// Constructs a native texture resource from the texture images
+void TextureD3D_2D::initializeStorage(bool renderTarget)
+{
+    // Only initialize the first time this texture is used as a render target or shader resource
+    if (mTexStorage)
+    {
+        return;
+    }
+
+    // do not attempt to create storage for nonexistant data
+    if (!isLevelComplete(0))
+    {
+        return;
+    }
+
+    bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
+
+    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+    ASSERT(mTexStorage);
+
+    // flush image data to the storage
+    updateStorage();
+}
+
+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 mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels);
+}
+
+void TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+{
+    SafeDelete(mTexStorage);
+    mTexStorage = newCompleteTexStorage;
+
+    if (mTexStorage && mTexStorage->isManaged())
+    {
+        for (int level = 0; level < mTexStorage->getLevelCount(); level++)
+        {
+            mImageArray[level]->setManagedSurface2D(mTexStorage, level);
+        }
+    }
+
+    mDirtyImages = true;
+}
+
+void TextureD3D_2D::updateStorage()
+{
+    ASSERT(mTexStorage != NULL);
+    GLint storageLevels = mTexStorage->getLevelCount();
+    for (int level = 0; level < storageLevels; level++)
+    {
+        if (mImageArray[level]->isDirty() && isLevelComplete(level))
+        {
+            updateStorageLevel(level);
+        }
+    }
+}
+
+bool TextureD3D_2D::ensureRenderTarget()
+{
+    initializeStorage(true);
+
+    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0)
+    {
+        ASSERT(mTexStorage);
+        if (!mTexStorage->isRenderTarget())
+        {
+            TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
+
+            if (!mRenderer->copyToRenderTarget2D(newRenderTargetStorage, mTexStorage))
+            {
+                delete newRenderTargetStorage;
+                return gl::error(GL_OUT_OF_MEMORY, false);
+            }
+
+            setCompleteTexStorage(newRenderTargetStorage);
+        }
+    }
+
+    return (mTexStorage && mTexStorage->isRenderTarget());
+}
+
+TextureStorage *TextureD3D_2D::getBaseLevelStorage()
+{
+    return mTexStorage;
+}
+
+const ImageD3D *TextureD3D_2D::getBaseLevelImage() const
+{
+    return mImageArray[0];
+}
+
+void TextureD3D_2D::updateStorageLevel(int level)
+{
+    ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
+    ASSERT(isLevelComplete(level));
+
+    if (mImageArray[level]->isDirty())
+    {
+        commitRect(level, 0, 0, getWidth(level), getHeight(level));
+    }
+}
+
+void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height)
+{
+    // If there currently is a corresponding storage texture image, it has these parameters
+    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
+    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
+    const GLenum storageFormat = getBaseLevelInternalFormat();
+
+    mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, width, height, 1, false);
+
+    if (mTexStorage)
+    {
+        const int storageLevels = mTexStorage->getLevelCount();
+
+        if ((level >= storageLevels && storageLevels != 0) ||
+            width != storageWidth ||
+            height != storageHeight ||
+            internalformat != storageFormat)   // Discard mismatched storage
+        {
+            for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+            {
+                mImageArray[i]->markDirty();
+            }
+
+            SafeDelete(mTexStorage);
+            mDirtyImages = true;
+        }
+    }
+}
+
+void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    if (isValidLevel(level))
+    {
+        ImageD3D *image = mImageArray[level];
+        if (image->copyToStorage2D(mTexStorage, level, xoffset, yoffset, width, height))
+        {
+            image->markClean();
+        }
+    }
+}
+
+
+TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer)
+    : TextureD3D(renderer),
+      mTexStorage(NULL)
+{
+    for (int i = 0; i < 6; i++)
+    {
+        for (int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
+        {
+            mImageArray[i][j] = ImageD3D::makeImageD3D(renderer->createImage());
+        }
+    }
+}
+
+TextureD3D_Cube::~TextureD3D_Cube()
+{
+    // 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)
+        {
+            SafeDelete(mImageArray[i][j]);
+        }
+    }
+
+    SafeDelete(mTexStorage);
+}
+
+Image *TextureD3D_Cube::getImage(int level, int layer) const
+{
+    ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(layer < 6);
+    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);
+    return 6;
+}
+
+GLenum TextureD3D_Cube::getInternalFormat(GLint level, GLint layer) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[layer][level]->getInternalFormat();
+    else
+        return GL_NONE;
+}
+
+bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const
+{
+    return gl::GetInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0;
+}
+
+void TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+{
+    ASSERT(depth == 1);
+
+    int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+    GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
+
+    redefineImage(faceIndex, level, sizedInternalFormat, width, height);
+
+    TextureD3D::setImage(unpack, type, pixels, mImageArray[faceIndex][level]);
+}
+
+void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+{
+    ASSERT(depth == 1);
+
+    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+    int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+
+    redefineImage(faceIndex, level, format, width, height);
+
+    TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]);
+}
+
+void TextureD3D_Cube::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)
+{
+    ASSERT(depth == 1 && zoffset == 0);
+
+    int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+
+    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);
+    }
+}
+
+void TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+{
+    ASSERT(depth == 1 && zoffset == 0);
+
+    int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+
+    if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[faceIndex][level]))
+    {
+        commitRect(faceIndex, level, xoffset, yoffset, width, height);
+    }
+}
+
+void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+    GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+
+    redefineImage(faceIndex, level, sizedInternalFormat, width, height);
+
+    if (!mImageArray[faceIndex][level]->isRenderableFormat())
+    {
+        mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
+        mDirtyImages = true;
+    }
+    else
+    {
+        ensureRenderTarget();
+        mImageArray[faceIndex][level]->markClean();
+
+        ASSERT(width == height);
+
+        if (width > 0 && isValidFaceLevel(faceIndex, level))
+        {
+            gl::Rectangle sourceRect;
+            sourceRect.x = x;
+            sourceRect.width = width;
+            sourceRect.y = y;
+            sourceRect.height = height;
+
+            mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level);
+        }
+    }
+}
+
+void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+
+    // We can only make our texture storage to a render target if the level we're copying *to* is complete
+    // and the base level is cube-complete. The base level must be cube complete (common case) because we cannot
+    // rely on the "getBaseLevel*" methods reliably otherwise.
+    bool canCreateRenderTarget = isFaceLevelComplete(faceIndex, level) && isCubeComplete();
+
+    if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+    {
+        mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
+        mDirtyImages = true;
+    }
+    else
+    {
+        ensureRenderTarget();
+
+        if (isValidFaceLevel(faceIndex, level))
+        {
+            updateStorageFaceLevel(faceIndex, level);
+
+            gl::Rectangle sourceRect;
+            sourceRect.x = x;
+            sourceRect.width = width;
+            sourceRect.y = y;
+            sourceRect.height = height;
+
+            mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+                                     xoffset, yoffset, mTexStorage, target, level);
+        }
+    }
+}
+
+void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+    ASSERT(width == height);
+    ASSERT(depth == 1);
+
+    for (int level = 0; level < levels; level++)
+    {
+        GLsizei mipSize = std::max(1, width >> level);
+        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+        {
+            mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, mipSize, mipSize, 1, true);
+        }
+    }
+
+    for (int level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+    {
+        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+        {
+            mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, GL_NONE, 0, 0, 0, true);
+        }
+    }
+
+    mImmutable = 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.
+bool TextureD3D_Cube::isCubeComplete() const
+{
+    int    baseWidth  = getBaseLevelWidth();
+    int    baseHeight = getBaseLevelHeight();
+    GLenum baseFormat = getBaseLevelInternalFormat();
+
+    if (baseWidth <= 0 || baseWidth != baseHeight)
+    {
+        return false;
+    }
+
+    for (int faceIndex = 1; faceIndex < 6; faceIndex++)
+    {
+        const ImageD3D &faceBaseImage = *mImageArray[faceIndex][0];
+
+        if (faceBaseImage.getWidth()          != baseWidth  ||
+            faceBaseImage.getHeight()         != baseHeight ||
+            faceBaseImage.getInternalFormat() != baseFormat )
+        {
+            return false;
+        }
+    }
+
+    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.
+    int levelCount = mipLevels();
+    for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+    {
+        for (int level = 1; level < levelCount; level++)
+        {
+            int faceLevelSize = (std::max(mImageArray[faceIndex][0]->getWidth() >> level, 1));
+            redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
+        }
+    }
+
+    if (mTexStorage && mTexStorage->isRenderTarget())
+    {
+        mTexStorage->generateMipmaps();
+
+        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+        {
+            for (int level = 1; level < levelCount; level++)
+            {
+                mImageArray[faceIndex][level]->markClean();
+            }
+        }
+    }
+    else
+    {
+        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+        {
+            for (int level = 1; level < levelCount; level++)
+            {
+                mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]);
+            }
+        }
+    }
+}
+
+unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index)
+{
+    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+}
+
+RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index)
+{
+    ASSERT(gl::IsCubemapTextureTarget(index.type));
+
+    // ensure the underlying texture is created
+    if (!ensureRenderTarget())
+    {
+        return NULL;
+    }
+
+    updateStorageFaceLevel(index.layerIndex, index.mipIndex);
+    return mTexStorage->getRenderTarget(index);
+}
+
+void TextureD3D_Cube::initializeStorage(bool renderTarget)
+{
+    // Only initialize the first time this texture is used as a render target or shader resource
+    if (mTexStorage)
+    {
+        return;
+    }
+
+    // do not attempt to create storage for nonexistant data
+    if (!isFaceLevelComplete(0, 0))
+    {
+        return;
+    }
+
+    bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
+
+    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+    ASSERT(mTexStorage);
+
+    // flush image data to the storage
+    updateStorage();
+}
+
+TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const
+{
+    GLsizei size = getBaseLevelWidth();
+
+    ASSERT(size > 0);
+
+    // use existing storage level count, when previously specified by TexStorage*D
+    GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
+
+    return mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels);
+}
+
+void TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+{
+    SafeDelete(mTexStorage);
+    mTexStorage = newCompleteTexStorage;
+
+    if (mTexStorage && mTexStorage->isManaged())
+    {
+        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+        {
+            for (int level = 0; level < mTexStorage->getLevelCount(); level++)
+            {
+                mImageArray[faceIndex][level]->setManagedSurfaceCube(mTexStorage, faceIndex, level);
+            }
+        }
+    }
+
+    mDirtyImages = true;
+}
+
+void TextureD3D_Cube::updateStorage()
+{
+    ASSERT(mTexStorage != NULL);
+    GLint storageLevels = mTexStorage->getLevelCount();
+    for (int face = 0; face < 6; face++)
+    {
+        for (int level = 0; level < storageLevels; level++)
+        {
+            if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
+            {
+                updateStorageFaceLevel(face, level);
+            }
+        }
+    }
+}
+
+bool TextureD3D_Cube::ensureRenderTarget()
+{
+    initializeStorage(true);
+
+    if (getBaseLevelWidth() > 0)
+    {
+        ASSERT(mTexStorage);
+        if (!mTexStorage->isRenderTarget())
+        {
+            TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
+
+            if (!mRenderer->copyToRenderTargetCube(newRenderTargetStorage, mTexStorage))
+            {
+                delete newRenderTargetStorage;
+                return gl::error(GL_OUT_OF_MEMORY, false);
+            }
+
+            setCompleteTexStorage(newRenderTargetStorage);
+        }
+    }
+
+    return (mTexStorage && mTexStorage->isRenderTarget());
+}
+
+TextureStorage *TextureD3D_Cube::getBaseLevelStorage()
+{
+    return mTexStorage;
+}
+
+const ImageD3D *TextureD3D_Cube::getBaseLevelImage() const
+{
+    // Note: if we are not cube-complete, there is no single base level image that can describe all
+    // cube faces, so this method is only well-defined for a cube-complete base level.
+    return mImageArray[0][0];
+}
+
+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);
+
+    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 ImageD3D *faceLevelImage = mImageArray[faceIndex][level];
+
+    if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
+    {
+        return false;
+    }
+
+    if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+void TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
+{
+    ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
+    ImageD3D *image = mImageArray[faceIndex][level];
+
+    if (image->isDirty())
+    {
+        commitRect(faceIndex, level, 0, 0, image->getWidth(), image->getHeight());
+    }
+}
+
+void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height)
+{
+    // If there currently is a corresponding storage texture image, it has these parameters
+    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
+    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
+    const GLenum storageFormat = getBaseLevelInternalFormat();
+
+    mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, width, height, 1, false);
+
+    if (mTexStorage)
+    {
+        const int storageLevels = mTexStorage->getLevelCount();
+
+        if ((level >= storageLevels && storageLevels != 0) ||
+            width != storageWidth ||
+            height != storageHeight ||
+            internalformat != storageFormat)   // Discard mismatched storage
+        {
+            for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+            {
+                for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+                {
+                    mImageArray[faceIndex][level]->markDirty();
+                }
+            }
+
+            SafeDelete(mTexStorage);
+
+            mDirtyImages = true;
+        }
+    }
+}
+
+void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    if (isValidFaceLevel(faceIndex, level))
+    {
+        ImageD3D *image = mImageArray[faceIndex][level];
+        if (image->copyToStorageCube(mTexStorage, faceIndex, level, xoffset, yoffset, width, height))
+            image->markClean();
+    }
+}
+
+
+TextureD3D_3D::TextureD3D_3D(Renderer *renderer)
+    : TextureD3D(renderer),
+      mTexStorage(NULL)
+{
+    for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
+    {
+        mImageArray[i] = ImageD3D::makeImageD3D(renderer->createImage());
+    }
+}
+
+TextureD3D_3D::~TextureD3D_3D()
+{
+    // 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];
+    }
+
+    SafeDelete(mTexStorage);
+}
+
+Image *TextureD3D_3D::getImage(int level, int layer) const
+{
+    ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(layer == 0);
+    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);
+    return 1;
+}
+
+GLsizei TextureD3D_3D::getWidth(GLint level) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[level]->getWidth();
+    else
+        return 0;
+}
+
+GLsizei TextureD3D_3D::getHeight(GLint level) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[level]->getHeight();
+    else
+        return 0;
+}
+
+GLsizei TextureD3D_3D::getDepth(GLint level) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[level]->getDepth();
+    else
+        return 0;
+}
+
+GLenum TextureD3D_3D::getInternalFormat(GLint level) const
+{
+    if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+        return mImageArray[level]->getInternalFormat();
+    else
+        return GL_NONE;
+}
+
+bool TextureD3D_3D::isDepth(GLint level) const
+{
+    return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
+}
+
+void TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_3D);
+    GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
+
+    redefineImage(level, sizedInternalFormat, width, height, depth);
+
+    bool fastUnpacked = false;
+
+    // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
+    if (isFastUnpackable(unpack, sizedInternalFormat))
+    {
+        // Will try to create RT storage if it does not exist
+        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))
+        {
+            // Ensure we don't overwrite our newly initialized data
+            mImageArray[level]->markClean();
+
+            fastUnpacked = true;
+        }
+    }
+
+    if (!fastUnpacked)
+    {
+        TextureD3D::setImage(unpack, type, pixels, mImageArray[level]);
+    }
+}
+
+void TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_3D);
+
+    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+    redefineImage(level, format, width, height, depth);
+
+    TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]);
+}
+
+void TextureD3D_3D::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)
+{
+    ASSERT(target == GL_TEXTURE_3D);
+
+    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(index);
+        gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
+
+        if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget))
+        {
+            // Ensure we don't overwrite our newly initialized data
+            mImageArray[level]->markClean();
+
+            fastUnpacked = true;
+        }
+    }
+
+    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, index))
+    {
+        commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
+    }
+}
+
+void TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_3D);
+
+    if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, mImageArray[level]))
+    {
+        commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
+    }
+}
+
+void TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    UNIMPLEMENTED();
+}
+
+void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    ASSERT(target == GL_TEXTURE_3D);
+
+    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
+    // the current level we're copying to is defined (with appropriate format, width & height)
+    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
+
+    if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+    {
+        mImageArray[level]->copy(xoffset, yoffset, zoffset, x, y, width, height, source);
+        mDirtyImages = true;
+    }
+    else
+    {
+        ensureRenderTarget();
+
+        if (isValidLevel(level))
+        {
+            updateStorageLevel(level);
+
+            gl::Rectangle sourceRect;
+            sourceRect.x = x;
+            sourceRect.width = width;
+            sourceRect.y = y;
+            sourceRect.height = height;
+
+            mRenderer->copyImage3D(source, sourceRect,
+                                   gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+                                   xoffset, yoffset, zoffset, mTexStorage, level);
+        }
+    }
+}
+
+void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+    ASSERT(target == GL_TEXTURE_3D);
+
+    for (int level = 0; level < levels; level++)
+    {
+        GLsizei levelWidth = std::max(1, width >> level);
+        GLsizei levelHeight = std::max(1, height >> level);
+        GLsizei levelDepth = std::max(1, depth >> level);
+        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, levelWidth, levelHeight, levelDepth, true);
+    }
+
+    for (int level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+    {
+        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, GL_NONE, 0, 0, 0, true);
+    }
+
+    mImmutable = true;
+
+    bool renderTarget = IsRenderTargetUsage(mUsage);
+    TextureStorage *storage = mRenderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels);
+    setCompleteTexStorage(storage);
+}
+
+void TextureD3D_3D::bindTexImage(egl::Surface *surface)
+{
+    UNREACHABLE();
+}
+
+void TextureD3D_3D::releaseTexImage()
+{
+    UNREACHABLE();
+}
+
+
+void TextureD3D_3D::generateMipmaps()
+{
+    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
+    int levelCount = mipLevels();
+    for (int level = 1; level < levelCount; level++)
+    {
+        redefineImage(level, getBaseLevelInternalFormat(),
+                      std::max(getBaseLevelWidth() >> level, 1),
+                      std::max(getBaseLevelHeight() >> level, 1),
+                      std::max(getBaseLevelDepth() >> level, 1));
+    }
+
+    if (mTexStorage && mTexStorage->isRenderTarget())
+    {
+        mTexStorage->generateMipmaps();
+
+        for (int level = 1; level < levelCount; level++)
+        {
+            mImageArray[level]->markClean();
+        }
+    }
+    else
+    {
+        for (int level = 1; level < levelCount; level++)
+        {
+            mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
+        }
+    }
+}
+
+unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index)
+{
+    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+}
+
+RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index)
+{
+    // ensure the underlying texture is created
+    if (!ensureRenderTarget())
+    {
+        return NULL;
+    }
+
+    if (index.hasLayer())
+    {
+        updateStorage();
+    }
+    else
+    {
+        updateStorageLevel(index.mipIndex);
+    }
+
+    return mTexStorage->getRenderTarget(index);
+}
+
+void TextureD3D_3D::initializeStorage(bool renderTarget)
+{
+    // Only initialize the first time this texture is used as a render target or shader resource
+    if (mTexStorage)
+    {
+        return;
+    }
+
+    // do not attempt to create storage for nonexistant data
+    if (!isLevelComplete(0))
+    {
+        return;
+    }
+
+    bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+
+    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+    ASSERT(mTexStorage);
+
+    // flush image data to the storage
+    updateStorage();
+}
+
+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 mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels);
+}
+
+void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+{
+    SafeDelete(mTexStorage);
+    mTexStorage = newCompleteTexStorage;
+    mDirtyImages = true;
+
+    // We do not support managed 3D storage, as that is D3D9/ES2-only
+    ASSERT(!mTexStorage->isManaged());
+}
+
+void TextureD3D_3D::updateStorage()
+{
+    ASSERT(mTexStorage != NULL);
+    GLint storageLevels = mTexStorage->getLevelCount();
+    for (int level = 0; level < storageLevels; level++)
+    {
+        if (mImageArray[level]->isDirty() && isLevelComplete(level))
+        {
+            updateStorageLevel(level);
+        }
+    }
+}
+
+bool TextureD3D_3D::ensureRenderTarget()
+{
+    initializeStorage(true);
+
+    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0)
+    {
+        ASSERT(mTexStorage);
+        if (!mTexStorage->isRenderTarget())
+        {
+            TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
+
+            if (!mRenderer->copyToRenderTarget3D(newRenderTargetStorage, mTexStorage))
+            {
+                delete newRenderTargetStorage;
+                return gl::error(GL_OUT_OF_MEMORY, false);
+            }
+
+            setCompleteTexStorage(newRenderTargetStorage);
+        }
+    }
+
+    return (mTexStorage && mTexStorage->isRenderTarget());
+}
+
+TextureStorage *TextureD3D_3D::getBaseLevelStorage()
+{
+    return mTexStorage;
+}
+
+const ImageD3D *TextureD3D_3D::getBaseLevelImage() const
+{
+    return mImageArray[0];
+}
+
+bool TextureD3D_3D::isValidLevel(int level) const
+{
+    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
+}
+
+bool TextureD3D_3D::isLevelComplete(int level) const
+{
+    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != 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;
+    }
+
+    ImageD3D *levelImage = mImageArray[level];
+
+    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;
+}
+
+void TextureD3D_3D::updateStorageLevel(int level)
+{
+    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
+    ASSERT(isLevelComplete(level));
+
+    if (mImageArray[level]->isDirty())
+    {
+        commitRect(level, 0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
+    }
+}
+
+void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+    // If there currently is a corresponding storage texture image, it has these parameters
+    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
+    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
+    const int storageDepth = std::max(1, getBaseLevelDepth() >> level);
+    const GLenum storageFormat = getBaseLevelInternalFormat();
+
+    mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, width, height, depth, false);
+
+    if (mTexStorage)
+    {
+        const int storageLevels = mTexStorage->getLevelCount();
+
+        if ((level >= storageLevels && storageLevels != 0) ||
+            width != storageWidth ||
+            height != storageHeight ||
+            depth != storageDepth ||
+            internalformat != storageFormat)   // Discard mismatched storage
+        {
+            for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+            {
+                mImageArray[i]->markDirty();
+            }
+
+            SafeDelete(mTexStorage);
+            mDirtyImages = true;
+        }
+    }
+}
+
+void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
+{
+    if (isValidLevel(level))
+    {
+        ImageD3D *image = mImageArray[level];
+        if (image->copyToStorage3D(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth))
+        {
+            image->markClean();
+        }
+    }
+}
+
+
+TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer)
+    : TextureD3D(renderer),
+      mTexStorage(NULL)
+{
+    for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
+    {
+        mLayerCounts[level] = 0;
+        mImageArray[level] = NULL;
+    }
+}
+
+TextureD3D_2DArray::~TextureD3D_2DArray()
+{
+    // 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();
+    SafeDelete(mTexStorage);
+}
+
+Image *TextureD3D_2DArray::getImage(int level, int layer) const
+{
+    ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(layer < mLayerCounts[level]);
+    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);
+    return mLayerCounts[level];
+}
+
+GLsizei TextureD3D_2DArray::getWidth(GLint level) const
+{
+    return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getWidth() : 0;
+}
+
+GLsizei TextureD3D_2DArray::getHeight(GLint level) const
+{
+    return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getHeight() : 0;
+}
+
+GLsizei TextureD3D_2DArray::getLayers(GLint level) const
+{
+    return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mLayerCounts[level] : 0;
+}
+
+GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const
+{
+    return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getInternalFormat() : GL_NONE;
+}
+
+bool TextureD3D_2DArray::isDepth(GLint level) const
+{
+    return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
+}
+
+void TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+
+    GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
+
+    redefineImage(level, sizedInternalFormat, width, height, depth);
+
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
+    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpack.alignment);
+
+    for (int i = 0; i < depth; i++)
+    {
+        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
+        TextureD3D::setImage(unpack, type, layerPixels, mImageArray[level][i]);
+    }
+}
+
+void TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+
+    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+    redefineImage(level, format, width, height, depth);
+
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
+    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
+
+    for (int i = 0; i < depth; i++)
+    {
+        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
+        TextureD3D::setCompressedImage(imageSize, layerPixels, mImageArray[level][i]);
+    }
+}
+
+void TextureD3D_2DArray::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)
+{
+    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(level));
+    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpack.alignment);
+
+    for (int i = 0; i < depth; i++)
+    {
+        int layer = zoffset + i;
+        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
+
+        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);
+        }
+    }
+}
+
+void TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+{
+    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
+    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
+
+    for (int i = 0; i < depth; i++)
+    {
+        int layer = zoffset + i;
+        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
+
+        if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, layerPixels, mImageArray[level][layer]))
+        {
+            commitRect(level, xoffset, yoffset, layer, width, height);
+        }
+    }
+}
+
+void TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    UNIMPLEMENTED();
+}
+
+void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+
+    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
+    // the current level we're copying to is defined (with appropriate format, width & height)
+    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
+
+    if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+    {
+        mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, x, y, width, height, source);
+        mDirtyImages = true;
+    }
+    else
+    {
+        ensureRenderTarget();
+
+        if (isValidLevel(level))
+        {
+            updateStorageLevel(level);
+
+            gl::Rectangle sourceRect;
+            sourceRect.x = x;
+            sourceRect.width = width;
+            sourceRect.y = y;
+            sourceRect.height = height;
+
+            mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
+                                        xoffset, yoffset, zoffset, mTexStorage, level);
+        }
+    }
+}
+
+void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+    ASSERT(target == GL_TEXTURE_2D_ARRAY);
+
+    deleteImages();
+
+    for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+    {
+        GLsizei levelWidth = std::max(1, width >> level);
+        GLsizei levelHeight = std::max(1, height >> level);
+
+        mLayerCounts[level] = (level < levels ? depth : 0);
+
+        if (mLayerCounts[level] > 0)
+        {
+            // Create new images for this level
+            mImageArray[level] = new ImageD3D*[mLayerCounts[level]];
+
+            for (int layer = 0; layer < mLayerCounts[level]; layer++)
+            {
+                mImageArray[level][layer] = ImageD3D::makeImageD3D(mRenderer->createImage());
+                mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, levelWidth,
+                                                    levelHeight, 1, true);
+            }
+        }
+    }
+
+    mImmutable = true;
+
+    bool renderTarget = IsRenderTargetUsage(mUsage);
+    TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels);
+    setCompleteTexStorage(storage);
+}
+
+void TextureD3D_2DArray::bindTexImage(egl::Surface *surface)
+{
+    UNREACHABLE();
+}
+
+void TextureD3D_2DArray::releaseTexImage()
+{
+    UNREACHABLE();
+}
+
+
+void TextureD3D_2DArray::generateMipmaps()
+{
+    int baseWidth = getBaseLevelWidth();
+    int baseHeight = getBaseLevelHeight();
+    int baseDepth = getBaseLevelDepth();
+    GLenum baseFormat = getBaseLevelInternalFormat();
+
+    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
+    int levelCount = mipLevels();
+    for (int level = 1; level < levelCount; level++)
+    {
+        redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
+    }
+
+    if (mTexStorage && mTexStorage->isRenderTarget())
+    {
+        mTexStorage->generateMipmaps();
+
+        for (int level = 1; level < levelCount; level++)
+        {
+            for (int layer = 0; layer < mLayerCounts[level]; layer++)
+            {
+                mImageArray[level][layer]->markClean();
+            }
+        }
+    }
+    else
+    {
+        for (int level = 1; level < levelCount; level++)
+        {
+            for (int layer = 0; layer < mLayerCounts[level]; layer++)
+            {
+                mRenderer->generateMipmap(mImageArray[level][layer], mImageArray[level - 1][layer]);
+            }
+        }
+    }
+}
+
+unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index)
+{
+    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+}
+
+RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index)
+{
+    // ensure the underlying texture is created
+    if (!ensureRenderTarget())
+    {
+        return NULL;
+    }
+
+    updateStorageLevel(index.mipIndex);
+    return mTexStorage->getRenderTarget(index);
+}
+
+void TextureD3D_2DArray::initializeStorage(bool renderTarget)
+{
+    // Only initialize the first time this texture is used as a render target or shader resource
+    if (mTexStorage)
+    {
+        return;
+    }
+
+    // do not attempt to create storage for nonexistant data
+    if (!isLevelComplete(0))
+    {
+        return;
+    }
+
+    bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+
+    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+    ASSERT(mTexStorage);
+
+    // flush image data to the storage
+    updateStorage();
+}
+
+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 mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels);
+}
+
+void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+{
+    SafeDelete(mTexStorage);
+    mTexStorage = newCompleteTexStorage;
+    mDirtyImages = true;
+
+    // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
+    ASSERT(!mTexStorage->isManaged());
+}
+
+void TextureD3D_2DArray::updateStorage()
+{
+    ASSERT(mTexStorage != NULL);
+    GLint storageLevels = mTexStorage->getLevelCount();
+    for (int level = 0; level < storageLevels; level++)
+    {
+        if (isLevelComplete(level))
+        {
+            updateStorageLevel(level);
+        }
+    }
+}
+
+bool TextureD3D_2DArray::ensureRenderTarget()
+{
+    initializeStorage(true);
+
+    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getLayers(0) > 0)
+    {
+        ASSERT(mTexStorage);
+        if (!mTexStorage->isRenderTarget())
+        {
+            TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
+
+            if (!mRenderer->copyToRenderTarget2DArray(newRenderTargetStorage, mTexStorage))
+            {
+                delete newRenderTargetStorage;
+                return gl::error(GL_OUT_OF_MEMORY, false);
+            }
+
+            setCompleteTexStorage(newRenderTargetStorage);
+        }
+    }
+
+    return (mTexStorage && mTexStorage->isRenderTarget());
+}
+
+const ImageD3D *TextureD3D_2DArray::getBaseLevelImage() const
+{
+    return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL);
+}
+
+TextureStorage *TextureD3D_2DArray::getBaseLevelStorage()
+{
+    return mTexStorage;
+}
+
+bool TextureD3D_2DArray::isValidLevel(int level) const
+{
+    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
+}
+
+bool TextureD3D_2DArray::isLevelComplete(int level) const
+{
+    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray));
+
+    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;
+}
+
+void TextureD3D_2DArray::updateStorageLevel(int level)
+{
+    ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts));
+    ASSERT(isLevelComplete(level));
+
+    for (int layer = 0; layer < mLayerCounts[level]; layer++)
+    {
+        ASSERT(mImageArray[level] != NULL && mImageArray[level][layer] != NULL);
+        if (mImageArray[level][layer]->isDirty())
+        {
+            commitRect(level, 0, 0, layer, getWidth(level), getHeight(level));
+        }
+    }
+}
+
+void TextureD3D_2DArray::deleteImages()
+{
+    for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
+    {
+        for (int layer = 0; layer < mLayerCounts[level]; ++layer)
+        {
+            delete mImageArray[level][layer];
+        }
+        delete[] mImageArray[level];
+        mImageArray[level] = NULL;
+        mLayerCounts[level] = 0;
+    }
+}
+
+void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+    // If there currently is a corresponding storage texture image, it has these parameters
+    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
+    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
+    const int storageDepth = getLayers(0);
+    const GLenum storageFormat = getBaseLevelInternalFormat();
+
+    for (int layer = 0; layer < mLayerCounts[level]; layer++)
+    {
+        delete mImageArray[level][layer];
+    }
+    delete[] mImageArray[level];
+    mImageArray[level] = NULL;
+    mLayerCounts[level] = depth;
+
+    if (depth > 0)
+    {
+        mImageArray[level] = new ImageD3D*[depth]();
+
+        for (int layer = 0; layer < mLayerCounts[level]; layer++)
+        {
+            mImageArray[level][layer] = ImageD3D::makeImageD3D(mRenderer->createImage());
+            mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, width, height, 1, false);
+        }
+    }
+
+    if (mTexStorage)
+    {
+        const int storageLevels = mTexStorage->getLevelCount();
+
+        if ((level >= storageLevels && storageLevels != 0) ||
+            width != storageWidth ||
+            height != storageHeight ||
+            depth != storageDepth ||
+            internalformat != storageFormat)   // Discard mismatched storage
+        {
+            for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+            {
+                for (int layer = 0; layer < mLayerCounts[level]; layer++)
+                {
+                    mImageArray[level][layer]->markDirty();
+                }
+            }
+
+            delete mTexStorage;
+            mTexStorage = NULL;
+            mDirtyImages = true;
+        }
+    }
+}
+
+void TextureD3D_2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height)
+{
+    if (isValidLevel(level) && layerTarget < getLayers(level))
+    {
+        ImageD3D *image = mImageArray[level][layerTarget];
+        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
new file mode 100644
index 0000000..41c7318
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.h
@@ -0,0 +1,320 @@
+//
+// 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.
+//
+
+// TextureD3D.h: Implementations of the Texture interfaces shared betweeen the D3D backends.
+
+#ifndef LIBGLESV2_RENDERER_TEXTURED3D_H_
+#define LIBGLESV2_RENDERER_TEXTURED3D_H_
+
+#include "libGLESv2/renderer/TextureImpl.h"
+#include "libGLESv2/angletypes.h"
+#include "libGLESv2/constants.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+
+class Image;
+class ImageD3D;
+class Renderer;
+class RenderTarget;
+class TextureStorage;
+
+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;
+    GLenum getBaseLevelInternalFormat() const;
+
+    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, 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);
+
+    GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
+    int mipLevels() const;
+
+    Renderer *mRenderer;
+
+    GLenum mUsage;
+
+    bool mDirtyImages;
+
+    bool mImmutable;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureD3D);
+
+    virtual void initializeStorage(bool renderTarget) = 0;
+
+    virtual void updateStorage() = 0;
+    virtual TextureStorage *getBaseLevelStorage() = 0;
+    virtual const ImageD3D *getBaseLevelImage() const = 0;
+};
+
+class TextureD3D_2D : public TextureD3D
+{
+  public:
+    TextureD3D_2D(Renderer *renderer);
+    virtual ~TextureD3D_2D();
+
+    virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
+    virtual GLsizei getLayerCount(int level) const;
+
+    GLsizei getWidth(GLint level) const;
+    GLsizei getHeight(GLint level) const;
+    GLenum getInternalFormat(GLint level) const;
+    GLenum getActualFormat(GLint level) const;
+    bool isDepth(GLint level) const;
+
+    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);
+    virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+    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);
+    virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+    virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+    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 void bindTexImage(egl::Surface *surface);
+    virtual void releaseTexImage();
+
+    virtual void generateMipmaps();
+
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
+
+    virtual void initializeStorage(bool renderTarget);
+    TextureStorage *createCompleteStorage(bool renderTarget) const;
+    void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+
+    virtual void updateStorage();
+    bool ensureRenderTarget();
+    virtual TextureStorage *getBaseLevelStorage();
+    virtual const ImageD3D *getBaseLevelImage() const;
+
+    bool isValidLevel(int level) const;
+    bool isLevelComplete(int level) const;
+
+    void updateStorageLevel(int level);
+
+    void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
+    void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+    TextureStorage *mTexStorage;
+    ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+};
+
+class TextureD3D_Cube : public TextureD3D
+{
+  public:
+    TextureD3D_Cube(Renderer *renderer);
+    virtual ~TextureD3D_Cube();
+
+    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; }
+
+    GLenum getInternalFormat(GLint level, GLint layer) const;
+    bool isDepth(GLint level, GLint layer) const;
+
+    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);
+    virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+    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);
+    virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+    virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+    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 void bindTexImage(egl::Surface *surface);
+    virtual void releaseTexImage();
+
+    virtual void generateMipmaps();
+
+    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
+
+    virtual void initializeStorage(bool renderTarget);
+    TextureStorage *createCompleteStorage(bool renderTarget) const;
+    void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+
+    virtual void updateStorage();
+    bool ensureRenderTarget();
+    virtual TextureStorage *getBaseLevelStorage();
+    virtual const ImageD3D *getBaseLevelImage() 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);
+    void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+    ImageD3D *mImageArray[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    TextureStorage *mTexStorage;
+};
+
+class TextureD3D_3D : public TextureD3D
+{
+  public:
+    TextureD3D_3D(Renderer *renderer);
+    virtual ~TextureD3D_3D();
+
+    virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
+    virtual GLsizei getLayerCount(int level) const;
+
+    GLsizei getWidth(GLint level) const;
+    GLsizei getHeight(GLint level) const;
+    GLsizei getDepth(GLint level) const;
+    GLenum getInternalFormat(GLint level) const;
+    bool isDepth(GLint level) const;
+
+    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);
+    virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+    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);
+    virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+    virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+    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 void bindTexImage(egl::Surface *surface);
+    virtual void releaseTexImage();
+
+    virtual void generateMipmaps();
+
+    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);
+    TextureStorage *createCompleteStorage(bool renderTarget) const;
+    void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+
+    virtual void updateStorage();
+    bool ensureRenderTarget();
+    virtual TextureStorage *getBaseLevelStorage();
+    virtual const ImageD3D *getBaseLevelImage() const;
+
+    bool isValidLevel(int level) const;
+    bool isLevelComplete(int level) const;
+    void updateStorageLevel(int level);
+
+    void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+    void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+
+    ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    TextureStorage *mTexStorage;
+};
+
+class TextureD3D_2DArray : public TextureD3D
+{
+  public:
+    TextureD3D_2DArray(Renderer *renderer);
+    virtual ~TextureD3D_2DArray();
+
+    virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
+    virtual GLsizei getLayerCount(int level) const;
+
+    GLsizei getWidth(GLint level) const;
+    GLsizei getHeight(GLint level) const;
+    GLsizei getLayers(GLint level) const;
+    GLenum getInternalFormat(GLint level) const;
+    bool isDepth(GLint level) const;
+
+    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);
+    virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+    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);
+    virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+    virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+    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 void bindTexImage(egl::Surface *surface);
+    virtual void releaseTexImage();
+
+    virtual void generateMipmaps();
+
+    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);
+    TextureStorage *createCompleteStorage(bool renderTarget) const;
+    void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+
+    virtual void updateStorage();
+    bool ensureRenderTarget();
+    virtual TextureStorage *getBaseLevelStorage();
+    virtual const ImageD3D *getBaseLevelImage() const;
+
+    bool isValidLevel(int level) const;
+    bool isLevelComplete(int level) const;
+    void updateStorageLevel(int level);
+
+    void deleteImages();
+    void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+    void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height);
+
+    // Storing images as an array of single depth textures since D3D11 treats each array level of a
+    // Texture2D object as a separate subresource.  Each layer would have to be looped over
+    // to update all the texture layers since they cannot all be updated at once and it makes the most
+    // sense for the Image class to not have to worry about layer subresource as well as mip subresources.
+    GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+    ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    TextureStorage *mTexStorage;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURED3D_H_
diff --git a/src/libGLESv2/renderer/d3d/TextureStorage.cpp b/src/libGLESv2/renderer/d3d/TextureStorage.cpp
new file mode 100644
index 0000000..dedd266
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/TextureStorage.cpp
@@ -0,0 +1,51 @@
+//
+// 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: Shared members of abstract rx::TextureStorage class.
+
+#include "libGLESv2/renderer/d3d/TextureStorage.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/Texture.h"
+
+#include "common/debug.h"
+#include "common/mathutil.h"
+
+namespace rx
+{
+
+unsigned int TextureStorage::mCurrentTextureSerial = 1;
+
+TextureStorage::TextureStorage()
+    : mTextureSerial(issueTextureSerial()),
+      mFirstRenderTargetSerial(0),
+      mRenderTargetSerialsLayerStride(0)
+{}
+
+void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride)
+{
+    mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(rtSerialsToReserve);
+    mRenderTargetSerialsLayerStride = rtSerialsLayerStride;
+}
+
+unsigned int TextureStorage::getRenderTargetSerial(const gl::ImageIndex &index) const
+{
+    unsigned int layerOffset = (index.hasLayer() ? (static_cast<unsigned int>(index.layerIndex) * mRenderTargetSerialsLayerStride) : 0);
+    return mFirstRenderTargetSerial + static_cast<unsigned int>(index.mipIndex) + layerOffset;
+}
+
+unsigned int TextureStorage::getTextureSerial() const
+{
+    return mTextureSerial;
+}
+
+unsigned int TextureStorage::issueTextureSerial()
+{
+    return mCurrentTextureSerial++;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/TextureStorage.h b/src/libGLESv2/renderer/d3d/TextureStorage.h
new file mode 100644
index 0000000..9cc2c29
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/TextureStorage.h
@@ -0,0 +1,61 @@
+//
+// 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.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;
+class SwapChain;
+class RenderTarget;
+
+class TextureStorage
+{
+  public:
+    TextureStorage();
+    virtual ~TextureStorage() {};
+
+    virtual int getTopLevel() const = 0;
+    virtual bool isRenderTarget() const = 0;
+    virtual bool isManaged() const = 0;
+    virtual int getLevelCount() const = 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);
+
+    const unsigned int mTextureSerial;
+    static unsigned int issueTextureSerial();
+
+    static unsigned int mCurrentTextureSerial;
+
+    unsigned int mFirstRenderTargetSerial;
+    unsigned int mRenderTargetSerialsLayerStride;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
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
new file mode 100644
index 0000000..4f85eb9
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
@@ -0,0 +1,307 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
+// 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 "common/mathutil.h"
+
+namespace rx
+{
+
+unsigned int VertexBuffer::mNextSerial = 1;
+
+VertexBuffer::VertexBuffer()
+{
+    updateSerial();
+}
+
+VertexBuffer::~VertexBuffer()
+{
+}
+
+void VertexBuffer::updateSerial()
+{
+    mSerial = mNextSerial++;
+}
+
+unsigned int VertexBuffer::getSerial() const
+{
+    return mSerial;
+}
+
+VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
+{
+    mDynamic = dynamic;
+    mWritePosition = 0;
+    mReservedSpace = 0;
+
+    mVertexBuffer = renderer->createVertexBuffer();
+}
+
+VertexBufferInterface::~VertexBufferInterface()
+{
+    delete mVertexBuffer;
+}
+
+unsigned int VertexBufferInterface::getSerial() const
+{
+    return mVertexBuffer->getSerial();
+}
+
+unsigned int VertexBufferInterface::getBufferSize() const
+{
+    return mVertexBuffer->getBufferSize();
+}
+
+gl::Error VertexBufferInterface::setBufferSize(unsigned int size)
+{
+    if (mVertexBuffer->getBufferSize() == 0)
+    {
+        return mVertexBuffer->initialize(size, mDynamic);
+    }
+    else
+    {
+        return mVertexBuffer->setBufferSize(size);
+    }
+}
+
+unsigned int VertexBufferInterface::getWritePosition() const
+{
+    return mWritePosition;
+}
+
+void VertexBufferInterface::setWritePosition(unsigned int writePosition)
+{
+    mWritePosition = writePosition;
+}
+
+gl::Error VertexBufferInterface::discard()
+{
+    return mVertexBuffer->discard();
+}
+
+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;
+    error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    if (mWritePosition + spaceRequired < mWritePosition)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow.");
+    }
+
+    error = reserveSpace(mReservedSpace);
+    if (error.isError())
+    {
+        return error;
+    }
+    mReservedSpace = 0;
+
+    error = mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    if (outStreamOffset)
+    {
+        *outStreamOffset = mWritePosition;
+    }
+
+    mWritePosition += spaceRequired;
+
+    // Align to 16-byte boundary
+    mWritePosition = rx::roundUp(mWritePosition, 16u);
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances)
+{
+    gl::Error error(GL_NO_ERROR);
+
+    unsigned int requiredSpace;
+    error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    // Protect against integer overflow
+    if (mReservedSpace + requiredSpace < mReservedSpace)
+    {
+        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;
+
+    // Align to 16-byte boundary
+    mReservedSpace = rx::roundUp(mReservedSpace, 16u);
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+VertexBuffer* VertexBufferInterface::getVertexBuffer() const
+{
+    return mVertexBuffer;
+}
+
+bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &attrib,
+                                                  const gl::VertexAttribCurrentValueData &currentValue) const
+{
+    gl::Buffer *buffer = attrib.buffer.get();
+    BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
+
+    if (!storage || !storage->supportsDirectBinding())
+    {
+        return false;
+    }
+
+    // Alignment restrictions: In D3D, vertex data must be aligned to
+    //  the format stride, or to a 4-byte boundary, whichever is smaller.
+    //  (Undocumented, and experimentally confirmed)
+    size_t alignment = 4;
+    bool requiresConversion = false;
+
+    if (attrib.type != GL_FLOAT)
+    {
+        gl::VertexFormat vertexFormat(attrib, currentValue.Type);
+
+        unsigned int outputElementSize;
+        getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
+        alignment = std::min<size_t>(outputElementSize, 4);
+
+        requiresConversion = (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0;
+    }
+
+    bool isAligned = (static_cast<size_t>(ComputeVertexAttributeStride(attrib)) % alignment == 0) &&
+                     (static_cast<size_t>(attrib.offset) % alignment == 0);
+
+    return !requiresConversion && isAligned;
+}
+
+StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
+{
+    setBufferSize(initialSize);
+}
+
+StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
+{
+}
+
+gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size)
+{
+    unsigned int curBufferSize = getBufferSize();
+    if (size > curBufferSize)
+    {
+        gl::Error error = setBufferSize(std::max(size, 3 * curBufferSize / 2));
+        if (error.isError())
+        {
+            return error;
+        }
+        setWritePosition(0);
+    }
+    else if (getWritePosition() + size > curBufferSize)
+    {
+        gl::Error error = discard();
+        if (error.isError())
+        {
+            return error;
+        }
+        setWritePosition(0);
+    }
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
+{
+}
+
+StaticVertexBufferInterface::~StaticVertexBufferInterface()
+{
+}
+
+bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attrib, unsigned int *outStreamOffset)
+{
+    for (unsigned int element = 0; element < mCache.size(); element++)
+    {
+        if (mCache[element].type == attrib.type &&
+            mCache[element].size == attrib.size &&
+            mCache[element].stride == ComputeVertexAttributeStride(attrib) &&
+            mCache[element].normalized == attrib.normalized &&
+            mCache[element].pureInteger == attrib.pureInteger)
+        {
+            size_t offset = (static_cast<size_t>(attrib.offset) % ComputeVertexAttributeStride(attrib));
+            if (mCache[element].attributeOffset == offset)
+            {
+                if (outStreamOffset)
+                {
+                    *outStreamOffset = mCache[element].streamOffset;
+                }
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+gl::Error StaticVertexBufferInterface::reserveSpace(unsigned int size)
+{
+    unsigned int curSize = getBufferSize();
+    if (curSize == 0)
+    {
+        return setBufferSize(size);
+    }
+    else if (curSize >= size)
+    {
+        return gl::Error(GL_NO_ERROR);
+    }
+    else
+    {
+        UNREACHABLE();
+        return gl::Error(GL_INVALID_OPERATION, "Internal error, Static vertex buffers can't be resized.");
+    }
+}
+
+gl::Error StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                                             GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset)
+{
+    unsigned int streamOffset;
+    gl::Error error = VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances, &streamOffset);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    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 gl::Error(GL_NO_ERROR);
+}
+
+}
diff --git a/src/libGLESv2/renderer/VertexBuffer.h b/src/libGLESv2/renderer/d3d/VertexBuffer.h
similarity index 60%
rename from src/libGLESv2/renderer/VertexBuffer.h
rename to src/libGLESv2/renderer/d3d/VertexBuffer.h
index d4cdf9e..fa747d9 100644
--- a/src/libGLESv2/renderer/VertexBuffer.h
+++ b/src/libGLESv2/renderer/d3d/VertexBuffer.h
@@ -11,10 +11,16 @@
 #define LIBGLESV2_RENDERER_VERTEXBUFFER_H_
 
 #include "common/angleutils.h"
+#include "libGLESv2/Error.h"
+
+#include <GLES2/gl2.h>
+
+#include <cstddef>
+#include <vector>
 
 namespace gl
 {
-class VertexAttribute;
+struct VertexAttribute;
 struct VertexAttribCurrentValueData;
 }
 
@@ -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,23 +115,23 @@
     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
     {
         GLenum type;
-        GLint size;
-        GLsizei stride;
+        GLuint size;
+        GLuint stride;
         bool normalized;
         bool pureInteger;
-        int attributeOffset;
+        size_t attributeOffset;
 
         unsigned int streamOffset;
     };
diff --git a/src/libGLESv2/renderer/d3d/VertexDataManager.cpp b/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
new file mode 100644
index 0000000..7034b78
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
@@ -0,0 +1,348 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#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"
+
+namespace
+{
+    enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 };
+    // This has to be at least 4k or else it fails on ATI cards.
+    enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 };
+}
+
+namespace rx
+{
+
+static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size)
+{
+    // Size cannot be larger than a GLsizei
+    if (size > static_cast<unsigned int>(std::numeric_limits<int>::max()))
+    {
+        size = static_cast<unsigned int>(std::numeric_limits<int>::max());
+    }
+
+    GLsizei stride = ComputeVertexAttributeStride(attrib);
+    return (size - attrib.offset % stride + (stride - ComputeVertexAttributeTypeSize(attrib))) / stride;
+}
+
+static int StreamingBufferElementCount(const gl::VertexAttribute &attrib, int vertexDrawCount, int instanceDrawCount)
+{
+    // For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices.
+    //
+    // A vertex attribute with a positive divisor loads one instanced vertex for every set of
+    // non-instanced vertices, and the instanced vertex index advances once every "mDivisor" instances.
+    if (instanceDrawCount > 0 && attrib.divisor > 0)
+    {
+        return instanceDrawCount / attrib.divisor;
+    }
+
+    return vertexDrawCount;
+}
+
+VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
+{
+    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        mCurrentValue[i].FloatValues[0] = std::numeric_limits<float>::quiet_NaN();
+        mCurrentValue[i].FloatValues[1] = std::numeric_limits<float>::quiet_NaN();
+        mCurrentValue[i].FloatValues[2] = std::numeric_limits<float>::quiet_NaN();
+        mCurrentValue[i].FloatValues[3] = std::numeric_limits<float>::quiet_NaN();
+        mCurrentValue[i].Type = GL_FLOAT;
+        mCurrentValueBuffer[i] = NULL;
+        mCurrentValueOffsets[i] = 0;
+    }
+
+    mStreamingBuffer = new StreamingVertexBufferInterface(renderer, INITIAL_STREAM_BUFFER_SIZE);
+
+    if (!mStreamingBuffer)
+    {
+        ERR("Failed to allocate the streaming vertex buffer.");
+    }
+}
+
+VertexDataManager::~VertexDataManager()
+{
+    delete mStreamingBuffer;
+
+    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        delete mCurrentValueBuffer[i];
+    }
+}
+
+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::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL.");
+    }
+
+    // Invalidate static buffers that don't contain matching attributes
+    for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+    {
+        translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+
+        if (translated[attributeIndex].active && attribs[attributeIndex].enabled)
+        {
+            invalidateMatchingStaticData(attribs[attributeIndex], currentValues[attributeIndex]);
+        }
+    }
+
+    // Reserve the required space in the buffers
+    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        if (translated[i].active && attribs[i].enabled)
+        {
+            gl::Error error = reserveSpaceForAttrib(attribs[i], currentValues[i], count, instances);
+            if (error.isError())
+            {
+                return error;
+            }
+        }
+    }
+
+    // Perform the vertex data translations
+    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        if (translated[i].active)
+        {
+            if (attribs[i].enabled)
+            {
+                gl::Error error = storeAttribute(attribs[i], currentValues[i], &translated[i],
+                                                 start, count, instances);
+                if (error.isError())
+                {
+                    return error;
+                }
+            }
+            else
+            {
+                if (!mCurrentValueBuffer[i])
+                {
+                    mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE);
+                }
+
+                gl::Error error = storeCurrentValue(attribs[i], currentValues[i], &translated[i],
+                                                    &mCurrentValue[i], &mCurrentValueOffsets[i],
+                                                    mCurrentValueBuffer[i]);
+                if (error.isError())
+                {
+                    return error;
+                }
+            }
+        }
+    }
+
+    for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        if (translated[i].active && attribs[i].enabled)
+        {
+            gl::Buffer *buffer = attribs[i].buffer.get();
+
+            if (buffer)
+            {
+                BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
+                bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(attribs[i]));
+            }
+        }
+    }
+
+    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
new file mode 100644
index 0000000..7728722
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/VertexDataManager.h
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
+#define LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
+
+#include "libGLESv2/Constants.h"
+#include "libGLESv2/VertexAttribute.h"
+#include "common/angleutils.h"
+
+namespace gl
+{
+struct VertexAttribute;
+class ProgramBinary;
+struct VertexAttribCurrentValueData;
+}
+
+namespace rx
+{
+class BufferD3D;
+class StreamingVertexBufferInterface;
+class VertexBuffer;
+class Renderer;
+
+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;
+    GLenum currentValueType;
+    unsigned int offset;
+    unsigned int stride;   // 0 means not to advance the read pointer at all
+
+    VertexBuffer *vertexBuffer;
+    BufferD3D *storage;
+    unsigned int serial;
+    unsigned int divisor;
+};
+
+class VertexDataManager
+{
+  public:
+    VertexDataManager(rx::Renderer *renderer);
+    virtual ~VertexDataManager();
+
+    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;
+
+    gl::VertexAttribCurrentValueData mCurrentValue[gl::MAX_VERTEX_ATTRIBS];
+
+    StreamingVertexBufferInterface *mCurrentValueBuffer[gl::MAX_VERTEX_ATTRIBS];
+    std::size_t mCurrentValueOffsets[gl::MAX_VERTEX_ATTRIBS];
+};
+
+}
+
+#endif   // LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
diff --git a/src/libGLESv2/renderer/d3d11/Blit11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
similarity index 90%
rename from src/libGLESv2/renderer/d3d11/Blit11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
index 9a41713..edbc169 100644
--- a/src/libGLESv2/renderer/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,56 +6,56 @@
 
 // Blit11.cpp: Texture copy utility class.
 
+#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/d3d11/Blit11.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
 
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2dui11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2di11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2dui11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2di11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2dui11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2di11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2dui11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2di11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum2d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h"
 
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11vs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11gs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3dui11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3di11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3dui11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3di11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3dui11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3di11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3dui11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3di11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum3d11ps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h"
 
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2dps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2dps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2dps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef3dps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei3dps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui3dps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2darrayps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2darrayps.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2darrayps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h"
 
 namespace rx
 {
@@ -186,7 +185,7 @@
 
     D3D11_BUFFER_DESC vbDesc;
     vbDesc.ByteWidth = std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex), sizeof(d3d11::PositionTexCoordVertex)) *
-                       6 * renderer->getMaxTextureDepth();
+                       6 * renderer->getRendererCaps().max3DTextureSize;
     vbDesc.Usage = D3D11_USAGE_DYNAMIC;
     vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
     vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
@@ -377,10 +376,12 @@
 
     D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
     source->GetDesc(&sourceSRVDesc);
-    GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceSRVDesc.Format, mRenderer->getCurrentClientVersion());
+
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format);
+    const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat);
 
     GLenum shaderType = GL_NONE;
-    switch (gl::GetComponentType(sourceInternalFormat, mRenderer->getCurrentClientVersion()))
+    switch (sourceFormatInfo.componentType)
     {
       case GL_UNSIGNED_NORMALIZED:
       case GL_SIGNED_NORMALIZED:
@@ -516,11 +517,13 @@
     // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned.
     D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
     source->GetDesc(&sourceSRVDesc);
-    GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceSRVDesc.Format, mRenderer->getCurrentClientVersion());
+
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format);
+    const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat);
 
     BlitParameters parameters = { 0 };
     parameters.mDestinationFormat = destFormat;
-    parameters.mSignedInteger = gl::GetComponentType(sourceInternalFormat, mRenderer->getCurrentClientVersion()) == GL_INT;
+    parameters.mSignedInteger = (internalFormatInfo.componentType == GL_INT);
     parameters.m3DBlit = sourceArea.depth > 1;
 
     BlitShaderMap::const_iterator i = mBlitShaderMap.find(parameters);
@@ -766,18 +769,19 @@
     DXGI_FORMAT format = GetTextureFormat(source);
     ASSERT(format == GetTextureFormat(dest));
 
-    unsigned int pixelSize = d3d11::GetFormatPixelBytes(format);
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
+    unsigned int pixelSize = dxgiFormatInfo.pixelBytes;
     unsigned int copyOffset = 0;
     unsigned int copySize = pixelSize;
     if (stencilOnly)
     {
-        copyOffset = d3d11::GetStencilOffset(format) / 8;
-        copySize = d3d11::GetStencilBits(format) / 8;
+        copyOffset = dxgiFormatInfo.depthBits / 8;
+        copySize = dxgiFormatInfo.stencilBits / 8;
 
         // It would be expensive to have non-byte sized stencil sizes since it would
         // require reading from the destination, currently there aren't any though.
-        ASSERT(d3d11::GetStencilBits(format)   % 8 == 0 &&
-               d3d11::GetStencilOffset(format) % 8 == 0);
+        ASSERT(dxgiFormatInfo.stencilBits % 8 == 0 &&
+               dxgiFormatInfo.depthBits   % 8 == 0);
     }
 
     D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping;
diff --git a/src/libGLESv2/renderer/d3d11/Blit11.h b/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
similarity index 99%
rename from src/libGLESv2/renderer/d3d11/Blit11.h
rename to src/libGLESv2/renderer/d3d/d3d11/Blit11.h
index fba89e2..4e57042 100644
--- a/src/libGLESv2/renderer/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/d3d11/BufferStorage11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
similarity index 61%
rename from src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
index 5109779..43ce5ba 100644
--- a/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
@@ -1,17 +1,15 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 
-// BufferStorage11.cpp Defines the BufferStorage11 class.
+// Buffer11.cpp Defines the Buffer11 class.
 
-#include "libGLESv2/renderer/d3d11/BufferStorage11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
 #include "libGLESv2/main.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
-#include "libGLESv2/Buffer.h"
 
 namespace rx
 {
@@ -69,15 +67,15 @@
 
 }
 
-// Each instance of BufferStorageD3DBuffer11 is specialized for a class of D3D binding points
+// Each instance of Buffer11::BufferStorage11 is specialized for a class of D3D binding points
 // - vertex/transform feedback buffers
 // - index buffers
 // - pixel unpack buffers
 // - uniform buffers
-class BufferStorage11::TypedBufferStorage11
+class Buffer11::BufferStorage11
 {
   public:
-    virtual ~TypedBufferStorage11() {}
+    virtual ~BufferStorage11() {}
 
     DataRevision getDataRevision() const { return mRevision; }
     BufferUsage getUsage() const { return mUsage; }
@@ -86,15 +84,15 @@
 
     void setDataRevision(DataRevision rev) { mRevision = rev; }
 
-    virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
+    virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
                                  size_t size, size_t destOffset) = 0;
     virtual bool resize(size_t size, bool preserveData) = 0;
 
-    virtual void *map(GLbitfield access) = 0;
+    virtual void *map(size_t offset, size_t length, GLbitfield access) = 0;
     virtual void unmap() = 0;
 
   protected:
-    TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage);
+    BufferStorage11(Renderer11 *renderer, BufferUsage usage);
 
     Renderer11 *mRenderer;
     DataRevision mRevision;
@@ -104,7 +102,7 @@
 
 // A native buffer storage represents an underlying D3D11 buffer for a particular
 // type of storage.
-class BufferStorage11::NativeBuffer11 : public BufferStorage11::TypedBufferStorage11
+class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11
 {
   public:
     NativeBuffer11(Renderer11 *renderer, BufferUsage usage);
@@ -112,13 +110,15 @@
 
     ID3D11Buffer *getNativeBuffer() const { return mNativeBuffer; }
 
-    virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
+    virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
                                  size_t size, size_t destOffset);
     virtual bool resize(size_t size, bool preserveData);
 
-    virtual void *map(GLbitfield access);
+    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;
 
@@ -127,20 +127,20 @@
 
 // Pack storage represents internal storage for pack buffers. We implement pack buffers
 // as CPU memory, tied to a staging texture, for asynchronous texture readback.
-class BufferStorage11::PackStorage11 : public BufferStorage11::TypedBufferStorage11
+class Buffer11::PackStorage11 : public Buffer11::BufferStorage11
 {
   public:
     PackStorage11(Renderer11 *renderer);
     ~PackStorage11();
 
-    virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
+    virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
                                  size_t size, size_t destOffset);
     virtual bool resize(size_t size, bool preserveData);
 
-    virtual void *map(GLbitfield access);
+    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:
 
@@ -149,36 +149,53 @@
     ID3D11Texture2D *mStagingTexture;
     DXGI_FORMAT mTextureFormat;
     gl::Extents mTextureSize;
-    std::vector<unsigned char> mMemoryBuffer;
+    MemoryBuffer mMemoryBuffer;
     PackPixelsParams *mQueuedPackCommand;
     PackPixelsParams mPackParams;
     bool mDataModified;
 };
 
-BufferStorage11::BufferStorage11(Renderer11 *renderer)
-    : mRenderer(renderer),
+
+Buffer11::Buffer11(Renderer11 *renderer)
+    : BufferD3D(),
+      mRenderer(renderer),
+      mSize(0),
       mMappedStorage(NULL),
       mResolvedDataRevision(0),
-      mReadUsageCount(0),
-      mSize(0)
-{
-}
+      mReadUsageCount(0)
+{}
 
-BufferStorage11::~BufferStorage11()
+Buffer11::~Buffer11()
 {
-    for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++)
+    for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++)
     {
         SafeDelete(it->second);
     }
 }
 
-BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage)
+Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer)
 {
-    ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage));
-    return static_cast<BufferStorage11*>(bufferStorage);
+    ASSERT(HAS_DYNAMIC_TYPE(Buffer11*, buffer));
+    return static_cast<Buffer11*>(buffer);
 }
 
-void *BufferStorage11::getData()
+gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
+{
+    gl::Error error = setSubData(data, size, 0);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    if (usage == GL_STATIC_DRAW)
+    {
+        initializeStaticData();
+    }
+
+    return error;
+}
+
+void *Buffer11::getData()
 {
     NativeBuffer11 *stagingBuffer = getStagingBuffer();
 
@@ -192,7 +209,10 @@
     {
         if (stagingBuffer->getSize() > mResolvedData.size())
         {
-            mResolvedData.resize(stagingBuffer->getSize());
+            if (!mResolvedData.resize(stagingBuffer->getSize()))
+            {
+                return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+            }
         }
 
         ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -213,22 +233,31 @@
 
     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 BufferStorage11::setData(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);
 
-    if (data)
+    if (data && size > 0)
     {
         NativeBuffer11 *stagingBuffer = getStagingBuffer();
 
         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
@@ -238,89 +267,138 @@
             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 BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset)
+gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
 {
-    BufferStorage11* sourceStorage11 = makeBufferStorage11(sourceStorage);
-    if (sourceStorage11)
+    Buffer11 *sourceBuffer = makeBuffer11(source);
+    ASSERT(sourceBuffer != NULL);
+
+    BufferStorage11 *copyDest = getLatestBufferStorage();
+    if (!copyDest)
     {
-        TypedBufferStorage11 *dest = getLatestStorage();
-        if (!dest)
-        {
-            dest = getStagingBuffer();
-        }
-
-        TypedBufferStorage11 *source = sourceStorage11->getLatestStorage();
-        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 = sourceStorage11->getStagingBuffer();
-            }
-            else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable())
-            {
-                dest = getStagingBuffer();
-            }
-
-            dest->copyFromStorage(source, sourceOffset, size, destOffset);
-            dest->setDataRevision(dest->getDataRevision() + 1);
-        }
-
-        mSize = std::max<size_t>(mSize, destOffset + size);
+        copyDest = getStagingBuffer();
     }
+
+    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);
 }
 
-void BufferStorage11::clear()
+gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
 {
-    mSize = 0;
-    mResolvedDataRevision = 0;
+    ASSERT(!mMappedStorage);
+
+    BufferStorage11 *latestStorage = getLatestBufferStorage();
+    if (latestStorage &&
+        (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
+         latestStorage->getUsage() == BUFFER_USAGE_STAGING))
+    {
+        // Latest storage is mappable.
+        mMappedStorage = latestStorage;
+    }
+    else
+    {
+        // Fall back to using the staging buffer if the latest storage does
+        // not exist or is not CPU-accessible.
+        mMappedStorage = getStagingBuffer();
+    }
+
+    if (!mMappedStorage)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate mappable internal buffer.");
+    }
+
+    if ((access & GL_MAP_WRITE_BIT) > 0)
+    {
+        // Update the data revision immediately, since the data might be changed at any time
+        mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
+    }
+
+    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 BufferStorage11::markTransformFeedbackUsage()
+gl::Error Buffer11::unmap()
 {
-    TypedBufferStorage11 *transformFeedbackStorage = getStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+    ASSERT(mMappedStorage);
+    mMappedStorage->unmap();
+    mMappedStorage = NULL;
+    return gl::Error(GL_NO_ERROR);
+}
+
+void Buffer11::markTransformFeedbackUsage()
+{
+    BufferStorage11 *transformFeedbackStorage = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
 
     if (transformFeedbackStorage)
     {
         transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
     }
+
+    invalidateStaticData();
 }
 
-size_t BufferStorage11::getSize() const
-{
-    return mSize;
-}
-
-bool BufferStorage11::supportsDirectBinding() const
-{
-    return true;
-}
-
-void BufferStorage11::markBufferUsage()
+void Buffer11::markBufferUsage()
 {
     mReadUsageCount++;
 
@@ -333,26 +411,31 @@
     }
 }
 
-ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage)
+Renderer* Buffer11::getRenderer()
+{
+    return mRenderer;
+}
+
+ID3D11Buffer *Buffer11::getBuffer(BufferUsage usage)
 {
     markBufferUsage();
 
-    TypedBufferStorage11 *typedBuffer = getStorage(usage);
+    BufferStorage11 *bufferStorage = getBufferStorage(usage);
 
-    if (!typedBuffer)
+    if (!bufferStorage)
     {
         // Storage out-of-memory
         return NULL;
     }
 
-    ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, typedBuffer));
+    ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, bufferStorage));
 
-    return static_cast<NativeBuffer11*>(typedBuffer)->getNativeBuffer();
+    return static_cast<NativeBuffer11*>(bufferStorage)->getNativeBuffer();
 }
 
-ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
+ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
 {
-    TypedBufferStorage11 *storage = getStorage(BUFFER_USAGE_PIXEL_UNPACK);
+    BufferStorage11 *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK);
 
     if (!storage)
     {
@@ -381,9 +464,11 @@
     ID3D11Device *device = mRenderer->getDevice();
     ID3D11ShaderResourceView *bufferSRV = NULL;
 
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(srvFormat);
+
     D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc;
     bufferSRVDesc.Buffer.ElementOffset = 0;
-    bufferSRVDesc.Buffer.ElementWidth = mSize / d3d11::GetFormatPixelBytes(srvFormat);
+    bufferSRVDesc.Buffer.ElementWidth = mSize / dxgiFormatInfo.pixelBytes;
     bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
     bufferSRVDesc.Format = srvFormat;
 
@@ -396,24 +481,30 @@
     return bufferSRV;
 }
 
-void BufferStorage11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
+gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
 {
     PackStorage11 *packStorage = getPackStorage();
 
-    TypedBufferStorage11 *latestStorage = getLatestStorage();
+    BufferStorage11 *latestStorage = getLatestBufferStorage();
 
     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);
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage usage)
+Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage)
 {
-    TypedBufferStorage11 *directBuffer = NULL;
-    auto directBufferIt = mTypedBuffers.find(usage);
-    if (directBufferIt != mTypedBuffers.end())
+    BufferStorage11 *directBuffer = NULL;
+    auto directBufferIt = mBufferStorages.find(usage);
+    if (directBufferIt != mBufferStorages.end())
     {
         directBuffer = directBufferIt->second;
     }
@@ -430,7 +521,7 @@
             directBuffer = new NativeBuffer11(mRenderer, usage);
         }
 
-        mTypedBuffers.insert(std::make_pair(usage, directBuffer));
+        mBufferStorages.insert(std::make_pair(usage, directBuffer));
     }
 
     // resize buffer
@@ -443,7 +534,7 @@
         }
     }
 
-    TypedBufferStorage11 *latestBuffer = getLatestStorage();
+    BufferStorage11 *latestBuffer = getLatestBufferStorage();
     if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision())
     {
         // if copying from a pack buffer to a non-staging native buffer, we must first
@@ -470,15 +561,15 @@
     return directBuffer;
 }
 
-BufferStorage11::TypedBufferStorage11 *BufferStorage11::getLatestStorage() const
+Buffer11::BufferStorage11 *Buffer11::getLatestBufferStorage() const
 {
     // Even though we iterate over all the direct buffers, it is expected that only
     // 1 or 2 will be present.
-    TypedBufferStorage11 *latestStorage = NULL;
+    BufferStorage11 *latestStorage = NULL;
     DataRevision latestRevision = 0;
-    for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++)
+    for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++)
     {
-        TypedBufferStorage11 *storage = it->second;
+        BufferStorage11 *storage = it->second;
         if (!latestStorage || storage->getDataRevision() > latestRevision)
         {
             latestStorage = storage;
@@ -489,47 +580,9 @@
     return latestStorage;
 }
 
-bool BufferStorage11::isMapped() const
+Buffer11::NativeBuffer11 *Buffer11::getStagingBuffer()
 {
-    return mMappedStorage != NULL;
-}
-
-void *BufferStorage11::map(GLbitfield access)
-{
-    ASSERT(!mMappedStorage);
-
-    TypedBufferStorage11 *latestStorage = getLatestStorage();
-    ASSERT(latestStorage);
-
-    if (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
-        latestStorage->getUsage() == BUFFER_USAGE_STAGING)
-    {
-        mMappedStorage = latestStorage;
-    }
-    else
-    {
-        mMappedStorage = getStagingBuffer();
-    }
-
-    if (!mMappedStorage)
-    {
-        // Out-of-memory
-        return NULL;
-    }
-
-    return mMappedStorage->map(access);
-}
-
-void BufferStorage11::unmap()
-{
-    ASSERT(mMappedStorage);
-    mMappedStorage->unmap();
-    mMappedStorage = NULL;
-}
-
-BufferStorage11::NativeBuffer11 *BufferStorage11::getStagingBuffer()
-{
-    TypedBufferStorage11 *stagingStorage = getStorage(BUFFER_USAGE_STAGING);
+    BufferStorage11 *stagingStorage = getBufferStorage(BUFFER_USAGE_STAGING);
 
     if (!stagingStorage)
     {
@@ -541,9 +594,9 @@
     return static_cast<NativeBuffer11*>(stagingStorage);
 }
 
-BufferStorage11::PackStorage11 *BufferStorage11::getPackStorage()
+Buffer11::PackStorage11 *Buffer11::getPackStorage()
 {
-    TypedBufferStorage11 *packStorage = getStorage(BUFFER_USAGE_PIXEL_PACK);
+    BufferStorage11 *packStorage = getBufferStorage(BUFFER_USAGE_PIXEL_PACK);
 
     if (!packStorage)
     {
@@ -555,7 +608,15 @@
     return static_cast<PackStorage11*>(packStorage);
 }
 
-BufferStorage11::TypedBufferStorage11::TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage)
+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),
       mRevision(0),
@@ -563,20 +624,20 @@
 {
 }
 
-BufferStorage11::NativeBuffer11::NativeBuffer11(Renderer11 *renderer, BufferUsage usage)
-    : TypedBufferStorage11(renderer, usage),
+Buffer11::NativeBuffer11::NativeBuffer11(Renderer11 *renderer, BufferUsage usage)
+    : BufferStorage11(renderer, usage),
       mNativeBuffer(NULL)
 {
 }
 
-BufferStorage11::NativeBuffer11::~NativeBuffer11()
+Buffer11::NativeBuffer11::~NativeBuffer11()
 {
     SafeRelease(mNativeBuffer);
 }
 
 // Returns true if it recreates the direct buffer
-bool BufferStorage11::NativeBuffer11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
-                                                      size_t size, size_t destOffset)
+bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
+                                               size_t size, size_t destOffset)
 {
     ID3D11DeviceContext *context = mRenderer->getDeviceContext();
 
@@ -594,7 +655,7 @@
     {
         ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, source));
 
-        unsigned char *sourcePointer = static_cast<unsigned char *>(source->map(GL_MAP_READ_BIT)) + sourceOffset;
+        void *sourcePointer = source->map(sourceOffset, size, GL_MAP_READ_BIT);
 
         D3D11_MAPPED_SUBRESOURCE mappedResource;
         HRESULT hr = context->Map(mNativeBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
@@ -628,7 +689,7 @@
     return createBuffer;
 }
 
-bool BufferStorage11::NativeBuffer11::resize(size_t size, bool preserveData)
+bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
 {
     ID3D11Device *device = mRenderer->getDevice();
     ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -669,7 +730,7 @@
     return true;
 }
 
-void BufferStorage11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer,
+void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer,
                                                      BufferUsage usage, unsigned int bufferSize)
 {
     bufferDesc->ByteWidth = bufferSize;
@@ -710,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:
@@ -718,7 +779,7 @@
     }
 }
 
-void *BufferStorage11::NativeBuffer11::map(GLbitfield access)
+void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield access)
 {
     ASSERT(mUsage == BUFFER_USAGE_STAGING);
 
@@ -731,18 +792,37 @@
     UNUSED_ASSERTION_VARIABLE(result);
     ASSERT(SUCCEEDED(result));
 
-    return mappedResource.pData;
+    return static_cast<GLubyte*>(mappedResource.pData) + offset;
 }
 
-void BufferStorage11::NativeBuffer11::unmap()
+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);
     ID3D11DeviceContext *context = mRenderer->getDeviceContext();
     context->Unmap(mNativeBuffer, 0);
 }
 
-BufferStorage11::PackStorage11::PackStorage11(Renderer11 *renderer)
-    : TypedBufferStorage11(renderer, BUFFER_USAGE_PIXEL_PACK),
+Buffer11::PackStorage11::PackStorage11(Renderer11 *renderer)
+    : BufferStorage11(renderer, BUFFER_USAGE_PIXEL_PACK),
       mStagingTexture(NULL),
       mTextureFormat(DXGI_FORMAT_UNKNOWN),
       mQueuedPackCommand(NULL),
@@ -750,32 +830,38 @@
 {
 }
 
-BufferStorage11::PackStorage11::~PackStorage11()
+Buffer11::PackStorage11::~PackStorage11()
 {
     SafeRelease(mStagingTexture);
     SafeDelete(mQueuedPackCommand);
 }
 
-bool BufferStorage11::PackStorage11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
-                                                     size_t size, size_t destOffset)
+bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
+                                              size_t size, size_t destOffset)
 {
-    UNIMPLEMENTED();
+    // We copy through a staging buffer when drawing with a pack buffer,
+    // or for other cases where we access the pack buffer
+    UNREACHABLE();
     return false;
 }
 
-bool BufferStorage11::PackStorage11::resize(size_t size, bool preserveData)
+bool Buffer11::PackStorage11::resize(size_t size, bool preserveData)
 {
     if (size != mBufferSize)
     {
-        mMemoryBuffer.resize(size, 0);
+        if (!mMemoryBuffer.resize(size))
+        {
+            return false;
+        }
         mBufferSize = size;
     }
 
     return true;
 }
 
-void *BufferStorage11::PackStorage11::map(GLbitfield access)
+void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield access)
 {
+    ASSERT(offset + length <= getSize());
     // TODO: fast path
     //  We might be able to optimize out one or more memcpy calls by detecting when
     //  and if D3D packs the staging texture memory identically to how we would fill
@@ -784,15 +870,15 @@
     flushQueuedPackCommand();
     mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
 
-    return &mMemoryBuffer[0];
+    return mMemoryBuffer.data() + offset;
 }
 
-void BufferStorage11::PackStorage11::unmap()
+void Buffer11::PackStorage11::unmap()
 {
     // No-op
 }
 
-void BufferStorage11::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);
@@ -834,13 +920,15 @@
         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.");
+        }
     }
 
-    if (textureDesc.SampleDesc.Count > 1)
-    {
-        UNIMPLEMENTED();
-    }
+    // ReadPixels from multisampled FBOs isn't supported in current GL
+    ASSERT(textureDesc.SampleDesc.Count <= 1);
 
     ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
     D3D11_BOX srcBox;
@@ -853,15 +941,17 @@
 
     // Asynchronous copy
     immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-void BufferStorage11::PackStorage11::flushQueuedPackCommand()
+void Buffer11::PackStorage11::flushQueuedPackCommand()
 {
-    ASSERT(!mMemoryBuffer.empty());
+    ASSERT(mMemoryBuffer.size() > 0);
 
     if (mQueuedPackCommand)
     {
-        mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, &mMemoryBuffer[0]);
+        mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data());
         SafeDelete(mQueuedPackCommand);
     }
 }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
new file mode 100644
index 0000000..5f24fb4
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
@@ -0,0 +1,105 @@
+//
+// 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.
+//
+
+// Buffer11.h: Defines the rx::Buffer11 class which implements rx::BufferImpl via rx::BufferD3D.
+
+#ifndef LIBGLESV2_RENDERER_BUFFER11_H_
+#define LIBGLESV2_RENDERER_BUFFER11_H_
+
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
+#include "libGLESv2/angletypes.h"
+
+namespace rx
+{
+class Renderer11;
+
+enum BufferUsage
+{
+    BUFFER_USAGE_STAGING,
+    BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
+    BUFFER_USAGE_INDEX,
+    BUFFER_USAGE_PIXEL_UNPACK,
+    BUFFER_USAGE_PIXEL_PACK,
+    BUFFER_USAGE_UNIFORM,
+};
+
+struct PackPixelsParams
+{
+    PackPixelsParams();
+    PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch,
+                     const gl::PixelPackState &pack, ptrdiff_t offset);
+
+    gl::Rectangle area;
+    GLenum format;
+    GLenum type;
+    GLuint outputPitch;
+    gl::Buffer *packBuffer;
+    gl::PixelPackState pack;
+    ptrdiff_t offset;
+};
+
+typedef size_t DataRevision;
+
+class Buffer11 : public BufferD3D
+{
+  public:
+    Buffer11(rx::Renderer11 *renderer);
+    virtual ~Buffer11();
+
+    static Buffer11 *makeBuffer11(BufferImpl *buffer);
+
+    ID3D11Buffer *getBuffer(BufferUsage usage);
+    ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
+    bool isMapped() const { return mMappedStorage != NULL; }
+    gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
+
+    // BufferD3D implementation
+    virtual size_t getSize() const { return mSize; }
+    virtual bool supportsDirectBinding() const;
+    virtual Renderer* getRenderer();
+
+    // BufferImpl implementation
+    virtual gl::Error setData(const void* data, size_t size, GLenum usage);
+    virtual void *getData();
+    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:
+    DISALLOW_COPY_AND_ASSIGN(Buffer11);
+
+    class BufferStorage11;
+    class NativeBuffer11;
+    class PackStorage11;
+
+    rx::Renderer11 *mRenderer;
+    size_t mSize;
+
+    BufferStorage11 *mMappedStorage;
+
+    std::map<BufferUsage, BufferStorage11*> mBufferStorages;
+
+    typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
+    std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
+
+    MemoryBuffer mResolvedData;
+    DataRevision mResolvedDataRevision;
+    unsigned int mReadUsageCount;
+
+    void markBufferUsage();
+    NativeBuffer11 *getStagingBuffer();
+    PackStorage11 *getPackStorage();
+
+    BufferStorage11 *getBufferStorage(BufferUsage usage);
+    BufferStorage11 *getLatestBufferStorage() const;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFER11_H_
diff --git a/src/libGLESv2/renderer/d3d11/Clear11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
similarity index 78%
rename from src/libGLESv2/renderer/d3d11/Clear11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
index bb73241..c60b7a6 100644
--- a/src/libGLESv2/renderer/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
@@ -7,23 +6,23 @@
 
 // Clear11.cpp: Framebuffer clear utility class.
 
-#include "libGLESv2/renderer/d3d11/Clear11.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d11/RenderTarget11.h"
-
+#include "libGLESv2/renderer/d3d/d3d11/Clear11.h"
+#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/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
-#include "libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11vs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11ps.h"
+// Precompiled shaders
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h"
 
-#include "libGLESv2/renderer/d3d11/shaders/compiled/clearuint11vs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/clearuint11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h"
 
-#include "libGLESv2/renderer/d3d11/shaders/compiled/clearsint11vs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/clearsint11ps.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h"
 
 namespace rx
 {
@@ -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,16 +192,14 @@
                                        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 ||
                                                              clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
                                                              clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height);
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-    std::vector<RenderTarget11*> maskedClearRenderTargets;
+    std::vector<MaskedRenderTarget> maskedClearRenderTargets;
     RenderTarget11* maskedClearDepthStencil = NULL;
 
     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -214,44 +211,45 @@
             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.");
                 }
 
-                GLenum internalFormat = attachment->getInternalFormat();
-                GLenum actualFormat = attachment->getActualFormat();
-                GLenum componentType = gl::GetComponentType(internalFormat, clientVersion);
+                const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
+
                 if (clearParams.colorClearType == GL_FLOAT &&
-                    !(componentType == GL_FLOAT || componentType == GL_UNSIGNED_NORMALIZED || componentType == GL_SIGNED_NORMALIZED))
+                    !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED))
                 {
                     ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-"
-                        "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment, internalFormat);
+                        "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment,
+                        attachment->getInternalFormat());
                 }
 
-                GLuint internalRedBits = gl::GetRedBits(internalFormat, clientVersion);
-                GLuint internalGreenBits = gl::GetGreenBits(internalFormat, clientVersion);
-                GLuint internalBlueBits = gl::GetBlueBits(internalFormat, clientVersion);
-                GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat, clientVersion);
-
-                if ((internalRedBits   == 0 || !clearParams.colorMaskRed) &&
-                    (internalGreenBits == 0 || !clearParams.colorMaskGreen) &&
-                    (internalBlueBits  == 0 || !clearParams.colorMaskBlue) &&
-                    (internalAlphaBits == 0 || !clearParams.colorMaskAlpha))
+                if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) &&
+                    (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) &&
+                    (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) &&
+                    (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha))
                 {
                     // Every channel either does not exist in the render target or is masked out
                     continue;
                 }
                 else if (needScissoredClear || clearParams.colorClearType != GL_FLOAT ||
-                         (internalRedBits   > 0 && !clearParams.colorMaskRed)   ||
-                         (internalGreenBits > 0 && !clearParams.colorMaskGreen) ||
-                         (internalBlueBits  > 0 && !clearParams.colorMaskBlue)  ||
-                         (internalAlphaBits > 0 && !clearParams.colorMaskAlpha))
+                         (formatInfo.redBits   > 0 && !clearParams.colorMaskRed)   ||
+                         (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) ||
+                         (formatInfo.blueBits  > 0 && !clearParams.colorMaskBlue) ||
+                         (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha))
                 {
                     // A scissored or masked clear is required
-                    maskedClearRenderTargets.push_back(renderTarget);
+                    MaskedRenderTarget maskAndRt;
+                    bool clearColor = clearParams.clearColor[colorAttachment];
+                    maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed);
+                    maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen);
+                    maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue);
+                    maskAndRt.colorMask[3] = (clearColor && clearParams.colorMaskAlpha);
+                    maskAndRt.renderTarget = renderTarget;
+                    maskedClearRenderTargets.push_back(maskAndRt);
                 }
                 else
                 {
@@ -260,23 +258,19 @@
                     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());
+
                     // Check if the actual format has a channel that the internal format does not and set them to the
                     // default values
-                    GLuint actualRedBits   = gl::GetRedBits(actualFormat, clientVersion);
-                    GLuint actualGreenBits = gl::GetGreenBits(actualFormat, clientVersion);
-                    GLuint actualBlueBits  = gl::GetBlueBits(actualFormat, clientVersion);
-                    GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat, clientVersion);
-
                     const float clearValues[4] =
                     {
-                        ((internalRedBits   == 0 && actualRedBits   > 0) ? 0.0f : clearParams.colorFClearValue.red),
-                        ((internalGreenBits == 0 && actualGreenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
-                        ((internalBlueBits  == 0 && actualBlueBits  > 0) ? 0.0f : clearParams.colorFClearValue.blue),
-                        ((internalAlphaBits == 0 && actualAlphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
+                        ((formatInfo.redBits == 0 && actualFormatInfo.redBits   > 0) ? 0.0f : clearParams.colorFClearValue.red),
+                        ((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
+                        ((formatInfo.blueBits == 0 && actualFormatInfo.blueBits  > 0) ? 0.0f : clearParams.colorFClearValue.blue),
+                        ((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
                     };
 
                     deviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
@@ -290,16 +284,15 @@
         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.");
             }
 
-            GLenum actualFormat = attachment->getActualFormat();
+            const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
 
-            unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << gl::GetStencilBits(actualFormat, clientVersion)) - 1 : 0;
+            unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << actualFormatInfo.stencilBits) - 1 : 0;
             bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
 
             if (needScissoredClear || needMaskedStencilClear)
@@ -311,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) |
@@ -351,22 +343,22 @@
         // be a compatible clear type.
 
         // Bind all the render targets which need clearing
-        ASSERT(maskedClearRenderTargets.size() <= mRenderer->getMaxRenderTargets());
+        ASSERT(maskedClearRenderTargets.size() <= mRenderer->getRendererCaps().maxDrawBuffers);
         std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size());
         for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++)
         {
-            ID3D11RenderTargetView *renderTarget = maskedClearRenderTargets[i]->getRenderTargetView();
-            if (!renderTarget)
+            RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget;
+            ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView();
+            if (!rtv)
             {
-                ERR("Render target pointer unexpectedly null.");
-                return;
+                return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
             }
 
-            rtvs[i] = renderTarget;
+            rtvs[i] = rtv;
         }
         ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL;
 
-        ID3D11BlendState *blendState = getBlendState(clearParams, maskedClearRenderTargets);
+        ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets);
         const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
         const UINT sampleMask = 0xFFFFFFFF;
 
@@ -381,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;
@@ -447,23 +438,24 @@
         // Clean up
         mRenderer->markAllStateDirty();
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
-ID3D11BlendState *Clear11::getBlendState(const gl::ClearParameters &clearParams, const std::vector<RenderTarget11*>& rts)
+ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts)
 {
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
     ClearBlendInfo blendKey = { 0 };
     for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
     {
         if (i < rts.size())
         {
-            GLint internalFormat = rts[i]->getInternalFormat();
+            RenderTarget11 *rt = rts[i].renderTarget;
+            const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(rt->getInternalFormat());
 
-            blendKey.maskChannels[i][0] = clearParams.clearColor ? (clearParams.colorMaskRed   && gl::GetRedBits(internalFormat, clientVersion)   > 0) : false;
-            blendKey.maskChannels[i][1] = clearParams.clearColor ? (clearParams.colorMaskGreen && gl::GetGreenBits(internalFormat, clientVersion) > 0) : false;
-            blendKey.maskChannels[i][2] = clearParams.clearColor ? (clearParams.colorMaskBlue  && gl::GetBlueBits(internalFormat, clientVersion)  > 0) : false;
-            blendKey.maskChannels[i][3] = clearParams.clearColor ? (clearParams.colorMaskAlpha && gl::GetAlphaBits(internalFormat, clientVersion) > 0) : false;
+            blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && formatInfo.redBits   > 0);
+            blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && formatInfo.greenBits > 0);
+            blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && formatInfo.blueBits  > 0);
+            blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && formatInfo.alphaBits > 0);
         }
         else
         {
diff --git a/src/libGLESv2/renderer/d3d11/Clear11.h b/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
similarity index 85%
rename from src/libGLESv2/renderer/d3d11/Clear11.h
rename to src/libGLESv2/renderer/d3d/d3d11/Clear11.h
index e8e4c9e..be8e187 100644
--- a/src/libGLESv2/renderer/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;
@@ -41,7 +45,13 @@
     typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap;
     ClearBlendStateMap mClearBlendStates;
 
-    ID3D11BlendState *getBlendState(const gl::ClearParameters &clearParams, const std::vector<RenderTarget11*>& rts);
+    struct MaskedRenderTarget
+    {
+        bool colorMask[4];
+        RenderTarget11 *renderTarget;
+    };
+
+    ID3D11BlendState *getBlendState(const std::vector<MaskedRenderTarget> &rts);
 
     struct ClearShader
     {
diff --git a/src/libGLESv2/renderer/d3d11/Fence11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
similarity index 91%
rename from src/libGLESv2/renderer/d3d11/Fence11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
index f2a7543..a841b52 100644
--- a/src/libGLESv2/renderer/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
@@ -7,9 +6,9 @@
 
 // Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl.
 
-#include "libGLESv2/renderer/d3d11/Fence11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Fence11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/main.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
 
 namespace rx
 {
diff --git a/src/libGLESv2/renderer/d3d11/Fence11.h b/src/libGLESv2/renderer/d3d/d3d11/Fence11.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/Fence11.h
rename to src/libGLESv2/renderer/d3d/d3d11/Fence11.h
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
new file mode 100644
index 0000000..7536713
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
@@ -0,0 +1,569 @@
+//
+// 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
+// found in the LICENSE file.
+//
+
+// Image11.h: Implements the rx::Image11 class, which acts as the interface to
+// the actual underlying resources of a Texture
+
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
+#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.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
+{
+
+Image11::Image11()
+{
+    mStagingTexture = NULL;
+    mRenderer = NULL;
+    mDXGIFormat = DXGI_FORMAT_UNKNOWN;
+    mRecoverFromStorage = false;
+    mAssociatedStorage = NULL;
+    mAssociatedStorageLevel = 0;
+    mAssociatedStorageLayerTarget = 0;
+    mRecoveredFromStorageCount = 0;
+}
+
+Image11::~Image11()
+{
+    disassociateStorage();
+    releaseStagingTexture();
+}
+
+Image11 *Image11::makeImage11(Image *img)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
+    return static_cast<rx::Image11*>(img);
+}
+
+void Image11::generateMipmap(Image11 *dest, Image11 *src)
+{
+    ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
+    ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
+    ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight());
+
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(src->getDXGIFormat());
+    ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL);
+
+    D3D11_MAPPED_SUBRESOURCE destMapped;
+    HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped);
+    if (FAILED(destMapResult))
+    {
+        ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult);
+        return;
+    }
+
+    D3D11_MAPPED_SUBRESOURCE srcMapped;
+    HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped);
+    if (FAILED(srcMapResult))
+    {
+        ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult);
+
+        dest->unmap();
+        return;
+    }
+
+    const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData);
+    uint8_t *destData = reinterpret_cast<uint8_t*>(destMapped.pData);
+
+    dxgiFormatInfo.mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(),
+                                         sourceData, srcMapped.RowPitch, srcMapped.DepthPitch,
+                                         destData, destMapped.RowPitch, destMapped.DepthPitch);
+
+    dest->unmap();
+    src->unmap();
+
+    dest->markDirty();
+}
+
+bool Image11::isDirty() const
+{
+    // If mDirty is true
+    // AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be recovered from TextureStorage
+    // AND the texture doesn't require init data (i.e. a blank new texture will suffice)
+    // then isDirty should still return false.
+    if (mDirty && !mStagingTexture && !mRecoverFromStorage && !(d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL))
+    {
+        return false;
+    }
+
+    return mDirty;
+}
+
+bool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
+    return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, 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);
+    return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height);
+}
+
+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);
+    return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, 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);
+    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)
+{
+    if (mWidth != width ||
+        mHeight != height ||
+        mInternalFormat != internalformat ||
+        forceRelease)
+    {
+        // End the association with the TextureStorage, since that data will be out of date.
+        // Also reset mRecoveredFromStorageCount since this Image is getting completely redefined.
+        disassociateStorage();
+        mRecoveredFromStorageCount = 0;
+
+        mRenderer = Renderer11::makeRenderer11(renderer);
+
+        mWidth = width;
+        mHeight = height;
+        mDepth = depth;
+        mInternalFormat = internalformat;
+        mTarget = target;
+
+        // compute the d3d format that will be used
+        const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+        const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
+        mDXGIFormat = formatInfo.texFormat;
+        mActualFormat = dxgiFormatInfo.internalFormat;
+        mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
+
+        SafeRelease(mStagingTexture);
+        mDirty = (formatInfo.dataInitializerFunction != NULL);
+
+        return true;
+    }
+
+    return false;
+}
+
+DXGI_FORMAT Image11::getDXGIFormat() const
+{
+    // this should only happen if the image hasn't been redefined first
+    // which would be a bug by the caller
+    ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN);
+
+    return mDXGIFormat;
+}
+
+// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
+// into the target pixel rectangle.
+void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+                       GLint unpackAlignment, GLenum type, const void *input)
+{
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
+    GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
+    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpackAlignment);
+
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
+    GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
+
+    const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat);
+    LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type);
+
+    D3D11_MAPPED_SUBRESOURCE mappedImage;
+    HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
+    if (FAILED(result))
+    {
+        ERR("Could not map image for loading.");
+        return;
+    }
+
+    uint8_t* offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch));
+    loadFunction(width, height, depth,
+                 reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
+                 offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
+
+    unmap();
+}
+
+void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+                                 const void *input)
+{
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
+    GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
+    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
+
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
+    GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
+    GLuint outputBlockWidth = dxgiFormatInfo.blockWidth;
+    GLuint outputBlockHeight = dxgiFormatInfo.blockHeight;
+
+    ASSERT(xoffset % outputBlockWidth == 0);
+    ASSERT(yoffset % outputBlockHeight == 0);
+
+    const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat);
+    LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE);
+
+    D3D11_MAPPED_SUBRESOURCE mappedImage;
+    HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
+    if (FAILED(result))
+    {
+        ERR("Could not map image for loading.");
+        return;
+    }
+
+    uint8_t* offsetMappedData = reinterpret_cast<uint8_t*>(mappedImage.pData) + ((yoffset / outputBlockHeight) * mappedImage.RowPitch +
+                                                                           (xoffset / outputBlockWidth) * outputPixelSize +
+                                                                           zoffset * mappedImage.DepthPitch);
+
+    loadFunction(width, height, depth,
+                 reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
+                 offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
+
+    unmap();
+}
+
+void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
+
+    if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat)
+    {
+        // No conversion needed-- use copyback fastpath
+        ID3D11Texture2D *colorBufferTexture = NULL;
+        unsigned int subresourceIndex = 0;
+
+        if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
+        {
+            D3D11_TEXTURE2D_DESC textureDesc;
+            colorBufferTexture->GetDesc(&textureDesc);
+
+            ID3D11Device *device = mRenderer->getDevice();
+            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+            ID3D11Texture2D* srcTex = NULL;
+            if (textureDesc.SampleDesc.Count > 1)
+            {
+                D3D11_TEXTURE2D_DESC resolveDesc;
+                resolveDesc.Width = textureDesc.Width;
+                resolveDesc.Height = textureDesc.Height;
+                resolveDesc.MipLevels = 1;
+                resolveDesc.ArraySize = 1;
+                resolveDesc.Format = textureDesc.Format;
+                resolveDesc.SampleDesc.Count = 1;
+                resolveDesc.SampleDesc.Quality = 0;
+                resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+                resolveDesc.BindFlags = 0;
+                resolveDesc.CPUAccessFlags = 0;
+                resolveDesc.MiscFlags = 0;
+
+                HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
+                if (FAILED(result))
+                {
+                    ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
+                    return;
+                }
+
+                deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
+                subresourceIndex = 0;
+            }
+            else
+            {
+                srcTex = colorBufferTexture;
+                srcTex->AddRef();
+            }
+
+            D3D11_BOX srcBox;
+            srcBox.left = x;
+            srcBox.right = x + width;
+            srcBox.top = y;
+            srcBox.bottom = y + height;
+            srcBox.front = 0;
+            srcBox.back = 1;
+
+            deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox);
+
+            SafeRelease(srcTex);
+            SafeRelease(colorBufferTexture);
+        }
+    }
+    else
+    {
+        // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
+        D3D11_MAPPED_SUBRESOURCE mappedImage;
+        HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
+        if (FAILED(result))
+        {
+            ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result);
+            return;
+        }
+
+        // determine the offset coordinate into the destination buffer
+        GLsizei rowOffset = gl::GetInternalFormatInfo(mActualFormat).pixelBytes * xoffset;
+        uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch;
+
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
+
+        mRenderer->readPixels(source, x, y, width, height, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
+
+        unmap();
+    }
+}
+
+ID3D11Resource *Image11::getStagingTexture()
+{
+    createStagingTexture();
+
+    return mStagingTexture;
+}
+
+void Image11::releaseStagingTexture()
+{
+    SafeRelease(mStagingTexture);
+}
+
+unsigned int Image11::getStagingSubresource()
+{
+    createStagingTexture();
+
+    return mStagingSubresource;
+}
+
+void Image11::createStagingTexture()
+{
+    if (mStagingTexture)
+    {
+        return;
+    }
+
+    const DXGI_FORMAT dxgiFormat = getDXGIFormat();
+
+    if (mWidth > 0 && mHeight > 0 && mDepth > 0)
+    {
+        ID3D11Device *device = mRenderer->getDevice();
+        HRESULT result;
+
+        int lodOffset = 1;
+        GLsizei width = mWidth;
+        GLsizei height = mHeight;
+
+        // adjust size if needed for compressed textures
+        d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
+
+        if (mTarget == GL_TEXTURE_3D)
+        {
+            ID3D11Texture3D *newTexture = NULL;
+
+            D3D11_TEXTURE3D_DESC desc;
+            desc.Width = width;
+            desc.Height = height;
+            desc.Depth = mDepth;
+            desc.MipLevels = lodOffset + 1;
+            desc.Format = dxgiFormat;
+            desc.Usage = D3D11_USAGE_STAGING;
+            desc.BindFlags = 0;
+            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+            desc.MiscFlags = 0;
+
+            if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
+            {
+                std::vector<D3D11_SUBRESOURCE_DATA> initialData;
+                std::vector< std::vector<BYTE> > textureData;
+                d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
+                                                  lodOffset + 1, &initialData, &textureData);
+
+                result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
+            }
+            else
+            {
+                result = device->CreateTexture3D(&desc, NULL, &newTexture);
+            }
+
+            if (FAILED(result))
+            {
+                ASSERT(result == E_OUTOFMEMORY);
+                ERR("Creating image failed.");
+                return gl::error(GL_OUT_OF_MEMORY);
+            }
+
+            mStagingTexture = newTexture;
+            mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+        }
+        else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
+        {
+            ID3D11Texture2D *newTexture = NULL;
+
+            D3D11_TEXTURE2D_DESC desc;
+            desc.Width = width;
+            desc.Height = height;
+            desc.MipLevels = lodOffset + 1;
+            desc.ArraySize = 1;
+            desc.Format = dxgiFormat;
+            desc.SampleDesc.Count = 1;
+            desc.SampleDesc.Quality = 0;
+            desc.Usage = D3D11_USAGE_STAGING;
+            desc.BindFlags = 0;
+            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+            desc.MiscFlags = 0;
+
+            if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
+            {
+                std::vector<D3D11_SUBRESOURCE_DATA> initialData;
+                std::vector< std::vector<BYTE> > textureData;
+                d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
+                                                  lodOffset + 1, &initialData, &textureData);
+
+                result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
+            }
+            else
+            {
+                result = device->CreateTexture2D(&desc, NULL, &newTexture);
+            }
+
+            if (FAILED(result))
+            {
+                ASSERT(result == E_OUTOFMEMORY);
+                ERR("Creating image failed.");
+                return gl::error(GL_OUT_OF_MEMORY);
+            }
+
+            mStagingTexture = newTexture;
+            mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+        }
+        else
+        {
+            UNREACHABLE();
+        }
+    }
+
+    mDirty = false;
+}
+
+HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
+{
+    createStagingTexture();
+
+    // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
+    recoverFromAssociatedStorage();
+
+    HRESULT result = E_FAIL;
+
+    if (mStagingTexture)
+    {
+        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+        result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map);
+
+        // this can fail if the device is removed (from TDR)
+        if (d3d11::isDeviceLostError(result))
+        {
+            mRenderer->notifyDeviceLost();
+        }
+        else if (SUCCEEDED(result))
+        {
+            mDirty = true;
+        }
+    }
+
+    return result;
+}
+
+void Image11::unmap()
+{
+    if (mStagingTexture)
+    {
+        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+        deviceContext->Unmap(mStagingTexture, mStagingSubresource);
+    }
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Image11.h b/src/libGLESv2/renderer/d3d/d3d11/Image11.h
new file mode 100644
index 0000000..a76a61f
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/Image11.h
@@ -0,0 +1,89 @@
+//
+// 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
+// found in the LICENSE file.
+//
+
+// Image11.h: Defines the rx::Image11 class, which acts as the interface to
+// the actual underlying resources of a Texture
+
+#ifndef LIBGLESV2_RENDERER_IMAGE11_H_
+#define LIBGLESV2_RENDERER_IMAGE11_H_
+
+#include "libGLESv2/renderer/d3d/ImageD3D.h"
+
+#include "common/debug.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class Renderer;
+class Renderer11;
+class TextureStorage11;
+
+class Image11 : public ImageD3D
+{
+  public:
+    Image11();
+    virtual ~Image11();
+
+    static Image11 *makeImage11(Image *img);
+
+    static void generateMipmap(Image11 *dest, Image11 *src);
+
+    virtual bool isDirty() const;
+
+    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);
+
+    DXGI_FORMAT getDXGIFormat() const;
+    
+    virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+                          GLint unpackAlignment, GLenum type, const void *input);
+    virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+                                    const void *input);
+
+    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();
+
+  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;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_IMAGE11_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp
new file mode 100644
index 0000000..9a61182
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp
@@ -0,0 +1,162 @@
+//
+// 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
+// found in the LICENSE file.
+//
+
+// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
+
+#include "libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+
+namespace rx
+{
+
+IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
+{
+    mBuffer = NULL;
+    mBufferSize = 0;
+    mDynamicUsage = false;
+}
+
+IndexBuffer11::~IndexBuffer11()
+{
+    SafeRelease(mBuffer);
+}
+
+gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+{
+    SafeRelease(mBuffer);
+
+    updateSerial();
+
+    if (bufferSize > 0)
+    {
+        ID3D11Device* dxDevice = mRenderer->getDevice();
+
+        D3D11_BUFFER_DESC bufferDesc;
+        bufferDesc.ByteWidth = bufferSize;
+        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+        bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        bufferDesc.MiscFlags = 0;
+        bufferDesc.StructureByteStride = 0;
+
+        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+        if (FAILED(result))
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
+        }
+    }
+
+    mBufferSize = bufferSize;
+    mIndexType = indexType;
+    mDynamicUsage = dynamic;
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer));
+    return static_cast<IndexBuffer11*>(indexBuffer);
+}
+
+gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+{
+    if (!mBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
+    }
+
+    // Check for integer overflows and out-out-bounds map requests
+    if (offset + size < offset || offset + size > mBufferSize)
+    {
+        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);
+}
+
+gl::Error IndexBuffer11::unmapBuffer()
+{
+    if (!mBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
+    }
+
+    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+    dxContext->Unmap(mBuffer, 0);
+    return gl::Error(GL_NO_ERROR);
+}
+
+GLenum IndexBuffer11::getIndexType() const
+{
+    return mIndexType;
+}
+
+unsigned int IndexBuffer11::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+gl::Error IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
+{
+    if (bufferSize > mBufferSize || indexType != mIndexType)
+    {
+        return initialize(bufferSize, indexType, mDynamicUsage);
+    }
+    else
+    {
+        return gl::Error(GL_NO_ERROR);
+    }
+}
+
+gl::Error IndexBuffer11::discard()
+{
+    if (!mBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
+    }
+
+    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+    if (FAILED(result))
+    {
+        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
+{
+    switch (mIndexType)
+    {
+      case GL_UNSIGNED_BYTE:    return DXGI_FORMAT_R16_UINT;
+      case GL_UNSIGNED_SHORT:   return DXGI_FORMAT_R16_UINT;
+      case GL_UNSIGNED_INT:     return DXGI_FORMAT_R32_UINT;
+      default: UNREACHABLE();   return DXGI_FORMAT_UNKNOWN;
+    }
+}
+
+ID3D11Buffer *IndexBuffer11::getBuffer() const
+{
+    return mBuffer;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d11/IndexBuffer11.h b/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
similarity index 72%
rename from src/libGLESv2/renderer/d3d11/IndexBuffer11.h
rename to src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
index 39a6194..f7c2b38 100644
--- a/src/libGLESv2/renderer/d3d11/IndexBuffer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
@@ -9,7 +9,7 @@
 #ifndef LIBGLESV2_RENDERER_INDEXBUFFER11_H_
 #define LIBGLESV2_RENDERER_INDEXBUFFER11_H_
 
-#include "libGLESv2/renderer/IndexBuffer.h"
+#include "libGLESv2/renderer/d3d/IndexBuffer.h"
 
 namespace rx
 {
@@ -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/d3d11/InputLayoutCache.cpp b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
similarity index 87%
rename from src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
index 7092dc5..b006c04 100644
--- a/src/libGLESv2/renderer/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
@@ -8,14 +7,14 @@
 // InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches
 // D3D11 input layouts.
 
-#include "libGLESv2/renderer/d3d11/InputLayoutCache.h"
-#include "libGLESv2/renderer/d3d11/VertexBuffer11.h"
-#include "libGLESv2/renderer/d3d11/BufferStorage11.h"
-#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h"
+#include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h"
+#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/VertexDataManager.h"
-#include "libGLESv2/renderer/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 };
@@ -109,7 +107,7 @@
             D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
 
             gl::VertexFormat vertexFormat(*attributes[i].attribute, attributes[i].currentValueType);
-            DXGI_FORMAT dxgiFormat = gl_d3d11::GetNativeVertexFormat(vertexFormat);
+            const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
 
             // Record the type of the associated vertex shader vector in our key
             // This will prevent mismatched vertex shaders from using the same input layout
@@ -118,7 +116,7 @@
 
             ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName;
             ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i];
-            ilKey.elements[ilKey.elementCount].desc.Format = dxgiFormat;
+            ilKey.elements[ilKey.elementCount].desc.Format = vertexFormatInfo.nativeFormat;
             ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
             ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
             ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass;
@@ -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)
@@ -194,7 +191,7 @@
         if (attributes[i].active)
         {
             VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
-            BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL;
+            Buffer11 *bufferStorage = attributes[i].storage ? Buffer11::makeBuffer11(attributes[i].storage) : NULL;
 
             buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK)
                                    : vertexBuffer->getBuffer();
@@ -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/d3d11/InputLayoutCache.h b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h
similarity index 90%
rename from src/libGLESv2/renderer/d3d11/InputLayoutCache.h
rename to src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h
index 5d0ac60..cc71ac3 100644
--- a/src/libGLESv2/renderer/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/d3d11/PixelTransfer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
similarity index 86%
rename from src/libGLESv2/renderer/d3d11/PixelTransfer11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
index dcd1f99..f54bacc 100644
--- a/src/libGLESv2/renderer/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
@@ -10,24 +9,24 @@
 //   Used to implement pixel transfers from unpack and to pack buffers.
 //
 
-#include "libGLESv2/renderer/d3d11/PixelTransfer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.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/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d11/BufferStorage11.h"
-#include "libGLESv2/renderer/d3d11/TextureStorage11.h"
-#include "libGLESv2/renderer/d3d11/RenderTarget11.h"
 #include "libGLESv2/Context.h"
 
 // Precompiled shaders
-#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_vs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_gs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4f.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4i.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h"
 
 namespace rx
 {
@@ -122,7 +121,7 @@
     float texelCenterX = 0.5f / static_cast<float>(destSize.width - 1);
     float texelCenterY = 0.5f / static_cast<float>(destSize.height - 1);
 
-    unsigned int bytesPerPixel = gl::GetPixelBytes(internalFormat, 3);
+    unsigned int bytesPerPixel = gl::GetInternalFormatInfo(internalFormat).pixelBytes;
     unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment);
     unsigned int alignmentPixels = (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel);
 
@@ -148,7 +147,6 @@
         return false;
     }
 
-    int clientVersion = mRenderer->getCurrentClientVersion();
     const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get();
 
     ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
@@ -158,12 +156,13 @@
 
     // The SRV must be in the proper read format, which may be different from the destination format
     // EG: for half float data, we can load full precision floats with implicit conversion
-    GLenum unsizedFormat = gl::GetFormat(destinationFormat, clientVersion);
-    GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType, clientVersion);
+    GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format;
+    GLenum sourceFormat = gl::GetFormatTypeInfo(unsizedFormat, sourcePixelsType).internalFormat;
 
-    DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(sourceFormat, clientVersion);
+    const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat);
+    DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat;
     ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
-    BufferStorage11 *bufferStorage11 = BufferStorage11::makeBufferStorage11(sourceBuffer.getStorage());
+    Buffer11 *bufferStorage11 = Buffer11::makeBuffer11(sourceBuffer.getImplementation());
     ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat);
     ASSERT(bufferSRV != NULL);
 
@@ -237,9 +236,7 @@
 
 ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const
 {
-    int clientVersion = mRenderer->getCurrentClientVersion();
-    GLenum componentType = gl::GetComponentType(internalFormat, clientVersion);
-
+    GLenum componentType = gl::GetInternalFormatInfo(internalFormat).componentType;
     if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED)
     {
         componentType = GL_FLOAT;
diff --git a/src/libGLESv2/renderer/d3d11/PixelTransfer11.h b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
similarity index 96%
rename from src/libGLESv2/renderer/d3d11/PixelTransfer11.h
rename to src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
index 574140d..ed1a3ae 100644
--- a/src/libGLESv2/renderer/d3d11/PixelTransfer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
@@ -11,6 +11,12 @@
 #ifndef LIBGLESV2_PIXELTRANSFER11_H_
 #define LIBGLESV2_PIXELTRANSFER11_H_
 
+#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
new file mode 100644
index 0000000..7109be3
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
@@ -0,0 +1,156 @@
+//
+// 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.
+//
+
+// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl.
+
+#include "libGLESv2/renderer/d3d/d3d11/Query11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libGLESv2/main.h"
+
+#include <GLES2/gl2ext.h>
+
+namespace rx
+{
+
+Query11::Query11(rx::Renderer11 *renderer, GLenum type)
+    : QueryImpl(type),
+      mResult(0),
+      mQueryFinished(false),
+      mRenderer(renderer),
+      mQuery(NULL)
+{
+}
+
+Query11::~Query11()
+{
+    SafeRelease(mQuery);
+}
+
+gl::Error Query11::begin()
+{
+    if (mQuery == NULL)
+    {
+        D3D11_QUERY_DESC queryDesc;
+        queryDesc.Query = gl_d3d11::ConvertQueryType(getType());
+        queryDesc.MiscFlags = 0;
+
+        HRESULT result = mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery);
+        if (FAILED(result))
+        {
+            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);
+}
+
+gl::Error Query11::end()
+{
+    ASSERT(mQuery);
+    mRenderer->getDeviceContext()->End(mQuery);
+
+    mQueryFinished = false;
+    mResult = GL_FALSE;
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Query11::getResult(GLuint *params)
+{
+    while (!mQueryFinished)
+    {
+        gl::Error error = testQuery();
+        if (error.isError())
+        {
+            return error;
+        }
+
+        if (!mQueryFinished)
+        {
+            Sleep(0);
+        }
+    }
+
+    ASSERT(mQueryFinished);
+    *params = mResult;
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Query11::isResultAvailable(GLuint *available)
+{
+    gl::Error error = testQuery();
+    if (error.isError())
+    {
+        return error;
+    }
+
+    *available = (mQueryFinished ? GL_TRUE : GL_FALSE);
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Query11::testQuery()
+{
+    if (!mQueryFinished)
+    {
+        ASSERT(mQuery);
+
+        ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+        switch (getType())
+        {
+          case GL_ANY_SAMPLES_PASSED_EXT:
+          case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+            {
+                UINT64 numPixels = 0;
+                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;
+                }
+            }
+            break;
+
+          case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+            {
+                D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 };
+                HRESULT result = context->GetData(mQuery, &soStats, sizeof(soStats), 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 = static_cast<GLuint>(soStats.NumPrimitivesWritten);
+                }
+            }
+            break;
+
+        default:
+            UNREACHABLE();
+            break;
+        }
+
+        if (!mQueryFinished && mRenderer->testDeviceLost(true))
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost.");
+        }
+    }
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d11/Query11.h b/src/libGLESv2/renderer/d3d/d3d11/Query11.h
similarity index 73%
rename from src/libGLESv2/renderer/d3d11/Query11.h
rename to src/libGLESv2/renderer/d3d/d3d11/Query11.h
index 7a3df46..822f254 100644
--- a/src/libGLESv2/renderer/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/d3d11/RenderStateCache.cpp b/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
similarity index 82%
rename from src/libGLESv2/renderer/d3d11/RenderStateCache.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
index b58569a..71b931f 100644
--- a/src/libGLESv2/renderer/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
@@ -8,13 +7,14 @@
 // RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render
 // state objects.
 
-#include "libGLESv2/renderer/d3d11/RenderStateCache.h"
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/d3d11/RenderStateCache.h"
+#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "common/debug.h"
+
 #include "third_party/murmurhash/MurmurHash3.h"
 
 namespace rx
@@ -23,7 +23,7 @@
 template <typename mapType>
 static void ClearStateMap(mapType &map)
 {
-    for (mapType::iterator i = map.begin(); i != map.end(); i++)
+    for (typename mapType::iterator i = map.begin(); i != map.end(); i++)
     {
         SafeRelease(i->second.first);
     }
@@ -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)
     {
-        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/d3d11/RenderStateCache.h b/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
similarity index 88%
rename from src/libGLESv2/renderer/d3d11/RenderStateCache.h
rename to src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
index 7f33496..d5471a3 100644
--- a/src/libGLESv2/renderer/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;
@@ -20,6 +23,7 @@
 
 namespace rx
 {
+class Renderer11;
 
 class RenderStateCache
 {
@@ -30,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/d3d11/RenderTarget11.cpp b/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
similarity index 85%
rename from src/libGLESv2/renderer/d3d11/RenderTarget11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
index 38c55f3..3041f21 100644
--- a/src/libGLESv2/renderer/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
@@ -8,11 +7,10 @@
 // RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
 // retained by Renderbuffers.
 
-#include "libGLESv2/renderer/d3d11/RenderTarget11.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
+#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"
 
 namespace rx
@@ -219,8 +217,9 @@
         mDepth = depth;
         mSamples = samples;
 
-        mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
-        mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
+        const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
+        mInternalFormat = dxgiFormatInfo.internalFormat;
+        mActualFormat = dxgiFormatInfo.internalFormat;
     }
 }
 
@@ -265,8 +264,9 @@
         mDepth = depth;
         mSamples = samples;
 
-        mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
-        mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
+        const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
+        mInternalFormat = dxgiFormatInfo.internalFormat;
+        mActualFormat = dxgiFormatInfo.internalFormat;
     }
 }
 
@@ -278,20 +278,11 @@
     mDepthStencil = NULL;
     mShaderResource = NULL;
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
+    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
 
-    DXGI_FORMAT texFormat = gl_d3d11::GetTexFormat(internalFormat, clientVersion);
-    DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat, clientVersion);
-    DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat, clientVersion);
-    DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat, clientVersion);
-
-    DXGI_FORMAT multisampleFormat = (dsvFormat != DXGI_FORMAT_UNKNOWN ? dsvFormat : rtvFormat);
-    int supportedSamples = mRenderer->getNearestSupportedSamples(multisampleFormat, samples);
-    if (supportedSamples < 0)
-    {
-        gl::error(GL_OUT_OF_MEMORY);
-        return;
-    }
+    const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
+    GLuint supportedSamples = textureCaps.getNearestSamples(samples);
 
     if (width > 0 && height > 0)
     {
@@ -301,7 +292,7 @@
         desc.Height = height;
         desc.MipLevels = 1;
         desc.ArraySize = 1;
-        desc.Format = texFormat;
+        desc.Format = formatInfo.texFormat;
         desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
         desc.SampleDesc.Quality = 0;
         desc.Usage = D3D11_USAGE_DEFAULT;
@@ -312,14 +303,14 @@
         // we'll flag it to allow binding that way. Shader resource views are a little
         // more complicated.
         bool bindRTV = false, bindDSV = false, bindSRV = false;
-        bindRTV = (rtvFormat != DXGI_FORMAT_UNKNOWN);
-        bindDSV = (dsvFormat != DXGI_FORMAT_UNKNOWN);
-        if (srvFormat != DXGI_FORMAT_UNKNOWN)
+        bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
+        bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
+        if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
         {
             // Multisample targets flagged for binding as depth stencil cannot also be
             // flagged for binding as SRV, so make certain not to add the SRV flag for
             // these targets.
-            bindSRV = !(dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
+            bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
         }
 
         desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET   : 0) |
@@ -341,7 +332,7 @@
         if (bindSRV)
         {
             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
-            srvDesc.Format = srvFormat;
+            srvDesc.Format = formatInfo.srvFormat;
             srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
             srvDesc.Texture2D.MostDetailedMip = 0;
             srvDesc.Texture2D.MipLevels = 1;
@@ -359,7 +350,7 @@
         if (bindDSV)
         {
             D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
-            dsvDesc.Format = dsvFormat;
+            dsvDesc.Format = formatInfo.dsvFormat;
             dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
             dsvDesc.Texture2D.MipSlice = 0;
             dsvDesc.Flags = 0;
@@ -378,7 +369,7 @@
         if (bindRTV)
         {
             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
-            rtvDesc.Format = rtvFormat;
+            rtvDesc.Format = formatInfo.rtvFormat;
             rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
             rtvDesc.Texture2D.MipSlice = 0;
             result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
@@ -393,7 +384,7 @@
             }
             ASSERT(SUCCEEDED(result));
 
-            if (gl_d3d11::RequiresTextureDataInitialization(internalFormat))
+            if (formatInfo.dataInitializerFunction != NULL)
             {
                 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
 
@@ -403,12 +394,13 @@
         }
     }
 
+
     mWidth = width;
     mHeight = height;
     mDepth = 1;
     mInternalFormat = internalFormat;
     mSamples = supportedSamples;
-    mActualFormat = d3d11_gl::GetInternalFormat(texFormat, renderer->getCurrentClientVersion());
+    mActualFormat = dxgiFormatInfo.internalFormat;
     mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
 }
 
diff --git a/src/libGLESv2/renderer/d3d11/RenderTarget11.h b/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
similarity index 97%
rename from src/libGLESv2/renderer/d3d11/RenderTarget11.h
rename to src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
index ba9f76e..8218295 100644
--- a/src/libGLESv2/renderer/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/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
similarity index 68%
rename from src/libGLESv2/renderer/d3d11/Renderer11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index f02e334..c93def8 100644
--- a/src/libGLESv2/renderer/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,31 +7,43 @@
 // 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/RenderBuffer.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/RenderTarget11.h"
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h"
-#include "libGLESv2/renderer/d3d11/SwapChain11.h"
-#include "libGLESv2/renderer/d3d11/Image11.h"
-#include "libGLESv2/renderer/d3d11/VertexBuffer11.h"
-#include "libGLESv2/renderer/d3d11/IndexBuffer11.h"
-#include "libGLESv2/renderer/d3d11/BufferStorage11.h"
-#include "libGLESv2/renderer/VertexDataManager.h"
-#include "libGLESv2/renderer/IndexDataManager.h"
-#include "libGLESv2/renderer/d3d11/TextureStorage11.h"
-#include "libGLESv2/renderer/d3d11/Query11.h"
-#include "libGLESv2/renderer/d3d11/Fence11.h"
-#include "libGLESv2/renderer/d3d11/Blit11.h"
-#include "libGLESv2/renderer/d3d11/Clear11.h"
-#include "libGLESv2/renderer/d3d11/PixelTransfer11.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"
+#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
+#include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
+#include "libGLESv2/renderer/d3d/VertexDataManager.h"
+#include "libGLESv2/renderer/d3d/IndexDataManager.h"
+#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Query11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Fence11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Clear11.h"
+#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
@@ -65,7 +76,10 @@
     MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
 };
 
-Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
+Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay)
+    : Renderer(display),
+      mDc(hDc),
+      mRequestedDisplay(requestedDisplay)
 {
     mVertexDataManager = NULL;
     mIndexDataManager = NULL;
@@ -85,8 +99,6 @@
 
     mDeviceLost = false;
 
-    mMaxSupportedSamples = 0;
-
     mDevice = NULL;
     mDeviceContext = NULL;
     mDxgiAdapter = NULL;
@@ -95,8 +107,6 @@
     mDriverConstantBufferVS = NULL;
     mDriverConstantBufferPS = NULL;
 
-    mBGRATextureSupport = false;
-
     mAppliedVertexShader = NULL;
     mAppliedGeometryShader = NULL;
     mCurPointGeometryShader = NULL;
@@ -151,11 +161,17 @@
         D3D_FEATURE_LEVEL_10_0,
     };
 
+    D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;
+    if (mRequestedDisplay == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE)
+    {
+        driverType = D3D_DRIVER_TYPE_WARP;
+    }
+
     HRESULT result = S_OK;
 
 #ifdef _DEBUG
     result = D3D11CreateDevice(NULL,
-                               D3D_DRIVER_TYPE_HARDWARE,
+                               driverType,
                                NULL,
                                D3D11_CREATE_DEVICE_DEBUG,
                                featureLevels,
@@ -174,7 +190,7 @@
 #endif
     {
         result = D3D11CreateDevice(NULL,
-                                   D3D_DRIVER_TYPE_HARDWARE,
+                                   driverType,
                                    NULL,
                                    0,
                                    featureLevels,
@@ -273,166 +289,8 @@
     }
 #endif
 
-    mMaxSupportedSamples = 0;
-
-    const d3d11::DXGIFormatSet &dxgiFormats = d3d11::GetAllUsedDXGIFormats();
-    for (d3d11::DXGIFormatSet::const_iterator i = dxgiFormats.begin(); i != dxgiFormats.end(); ++i)
-    {
-        MultisampleSupportInfo support = getMultisampleSupportInfo(*i);
-        mMultisampleSupportMap.insert(std::make_pair(*i, support));
-        mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples);
-    }
-
     initializeDevice();
 
-    // BGRA texture support is optional in feature levels 10 and 10_1
-    UINT formatSupport;
-    result = mDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupport);
-    if (FAILED(result))
-    {
-        ERR("Error checking BGRA format support: 0x%08X", result);
-    }
-    else
-    {
-        const int flags = (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET);
-        mBGRATextureSupport = (formatSupport & flags) == flags;
-    }
-
-    // Check floating point texture support
-    static const unsigned int requiredTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
-    static const unsigned int requiredRenderableFlags = D3D11_FORMAT_SUPPORT_RENDER_TARGET;
-    static const unsigned int requiredFilterFlags = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
-
-    DXGI_FORMAT float16Formats[] =
-    {
-        DXGI_FORMAT_R16_FLOAT,
-        DXGI_FORMAT_R16G16_FLOAT,
-        DXGI_FORMAT_R16G16B16A16_FLOAT,
-    };
-
-    DXGI_FORMAT float32Formats[] =
-    {
-        DXGI_FORMAT_R32_FLOAT,
-        DXGI_FORMAT_R32G32_FLOAT,
-        DXGI_FORMAT_R32G32B32A32_FLOAT,
-    };
-
-    mFloat16TextureSupport = true;
-    mFloat16FilterSupport = true;
-    mFloat16RenderSupport = true;
-    for (unsigned int i = 0; i < ArraySize(float16Formats); i++)
-    {
-        if (SUCCEEDED(mDevice->CheckFormatSupport(float16Formats[i], &formatSupport)))
-        {
-            mFloat16TextureSupport = mFloat16TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
-            mFloat16FilterSupport = mFloat16FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
-            mFloat16RenderSupport = mFloat16RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
-        }
-        else
-        {
-            mFloat16TextureSupport = false;
-            mFloat16RenderSupport = false;
-            mFloat16FilterSupport = false;
-        }
-    }
-
-    mFloat32TextureSupport = true;
-    mFloat32FilterSupport = true;
-    mFloat32RenderSupport = true;
-    for (unsigned int i = 0; i < ArraySize(float32Formats); i++)
-    {
-        if (SUCCEEDED(mDevice->CheckFormatSupport(float32Formats[i], &formatSupport)))
-        {
-            mFloat32TextureSupport = mFloat32TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
-            mFloat32FilterSupport = mFloat32FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
-            mFloat32RenderSupport = mFloat32RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
-        }
-        else
-        {
-            mFloat32TextureSupport = false;
-            mFloat32FilterSupport = false;
-            mFloat32RenderSupport = false;
-        }
-    }
-
-    DXGI_FORMAT rgTextureFormats[] =
-    {
-        DXGI_FORMAT_R8_UNORM,
-        DXGI_FORMAT_R8G8_UNORM,
-        DXGI_FORMAT_R16_FLOAT,
-        DXGI_FORMAT_R16G16_FLOAT,
-        DXGI_FORMAT_R32_FLOAT,
-        DXGI_FORMAT_R32G32_FLOAT,
-    };
-
-    mRGTextureSupport = true;
-    for (unsigned int i = 0; i < ArraySize(rgTextureFormats); i++)
-    {
-        if (SUCCEEDED(mDevice->CheckFormatSupport(rgTextureFormats[i], &formatSupport)))
-        {
-            mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
-            mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
-            mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
-        }
-        else
-        {
-            mRGTextureSupport = false;
-        }
-    }
-
-    // Check compressed texture support
-    const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D;
-
-    if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &formatSupport)))
-    {
-        mDXT1TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
-    }
-    else
-    {
-        mDXT1TextureSupport = false;
-    }
-
-    if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &formatSupport)))
-    {
-        mDXT3TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
-    }
-    else
-    {
-        mDXT3TextureSupport = false;
-    }
-
-    if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC5_UNORM, &formatSupport)))
-    {
-        mDXT5TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
-    }
-    else
-    {
-        mDXT5TextureSupport = false;
-    }
-
-    // Check depth texture support
-    DXGI_FORMAT depthTextureFormats[] =
-    {
-        DXGI_FORMAT_D16_UNORM,
-        DXGI_FORMAT_D24_UNORM_S8_UINT,
-    };
-
-    static const unsigned int requiredDepthTextureFlags = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL |
-                                                          D3D11_FORMAT_SUPPORT_TEXTURE2D;
-
-    mDepthTextureSupport = true;
-    for (unsigned int i = 0; i < ArraySize(depthTextureFormats); i++)
-    {
-        if (SUCCEEDED(mDevice->CheckFormatSupport(depthTextureFormats[i], &formatSupport)))
-        {
-            mDepthTextureSupport = mDepthTextureSupport && ((formatSupport & requiredDepthTextureFlags) == requiredDepthTextureFlags);
-        }
-        else
-        {
-            mDepthTextureSupport = false;
-        }
-    }
-
     return EGL_SUCCESS;
 }
 
@@ -457,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();
 }
 
@@ -466,38 +335,22 @@
     unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
     (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
     int numConfigs = 0;
-    
+
     for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
     {
-        for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
+        const d3d11::DXGIFormat &renderTargetFormatInfo = d3d11::GetDXGIFormatInfo(RenderTargetFormats[formatIndex]);
+        const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat);
+        if (renderTargetFormatCaps.renderable)
         {
-            DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
-
-            UINT formatSupport = 0;
-            HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
-
-            if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
+            for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
             {
-                DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
-
-                bool depthStencilFormatOK = true;
-
-                if (depthStencilFormat != DXGI_FORMAT_UNKNOWN)
+                const d3d11::DXGIFormat &depthStencilFormatInfo = d3d11::GetDXGIFormatInfo(DepthStencilFormats[depthStencilIndex]);
+                const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat);
+                if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == DXGI_FORMAT_UNKNOWN)
                 {
-                    UINT depthStencilSupport = 0;
-                    result = mDevice->CheckFormatSupport(depthStencilFormat, &depthStencilSupport);
-                    depthStencilFormatOK = SUCCEEDED(result) && (depthStencilSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL);
-                }
-
-                if (depthStencilFormatOK)
-                {
-                    // FIXME: parse types from context version
-                    ASSERT(d3d11_gl::GetInternalFormat(renderTargetFormat, 2) == d3d11_gl::GetInternalFormat(renderTargetFormat, 3));
-                    ASSERT(d3d11_gl::GetInternalFormat(depthStencilFormat, 2) == d3d11_gl::GetInternalFormat(depthStencilFormat, 3));
-
                     ConfigDesc newConfig;
-                    newConfig.renderTargetFormat = d3d11_gl::GetInternalFormat(renderTargetFormat, getCurrentClientVersion());
-                    newConfig.depthStencilFormat = d3d11_gl::GetInternalFormat(depthStencilFormat, getCurrentClientVersion());
+                    newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat;
+                    newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat;
                     newConfig.multiSample = 0;     // FIXME: enumerate multi-sampling
                     newConfig.fastConfig = true;   // Assume all DX11 format conversions to be fast
                     newConfig.es3Capable = true;
@@ -564,13 +417,15 @@
 {
     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->getSwizzleRed(), texture->getSwizzleGreen(), texture->getSwizzleBlue(),
-                                        texture->getSwizzleAlpha());
+            storage11->generateSwizzles(texture->getSamplerState().swizzleRed,
+                                        texture->getSamplerState().swizzleGreen,
+                                        texture->getSamplerState().swizzleBlue,
+                                        texture->getSamplerState().swizzleAlpha);
         }
     }
 }
@@ -579,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);
@@ -604,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);
@@ -637,12 +486,14 @@
 
     if (texture)
     {
-        TextureStorageInterface *texStorage = texture->getNativeTexture();
+        TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
+
+        TextureStorage *texStorage = textureImpl->getNativeTexture();
         if (texStorage)
         {
-            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
+            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
             gl::SamplerState samplerState;
-            texture->getSamplerState(&samplerState);
+            texture->getSamplerStateWithNativeOffset(&samplerState);
             textureSRV = storage11->getSRV(samplerState);
         }
 
@@ -650,16 +501,13 @@
         // missing the shader resource view
         ASSERT(textureSRV != NULL);
 
-        forceSetTexture = texture->hasDirtyImages();
+        forceSetTexture = textureImpl->hasDirtyImages();
+        textureImpl->resetDirty();
     }
 
     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)
         {
@@ -670,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)
         {
@@ -693,7 +537,7 @@
         const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex];
         if (uniformBuffer)
         {
-            BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
+            Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
             ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
 
             if (!constantBuffer)
@@ -715,7 +559,7 @@
         const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex];
         if (uniformBuffer)
         {
-            BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
+            Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
             ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
 
             if (!constantBuffer)
@@ -739,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);
@@ -762,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};
@@ -803,20 +651,17 @@
         memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
         stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
     {
-        if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
-            stencilRef != stencilBackRef ||
-            depthStencilState.stencilMask != depthStencilState.stencilBackMask)
-        {
-            ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
-                "invalid under WebGL.");
-            return gl::error(GL_INVALID_OPERATION);
-        }
+        ASSERT(depthStencilState.stencilWritemask == depthStencilState.stencilBackWritemask);
+        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
@@ -863,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;
@@ -879,25 +724,17 @@
         actualZFar = 1.0f;
     }
 
-    // Get D3D viewport bounds, which depends on the feature level
-    const Range& viewportBounds = getViewportBounds();
+    const gl::Caps& caps = getRendererCaps();
 
     // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds
     D3D11_VIEWPORT dxViewport;
-    dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end);
-    dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end);
-    dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension());
-    dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension());
-    dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast<int>(dxViewport.TopLeftX));
-    dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast<int>(dxViewport.TopLeftY));
+    dxViewport.TopLeftX = gl::clamp(actualViewport.x, -static_cast<int>(caps.maxViewportWidth), static_cast<int>(caps.maxViewportWidth));
+    dxViewport.TopLeftY = gl::clamp(actualViewport.y, -static_cast<int>(caps.maxViewportHeight), static_cast<int>(caps.maxViewportHeight));
+    dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(caps.maxViewportWidth - dxViewport.TopLeftX));
+    dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(caps.maxViewportHeight - dxViewport.TopLeftY));
     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;
 
@@ -927,7 +764,6 @@
     }
 
     mForceSetViewport = false;
-    return true;
 }
 
 bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
@@ -947,7 +783,8 @@
           // emulate fans via rewriting index buffer
       case GL_TRIANGLE_FAN:   primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        UNREACHABLE();
+        return false;
     }
 
     if (primitiveTopology != mCurrentPrimitiveTopology)
@@ -970,22 +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);
+    const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender();
 
-        if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE && 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));
-
-            gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(colorAttachment);
-
-            if (!colorbuffer)
-            {
-                ERR("render target pointer unexpectedly null.");
-                return false;
-            }
 
             // 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.
@@ -995,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.");
@@ -1025,39 +855,24 @@
         }
     }
 
-    // Get the depth stencil render buffer and serials
-    gl::FramebufferAttachment *depthStencil = NULL;
+    // Get the depth stencil render buffter and serials
+    gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer();
     unsigned int depthbufferSerial = 0;
     unsigned int stencilbufferSerial = 0;
-    if (framebuffer->getDepthbufferType() != GL_NONE)
+    if (depthStencil)
     {
-        depthStencil = framebuffer->getDepthbuffer();
-        if (!depthStencil)
-        {
-            ERR("Depth stencil pointer unexpectedly null.");
-            SafeRelease(framebufferRTVs);
-            return false;
-        }
-
-        depthbufferSerial = depthStencil->getSerial();
+        depthbufferSerial = GetAttachmentSerial(depthStencil);
     }
-    else if (framebuffer->getStencilbufferType() != GL_NONE)
+    else if (framebuffer->getStencilbuffer())
     {
         depthStencil = framebuffer->getStencilbuffer();
-        if (!depthStencil)
-        {
-            ERR("Depth stencil pointer unexpectedly null.");
-            SafeRelease(framebufferRTVs);
-            return false;
-        }
-
-        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.");
@@ -1089,7 +904,7 @@
         depthbufferSerial != mAppliedDepthbufferSerial ||
         stencilbufferSerial != mAppliedStencilbufferSerial)
     {
-        mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), framebufferRTVs, framebufferDSV);
+        mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, framebufferRTVs, framebufferDSV);
 
         mRenderTargetDesc.width = renderTargetWidth;
         mRenderTargetDesc.height = renderTargetHeight;
@@ -1118,50 +933,51 @@
     return true;
 }
 
-GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], 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)
-        {
-            BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(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[])
@@ -1173,7 +989,7 @@
     {
         if (transformFeedbackBuffers[i])
         {
-            BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(transformFeedbackBuffers[i]->getStorage());
+            Buffer11 *storage = Buffer11::makeBuffer11(transformFeedbackBuffers[i]->getImplementation());
             ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
 
             d3dBuffers[i] = buffer;
@@ -1257,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);
     }
 }
 
@@ -1281,7 +1099,7 @@
     if (type != GL_NONE && elementArrayBuffer)
     {
         gl::Buffer *indexBuffer = elementArrayBuffer;
-        BufferStorage *storage = indexBuffer->getStorage();
+        BufferImpl *storage = indexBuffer->getImplementation();
         intptr_t offset = reinterpret_cast<intptr_t>(indices);
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
@@ -1289,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);
@@ -1309,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);
@@ -1317,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);
@@ -1359,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);
@@ -1386,7 +1207,7 @@
     if (type != GL_NONE && elementArrayBuffer)
     {
         gl::Buffer *indexBuffer = elementArrayBuffer;
-        BufferStorage *storage = indexBuffer->getStorage();
+        BufferImpl *storage = indexBuffer->getImplementation();
         intptr_t offset = reinterpret_cast<intptr_t>(indices);
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
@@ -1394,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);
@@ -1416,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);
@@ -1424,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);
@@ -1470,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);
@@ -1498,10 +1322,11 @@
     }
 }
 
-void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[])
+void Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+                              bool rasterizerDiscard, bool transformFeedbackActive)
 {
     ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
-    ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
+    ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer);
     ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
 
     ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
@@ -1588,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);
 
@@ -1717,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()
@@ -1734,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;
@@ -1894,6 +1730,7 @@
 
 void Renderer11::release()
 {
+    releaseShaderCompiler();
     releaseDeviceResources();
 
     SafeRelease(mDxgiFactory);
@@ -1968,143 +1805,6 @@
     return adapterId;
 }
 
-bool Renderer11::getBGRATextureSupport() const
-{
-    return mBGRATextureSupport;
-}
-
-bool Renderer11::getDXT1TextureSupport() const
-{
-    return mDXT1TextureSupport;
-}
-
-bool Renderer11::getDXT3TextureSupport() const
-{
-    return mDXT3TextureSupport;
-}
-
-bool Renderer11::getDXT5TextureSupport() const
-{
-    return mDXT5TextureSupport;
-}
-
-bool Renderer11::getDepthTextureSupport() const
-{
-    return mDepthTextureSupport;
-}
-
-bool Renderer11::getFloat32TextureSupport() const
-{
-    return mFloat32TextureSupport;
-}
-
-bool Renderer11::getFloat32TextureFilteringSupport() const
-{
-    return mFloat32FilterSupport;
-}
-
-bool Renderer11::getFloat32TextureRenderingSupport() const
-{
-    return mFloat32RenderSupport;
-}
-
-bool Renderer11::getFloat16TextureSupport() const
-{
-    return mFloat16TextureSupport;
-}
-
-bool Renderer11::getFloat16TextureFilteringSupport() const
-{
-    return mFloat16FilterSupport;
-}
-
-bool Renderer11::getFloat16TextureRenderingSupport() const
-{
-    return mFloat16RenderSupport;
-}
-
-bool Renderer11::getRGB565TextureSupport() const
-{
-    return false;
-}
-
-bool Renderer11::getLuminanceTextureSupport() const
-{
-    return false;
-}
-
-bool Renderer11::getLuminanceAlphaTextureSupport() const
-{
-    return false;
-}
-
-bool Renderer11::getRGTextureSupport() const
-{
-    return mRGTextureSupport;
-}
-
-bool Renderer11::getTextureFilterAnisotropySupport() const
-{
-    return true;
-}
-
-bool Renderer11::getPBOSupport() const
-{
-    return true;
-}
-
-float Renderer11::getTextureMaxAnisotropy() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return D3D11_MAX_MAXANISOTROPY;
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return D3D10_MAX_MAXANISOTROPY;
-      default: UNREACHABLE();
-        return 0;
-    }
-}
-
-bool Renderer11::getEventQuerySupport() const
-{
-    return true;
-}
-
-Range Renderer11::getViewportBounds() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
-      default: UNREACHABLE();
-        return Range(0, 0);
-    }
-}
-
-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
@@ -2115,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
@@ -2193,127 +1827,12 @@
     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::getNonPower2TextureSupport() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return true;
-      default: UNREACHABLE();
-        return false;
-    }
-}
-
-bool Renderer11::getOcclusionQuerySupport() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return true;
-      default: UNREACHABLE();
-        return false;
-    }
-}
-
-bool Renderer11::getInstancingSupport() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return true;
-      default: UNREACHABLE();
-        return false;
-    }
-}
-
 bool Renderer11::getShareHandleSupport() const
 {
     // We only currently support share handles with BGRA surfaces, because
     // chrome needs BGRA. Once chrome fixes this, we should always support them.
     // PIX doesn't seem to support using share handles, so disable them.
-    return getBGRATextureSupport() && !gl::perfActive();
-}
-
-bool Renderer11::getDerivativeInstructionSupport() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        return true;
-      default: UNREACHABLE();
-        return false;
-    }
+    return getRendererExtensions().textureFormatBGRA8888 && !gl::perfActive();
 }
 
 bool Renderer11::getPostSubBufferSupport() const
@@ -2322,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)
@@ -2362,87 +1863,6 @@
     }
 }
 
-float Renderer11::getMaxPointSize() const
-{
-    // choose a reasonable maximum. we enforce this in the shader.
-    // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size)
-    return 1024.0f;
-}
-
-int Renderer11::getMaxViewportDimension() const
-{
-    // Maximum viewport size must be at least as large as the largest render buffer (or larger).
-    // In our case return the maximum texture size, which is the maximum render buffer size.
-    META_ASSERT(D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D11_VIEWPORT_BOUNDS_MAX);
-    META_ASSERT(D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D10_VIEWPORT_BOUNDS_MAX);
-
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0: 
-        return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0: 
-        return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
-      default: UNREACHABLE();      
-        return 0;
-    }
-}
-
-int Renderer11::getMaxTextureWidth() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
-      default: UNREACHABLE();      return 0;
-    }
-}
-
-int Renderer11::getMaxTextureHeight() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
-      default: UNREACHABLE();      return 0;
-    }
-}
-
-int Renderer11::getMaxTextureDepth() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;   // 2048
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;   // 2048
-      default: UNREACHABLE();      return 0;
-    }
-}
-
-int Renderer11::getMaxTextureArrayLayers() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;   // 2048
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;   // 512
-      default: UNREACHABLE();      return 0;
-    }
-}
-
-bool Renderer11::get32BitIndexSupport() const
-{
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0: 
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32;   // true
-      default: UNREACHABLE();      return false;
-    }
-}
-
 int Renderer11::getMinSwapInterval() const
 {
     return 0;
@@ -2453,121 +1873,12 @@
     return 4;
 }
 
-int Renderer11::getMaxSupportedSamples() const
-{
-    return mMaxSupportedSamples;
-}
-
-GLsizei Renderer11::getMaxSupportedFormatSamples(GLenum internalFormat) const
-{
-    DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
-    MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
-    return (iter != mMultisampleSupportMap.end()) ? iter->second.maxSupportedSamples : 0;
-}
-
-GLsizei Renderer11::getNumSampleCounts(GLenum internalFormat) const
-{
-    unsigned int numCounts = 0;
-
-    // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not
-    GLenum componentType = gl::GetComponentType(internalFormat, getCurrentClientVersion());
-    if (componentType != GL_INT && componentType != GL_UNSIGNED_INT)
-    {
-        DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
-        MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
-
-        if (iter != mMultisampleSupportMap.end())
-        {
-            const MultisampleSupportInfo& info = iter->second;
-            for (int i = 0; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
-            {
-                if (info.qualityLevels[i] > 0)
-                {
-                    numCounts++;
-                }
-            }
-        }
-    }
-
-    return numCounts;
-}
-
-void Renderer11::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
-{
-    // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not
-    GLenum componentType = gl::GetComponentType(internalFormat, getCurrentClientVersion());
-    if (componentType == GL_INT || componentType == GL_UNSIGNED_INT)
-    {
-        return;
-    }
-
-    DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
-    MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
-
-    if (iter != mMultisampleSupportMap.end())
-    {
-        const MultisampleSupportInfo& info = iter->second;
-        int bufPos = 0;
-        for (int i = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT - 1; i >= 0 && bufPos < bufSize; i--)
-        {
-            if (info.qualityLevels[i] > 0)
-            {
-                params[bufPos++] = i + 1;
-            }
-        }
-    }
-}
-
-int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const
-{
-    if (requested == 0)
-    {
-        return 0;
-    }
-
-    MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
-    if (iter != mMultisampleSupportMap.end())
-    {
-        const MultisampleSupportInfo& info = iter->second;
-        for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
-        {
-            if (info.qualityLevels[i] > 0)
-            {
-                return i + 1;
-            }
-        }
-    }
-
-    return -1;
-}
-
-unsigned int Renderer11::getMaxRenderTargets() const
-{
-    META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
-
-    switch (mFeatureLevel)
-    {
-      case D3D_FEATURE_LEVEL_11_0:
-        return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;  // 8
-      case D3D_FEATURE_LEVEL_10_1:
-      case D3D_FEATURE_LEVEL_10_0:
-        // Feature level 10.0 and 10.1 cards perform very poorly when the pixel shader
-        // outputs to multiple RTs that are not bound.
-        // TODO: Remove pixel shader outputs for render targets that are not bound.
-        return 1;
-      default:
-        UNREACHABLE();
-        return 1;
-    }
-}
-
-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());
 
@@ -2579,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());
 
@@ -2596,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());
 
@@ -2613,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());
 
@@ -2630,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)
@@ -2640,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.");
@@ -2654,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.");
@@ -2691,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)
@@ -2701,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.");
@@ -2715,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.");
@@ -2752,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)
@@ -2762,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.");
@@ -2776,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.");
@@ -2813,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)
@@ -2823,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.");
@@ -2837,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);
@@ -2845,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);
@@ -2887,7 +2202,7 @@
 
     rtvArray[0] = renderTargetView;
 
-    mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), rtvArray, NULL);
+    mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, rtvArray, NULL);
 
     // Do not preserve the serial for this one-time-use render target
     for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
@@ -2926,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)
@@ -2949,6 +2279,8 @@
                 for (size_t i = 0; i < transformFeedbackVaryings.size(); i++)
                 {
                     const gl::LinkedVarying &varying = transformFeedbackVaryings[i];
+                    GLenum transposedType = gl::TransposeMatrixType(varying.type);
+
                     for (size_t j = 0; j < varying.semanticIndexCount; j++)
                     {
                         D3D11_SO_DECLARATION_ENTRY entry = { 0 };
@@ -2956,7 +2288,7 @@
                         entry.SemanticName = varying.semanticName.c_str();
                         entry.SemanticIndex = varying.semanticIndex + j;
                         entry.StartComponent = 0;
-                        entry.ComponentCount = gl::VariableRowCount(type);
+                        entry.ComponentCount = gl::VariableColumnCount(transposedType);
                         entry.OutputSlot = (separatedOutputBuffers ? i : 0);
                         soDeclaration.push_back(entry);
                     }
@@ -3109,9 +2441,14 @@
     return new IndexBuffer11(this);
 }
 
-BufferStorage *Renderer11::createBufferStorage()
+BufferImpl *Renderer11::createBuffer()
 {
-    return new BufferStorage11(this);
+    return new Buffer11(this);
+}
+
+VertexArrayImpl *Renderer11::createVertexArray()
+{
+    return new VertexArray11(this);
 }
 
 QueryImpl *Renderer11::createQuery(GLenum type)
@@ -3124,36 +2461,39 @@
     return new Fence11(this);
 }
 
+TransformFeedbackImpl* Renderer11::createTransformFeedback()
+{
+    return new TransformFeedbackD3D();
+}
+
 bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
 {
-    int clientVersion = getCurrentClientVersion();
+    ASSERT(getRendererExtensions().pixelBufferObject);
 
-    // We only support buffer to texture copies in ES3
-    if (clientVersion <= 2)
-    {
-        return false;
-    }
+    const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
+    const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat);
 
     // sRGB formats do not work with D3D11 buffer SRVs
-    if (gl::GetColorEncoding(internalFormat, clientVersion) == GL_SRGB)
+    if (internalFormatInfo.colorEncoding == GL_SRGB)
     {
         return false;
     }
 
     // We cannot support direct copies to non-color-renderable formats
-    if (!gl::IsColorRenderingSupported(internalFormat, this))
+    if (d3d11FormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
     {
         return false;
     }
 
     // We skip all 3-channel formats since sometimes format support is missing
-    if (gl::GetComponentCount(internalFormat, clientVersion) == 3)
+    if (internalFormatInfo.componentCount == 3)
     {
         return false;
     }
 
     // We don't support formats which we can't represent without conversion
-    if (getNativeTextureFormat(internalFormat) != internalFormat)
+    if (dxgiFormatInfo.internalFormat != internalFormat)
     {
         return false;
     }
@@ -3172,7 +2512,7 @@
 {
     ASSERT(colorbuffer != NULL);
 
-    RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+    RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
     if (renderTarget)
     {
         *subresourceIndex = renderTarget->getSubresourceIndex();
@@ -3217,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++)
         {
@@ -3231,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))
@@ -3259,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))
@@ -3274,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;
@@ -3290,19 +2631,33 @@
         area.width = width;
         area.height = height;
 
-        if (pack.pixelBuffer.get() != NULL)
+        gl::Buffer *packBuffer = pack.pixelBuffer.get();
+        if (packBuffer != NULL)
         {
-            rx::BufferStorage11 *packBufferStorage = BufferStorage11::makeBufferStorage11(pack.pixelBuffer.get()->getStorage());
+            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()
@@ -3314,7 +2669,7 @@
 {
     Image11 *dest11 = Image11::makeImage11(dest);
     Image11 *src11 = Image11::makeImage11(src);
-    Image11::generateMipmap(getCurrentClientVersion(), dest11, src11);
+    Image11::generateMipmap(dest11, src11);
 }
 
 TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
@@ -3343,8 +2698,23 @@
     return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels);
 }
 
-void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
-                                 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels)
+TextureImpl *Renderer11::createTexture(GLenum target)
+{
+    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;
+}
+
+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);
@@ -3369,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;
@@ -3389,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;
@@ -3412,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);
@@ -3442,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);
@@ -3454,41 +2824,37 @@
     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);
     }
 
-    GLuint clientVersion = getCurrentClientVersion();
-
-    GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(textureDesc.Format, clientVersion);
-    GLenum sourceFormat = gl::GetFormat(sourceInternalFormat, clientVersion);
-    GLenum sourceType = gl::GetType(sourceInternalFormat, clientVersion);
-
-    GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
-
-    if (sourceFormat == params.format && sourceType == params.type)
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format);
+    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 * sourcePixelSize);
+            memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourceFormatInfo.pixelBytes);
         }
     }
     else
     {
-        GLenum destInternalFormat = gl::GetSizedInternalFormat(params.format, params.type, clientVersion);
-        GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion);
+        const d3d11::DXGIFormat &sourceDXGIFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format);
+        ColorCopyFunction fastCopyFunc = sourceDXGIFormatInfo.getFastCopyFunction(params.format, params.type);
 
-        ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, params.format, params.type);
+        const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(params.format, params.type);
+        const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat);
+
         if (fastCopyFunc)
         {
             // Fast copy is possible through some special function
@@ -3496,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 * destPixelSize;
-                    void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
+                    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);
                 }
@@ -3505,10 +2871,7 @@
         }
         else
         {
-            ColorReadFunction readFunc = d3d11::GetColorReadFunction(textureDesc.Format);
-            ColorWriteFunction writeFunc = gl::GetColorWriteFunction(params.format, params.type, clientVersion);
-
-            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));
@@ -3517,13 +2880,13 @@
             {
                 for (int x = 0; x < params.area.width; x++)
                 {
-                    void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize;
-                    void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
+                    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.
-                    readFunc(src, temp);
-                    writeFunc(temp, dest);
+                    sourceDXGIFormatInfo.colorReadFunction(src, temp);
+                    destFormatTypeInfo.colorWriteFunction(temp, dest);
                 }
             }
         }
@@ -3622,9 +2985,8 @@
                        drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width ||
                        drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height;
 
-    bool hasDepth = gl::GetDepthBits(drawRenderTarget11->getActualFormat(), getCurrentClientVersion()) > 0;
-    bool hasStencil = gl::GetStencilBits(drawRenderTarget11->getActualFormat(), getCurrentClientVersion()) > 0;
-    bool partialDSBlit = (hasDepth && depthBlit) != (hasStencil && stencilBlit);
+    const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat());
+    bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit);
 
     if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() &&
         !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
@@ -3698,7 +3060,7 @@
         }
         else
         {
-            GLenum format = gl::GetFormat(drawRenderTarget->getInternalFormat(), getCurrentClientVersion());
+            GLenum format = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()).format;
             result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize,
                                         scissor, format, filter);
         }
@@ -3751,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);
@@ -3772,20 +3136,20 @@
         gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(colorAttachment);
         if (attachment && attachment->isTexture())
         {
-            invalidateFBOAttachmentSwizzles(attachment, framebuffer->getColorbufferMipLevel(colorAttachment));
+            invalidateFBOAttachmentSwizzles(attachment, attachment->mipLevel());
         }
     }
 
     gl::FramebufferAttachment *depthAttachment = framebuffer->getDepthbuffer();
     if (depthAttachment && depthAttachment->isTexture())
     {
-        invalidateFBOAttachmentSwizzles(depthAttachment, framebuffer->getDepthbufferMipLevel());
+        invalidateFBOAttachmentSwizzles(depthAttachment, depthAttachment->mipLevel());
     }
 
     gl::FramebufferAttachment *stencilAttachment = framebuffer->getStencilbuffer();
     if (stencilAttachment && stencilAttachment->isTexture())
     {
-        invalidateFBOAttachmentSwizzles(stencilAttachment, framebuffer->getStencilbufferMipLevel());
+        invalidateFBOAttachmentSwizzles(stencilAttachment, stencilAttachment->mipLevel());
     }
 }
 
@@ -3809,47 +3173,19 @@
     return true;
 }
 
-GLenum Renderer11::getNativeTextureFormat(GLenum internalFormat) const
-{
-    int clientVersion = getCurrentClientVersion();
-    return d3d11_gl::GetInternalFormat(gl_d3d11::GetTexFormat(internalFormat, clientVersion), clientVersion);
-}
-
 rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
 {
-    return gl_d3d11::GetVertexConversionType(vertexFormat);
+    return d3d11::GetVertexFormatInfo(vertexFormat).conversionType;
 }
 
 GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const
 {
-    return d3d11::GetComponentType(gl_d3d11::GetNativeVertexFormat(vertexFormat));
+    return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat).nativeFormat).componentType;
 }
 
-Renderer11::MultisampleSupportInfo Renderer11::getMultisampleSupportInfo(DXGI_FORMAT format)
+void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const
 {
-    MultisampleSupportInfo supportInfo = { 0 };
-
-    UINT formatSupport;
-    HRESULT result;
-
-    result = mDevice->CheckFormatSupport(format, &formatSupport);
-    if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
-    {
-        for (unsigned int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
-        {
-            result = mDevice->CheckMultisampleQualityLevels(format, i, &supportInfo.qualityLevels[i - 1]);
-            if (SUCCEEDED(result) && supportInfo.qualityLevels[i - 1] > 0)
-            {
-                supportInfo.maxSupportedSamples = std::max(supportInfo.maxSupportedSamples, i);
-            }
-            else
-            {
-                supportInfo.qualityLevels[i - 1] = 0;
-            }
-        }
-    }
-
-    return supportInfo;
+    d3d11_gl::GenerateCaps(mDevice, outCaps, outTextureCaps, outExtensions);
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
similarity index 62%
rename from src/libGLESv2/renderer/d3d11/Renderer11.h
rename to src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index bbd0de4..19e2747 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -15,8 +15,8 @@
 
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/d3d/HLSLCompiler.h"
-#include "libGLESv2/renderer/d3d11/RenderStateCache.h"
-#include "libGLESv2/renderer/d3d11/InputLayoutCache.h"
+#include "libGLESv2/renderer/d3d/d3d11/RenderStateCache.h"
+#include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h"
 #include "libGLESv2/renderer/RenderTarget.h"
 
 namespace gl
@@ -44,7 +44,7 @@
 class Renderer11 : public Renderer
 {
   public:
-    Renderer11(egl::Display *display, HDC hDc);
+    Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay);
     virtual ~Renderer11();
 
     static Renderer11 *makeRenderer11(Renderer *renderer);
@@ -72,23 +72,24 @@
                                       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);
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
-    virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]);
+    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[], 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();
 
@@ -98,99 +99,52 @@
     virtual bool testDeviceLost(bool notify);
     virtual bool testDeviceResettable();
 
-    // Renderer capabilities
     virtual DWORD getAdapterVendor() const;
     virtual std::string getRendererDescription() const;
     virtual GUID getAdapterIdentifier() const;
 
-    virtual bool getBGRATextureSupport() const;
-    virtual bool getDXT1TextureSupport() const;
-    virtual bool getDXT3TextureSupport() const;
-    virtual bool getDXT5TextureSupport() const;
-    virtual bool getEventQuerySupport() const;
-    virtual bool getFloat32TextureSupport() const;
-    virtual bool getFloat32TextureFilteringSupport() const;
-    virtual bool getFloat32TextureRenderingSupport() const;
-    virtual bool getFloat16TextureSupport() const;
-    virtual bool getFloat16TextureFilteringSupport() const;
-    virtual bool getFloat16TextureRenderingSupport() const;
-    virtual bool getRGB565TextureSupport() const;
-    virtual bool getLuminanceTextureSupport() const;
-    virtual bool getLuminanceAlphaTextureSupport() const;
-    virtual bool getRGTextureSupport() 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 getNonPower2TextureSupport() const;
-    virtual bool getDepthTextureSupport() const;
-    virtual bool getOcclusionQuerySupport() const;
-    virtual bool getInstancingSupport() const;
-    virtual bool getTextureFilterAnisotropySupport() const;
-    virtual bool getPBOSupport() const;
-    virtual float getTextureMaxAnisotropy() const;
     virtual bool getShareHandleSupport() const;
-    virtual bool getDerivativeInstructionSupport() const;
     virtual bool getPostSubBufferSupport() const;
-    virtual int getMaxRecommendedElementsIndices() const;
-    virtual int getMaxRecommendedElementsVertices() const;
 
     virtual int getMajorShaderModel() const;
-    virtual float getMaxPointSize() const;
-    virtual int getMaxViewportDimension() const;
-    virtual int getMaxTextureWidth() const;
-    virtual int getMaxTextureHeight() const;
-    virtual int getMaxTextureDepth() const;
-    virtual int getMaxTextureArrayLayers() const;
-    virtual bool get32BitIndexSupport() const;
     virtual int getMinSwapInterval() const;
     virtual int getMaxSwapInterval() const;
 
-    virtual GLsizei getMaxSupportedSamples() const;
-    virtual GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const;
-    virtual GLsizei getNumSampleCounts(GLenum internalFormat) const;
-    virtual void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const;
-    int getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const;
-
-    virtual unsigned int getMaxRenderTargets() 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);
@@ -208,15 +162,24 @@
     virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
 
+    // Texture creation
+    virtual TextureImpl *createTexture(GLenum target);
+
     // Buffer creation
+    virtual BufferImpl *createBuffer();
     virtual VertexBuffer *createVertexBuffer();
     virtual IndexBuffer *createIndexBuffer();
-    virtual BufferStorage *createBufferStorage();
+
+    // Vertex Array creation
+    virtual VertexArrayImpl *createVertexArray();
 
     // Query and Fence creation
     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; };
@@ -232,23 +195,22 @@
     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 GLenum getNativeTextureFormat(GLenum internalFormat) const;
     virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
     virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Renderer11);
 
+    virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const;
+
     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);
-
-    rx::Range getViewportBounds() const;
+    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,
@@ -261,6 +223,7 @@
     HMODULE mD3d11Module;
     HMODULE mDxgiModule;
     HDC mDc;
+    EGLint mRequestedDisplay;
 
     HLSLCompiler mCompiler;
 
@@ -273,36 +236,6 @@
 
     RenderStateCache mStateCache;
 
-    // Support flags
-    bool mFloat16TextureSupport;
-    bool mFloat16FilterSupport;
-    bool mFloat16RenderSupport;
-
-    bool mFloat32TextureSupport;
-    bool mFloat32FilterSupport;
-    bool mFloat32RenderSupport;
-
-    bool mDXT1TextureSupport;
-    bool mDXT3TextureSupport;
-    bool mDXT5TextureSupport;
-
-    bool mRGTextureSupport;
-
-    bool mDepthTextureSupport;
-
-    // Multisample format support
-    struct MultisampleSupportInfo
-    {
-        unsigned int qualityLevels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT];
-        unsigned int maxSupportedSamples;
-    };
-    MultisampleSupportInfo getMultisampleSupportInfo(DXGI_FORMAT format);
-
-    typedef std::unordered_map<DXGI_FORMAT, MultisampleSupportInfo> MultisampleSupportMap;
-    MultisampleSupportMap mMultisampleSupportMap;
-
-    unsigned int mMaxSupportedSamples;
-
     // current render target states
     unsigned int mAppliedRenderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
     unsigned int mAppliedDepthbufferSerial;
@@ -312,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;
@@ -406,9 +339,6 @@
     DXGI_ADAPTER_DESC mAdapterDescription;
     char mDescription[128];
     IDXGIFactory *mDxgiFactory;
-
-    // Cached device caps
-    bool mBGRATextureSupport;
 };
 
 }
diff --git a/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp b/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp
similarity index 95%
rename from src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp
index de2eeda..52f3488 100644
--- a/src/libGLESv2/renderer/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
@@ -8,9 +7,8 @@
 // ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader
 // executable implementation details.
 
-#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h"
-
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 
 namespace rx
 {
diff --git a/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h b/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/ShaderExecutable11.h
rename to src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h
diff --git a/src/libGLESv2/renderer/d3d11/SwapChain11.cpp b/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
similarity index 92%
rename from src/libGLESv2/renderer/d3d11/SwapChain11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
index a15d061..5ec132e 100644
--- a/src/libGLESv2/renderer/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
@@ -7,13 +6,14 @@
 
 // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
 
-#include "libGLESv2/renderer/d3d11/SwapChain11.h"
+#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"
 
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h"
-#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
+// Precompiled shaders
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
 
 namespace rx
 {
@@ -102,6 +102,8 @@
 
     releaseOffscreenTexture();
 
+    const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
+
     // If the app passed in a share handle, open the resource
     // See EGL_ANGLE_d3d_share_handle_client_buffer
     if (mAppCreatedShareHandle)
@@ -130,11 +132,11 @@
         D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
         mOffscreenTexture->GetDesc(&offscreenTextureDesc);
 
-        if (offscreenTextureDesc.Width != (UINT)backbufferWidth
-            || offscreenTextureDesc.Height != (UINT)backbufferHeight
-            || offscreenTextureDesc.Format != gl_d3d11::GetTexFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion())
-            || offscreenTextureDesc.MipLevels != 1
-            || offscreenTextureDesc.ArraySize != 1)
+        if (offscreenTextureDesc.Width != (UINT)backbufferWidth ||
+            offscreenTextureDesc.Height != (UINT)backbufferHeight ||
+            offscreenTextureDesc.Format != backbufferFormatInfo.texFormat ||
+            offscreenTextureDesc.MipLevels != 1 ||
+            offscreenTextureDesc.ArraySize != 1)
         {
             ERR("Invalid texture parameters in the shared offscreen texture pbuffer");
             release();
@@ -148,7 +150,7 @@
         D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
         offscreenTextureDesc.Width = backbufferWidth;
         offscreenTextureDesc.Height = backbufferHeight;
-        offscreenTextureDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion());
+        offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
         offscreenTextureDesc.MipLevels = 1;
         offscreenTextureDesc.ArraySize = 1;
         offscreenTextureDesc.SampleDesc.Count = 1;
@@ -204,7 +206,7 @@
 
 
     D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
-    offscreenRTVDesc.Format = gl_d3d11::GetRTVFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion());
+    offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat;
     offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
     offscreenRTVDesc.Texture2D.MipSlice = 0;
 
@@ -213,7 +215,7 @@
     d3d11::SetDebugName(mOffscreenRTView, "Offscreen back buffer render target");
 
     D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc;
-    offscreenSRVDesc.Format = gl_d3d11::GetSRVFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion());
+    offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat;
     offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
     offscreenSRVDesc.Texture2D.MostDetailedMip = 0;
     offscreenSRVDesc.Texture2D.MipLevels = -1;
@@ -222,12 +224,14 @@
     ASSERT(SUCCEEDED(result));
     d3d11::SetDebugName(mOffscreenSRView, "Offscreen back buffer shader resource");
 
+    const d3d11::TextureFormat &depthBufferFormatInfo = d3d11::GetTextureFormatInfo(mDepthBufferFormat);
+
     if (mDepthBufferFormat != GL_NONE)
     {
         D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
         depthStencilTextureDesc.Width = backbufferWidth;
         depthStencilTextureDesc.Height = backbufferHeight;
-        depthStencilTextureDesc.Format = gl_d3d11::GetTexFormat(mDepthBufferFormat, mRenderer->getCurrentClientVersion());
+        depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
         depthStencilTextureDesc.MipLevels = 1;
         depthStencilTextureDesc.ArraySize = 1;
         depthStencilTextureDesc.SampleDesc.Count = 1;
@@ -255,7 +259,7 @@
         d3d11::SetDebugName(mDepthStencilTexture, "Offscreen depth stencil texture");
 
         D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc;
-        depthStencilDesc.Format = gl_d3d11::GetDSVFormat(mDepthBufferFormat, mRenderer->getCurrentClientVersion());
+        depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat;
         depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
         depthStencilDesc.Flags = 0;
         depthStencilDesc.Texture2D.MipSlice = 0;
@@ -265,7 +269,7 @@
         d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view");
 
         D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc;
-        depthStencilSRVDesc.Format = gl_d3d11::GetSRVFormat(mDepthBufferFormat, mRenderer->getCurrentClientVersion());
+        depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat;
         depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
         depthStencilSRVDesc.Texture2D.MostDetailedMip = 0;
         depthStencilSRVDesc.Texture2D.MipLevels = -1;
@@ -325,8 +329,8 @@
     SafeRelease(mBackBufferRTView);
 
     // Resize swap chain
-    DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::GetTexFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion());
-    HRESULT result = mSwapChain->ResizeBuffers(1, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0);
+    const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
+    HRESULT result = mSwapChain->ResizeBuffers(1, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
 
     if (FAILED(result))
     {
@@ -391,6 +395,8 @@
 
     if (mWindow)
     {
+        const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
+
         IDXGIFactory *factory = mRenderer->getDxgiFactory();
 
         DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
@@ -398,7 +404,7 @@
         swapChainDesc.BufferDesc.Height = backbufferHeight;
         swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
         swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
-        swapChainDesc.BufferDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion());
+        swapChainDesc.BufferDesc.Format = backbufferFormatInfo.texFormat;
         swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
         swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
         swapChainDesc.SampleDesc.Count = 1;
@@ -584,7 +590,7 @@
     // Draw
     deviceContext->Draw(4, 0);
 
-#if ANGLE_FORCE_VSYNC_OFF
+#ifdef ANGLE_FORCE_VSYNC_OFF
     result = mSwapChain->Present(0, 0);
 #else
     result = mSwapChain->Present(mSwapInterval, 0);
@@ -593,7 +599,7 @@
     if (result == DXGI_ERROR_DEVICE_REMOVED)
     {
         HRESULT removedReason = device->GetDeviceRemovedReason();
-        UNUSED_ASSERTION_VARIABLE(removedReason);
+        UNUSED_TRACE_VARIABLE(removedReason);
         ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason);
         return EGL_CONTEXT_LOST;
     }
diff --git a/src/libGLESv2/renderer/d3d11/SwapChain11.h b/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/SwapChain11.h
rename to src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
diff --git a/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
similarity index 68%
rename from src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
index 7e024ac..c012637 100644
--- a/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// 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
 // found in the LICENSE file.
 //
@@ -8,17 +7,19 @@
 // TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
 // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
 
-#include "libGLESv2/renderer/d3d11/TextureStorage11.h"
-
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/RenderTarget11.h"
-#include "libGLESv2/renderer/d3d11/SwapChain11.h"
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d11/Blit11.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.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
 {
@@ -121,19 +122,20 @@
     return static_cast<TextureStorage11*>(storage);
 }
 
-DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, GLuint clientVersion, bool renderTarget)
+DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTarget)
 {
     UINT bindFlags = 0;
 
-    if (gl_d3d11::GetSRVFormat(internalFormat, clientVersion) != DXGI_FORMAT_UNKNOWN)
+    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+    if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
     {
         bindFlags |= D3D11_BIND_SHADER_RESOURCE;
     }
-    if (gl_d3d11::GetDSVFormat(internalFormat, clientVersion) != DXGI_FORMAT_UNKNOWN)
+    if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
     {
         bindFlags |= D3D11_BIND_DEPTH_STENCIL;
     }
-    if (gl_d3d11::GetRTVFormat(internalFormat, clientVersion) != DXGI_FORMAT_UNKNOWN && renderTarget)
+    if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget)
     {
         bindFlags |= D3D11_BIND_RENDER_TARGET;
     }
@@ -307,7 +309,8 @@
 
         ASSERT(dstTexture);
 
-        if (!fullCopy && (d3d11::GetDepthBits(mTextureFormat) > 0 || d3d11::GetStencilBits(mTextureFormat) > 0))
+        const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+        if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
         {
             // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
             Blit11 *blitter = mRenderer->getBlitter();
@@ -318,11 +321,13 @@
         }
         else
         {
+            const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+
             D3D11_BOX srcBox;
             srcBox.left = copyArea.x;
             srcBox.top = copyArea.y;
-            srcBox.right = copyArea.x + roundUp((unsigned int)width, d3d11::GetBlockWidth(mTextureFormat));
-            srcBox.bottom = copyArea.y + roundUp((unsigned int)height, d3d11::GetBlockHeight(mTextureFormat));
+            srcBox.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth);
+            srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight);
             srcBox.front = copyArea.z;
             srcBox.back = copyArea.z + copyArea.depth;
 
@@ -337,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)
@@ -355,8 +381,7 @@
             Blit11 *blitter = mRenderer->getBlitter();
 
             blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
-                                 gl::GetFormat(source->getInternalFormat(), mRenderer->getCurrentClientVersion()),
-                                 GL_LINEAR);
+                                 gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
         }
     }
 }
@@ -371,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;
     }
@@ -401,35 +427,37 @@
     offscreenRTV->GetDesc(&rtvDesc);
     mRenderTargetFormat = rtvDesc.Format;
 
-    GLint internalFormat = d3d11_gl::GetInternalFormat(mTextureFormat, renderer->getCurrentClientVersion());
-    mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalFormat, renderer);
-    mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalFormat, renderer);
-    mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalFormat, renderer);
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat);
+    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
+    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
+    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, renderer->getCurrentClientVersion(), 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;
     }
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-    mTextureFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion);
-    mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat, clientVersion);
-    mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat, clientVersion);
-    mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat, clientVersion);
-    mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat, renderer);
-    mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat, renderer);
-    mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat, renderer);
+    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+    mTextureFormat = formatInfo.texFormat;
+    mShaderResourceFormat = formatInfo.srvFormat;
+    mDepthStencilFormat = formatInfo.dsvFormat;
+    mRenderTargetFormat = formatInfo.rtvFormat;
+    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
+    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
+    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
 
     // if the width or height is not positive this should be treated as an incomplete texture
     // we handle that here by skipping the d3d texture creation
@@ -476,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);
 
@@ -496,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])
@@ -597,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()
@@ -673,13 +793,8 @@
     }
 }
 
-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, renderer->getCurrentClientVersion(), renderTarget))
+    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
 {
     mTexture = NULL;
     mSwizzleTexture = NULL;
@@ -689,19 +804,19 @@
         mSwizzleRenderTargets[level] = NULL;
         for (unsigned int face = 0; face < 6; face++)
         {
+            mAssociatedImages[face][level] = NULL;
             mRenderTarget[face][level] = NULL;
         }
     }
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-    mTextureFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion);
-    mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat, clientVersion);
-    mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat, clientVersion);
-    mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat, clientVersion);
-    mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat, renderer);
-    mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat, renderer);
-    mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat, renderer);
+    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+    mTextureFormat = formatInfo.texFormat;
+    mShaderResourceFormat = formatInfo.srvFormat;
+    mDepthStencilFormat = formatInfo.dsvFormat;
+    mRenderTargetFormat = formatInfo.rtvFormat;
+    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
+    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
+    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
 
     // if the size is not positive this should be treated as an incomplete texture
     // we handle that here by skipping the d3d texture creation
@@ -743,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);
 
@@ -766,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::targetToIndex(faceTarget);
         if (!mRenderTarget[faceIndex][level])
         {
             ID3D11Device *device = mRenderer->getDevice();
@@ -869,10 +1085,8 @@
     srvDesc.Format = format;
 
     // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures
-    bool unnormalizedInteger = (d3d11::GetComponentType(mTextureFormat) == GL_INT ||
-                                d3d11::GetComponentType(mTextureFormat) == GL_UNSIGNED_INT);
-
-    if(unnormalizedInteger)
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
+    if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT)
     {
         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
         srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
@@ -901,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()
@@ -980,33 +1205,28 @@
     }
 }
 
-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, renderer->getCurrentClientVersion(), renderTarget))
+    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
 {
     mTexture = NULL;
     mSwizzleTexture = NULL;
 
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
+        mAssociatedImages[i] = NULL;
         mLevelRenderTargets[i] = NULL;
         mSwizzleRenderTargets[i] = NULL;
     }
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-    mTextureFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion);
-    mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat, clientVersion);
-    mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat, clientVersion);
-    mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat, clientVersion);
-    mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat, renderer);
-    mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat, renderer);
-    mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat, renderer);
+    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+    mTextureFormat = formatInfo.texFormat;
+    mShaderResourceFormat = formatInfo.srvFormat;
+    mDepthStencilFormat = formatInfo.dsvFormat;
+    mRenderTargetFormat = formatInfo.rtvFormat;
+    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
+    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
+    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
 
     // If the width, height or depth are not positive this should be treated as an incomplete texture
     // we handle that here by skipping the d3d texture creation
@@ -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,15 +1578,9 @@
     }
 }
 
-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, renderer->getCurrentClientVersion(), renderTarget))
+    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
 {
     mTexture = NULL;
     mSwizzleTexture = NULL;
@@ -1303,15 +1590,14 @@
         mSwizzleRenderTargets[level] = NULL;
     }
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-    mTextureFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion);
-    mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat, clientVersion);
-    mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat, clientVersion);
-    mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat, clientVersion);
-    mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat, renderer);
-    mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat, renderer);
-    mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat, renderer);
+    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+    mTextureFormat = formatInfo.texFormat;
+    mShaderResourceFormat = formatInfo.srvFormat;
+    mDepthStencilFormat = formatInfo.dsvFormat;
+    mRenderTargetFormat = formatInfo.rtvFormat;
+    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
+    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
+    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
 
     // if the width, height or depth is not positive this should be treated as an incomplete texture
     // we handle that here by skipping the d3d texture creation
@@ -1358,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);
 
@@ -1383,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;
@@ -1412,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);
@@ -1478,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);
+        }
     }
 }
 
@@ -1559,9 +1933,4 @@
     }
 }
 
-unsigned int TextureStorage11_2DArray::getTextureLevelDepth(int mipLevel) const
-{
-    return mTextureDepth;
-}
-
 }
diff --git a/src/libGLESv2/renderer/d3d11/TextureStorage11.h b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
similarity index 72%
rename from src/libGLESv2/renderer/d3d11/TextureStorage11.h
rename to src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
index 8a612bd..da06aa6 100644
--- a/src/libGLESv2/renderer/d3d11/TextureStorage11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
@@ -11,7 +11,14 @@
 #define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
 
 #include "libGLESv2/Texture.h"
-#include "libGLESv2/renderer/TextureStorage.h"
+#include "libGLESv2/renderer/d3d/TextureStorage.h"
+
+#include <map>
+
+namespace gl
+{
+struct ImageIndex;
+}
 
 namespace rx
 {
@@ -20,6 +27,7 @@
 class Renderer;
 class Renderer11;
 class SwapChain11;
+class Image11;
 
 class TextureStorage11 : public TextureStorage
 {
@@ -28,18 +36,15 @@
 
     static TextureStorage11 *makeTextureStorage11(TextureStorage *storage);
 
-    static DWORD GetTextureBindFlags(GLenum internalFormat, GLuint clientVersion, bool renderTarget);
+    static DWORD GetTextureBindFlags(GLenum internalFormat, bool renderTarget);
 
     UINT getBindFlags() const;
 
     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/VertexArray11.h b/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
new file mode 100644
index 0000000..590cb9f
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+// VertexArray11.h: Defines the rx::VertexArray11 class which implements rx::VertexArrayImpl.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXARRAY11_H_
+#define LIBGLESV2_RENDERER_VERTEXARRAY11_H_
+
+#include "libGLESv2/renderer/VertexArrayImpl.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+
+namespace rx
+{
+class Renderer11;
+
+class VertexArray11 : public VertexArrayImpl
+{
+  public:
+    VertexArray11(rx::Renderer11 *renderer)
+        : VertexArrayImpl(),
+          mRenderer(renderer)
+    {
+    }
+    virtual ~VertexArray11() { }
+
+    virtual void setElementArrayBuffer(const gl::Buffer *buffer) { }
+    virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) { }
+    virtual void setAttributeDivisor(size_t idx, GLuint divisor) { }
+    virtual void enableAttribute(size_t idx, bool enabledState) { }
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexArray11);
+
+    rx::Renderer11 *mRenderer;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXARRAY11_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
new file mode 100644
index 0000000..9bc5b1d
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -0,0 +1,209 @@
+//
+// 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.
+//
+
+// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
+
+#include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/VertexAttribute.h"
+
+namespace rx
+{
+
+VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer)
+{
+    mBuffer = NULL;
+    mBufferSize = 0;
+    mDynamicUsage = false;
+}
+
+VertexBuffer11::~VertexBuffer11()
+{
+    SafeRelease(mBuffer);
+}
+
+gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
+{
+    SafeRelease(mBuffer);
+
+    updateSerial();
+
+    if (size > 0)
+    {
+        ID3D11Device* dxDevice = mRenderer->getDevice();
+
+        D3D11_BUFFER_DESC bufferDesc;
+        bufferDesc.ByteWidth = size;
+        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+        bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        bufferDesc.MiscFlags = 0;
+        bufferDesc.StructureByteStride = 0;
+
+        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+        if (FAILED(result))
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
+        }
+    }
+
+    mBufferSize = size;
+    mDynamicUsage = dynamicUsage;
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer));
+    return static_cast<VertexBuffer11*>(vetexBuffer);
+}
+
+gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                                GLint start, GLsizei count, GLsizei instances, unsigned int offset)
+{
+    if (!mBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
+    }
+
+    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)
+        {
+            Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation());
+            input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset);
+        }
+        else
+        {
+            input = static_cast<const uint8_t*>(attrib.pointer);
+        }
+    }
+    else
+    {
+        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);
+}
+
+gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
+                                           GLsizei instances, unsigned int *outSpaceRequired) const
+{
+    unsigned int elementCount = 0;
+    if (attrib.enabled)
+    {
+        if (instances == 0 || attrib.divisor == 0)
+        {
+            elementCount = count;
+        }
+        else
+        {
+            // Round up to divisor, if possible
+            elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
+        }
+
+        gl::VertexFormat vertexFormat(attrib);
+        const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
+        const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat);
+        unsigned int elementSize = dxgiFormatInfo.pixelBytes;
+        if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
+        {
+            if (outSpaceRequired)
+            {
+                *outSpaceRequired = elementSize * elementCount;
+            }
+            return gl::Error(GL_NO_ERROR);
+        }
+        else
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
+        }
+    }
+    else
+    {
+        const unsigned int elementSize = 4;
+        if (outSpaceRequired)
+        {
+            *outSpaceRequired = elementSize * 4;
+        }
+        return gl::Error(GL_NO_ERROR);
+    }
+}
+
+unsigned int VertexBuffer11::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+gl::Error VertexBuffer11::setBufferSize(unsigned int size)
+{
+    if (size > mBufferSize)
+    {
+        return initialize(size, mDynamicUsage);
+    }
+    else
+    {
+        return gl::Error(GL_NO_ERROR);
+    }
+}
+
+gl::Error VertexBuffer11::discard()
+{
+    if (!mBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
+    }
+
+    ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+    if (FAILED(result))
+    {
+        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
+{
+    return mBuffer;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
new file mode 100644
index 0000000..0e10da1
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
@@ -0,0 +1,52 @@
+//
+// 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
+// found in the LICENSE file.
+//
+
+// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
+#define LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
+
+#include "libGLESv2/renderer/d3d/VertexBuffer.h"
+
+namespace rx
+{
+class Renderer11;
+
+class VertexBuffer11 : public VertexBuffer
+{
+  public:
+    explicit VertexBuffer11(rx::Renderer11 *const renderer);
+    virtual ~VertexBuffer11();
+
+    virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
+
+    static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer);
+
+    virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                            GLint start, GLsizei count, GLsizei instances, unsigned int offset);
+
+    virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
+                                       unsigned int *outSpaceRequired) const;
+
+    virtual unsigned int getBufferSize() const;
+    virtual gl::Error setBufferSize(unsigned int size);
+    virtual gl::Error discard();
+
+    ID3D11Buffer *getBuffer() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexBuffer11);
+
+    rx::Renderer11 *const mRenderer;
+
+    ID3D11Buffer *mBuffer;
+    unsigned int mBufferSize;
+    bool mDynamicUsage;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
new file mode 100644
index 0000000..1ea916d
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
@@ -0,0 +1,1075 @@
+//
+// 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.
+//
+
+// formatutils11.cpp: Queries for GL image formats and their translations to D3D11
+// formats.
+
+#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/generatemip.h"
+#include "libGLESv2/renderer/loadimage.h"
+#include "libGLESv2/renderer/copyimage.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/copyvertex.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+typedef std::map<DXGI_FORMAT, GLenum> DXGIToESFormatMap;
+
+inline void AddDXGIToESEntry(DXGIToESFormatMap *map, DXGI_FORMAT key, GLenum value)
+{
+    map->insert(std::make_pair(key, value));
+}
+
+static DXGIToESFormatMap BuildDXGIToESFormatMap()
+{
+    DXGIToESFormatMap map;
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_UNKNOWN,                  GL_NONE);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_A8_UNORM,                 GL_ALPHA8_EXT);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UNORM,                 GL_R8);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UNORM,               GL_RG8);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM,           GL_RGBA8);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,      GL_SRGB8_ALPHA8);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_B8G8R8A8_UNORM,           GL_BGRA8_EXT);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SNORM,                 GL_R8_SNORM);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SNORM,               GL_RG8_SNORM);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SNORM,           GL_RGBA8_SNORM);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UINT,                  GL_R8UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UINT,                 GL_R16UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_UINT,                 GL_R32UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UINT,                GL_RG8UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_UINT,              GL_RG16UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_UINT,              GL_RG32UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_UINT,           GL_RGB32UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UINT,            GL_RGBA8UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_UINT,        GL_RGBA16UI);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_UINT,        GL_RGBA32UI);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SINT,                  GL_R8I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_SINT,                 GL_R16I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_SINT,                 GL_R32I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SINT,                GL_RG8I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_SINT,              GL_RG16I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_SINT,              GL_RG32I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_SINT,           GL_RGB32I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SINT,            GL_RGBA8I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_SINT,        GL_RGBA16I);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_SINT,        GL_RGBA32I);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UNORM,        GL_RGB10_A2);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UINT,         GL_RGB10_A2UI);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_FLOAT,                GL_R16F);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_FLOAT,             GL_RG16F);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_FLOAT,       GL_RGBA16F);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT,                GL_R32F);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_FLOAT,             GL_RG32F);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_FLOAT,          GL_RGB32F);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_FLOAT,       GL_RGBA32F);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP,       GL_RGB9_E5);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R11G11B10_FLOAT,          GL_R11F_G11F_B10F);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_TYPELESS,             GL_DEPTH_COMPONENT16);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UNORM,                GL_DEPTH_COMPONENT16);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_D16_UNORM,                GL_DEPTH_COMPONENT16);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R24G8_TYPELESS,           GL_DEPTH24_STENCIL8_OES);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    GL_DEPTH24_STENCIL8_OES);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_D24_UNORM_S8_UINT,        GL_DEPTH24_STENCIL8_OES);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G8X24_TYPELESS,        GL_DEPTH32F_STENCIL8);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, GL_DEPTH32F_STENCIL8);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT,     GL_DEPTH32F_STENCIL8);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS,             GL_DEPTH_COMPONENT32F);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT,                GL_DEPTH_COMPONENT32F);
+
+    AddDXGIToESEntry(&map, DXGI_FORMAT_BC1_UNORM,                GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_BC2_UNORM,                GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
+    AddDXGIToESEntry(&map, DXGI_FORMAT_BC3_UNORM,                GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
+
+    return map;
+}
+
+struct D3D11FastCopyFormat
+{
+    GLenum destFormat;
+    GLenum destType;
+    ColorCopyFunction copyFunction;
+
+    D3D11FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction)
+        : destFormat(destFormat), destType(destType), copyFunction(copyFunction)
+    { }
+
+    bool operator<(const D3D11FastCopyFormat& other) const
+    {
+        return memcmp(this, &other, sizeof(D3D11FastCopyFormat)) < 0;
+    }
+};
+
+typedef std::multimap<DXGI_FORMAT, D3D11FastCopyFormat> D3D11FastCopyMap;
+
+static D3D11FastCopyMap BuildFastCopyMap()
+{
+    D3D11FastCopyMap map;
+
+    map.insert(std::make_pair(DXGI_FORMAT_B8G8R8A8_UNORM, D3D11FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8)));
+
+    return map;
+}
+
+struct DXGIDepthStencilInfo
+{
+    unsigned int depthBits;
+    unsigned int depthOffset;
+    unsigned int stencilBits;
+    unsigned int stencilOffset;
+};
+
+typedef std::map<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoMap;
+typedef std::pair<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoPair;
+
+static inline void InsertDXGIDepthStencilInfo(DepthStencilInfoMap *map, DXGI_FORMAT format, unsigned int depthBits,
+                                              unsigned int depthOffset, unsigned int stencilBits, unsigned int stencilOffset)
+{
+    DXGIDepthStencilInfo info;
+    info.depthBits = depthBits;
+    info.depthOffset = depthOffset;
+    info.stencilBits = stencilBits;
+    info.stencilOffset = stencilOffset;
+
+    map->insert(std::make_pair(format, info));
+}
+
+static DepthStencilInfoMap BuildDepthStencilInfoMap()
+{
+    DepthStencilInfoMap map;
+
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_TYPELESS,             16, 0, 0,  0);
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_UNORM,                16, 0, 0,  0);
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D16_UNORM,                16, 0, 0,  0);
+
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24G8_TYPELESS,           24, 0, 8, 24);
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    24, 0, 8, 24);
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D24_UNORM_S8_UINT,        24, 0, 8, 24);
+
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_TYPELESS,             32, 0, 0,  0);
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT,                32, 0, 0,  0);
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT,                32, 0, 0,  0);
+
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32G8X24_TYPELESS,        32, 0, 8, 32);
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 32, 0, 8, 32);
+    InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT,     32, 0, 8, 32);
+
+    return map;
+}
+
+typedef std::map<DXGI_FORMAT, DXGIFormat> DXGIFormatInfoMap;
+
+DXGIFormat::DXGIFormat()
+    : pixelBytes(0),
+      blockWidth(0),
+      blockHeight(0),
+      depthBits(0),
+      depthOffset(0),
+      stencilBits(0),
+      stencilOffset(0),
+      internalFormat(GL_NONE),
+      componentType(GL_NONE),
+      mipGenerationFunction(NULL),
+      colorReadFunction(NULL),
+      fastCopyFunctions()
+{
+}
+
+ColorCopyFunction DXGIFormat::getFastCopyFunction(GLenum format, GLenum type) const
+{
+    FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type));
+    return (iter != fastCopyFunctions.end()) ? iter->second : NULL;
+}
+
+void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight,
+                   GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc)
+{
+    DXGIFormat info;
+    info.pixelBytes = pixelBits / 8;
+    info.blockWidth = blockWidth;
+    info.blockHeight = blockHeight;
+
+    static const DepthStencilInfoMap dsInfoMap = BuildDepthStencilInfoMap();
+    DepthStencilInfoMap::const_iterator dsInfoIter = dsInfoMap.find(dxgiFormat);
+    if (dsInfoIter != dsInfoMap.end())
+    {
+        info.depthBits = dsInfoIter->second.depthBits;
+        info.depthOffset = dsInfoIter->second.depthOffset;
+        info.stencilBits = dsInfoIter->second.stencilBits;
+        info.stencilOffset = dsInfoIter->second.stencilOffset;
+    }
+    else
+    {
+        info.depthBits = 0;
+        info.depthOffset = 0;
+        info.stencilBits = 0;
+        info.stencilOffset = 0;
+    }
+
+    static const DXGIToESFormatMap dxgiToESMap = BuildDXGIToESFormatMap();
+    DXGIToESFormatMap::const_iterator dxgiToESIter = dxgiToESMap.find(dxgiFormat);
+    info.internalFormat = (dxgiToESIter != dxgiToESMap.end()) ? dxgiToESIter->second : GL_NONE;
+
+    info.componentType = componentType;
+
+    info.mipGenerationFunction = mipFunc;
+    info.colorReadFunction = readFunc;
+
+    static const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap();
+    std::pair<D3D11FastCopyMap::const_iterator, D3D11FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(dxgiFormat);
+    for (D3D11FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++)
+    {
+        info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction));
+    }
+
+    map->insert(std::make_pair(dxgiFormat, info));
+}
+
+// A map to determine the pixel size and mipmap generation function of a given DXGI format
+static DXGIFormatInfoMap BuildDXGIFormatInfoMap()
+{
+    DXGIFormatInfoMap map;
+
+    //                | DXGI format                          |S   |W |H |Component Type         | Mip generation function   | Color read function
+    AddDXGIFormat(&map, DXGI_FORMAT_UNKNOWN,                  0,   0, 0, GL_NONE,                NULL,                       NULL);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_A8_UNORM,                 8,   1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<A8>,            ReadColor<A8, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8_UNORM,                 8,   1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8>,            ReadColor<R8, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UNORM,               16,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8>,          ReadColor<R8G8, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM,           32,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>,      ReadColor<R8G8B8A8, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,      32,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>,      ReadColor<R8G8B8A8, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_B8G8R8A8_UNORM,           32,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<B8G8R8A8>,      ReadColor<B8G8R8A8, GLfloat>);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_R8_SNORM,                 8,   1, 1, GL_SIGNED_NORMALIZED,   GenerateMip<R8S>,           ReadColor<R8S, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SNORM,               16,  1, 1, GL_SIGNED_NORMALIZED,   GenerateMip<R8G8S>,         ReadColor<R8G8S, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SNORM,           32,  1, 1, GL_SIGNED_NORMALIZED,   GenerateMip<R8G8B8A8S>,     ReadColor<R8G8B8A8S, GLfloat>);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_R8_UINT,                  8,   1, 1, GL_UNSIGNED_INT,        GenerateMip<R8>,            ReadColor<R8, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16_UINT,                 16,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R16>,           ReadColor<R16, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32_UINT,                 32,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R32>,           ReadColor<R32, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UINT,                16,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R8G8>,          ReadColor<R8G8, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UINT,              32,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R16G16>,        ReadColor<R16G16, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32_UINT,              64,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R32G32>,        ReadColor<R32G32, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_UINT,           96,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R32G32B32>,     ReadColor<R32G32B32, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UINT,            32,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R8G8B8A8>,      ReadColor<R8G8B8A8, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UINT,        64,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R16G16B16A16>,  ReadColor<R16G16B16A16, GLuint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_UINT,        128, 1, 1, GL_UNSIGNED_INT,        GenerateMip<R32G32B32A32>,  ReadColor<R32G32B32A32, GLuint>);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_R8_SINT,                  8,   1, 1, GL_INT,                 GenerateMip<R8S>,           ReadColor<R8S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16_SINT,                 16,  1, 1, GL_INT,                 GenerateMip<R16S>,          ReadColor<R16S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32_SINT,                 32,  1, 1, GL_INT,                 GenerateMip<R32S>,          ReadColor<R32S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SINT,                16,  1, 1, GL_INT,                 GenerateMip<R8G8S>,         ReadColor<R8G8S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SINT,              32,  1, 1, GL_INT,                 GenerateMip<R16G16S>,       ReadColor<R16G16S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32_SINT,              64,  1, 1, GL_INT,                 GenerateMip<R32G32S>,       ReadColor<R32G32S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_SINT,           96,  1, 1, GL_INT,                 GenerateMip<R32G32B32S>,    ReadColor<R32G32B32S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SINT,            32,  1, 1, GL_INT,                 GenerateMip<R8G8B8A8S>,     ReadColor<R8G8B8A8S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SINT,        64,  1, 1, GL_INT,                 GenerateMip<R16G16B16A16S>, ReadColor<R16G16B16A16S, GLint>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_SINT,        128, 1, 1, GL_INT,                 GenerateMip<R32G32B32A32S>, ReadColor<R32G32B32A32S, GLint>);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UNORM,        32,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R10G10B10A2>,   ReadColor<R10G10B10A2, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UINT,         32,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R10G10B10A2>,   ReadColor<R10G10B10A2, GLuint>);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_R16_FLOAT,                16,  1, 1, GL_FLOAT,               GenerateMip<R16F>,          ReadColor<R16F, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_FLOAT,             32,  1, 1, GL_FLOAT,               GenerateMip<R16G16F>,       ReadColor<R16G16F, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_FLOAT,       64,  1, 1, GL_FLOAT,               GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT,                32,  1, 1, GL_FLOAT,               GenerateMip<R32F>,          ReadColor<R32F, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32_FLOAT,             64,  1, 1, GL_FLOAT,               GenerateMip<R32G32F>,       ReadColor<R32G32F, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_FLOAT,          96,  1, 1, GL_FLOAT,               NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_FLOAT,       128, 1, 1, GL_FLOAT,               GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP,       32,  1, 1, GL_FLOAT,               GenerateMip<R9G9B9E5>,      ReadColor<R9G9B9E5, GLfloat>);
+    AddDXGIFormat(&map, DXGI_FORMAT_R11G11B10_FLOAT,          32,  1, 1, GL_FLOAT,               GenerateMip<R11G11B10F>,    ReadColor<R11G11B10F, GLfloat>);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_R16_TYPELESS,             16,  1, 1, GL_NONE,                NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM,                16,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_D16_UNORM,                16,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R24G8_TYPELESS,           32,  1, 1, GL_NONE,                NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    32,  1, 1, GL_NONE,                NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_D24_UNORM_S8_UINT,        32,  1, 1, GL_UNSIGNED_INT,        NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32G8X24_TYPELESS,        64,  1, 1, GL_NONE,                NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 64,  1, 1, GL_NONE,                NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT,     64,  1, 1, GL_UNSIGNED_INT,        NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R32_TYPELESS,             32,  1, 1, GL_NONE,                NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT,                32,  1, 1, GL_FLOAT,               NULL,                       NULL);
+
+    AddDXGIFormat(&map, DXGI_FORMAT_BC1_UNORM,                64,  4, 4, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_BC2_UNORM,                128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_BC3_UNORM,                128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
+
+    // Useful formats for vertex buffers
+    AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM,                16,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16_SNORM,                16,  1, 1, GL_SIGNED_NORMALIZED,   NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UNORM,             32,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SNORM,             32,  1, 1, GL_SIGNED_NORMALIZED,   NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UNORM,       64,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
+    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SNORM,       64,  1, 1, GL_SIGNED_NORMALIZED,   NULL,                       NULL);
+
+    return map;
+}
+
+const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format)
+{
+    static const DXGIFormatInfoMap infoMap = BuildDXGIFormatInfoMap();
+    DXGIFormatInfoMap::const_iterator iter = infoMap.find(format);
+    if (iter != infoMap.end())
+    {
+        return iter->second;
+    }
+    else
+    {
+        static DXGIFormat defaultInfo;
+        return defaultInfo;
+    }
+}
+
+struct SwizzleSizeType
+{
+    size_t maxComponentSize;
+    GLenum componentType;
+
+    SwizzleSizeType()
+        : maxComponentSize(0), componentType(GL_NONE)
+    { }
+
+    SwizzleSizeType(size_t maxComponentSize, GLenum componentType)
+        : maxComponentSize(maxComponentSize), componentType(componentType)
+    { }
+
+    bool operator<(const SwizzleSizeType& other) const
+    {
+        return (maxComponentSize != other.maxComponentSize) ? (maxComponentSize < other.maxComponentSize)
+                                                            : (componentType < other.componentType);
+    }
+};
+
+struct SwizzleFormatInfo
+{
+    DXGI_FORMAT mTexFormat;
+    DXGI_FORMAT mSRVFormat;
+    DXGI_FORMAT mRTVFormat;
+
+    SwizzleFormatInfo()
+        : mTexFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN)
+    { }
+
+    SwizzleFormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat)
+        : mTexFormat(texFormat), mSRVFormat(srvFormat), mRTVFormat(rtvFormat)
+    { }
+};
+
+typedef std::map<SwizzleSizeType, SwizzleFormatInfo> SwizzleInfoMap;
+typedef std::pair<SwizzleSizeType, SwizzleFormatInfo> SwizzleInfoPair;
+
+static SwizzleInfoMap BuildSwizzleInfoMap()
+{
+    SwizzleInfoMap map;
+
+    map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM    )));
+    map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM)));
+    map.insert(SwizzleInfoPair(SwizzleSizeType(24, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
+    map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
+
+    map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_SIGNED_NORMALIZED  ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM,     DXGI_FORMAT_R8G8B8A8_SNORM,     DXGI_FORMAT_R8G8B8A8_SNORM    )));
+
+    map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_FLOAT              ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT)));
+    map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_FLOAT              ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
+
+    map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_INT       ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UINT     )));
+    map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_INT       ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UINT,  DXGI_FORMAT_R16G16B16A16_UINT,  DXGI_FORMAT_R16G16B16A16_UINT )));
+    map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_INT       ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_UINT,  DXGI_FORMAT_R32G32B32A32_UINT,  DXGI_FORMAT_R32G32B32A32_UINT )));
+
+    map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_INT                ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SINT,      DXGI_FORMAT_R8G8B8A8_SINT,      DXGI_FORMAT_R8G8B8A8_SINT     )));
+    map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_INT                ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_SINT,  DXGI_FORMAT_R16G16B16A16_SINT,  DXGI_FORMAT_R16G16B16A16_SINT )));
+    map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_INT                ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_SINT,  DXGI_FORMAT_R32G32B32A32_SINT,  DXGI_FORMAT_R32G32B32A32_SINT )));
+
+    return map;
+}
+
+typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitializerPair;
+typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitializerMap;
+
+static InternalFormatInitializerMap BuildInternalFormatInitializerMap()
+{
+    InternalFormatInitializerMap map;
+
+    map.insert(InternalFormatInitializerPair(GL_RGB8,    Initialize4ComponentData<GLubyte,  0x00,       0x00,       0x00,       0xFF>          ));
+    map.insert(InternalFormatInitializerPair(GL_RGB565,  Initialize4ComponentData<GLubyte,  0x00,       0x00,       0x00,       0xFF>          ));
+    map.insert(InternalFormatInitializerPair(GL_SRGB8,   Initialize4ComponentData<GLubyte,  0x00,       0x00,       0x00,       0xFF>          ));
+    map.insert(InternalFormatInitializerPair(GL_RGB16F,  Initialize4ComponentData<GLhalf,   0x0000,     0x0000,     0x0000,     gl::Float16One>));
+    map.insert(InternalFormatInitializerPair(GL_RGB32F,  Initialize4ComponentData<GLfloat,  0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
+    map.insert(InternalFormatInitializerPair(GL_RGB8UI,  Initialize4ComponentData<GLubyte,  0x00,       0x00,       0x00,       0x01>          ));
+    map.insert(InternalFormatInitializerPair(GL_RGB8I,   Initialize4ComponentData<GLbyte,   0x00,       0x00,       0x00,       0x01>          ));
+    map.insert(InternalFormatInitializerPair(GL_RGB16UI, Initialize4ComponentData<GLushort, 0x0000,     0x0000,     0x0000,     0x0001>        ));
+    map.insert(InternalFormatInitializerPair(GL_RGB16I,  Initialize4ComponentData<GLshort,  0x0000,     0x0000,     0x0000,     0x0001>        ));
+    map.insert(InternalFormatInitializerPair(GL_RGB32UI, Initialize4ComponentData<GLuint,   0x00000000, 0x00000000, 0x00000000, 0x00000001>    ));
+    map.insert(InternalFormatInitializerPair(GL_RGB32I,  Initialize4ComponentData<GLint,    0x00000000, 0x00000000, 0x00000000, 0x00000001>    ));
+
+    return map;
+}
+
+// ES3 image loading functions vary based on the internal format and data type given,
+// this map type determines the loading function from the internal format and type supplied
+// to glTex*Image*D and the destination DXGI_FORMAT. Source formats and types are taken from
+// Tables 3.2 and 3.3 of the ES 3 spec.
+typedef std::pair<GLenum, LoadImageFunction> TypeLoadFunctionPair;
+typedef std::map<GLenum, std::vector<TypeLoadFunctionPair> > D3D11LoadFunctionMap;
+
+static void UnimplementedLoadFunction(size_t width, size_t height, size_t depth,
+                                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    UNIMPLEMENTED();
+}
+
+static void UnreachableLoadFunction(size_t width, size_t height, size_t depth,
+                                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    UNREACHABLE();
+}
+
+// A helper function to insert data into the D3D11LoadFunctionMap with fewer characters.
+static inline void InsertLoadFunction(D3D11LoadFunctionMap *map, GLenum internalFormat, GLenum type,
+                                      LoadImageFunction loadFunc)
+{
+    (*map)[internalFormat].push_back(TypeLoadFunctionPair(type, loadFunc));
+}
+
+D3D11LoadFunctionMap BuildD3D11LoadFunctionMap()
+{
+    D3D11LoadFunctionMap map;
+
+    //                      | Internal format      | Type                             | Load function                       |
+    InsertLoadFunction(&map, GL_RGBA8,              GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 4>             );
+    InsertLoadFunction(&map, GL_RGB5_A1,            GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 4>             );
+    InsertLoadFunction(&map, GL_RGBA4,              GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 4>             );
+    InsertLoadFunction(&map, GL_SRGB8_ALPHA8,       GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 4>             );
+    InsertLoadFunction(&map, GL_RGBA8_SNORM,        GL_BYTE,                           LoadToNative<GLbyte, 4>              );
+    InsertLoadFunction(&map, GL_RGBA4,              GL_UNSIGNED_SHORT_4_4_4_4,         LoadRGBA4ToRGBA8                     );
+    InsertLoadFunction(&map, GL_RGB10_A2,           GL_UNSIGNED_INT_2_10_10_10_REV,    LoadToNative<GLuint, 1>              );
+    InsertLoadFunction(&map, GL_RGB5_A1,            GL_UNSIGNED_SHORT_5_5_5_1,         LoadRGB5A1ToRGBA8                    );
+    InsertLoadFunction(&map, GL_RGB5_A1,            GL_UNSIGNED_INT_2_10_10_10_REV,    LoadRGB10A2ToRGBA8                   );
+    InsertLoadFunction(&map, GL_RGBA16F,            GL_HALF_FLOAT,                     LoadToNative<GLhalf, 4>              );
+    InsertLoadFunction(&map, GL_RGBA16F,            GL_HALF_FLOAT_OES,                 LoadToNative<GLhalf, 4>              );
+    InsertLoadFunction(&map, GL_RGBA32F,            GL_FLOAT,                          LoadToNative<GLfloat, 4>             );
+    InsertLoadFunction(&map, GL_RGBA16F,            GL_FLOAT,                          Load32FTo16F<4>                      );
+    InsertLoadFunction(&map, GL_RGBA8UI,            GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 4>             );
+    InsertLoadFunction(&map, GL_RGBA8I,             GL_BYTE,                           LoadToNative<GLbyte, 4>              );
+    InsertLoadFunction(&map, GL_RGBA16UI,           GL_UNSIGNED_SHORT,                 LoadToNative<GLushort, 4>            );
+    InsertLoadFunction(&map, GL_RGBA16I,            GL_SHORT,                          LoadToNative<GLshort, 4>             );
+    InsertLoadFunction(&map, GL_RGBA32UI,           GL_UNSIGNED_INT,                   LoadToNative<GLuint, 4>              );
+    InsertLoadFunction(&map, GL_RGBA32I,            GL_INT,                            LoadToNative<GLint, 4>               );
+    InsertLoadFunction(&map, GL_RGB10_A2UI,         GL_UNSIGNED_INT_2_10_10_10_REV,    LoadToNative<GLuint, 1>              );
+    InsertLoadFunction(&map, GL_RGB8,               GL_UNSIGNED_BYTE,                  LoadToNative3To4<GLubyte, 0xFF>      );
+    InsertLoadFunction(&map, GL_RGB565,             GL_UNSIGNED_BYTE,                  LoadToNative3To4<GLubyte, 0xFF>      );
+    InsertLoadFunction(&map, GL_SRGB8,              GL_UNSIGNED_BYTE,                  LoadToNative3To4<GLubyte, 0xFF>      );
+    InsertLoadFunction(&map, GL_RGB8_SNORM,         GL_BYTE,                           LoadToNative3To4<GLbyte, 0x7F>       );
+    InsertLoadFunction(&map, GL_RGB565,             GL_UNSIGNED_SHORT_5_6_5,           LoadR5G6B5ToRGBA8                    );
+    InsertLoadFunction(&map, GL_R11F_G11F_B10F,     GL_UNSIGNED_INT_10F_11F_11F_REV,   LoadToNative<GLuint, 1>              );
+    InsertLoadFunction(&map, GL_RGB9_E5,            GL_UNSIGNED_INT_5_9_9_9_REV,       LoadToNative<GLuint, 1>              );
+    InsertLoadFunction(&map, GL_RGB16F,             GL_HALF_FLOAT,                     LoadToNative3To4<GLhalf, gl::Float16One>);
+    InsertLoadFunction(&map, GL_RGB16F,             GL_HALF_FLOAT_OES,                 LoadToNative3To4<GLhalf, gl::Float16One>);
+    InsertLoadFunction(&map, GL_R11F_G11F_B10F,     GL_HALF_FLOAT,                     LoadRGB16FToRG11B10F                 );
+    InsertLoadFunction(&map, GL_R11F_G11F_B10F,     GL_HALF_FLOAT_OES,                 LoadRGB16FToRG11B10F                 );
+    InsertLoadFunction(&map, GL_RGB9_E5,            GL_HALF_FLOAT,                     LoadRGB16FToRGB9E5                   );
+    InsertLoadFunction(&map, GL_RGB9_E5,            GL_HALF_FLOAT_OES,                 LoadRGB16FToRGB9E5                   );
+    InsertLoadFunction(&map, GL_RGB32F,             GL_FLOAT,                          LoadToNative3To4<GLfloat, gl::Float32One>);
+    InsertLoadFunction(&map, GL_RGB16F,             GL_FLOAT,                          LoadRGB32FToRGBA16F                  );
+    InsertLoadFunction(&map, GL_R11F_G11F_B10F,     GL_FLOAT,                          LoadRGB32FToRG11B10F                 );
+    InsertLoadFunction(&map, GL_RGB9_E5,            GL_FLOAT,                          LoadRGB32FToRGB9E5                   );
+    InsertLoadFunction(&map, GL_RGB8UI,             GL_UNSIGNED_BYTE,                  LoadToNative3To4<GLubyte, 0x01>      );
+    InsertLoadFunction(&map, GL_RGB8I,              GL_BYTE,                           LoadToNative3To4<GLbyte, 0x01>       );
+    InsertLoadFunction(&map, GL_RGB16UI,            GL_UNSIGNED_SHORT,                 LoadToNative3To4<GLushort, 0x0001>   );
+    InsertLoadFunction(&map, GL_RGB16I,             GL_SHORT,                          LoadToNative3To4<GLshort, 0x0001>    );
+    InsertLoadFunction(&map, GL_RGB32UI,            GL_UNSIGNED_INT,                   LoadToNative3To4<GLuint, 0x00000001> );
+    InsertLoadFunction(&map, GL_RGB32I,             GL_INT,                            LoadToNative3To4<GLint, 0x00000001>  );
+    InsertLoadFunction(&map, GL_RG8,                GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 2>             );
+    InsertLoadFunction(&map, GL_RG8_SNORM,          GL_BYTE,                           LoadToNative<GLbyte, 2>              );
+    InsertLoadFunction(&map, GL_RG16F,              GL_HALF_FLOAT,                     LoadToNative<GLhalf, 2>              );
+    InsertLoadFunction(&map, GL_RG16F,              GL_HALF_FLOAT_OES,                 LoadToNative<GLhalf, 2>              );
+    InsertLoadFunction(&map, GL_RG32F,              GL_FLOAT,                          LoadToNative<GLfloat, 2>             );
+    InsertLoadFunction(&map, GL_RG16F,              GL_FLOAT,                          Load32FTo16F<2>                      );
+    InsertLoadFunction(&map, GL_RG8UI,              GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 2>             );
+    InsertLoadFunction(&map, GL_RG8I,               GL_BYTE,                           LoadToNative<GLbyte, 2>              );
+    InsertLoadFunction(&map, GL_RG16UI,             GL_UNSIGNED_SHORT,                 LoadToNative<GLushort, 2>            );
+    InsertLoadFunction(&map, GL_RG16I,              GL_SHORT,                          LoadToNative<GLshort, 2>             );
+    InsertLoadFunction(&map, GL_RG32UI,             GL_UNSIGNED_INT,                   LoadToNative<GLuint, 2>              );
+    InsertLoadFunction(&map, GL_RG32I,              GL_INT,                            LoadToNative<GLint, 2>               );
+    InsertLoadFunction(&map, GL_R8,                 GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 1>             );
+    InsertLoadFunction(&map, GL_R8_SNORM,           GL_BYTE,                           LoadToNative<GLbyte, 1>              );
+    InsertLoadFunction(&map, GL_R16F,               GL_HALF_FLOAT,                     LoadToNative<GLhalf, 1>              );
+    InsertLoadFunction(&map, GL_R16F,               GL_HALF_FLOAT_OES,                 LoadToNative<GLhalf, 1>              );
+    InsertLoadFunction(&map, GL_R32F,               GL_FLOAT,                          LoadToNative<GLfloat, 1>             );
+    InsertLoadFunction(&map, GL_R16F,               GL_FLOAT,                          Load32FTo16F<1>                      );
+    InsertLoadFunction(&map, GL_R8UI,               GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 1>             );
+    InsertLoadFunction(&map, GL_R8I,                GL_BYTE,                           LoadToNative<GLbyte, 1>              );
+    InsertLoadFunction(&map, GL_R16UI,              GL_UNSIGNED_SHORT,                 LoadToNative<GLushort, 1>            );
+    InsertLoadFunction(&map, GL_R16I,               GL_SHORT,                          LoadToNative<GLshort, 1>             );
+    InsertLoadFunction(&map, GL_R32UI,              GL_UNSIGNED_INT,                   LoadToNative<GLuint, 1>              );
+    InsertLoadFunction(&map, GL_R32I,               GL_INT,                            LoadToNative<GLint, 1>               );
+    InsertLoadFunction(&map, GL_DEPTH_COMPONENT16,  GL_UNSIGNED_SHORT,                 LoadToNative<GLushort, 1>            );
+    InsertLoadFunction(&map, GL_DEPTH_COMPONENT24,  GL_UNSIGNED_INT,                   LoadR32ToR24G8                       );
+    InsertLoadFunction(&map, GL_DEPTH_COMPONENT16,  GL_UNSIGNED_INT,                   LoadR32ToR16                         );
+    InsertLoadFunction(&map, GL_DEPTH_COMPONENT32F, GL_FLOAT,                          LoadToNative<GLfloat, 1>             );
+    InsertLoadFunction(&map, GL_DEPTH24_STENCIL8,   GL_UNSIGNED_INT_24_8,              LoadR32ToR24G8                       );
+    InsertLoadFunction(&map, GL_DEPTH32F_STENCIL8,  GL_FLOAT_32_UNSIGNED_INT_24_8_REV, LoadToNative<GLuint, 2>              );
+
+    // Unsized formats
+    // Load functions are unreachable because they are converted to sized internal formats based on
+    // the format and type before loading takes place.
+    InsertLoadFunction(&map, GL_RGBA,               GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
+    InsertLoadFunction(&map, GL_RGBA,               GL_UNSIGNED_SHORT_4_4_4_4,         UnreachableLoadFunction              );
+    InsertLoadFunction(&map, GL_RGBA,               GL_UNSIGNED_SHORT_5_5_5_1,         UnreachableLoadFunction              );
+    InsertLoadFunction(&map, GL_RGB,                GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
+    InsertLoadFunction(&map, GL_RGB,                GL_UNSIGNED_SHORT_5_6_5,           UnreachableLoadFunction              );
+    InsertLoadFunction(&map, GL_LUMINANCE_ALPHA,    GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
+    InsertLoadFunction(&map, GL_LUMINANCE,          GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
+    InsertLoadFunction(&map, GL_ALPHA,              GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
+
+    // From GL_OES_texture_float
+    InsertLoadFunction(&map, GL_LUMINANCE_ALPHA,    GL_FLOAT,                          LoadLA32FToRGBA32F                   );
+    InsertLoadFunction(&map, GL_LUMINANCE,          GL_FLOAT,                          LoadL32FToRGBA32F                    );
+    InsertLoadFunction(&map, GL_ALPHA,              GL_FLOAT,                          LoadA32FToRGBA32F                    );
+
+    // From GL_OES_texture_half_float
+    InsertLoadFunction(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT,                     LoadLA16FToRGBA16F                   );
+    InsertLoadFunction(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT_OES,                 LoadLA16FToRGBA16F                   );
+    InsertLoadFunction(&map, GL_LUMINANCE,          GL_HALF_FLOAT,                     LoadL16FToRGBA16F                    );
+    InsertLoadFunction(&map, GL_LUMINANCE,          GL_HALF_FLOAT_OES,                 LoadL16FToRGBA16F                    );
+    InsertLoadFunction(&map, GL_ALPHA,              GL_HALF_FLOAT,                     LoadA16FToRGBA16F                    );
+    InsertLoadFunction(&map, GL_ALPHA,              GL_HALF_FLOAT_OES,                 LoadA16FToRGBA16F                    );
+
+    // From GL_EXT_texture_storage
+    InsertLoadFunction(&map, GL_ALPHA8_EXT,             GL_UNSIGNED_BYTE,              LoadToNative<GLubyte, 1>             );
+    InsertLoadFunction(&map, GL_LUMINANCE8_EXT,         GL_UNSIGNED_BYTE,              LoadL8ToRGBA8                        );
+    InsertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT,  GL_UNSIGNED_BYTE,              LoadLA8ToRGBA8                       );
+    InsertLoadFunction(&map, GL_ALPHA32F_EXT,           GL_FLOAT,                      LoadA32FToRGBA32F                    );
+    InsertLoadFunction(&map, GL_LUMINANCE32F_EXT,       GL_FLOAT,                      LoadL32FToRGBA32F                    );
+    InsertLoadFunction(&map, GL_LUMINANCE_ALPHA32F_EXT, GL_FLOAT,                      LoadLA32FToRGBA32F                   );
+    InsertLoadFunction(&map, GL_ALPHA16F_EXT,           GL_HALF_FLOAT,                 LoadA16FToRGBA16F                    );
+    InsertLoadFunction(&map, GL_ALPHA16F_EXT,           GL_HALF_FLOAT_OES,             LoadA16FToRGBA16F                    );
+    InsertLoadFunction(&map, GL_LUMINANCE16F_EXT,       GL_HALF_FLOAT,                 LoadL16FToRGBA16F                    );
+    InsertLoadFunction(&map, GL_LUMINANCE16F_EXT,       GL_HALF_FLOAT_OES,             LoadL16FToRGBA16F                    );
+    InsertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT,                 LoadLA16FToRGBA16F                   );
+    InsertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT_OES,             LoadLA16FToRGBA16F                   );
+
+    // From GL_ANGLE_depth_texture
+    InsertLoadFunction(&map, GL_DEPTH_COMPONENT32_OES,  GL_UNSIGNED_INT,               LoadR32ToR24G8                       );
+
+    // From GL_EXT_texture_format_BGRA8888
+    InsertLoadFunction(&map, GL_BGRA8_EXT,              GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 4>         );
+    InsertLoadFunction(&map, GL_BGRA4_ANGLEX,           GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, LoadRGBA4ToRGBA8                 );
+    InsertLoadFunction(&map, GL_BGRA4_ANGLEX,           GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 4>         );
+    InsertLoadFunction(&map, GL_BGR5_A1_ANGLEX,         GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, LoadRGB5A1ToRGBA8                );
+    InsertLoadFunction(&map, GL_BGR5_A1_ANGLEX,         GL_UNSIGNED_BYTE,                  LoadToNative<GLubyte, 4>         );
+
+    // Compressed formats
+    // From ES 3.0.1 spec, table 3.16
+    //                      | Internal format                             | Type            | Load function                  |
+    InsertLoadFunction(&map, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+    InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE, UnimplementedLoadFunction       );
+
+    // From GL_EXT_texture_compression_dxt1
+    InsertLoadFunction(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4,  8>);
+    InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4,  8>);
+
+    // From GL_ANGLE_texture_compression_dxt3
+    InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>);
+
+    // From GL_ANGLE_texture_compression_dxt5
+    InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>);
+
+    return map;
+}
+
+// For sized GL internal formats, there is only one corresponding D3D11 format. This map type allows
+// querying for the DXGI texture formats to use for textures, SRVs, RTVs and DSVs given a GL internal
+// format.
+typedef std::map<GLenum, TextureFormat> D3D11ES3FormatMap;
+
+TextureFormat::TextureFormat()
+    : texFormat(DXGI_FORMAT_UNKNOWN),
+      srvFormat(DXGI_FORMAT_UNKNOWN),
+      rtvFormat(DXGI_FORMAT_UNKNOWN),
+      dsvFormat(DXGI_FORMAT_UNKNOWN),
+      renderFormat(DXGI_FORMAT_UNKNOWN),
+      swizzleTexFormat(DXGI_FORMAT_UNKNOWN),
+      swizzleSRVFormat(DXGI_FORMAT_UNKNOWN),
+      swizzleRTVFormat(DXGI_FORMAT_UNKNOWN),
+      dataInitializerFunction(NULL),
+      loadFunctions()
+{
+}
+
+static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat,
+                                         DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
+{
+    TextureFormat info;
+    info.texFormat = texFormat;
+    info.srvFormat = srvFormat;
+    info.rtvFormat = rtvFormat;
+    info.dsvFormat = dsvFormat;
+
+    // Given a GL internal format, the renderFormat is the DSV format if it is depth- or stencil-renderable,
+    // the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise.
+    if (dsvFormat != DXGI_FORMAT_UNKNOWN)
+    {
+        info.renderFormat = dsvFormat;
+    }
+    else if (rtvFormat != DXGI_FORMAT_UNKNOWN)
+    {
+        info.renderFormat = rtvFormat;
+    }
+    else if (texFormat != DXGI_FORMAT_UNKNOWN)
+    {
+        info.renderFormat = texFormat;
+    }
+    else
+    {
+        info.renderFormat = DXGI_FORMAT_UNKNOWN;
+    }
+
+    // Compute the swizzle formats
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+    if (internalFormat != GL_NONE && formatInfo.pixelBytes > 0)
+    {
+        if (formatInfo.componentCount != 4 || texFormat == DXGI_FORMAT_UNKNOWN ||
+            srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN)
+        {
+            // 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
+        {
+            // The original texture format is suitable for swizzle operations
+            info.swizzleTexFormat = texFormat;
+            info.swizzleSRVFormat = srvFormat;
+            info.swizzleRTVFormat = rtvFormat;
+        }
+    }
+    else
+    {
+        // 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
+    static const InternalFormatInitializerMap initializerMap = BuildInternalFormatInitializerMap();
+    InternalFormatInitializerMap::const_iterator initializerIter = initializerMap.find(internalFormat);
+    info.dataInitializerFunction = (initializerIter != initializerMap.end()) ? initializerIter->second : NULL;
+
+    // Gather all the load functions for this internal format
+    static const D3D11LoadFunctionMap loadFunctions = BuildD3D11LoadFunctionMap();
+    D3D11LoadFunctionMap::const_iterator loadFunctionIter = loadFunctions.find(internalFormat);
+    if (loadFunctionIter != loadFunctions.end())
+    {
+        const std::vector<TypeLoadFunctionPair> &loadFunctionVector = loadFunctionIter->second;
+        for (size_t i = 0; i < loadFunctionVector.size(); i++)
+        {
+            GLenum type = loadFunctionVector[i].first;
+            LoadImageFunction function = loadFunctionVector[i].second;
+            info.loadFunctions.insert(std::make_pair(type, function));
+        }
+    }
+
+    map->insert(std::make_pair(internalFormat, info));
+}
+
+static D3D11ES3FormatMap BuildD3D11FormatMap()
+{
+    D3D11ES3FormatMap map;
+
+    //                         | GL internal format  | D3D11 texture format            | D3D11 SRV format               | D3D11 RTV format               | D3D11 DSV format   |
+    InsertD3D11FormatInfo(&map, GL_NONE,              DXGI_FORMAT_UNKNOWN,              DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R8,                DXGI_FORMAT_R8_UNORM,             DXGI_FORMAT_R8_UNORM,            DXGI_FORMAT_R8_UNORM,            DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R8_SNORM,          DXGI_FORMAT_R8_SNORM,             DXGI_FORMAT_R8_SNORM,            DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG8,               DXGI_FORMAT_R8G8_UNORM,           DXGI_FORMAT_R8G8_UNORM,          DXGI_FORMAT_R8G8_UNORM,          DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG8_SNORM,         DXGI_FORMAT_R8G8_SNORM,           DXGI_FORMAT_R8G8_SNORM,          DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB8,              DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB8_SNORM,        DXGI_FORMAT_R8G8B8A8_SNORM,       DXGI_FORMAT_R8G8B8A8_SNORM,      DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB565,            DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA4,             DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB5_A1,           DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA8,             DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA8_SNORM,       DXGI_FORMAT_R8G8B8A8_SNORM,       DXGI_FORMAT_R8G8B8A8_SNORM,      DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB10_A2,          DXGI_FORMAT_R10G10B10A2_UNORM,    DXGI_FORMAT_R10G10B10A2_UNORM,   DXGI_FORMAT_R10G10B10A2_UNORM,   DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB10_A2UI,        DXGI_FORMAT_R10G10B10A2_UINT,     DXGI_FORMAT_R10G10B10A2_UINT,    DXGI_FORMAT_R10G10B10A2_UINT,    DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_SRGB8,             DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,  DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_SRGB8_ALPHA8,      DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,  DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R16F,              DXGI_FORMAT_R16_FLOAT,            DXGI_FORMAT_R16_FLOAT,           DXGI_FORMAT_R16_FLOAT,           DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG16F,             DXGI_FORMAT_R16G16_FLOAT,         DXGI_FORMAT_R16G16_FLOAT,        DXGI_FORMAT_R16G16_FLOAT,        DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB16F,            DXGI_FORMAT_R16G16B16A16_FLOAT,   DXGI_FORMAT_R16G16B16A16_FLOAT,  DXGI_FORMAT_R16G16B16A16_FLOAT,  DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA16F,           DXGI_FORMAT_R16G16B16A16_FLOAT,   DXGI_FORMAT_R16G16B16A16_FLOAT,  DXGI_FORMAT_R16G16B16A16_FLOAT,  DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R32F,              DXGI_FORMAT_R32_FLOAT,            DXGI_FORMAT_R32_FLOAT,           DXGI_FORMAT_R32_FLOAT,           DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG32F,             DXGI_FORMAT_R32G32_FLOAT,         DXGI_FORMAT_R32G32_FLOAT,        DXGI_FORMAT_R32G32_FLOAT,        DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB32F,            DXGI_FORMAT_R32G32B32A32_FLOAT,   DXGI_FORMAT_R32G32B32A32_FLOAT,  DXGI_FORMAT_R32G32B32A32_FLOAT,  DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA32F,           DXGI_FORMAT_R32G32B32A32_FLOAT,   DXGI_FORMAT_R32G32B32A32_FLOAT,  DXGI_FORMAT_R32G32B32A32_FLOAT,  DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R11F_G11F_B10F,    DXGI_FORMAT_R11G11B10_FLOAT,      DXGI_FORMAT_R11G11B10_FLOAT,     DXGI_FORMAT_R11G11B10_FLOAT,     DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB9_E5,           DXGI_FORMAT_R9G9B9E5_SHAREDEXP,   DXGI_FORMAT_R9G9B9E5_SHAREDEXP,  DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R8I,               DXGI_FORMAT_R8_SINT,              DXGI_FORMAT_R8_SINT,             DXGI_FORMAT_R8_SINT,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R8UI,              DXGI_FORMAT_R8_UINT,              DXGI_FORMAT_R8_UINT,             DXGI_FORMAT_R8_UINT,             DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R16I,              DXGI_FORMAT_R16_SINT,             DXGI_FORMAT_R16_SINT,            DXGI_FORMAT_R16_SINT,            DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R16UI,             DXGI_FORMAT_R16_UINT,             DXGI_FORMAT_R16_UINT,            DXGI_FORMAT_R16_UINT,            DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R32I,              DXGI_FORMAT_R32_SINT,             DXGI_FORMAT_R32_SINT,            DXGI_FORMAT_R32_SINT,            DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_R32UI,             DXGI_FORMAT_R32_UINT,             DXGI_FORMAT_R32_UINT,            DXGI_FORMAT_R32_UINT,            DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG8I,              DXGI_FORMAT_R8G8_SINT,            DXGI_FORMAT_R8G8_SINT,           DXGI_FORMAT_R8G8_SINT,           DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG8UI,             DXGI_FORMAT_R8G8_UINT,            DXGI_FORMAT_R8G8_UINT,           DXGI_FORMAT_R8G8_UINT,           DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG16I,             DXGI_FORMAT_R16G16_SINT,          DXGI_FORMAT_R16G16_SINT,         DXGI_FORMAT_R16G16_SINT,         DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG16UI,            DXGI_FORMAT_R16G16_UINT,          DXGI_FORMAT_R16G16_UINT,         DXGI_FORMAT_R16G16_UINT,         DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG32I,             DXGI_FORMAT_R32G32_SINT,          DXGI_FORMAT_R32G32_SINT,         DXGI_FORMAT_R32G32_SINT,         DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RG32UI,            DXGI_FORMAT_R32G32_UINT,          DXGI_FORMAT_R32G32_UINT,         DXGI_FORMAT_R32G32_UINT,         DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB8I,             DXGI_FORMAT_R8G8B8A8_SINT,        DXGI_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB8UI,            DXGI_FORMAT_R8G8B8A8_UINT,        DXGI_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB16I,            DXGI_FORMAT_R16G16B16A16_SINT,    DXGI_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB16UI,           DXGI_FORMAT_R16G16B16A16_UINT,    DXGI_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB32I,            DXGI_FORMAT_R32G32B32A32_SINT,    DXGI_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB32UI,           DXGI_FORMAT_R32G32B32A32_UINT,    DXGI_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA8I,            DXGI_FORMAT_R8G8B8A8_SINT,        DXGI_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA8UI,           DXGI_FORMAT_R8G8B8A8_UINT,        DXGI_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA16I,           DXGI_FORMAT_R16G16B16A16_SINT,    DXGI_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA16UI,          DXGI_FORMAT_R16G16B16A16_UINT,    DXGI_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA32I,           DXGI_FORMAT_R32G32B32A32_SINT,    DXGI_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA32UI,          DXGI_FORMAT_R32G32B32A32_UINT,    DXGI_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_UNKNOWN);
+
+    // Unsized formats, TODO: Are types of float and half float allowed for the unsized types? Would it change the DXGI format?
+    InsertD3D11FormatInfo(&map, GL_ALPHA,             DXGI_FORMAT_A8_UNORM,             DXGI_FORMAT_A8_UNORM,            DXGI_FORMAT_A8_UNORM,            DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_LUMINANCE,         DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA,   DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGB,               DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_RGBA,              DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_BGRA_EXT,          DXGI_FORMAT_B8G8R8A8_UNORM,       DXGI_FORMAT_B8G8R8A8_UNORM,      DXGI_FORMAT_B8G8R8A8_UNORM,      DXGI_FORMAT_UNKNOWN);
+
+    // From GL_EXT_texture_storage
+    //                           | GL internal format     | D3D11 texture format          | D3D11 SRV format                    | D3D11 RTV format              | D3D11 DSV format               |
+    InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT,             DXGI_FORMAT_A8_UNORM,           DXGI_FORMAT_A8_UNORM,                 DXGI_FORMAT_A8_UNORM,           DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT,         DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,           DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT,           DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,       DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT,       DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,       DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_ALPHA16F_EXT,           DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,       DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_LUMINANCE16F_EXT,       DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,       DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT,  DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,           DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,       DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,       DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_BGRA8_EXT,              DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,           DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_BGRA4_ANGLEX,           DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,           DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN           );
+    InsertD3D11FormatInfo(&map, GL_BGR5_A1_ANGLEX,         DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,           DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN           );
+
+    // Depth stencil formats
+    InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT16,     DXGI_FORMAT_R16_TYPELESS,        DXGI_FORMAT_R16_UNORM,                DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D16_UNORM         );
+    InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT24,     DXGI_FORMAT_R24G8_TYPELESS,      DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D24_UNORM_S8_UINT );
+    InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT32F,    DXGI_FORMAT_R32_TYPELESS,        DXGI_FORMAT_R32_FLOAT,                DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D32_FLOAT         );
+    InsertD3D11FormatInfo(&map, GL_DEPTH24_STENCIL8,      DXGI_FORMAT_R24G8_TYPELESS,      DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D24_UNORM_S8_UINT );
+    InsertD3D11FormatInfo(&map, GL_DEPTH32F_STENCIL8,     DXGI_FORMAT_R32G8X24_TYPELESS,   DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
+    InsertD3D11FormatInfo(&map, GL_STENCIL_INDEX8,        DXGI_FORMAT_R24G8_TYPELESS,      DXGI_FORMAT_X24_TYPELESS_G8_UINT,     DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D24_UNORM_S8_UINT );
+
+    // From GL_ANGLE_depth_texture
+    // Since D3D11 doesn't have a D32_UNORM format, use D24S8 which has comparable precision and matches the ES3 format.
+    InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, DXGI_FORMAT_R24G8_TYPELESS,      DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_D24_UNORM_S8_UINT);
+
+    // Compressed formats, From ES 3.0.1 spec, table 3.16
+    //                           | GL internal format                        | D3D11 texture format | D3D11 SRV format     | D3D11 RTV format   | D3D11 DSV format  |
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_R11_EAC,                        DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_SIGNED_R11_EAC,                 DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_RG11_EAC,                       DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_SIGNED_RG11_EAC,                DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB8_ETC2,                      DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_ETC2,                     DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA8_ETC2_EAC,                 DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+
+    // From GL_EXT_texture_compression_dxt1
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+
+    // From GL_ANGLE_texture_compression_dxt3
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+
+    // From GL_ANGLE_texture_compression_dxt5
+    InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+
+    return map;
+}
+
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat)
+{
+    static const D3D11ES3FormatMap formatMap = BuildD3D11FormatMap();
+    D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat);
+    if (iter != formatMap.end())
+    {
+        return iter->second;
+    }
+    else
+    {
+        static const TextureFormat defaultInfo;
+        return defaultInfo;
+    }
+}
+
+typedef std::map<gl::VertexFormat, VertexFormat> D3D11VertexFormatInfoMap;
+typedef std::pair<gl::VertexFormat, VertexFormat> D3D11VertexFormatPair;
+
+VertexFormat::VertexFormat()
+    : conversionType(VERTEX_CONVERT_NONE),
+      nativeFormat(DXGI_FORMAT_UNKNOWN),
+      copyFunction(NULL)
+{
+}
+
+static void AddVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLboolean normalized, GLuint componentCount,
+                                VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction)
+{
+    gl::VertexFormat inputFormat(inputType, normalized, componentCount, false);
+
+    VertexFormat info;
+    info.conversionType = conversionType;
+    info.nativeFormat = nativeFormat;
+    info.copyFunction = copyFunction;
+
+    map->insert(D3D11VertexFormatPair(inputFormat, info));
+}
+
+static void AddIntegerVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLuint componentCount,
+                                       VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction)
+{
+    gl::VertexFormat inputFormat(inputType, GL_FALSE, componentCount, true);
+
+    VertexFormat info;
+    info.conversionType = conversionType;
+    info.nativeFormat = nativeFormat;
+    info.copyFunction = copyFunction;
+
+    map->insert(D3D11VertexFormatPair(inputFormat, info));
+}
+
+static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap()
+{
+    D3D11VertexFormatInfoMap map;
+
+    // TODO: column legend
+
+    //
+    // Float formats
+    //
+
+    // GL_BYTE -- un-normalized
+    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,           &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,            &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,           &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,           &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,          &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,           &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,          &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,           &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,          &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,           &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,          &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,          &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,          &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,          &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, &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, &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,           &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,           &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,          &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,          &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,          &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,          &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, &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, &CopyNativeVertexData<GLuint, 1, 0>);
+
+    return map;
+}
+
+const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat)
+{
+    static const D3D11VertexFormatInfoMap vertexFormatMap = BuildD3D11VertexFormatInfoMap();
+
+    D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMap.find(vertexFormat);
+    if (iter != vertexFormatMap.end())
+    {
+        return iter->second;
+    }
+    else
+    {
+        static const VertexFormat defaultInfo;
+        return defaultInfo;
+    }
+}
+
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h b/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h
new file mode 100644
index 0000000..ea11aaa
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h
@@ -0,0 +1,84 @@
+//
+// 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.
+//
+
+// formatutils11.h: Queries for GL image formats and their translations to D3D11
+// formats.
+
+#ifndef LIBGLESV2_RENDERER_FORMATUTILS11_H_
+#define LIBGLESV2_RENDERER_FORMATUTILS11_H_
+
+#include "libGLESv2/formatutils.h"
+
+#include <map>
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
+
+struct DXGIFormat
+{
+    DXGIFormat();
+
+    GLuint pixelBytes;
+    GLuint blockWidth;
+    GLuint blockHeight;
+
+    GLuint depthBits;
+    GLuint depthOffset;
+    GLuint stencilBits;
+    GLuint stencilOffset;
+
+    GLenum internalFormat;
+    GLenum componentType;
+
+    MipGenerationFunction mipGenerationFunction;
+    ColorReadFunction colorReadFunction;
+
+    FastCopyFunctionMap fastCopyFunctions;
+    ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
+};
+const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format);
+
+struct TextureFormat
+{
+    TextureFormat();
+
+    DXGI_FORMAT texFormat;
+    DXGI_FORMAT srvFormat;
+    DXGI_FORMAT rtvFormat;
+    DXGI_FORMAT dsvFormat;
+    DXGI_FORMAT renderFormat;
+
+    DXGI_FORMAT swizzleTexFormat;
+    DXGI_FORMAT swizzleSRVFormat;
+    DXGI_FORMAT swizzleRTVFormat;
+
+    InitializeTextureDataFunction dataInitializerFunction;
+
+    typedef std::map<GLenum, LoadImageFunction> LoadFunctionMap;
+    LoadFunctionMap loadFunctions;
+};
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat);
+
+struct VertexFormat
+{
+    VertexFormat();
+
+    VertexConversionType conversionType;
+    DXGI_FORMAT nativeFormat;
+    VertexCopyFunction copyFunction;
+};
+const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat);
+
+}
+
+}
+
+#endif // LIBGLESV2_RENDERER_FORMATUTILS11_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
new file mode 100644
index 0000000..b1867fb
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -0,0 +1,1076 @@
+//
+// 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
+// found in the LICENSE file.
+//
+
+// renderer11_utils.cpp: Conversion functions and other utility routines
+// specific to the D3D11 renderer.
+
+#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
+{
+
+namespace gl_d3d11
+{
+
+D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
+{
+    D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
+
+    switch (glBlend)
+    {
+      case GL_ZERO:                     d3dBlend = D3D11_BLEND_ZERO;                break;
+      case GL_ONE:                      d3dBlend = D3D11_BLEND_ONE;                 break;
+      case GL_SRC_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR);           break;
+      case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR);   break;
+      case GL_DST_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR);         break;
+      case GL_ONE_MINUS_DST_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break;
+      case GL_SRC_ALPHA:                d3dBlend = D3D11_BLEND_SRC_ALPHA;           break;
+      case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3D11_BLEND_INV_SRC_ALPHA;       break;
+      case GL_DST_ALPHA:                d3dBlend = D3D11_BLEND_DEST_ALPHA;          break;
+      case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3D11_BLEND_INV_DEST_ALPHA;      break;
+      case GL_CONSTANT_COLOR:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
+      case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
+      case GL_CONSTANT_ALPHA:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
+      case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
+      case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;       break;
+      default: UNREACHABLE();
+    }
+
+    return d3dBlend;
+}
+
+D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
+{
+    D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
+
+    switch (glBlendOp)
+    {
+      case GL_FUNC_ADD:              d3dBlendOp = D3D11_BLEND_OP_ADD;           break;
+      case GL_FUNC_SUBTRACT:         d3dBlendOp = D3D11_BLEND_OP_SUBTRACT;      break;
+      case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT;  break;
+      case GL_MIN:                   d3dBlendOp = D3D11_BLEND_OP_MIN;           break;
+      case GL_MAX:                   d3dBlendOp = D3D11_BLEND_OP_MAX;           break;
+      default: UNREACHABLE();
+    }
+
+    return d3dBlendOp;
+}
+
+UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+{
+    UINT8 mask = 0;
+    if (red)
+    {
+        mask |= D3D11_COLOR_WRITE_ENABLE_RED;
+    }
+    if (green)
+    {
+        mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
+    }
+    if (blue)
+    {
+        mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
+    }
+    if (alpha)
+    {
+        mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
+    }
+    return mask;
+}
+
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
+{
+    D3D11_CULL_MODE cull = D3D11_CULL_NONE;
+
+    if (cullEnabled)
+    {
+        switch (cullMode)
+        {
+          case GL_FRONT:            cull = D3D11_CULL_FRONT;    break;
+          case GL_BACK:             cull = D3D11_CULL_BACK;     break;
+          case GL_FRONT_AND_BACK:   cull = D3D11_CULL_NONE;     break;
+          default: UNREACHABLE();
+        }
+    }
+    else
+    {
+        cull = D3D11_CULL_NONE;
+    }
+
+    return cull;
+}
+
+D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
+{
+    D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
+    switch (comparison)
+    {
+      case GL_NEVER:    d3dComp = D3D11_COMPARISON_NEVER;           break;
+      case GL_ALWAYS:   d3dComp = D3D11_COMPARISON_ALWAYS;          break;
+      case GL_LESS:     d3dComp = D3D11_COMPARISON_LESS;            break;
+      case GL_LEQUAL:   d3dComp = D3D11_COMPARISON_LESS_EQUAL;      break;
+      case GL_EQUAL:    d3dComp = D3D11_COMPARISON_EQUAL;           break;
+      case GL_GREATER:  d3dComp = D3D11_COMPARISON_GREATER;         break;
+      case GL_GEQUAL:   d3dComp = D3D11_COMPARISON_GREATER_EQUAL;   break;
+      case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL;       break;
+      default: UNREACHABLE();
+    }
+
+    return d3dComp;
+}
+
+D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
+{
+    return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
+}
+
+UINT8 ConvertStencilMask(GLuint stencilmask)
+{
+    return static_cast<UINT8>(stencilmask);
+}
+
+D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
+{
+    D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
+
+    switch (stencilOp)
+    {
+      case GL_ZERO:      d3dStencilOp = D3D11_STENCIL_OP_ZERO;      break;
+      case GL_KEEP:      d3dStencilOp = D3D11_STENCIL_OP_KEEP;      break;
+      case GL_REPLACE:   d3dStencilOp = D3D11_STENCIL_OP_REPLACE;   break;
+      case GL_INCR:      d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT;  break;
+      case GL_DECR:      d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT;  break;
+      case GL_INVERT:    d3dStencilOp = D3D11_STENCIL_OP_INVERT;    break;
+      case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR;      break;
+      case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR;      break;
+      default: UNREACHABLE();
+    }
+
+    return d3dStencilOp;
+}
+
+D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode)
+{
+    bool comparison = comparisonMode != GL_NONE;
+
+    if (maxAnisotropy > 1.0f)
+    {
+        return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison));
+    }
+    else
+    {
+        D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
+        D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
+        switch (minFilter)
+        {
+          case GL_NEAREST:                dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_LINEAR:                 dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_LINEAR_MIPMAP_NEAREST:  dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_NEAREST_MIPMAP_LINEAR:  dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_LINEAR; break;
+          case GL_LINEAR_MIPMAP_LINEAR:   dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
+          default:                        UNREACHABLE();
+        }
+
+        D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
+        switch (magFilter)
+        {
+          case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_LINEAR:  dxMag = D3D11_FILTER_TYPE_LINEAR; break;
+          default:         UNREACHABLE();
+        }
+
+        return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, static_cast<D3D11_COMPARISON_FUNC>(comparison));
+    }
+}
+
+D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
+{
+    switch (wrap)
+    {
+      case GL_REPEAT:          return D3D11_TEXTURE_ADDRESS_WRAP;
+      case GL_CLAMP_TO_EDGE:   return D3D11_TEXTURE_ADDRESS_CLAMP;
+      case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR;
+      default:                 UNREACHABLE();
+    }
+
+    return D3D11_TEXTURE_ADDRESS_WRAP;
+}
+
+D3D11_QUERY ConvertQueryType(GLenum queryType)
+{
+    switch (queryType)
+    {
+      case GL_ANY_SAMPLES_PASSED_EXT:
+      case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   return D3D11_QUERY_OCCLUSION;
+      case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS;
+      default: UNREACHABLE();                        return D3D11_QUERY_EVENT;
+    }
+}
+
+}
+
+
+namespace d3d11_gl
+{
+
+static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11Device *device)
+{
+    gl::TextureCaps textureCaps;
+
+    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+
+    UINT formatSupport;
+    if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport)))
+    {
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+        if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+        {
+            textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0);
+        }
+        else
+        {
+            textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0) &&
+                                     ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE) != 0) &&
+                                     ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D) != 0);
+        }
+    }
+
+    if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) &&
+        ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0))
+    {
+        for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++)
+        {
+            UINT qualityCount = 0;
+            if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount)) &&
+                qualityCount > 0)
+            {
+                textureCaps.sampleCounts.insert(sampleCount);
+            }
+        }
+    }
+
+    textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) &&
+                             ((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0;
+    textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) &&
+                              ((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) ||
+                             (SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) &&
+                              ((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0));
+
+    return textureCaps;
+}
+
+static bool GetNPOTTextureSupport(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 true;
+
+        // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return false;
+
+      default: UNREACHABLE();      return false;
+    }
+}
+
+static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_MAX_MAXANISOTROPY;
+
+        // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:  return 16;
+
+      case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static bool GetOcclusionQuerySupport(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 true;
+
+        // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:  return true;
+      case D3D_FEATURE_LEVEL_9_1:  return false;
+
+      default: UNREACHABLE();      return false;
+    }
+}
+
+static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
+{
+    // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery
+
+    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:
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return true;
+
+      default: UNREACHABLE();      return false;
+    }
+}
+
+static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+    // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout
+
+    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:
+      case D3D_FEATURE_LEVEL_9_3:  return true;
+
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return false;
+
+      default: UNREACHABLE();      return false;
+    }
+}
+
+static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+    // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that shader model
+    // ps_2_x is required for the ddx (and other derivative functions).
+
+    // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that feature level
+    // 9.3 supports shader model ps_2_x.
+
+    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:
+      case D3D_FEATURE_LEVEL_9_3:  return true;
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return false;
+
+      default: UNREACHABLE();      return false;
+    }
+}
+
+static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel)
+{
+    // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout
+
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      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:
+      case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+      case D3D_FEATURE_LEVEL_9_3:  return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURECUBE_DIMENSION;
+
+      case D3D_FEATURE_LEVEL_9_3:  return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION;
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
+
+      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 GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
+
+      case D3D_FEATURE_LEVEL_9_3:
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
+{
+    switch (featureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_1:
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
+
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX;
+
+        // No constants for D3D9 viewport size limits, use the maximum texture sizes
+      case D3D_FEATURE_LEVEL_9_3:  return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+      case D3D_FEATURE_LEVEL_9_2:
+      case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+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;
+    const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
+    for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat)
+    {
+        gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, device);
+        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();
+
+    // GL core feature limits
+    caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
+    caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel);
+    caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel);
+    caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel);
+    caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel);
+
+    // Unimplemented, set to minimum required
+    caps->maxLODBias = 2.0f;
+
+    // No specific limits on render target size, maximum 2D texture size is equivalent
+    caps->maxRenderbufferSize = caps->max2DTextureSize;
+
+    // Maximum draw buffers and color attachments are the same, max color attachments could eventually be
+    // increased to 16
+    caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel);
+    caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel);
+
+    // D3D11 has the same limit for viewport width and height
+    caps->maxViewportWidth = GetMaximumViewportSize(featureLevel);
+    caps->maxViewportHeight = caps->maxViewportWidth;
+
+    // Choose a reasonable maximum, enforced in the shader.
+    caps->minAliasedPointSize = 1.0f;
+    caps->maxAliasedPointSize = 1024.0f;
+
+    // Wide lines not supported
+    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;
+    extensions->packedDepthStencil = true;
+    extensions->getProgramBinary = true;
+    extensions->rgb8rgba8 = true;
+    extensions->readFormatBGRA = true;
+    extensions->pixelBufferObject = true;
+    extensions->mapBuffer = true;
+    extensions->mapBufferRange = true;
+    extensions->textureNPOT = GetNPOTTextureSupport(featureLevel);
+    extensions->drawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel) > 1;
+    extensions->textureStorage = true;
+    extensions->textureFilterAnisotropic = true;
+    extensions->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel);
+    extensions->occlusionQueryBoolean = GetOcclusionQuerySupport(featureLevel);
+    extensions->fence = GetEventQuerySupport(featureLevel);
+    extensions->timerQuery = false; // Unimplemented
+    extensions->robustness = true;
+    extensions->blendMinMax = true;
+    extensions->framebufferBlit = true;
+    extensions->framebufferMultisample = true;
+    extensions->maxSamples = maxSamples;
+    extensions->instancedArrays = GetInstancingSupport(featureLevel);
+    extensions->packReverseRowOrder = true;
+    extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel);
+    extensions->shaderTextureLOD = true;
+    extensions->fragDepth = true;
+    extensions->textureUsage = true; // This could be false since it has no effect in D3D11
+    extensions->translatedShaderSource = true;
+}
+
+}
+
+namespace d3d11
+{
+
+void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
+{
+    const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
+
+    int upsampleCount = 0;
+    // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
+    if (isImage || *requestWidth  < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) ||
+                   *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight))
+    {
+        while (*requestWidth % dxgiFormatInfo.blockWidth != 0 || *requestHeight % dxgiFormatInfo.blockHeight != 0)
+        {
+            *requestWidth <<= 1;
+            *requestHeight <<= 1;
+            upsampleCount++;
+        }
+    }
+    *levelOffset = upsampleCount;
+}
+
+void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth,
+                                GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
+                                std::vector< std::vector<BYTE> > *outData)
+{
+    const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+    ASSERT(d3dFormatInfo.dataInitializerFunction != NULL);
+
+    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat);
+
+    outSubresourceData->resize(mipLevels);
+    outData->resize(mipLevels);
+
+    for (unsigned int i = 0; i < mipLevels; i++)
+    {
+        unsigned int mipWidth = std::max(width >> i, 1U);
+        unsigned int mipHeight = std::max(height >> i, 1U);
+        unsigned int mipDepth = std::max(depth >> i, 1U);
+
+        unsigned int rowWidth = dxgiFormatInfo.pixelBytes * mipWidth;
+        unsigned int imageSize = rowWidth * height;
+
+        outData->at(i).resize(rowWidth * mipHeight * mipDepth);
+        d3dFormatInfo.dataInitializerFunction(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize);
+
+        outSubresourceData->at(i).pSysMem = outData->at(i).data();
+        outSubresourceData->at(i).SysMemPitch = rowWidth;
+        outSubresourceData->at(i).SysMemSlicePitch = imageSize;
+    }
+}
+
+void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
+{
+    vertex->x = x;
+    vertex->y = y;
+    vertex->u = u;
+    vertex->v = v;
+}
+
+void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y,
+                                      unsigned int layer, float u, float v, float s)
+{
+    vertex->x = x;
+    vertex->y = y;
+    vertex->l = layer;
+    vertex->u = u;
+    vertex->v = v;
+    vertex->s = s;
+}
+
+HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
+{
+#if defined(_DEBUG)
+    return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
+#else
+    return S_OK;
+#endif
+}
+
+RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+{
+    RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
+    return RenderTarget11::makeRenderTarget11(renderTarget);
+}
+
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d11/renderer11_utils.h b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
similarity index 87%
rename from src/libGLESv2/renderer/d3d11/renderer11_utils.h
rename to src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
index 94bb8f8..4c05eb9 100644
--- a/src/libGLESv2/renderer/d3d11/renderer11_utils.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// 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
 // found in the LICENSE file.
 //
@@ -11,9 +11,18 @@
 #define LIBGLESV2_RENDERER_RENDERER11_UTILS_H
 
 #include "libGLESv2/angletypes.h"
+#include "libGLESv2/Caps.h"
+
+#include <vector>
+
+namespace gl
+{
+class FramebufferAttachment;
+}
 
 namespace rx
 {
+class RenderTarget11;
 
 namespace gl_d3d11
 {
@@ -36,10 +45,19 @@
 
 }
 
+namespace d3d11_gl
+{
+
+void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions);
+
+}
+
 namespace d3d11
 {
 
-void GenerateInitialTextureData(GLint internalFormat, GLuint clientVersion, GLuint width, GLuint height, GLuint depth,
+void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
+
+void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth,
                                 GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
                                 std::vector< std::vector<BYTE> > *outData);
 
@@ -158,6 +176,8 @@
     context->Unmap(constantBuffer, 0);
 }
 
+RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d11/shaders/BufferToTexture11.hlsl b/src/libGLESv2/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/BufferToTexture11.hlsl
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl
diff --git a/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl b/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl
diff --git a/src/libGLESv2/renderer/d3d11/shaders/Passthrough2D11.hlsl b/src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/Passthrough2D11.hlsl
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
diff --git a/src/libGLESv2/renderer/d3d11/shaders/Passthrough3D11.hlsl b/src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/Passthrough3D11.hlsl
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl
diff --git a/src/libGLESv2/renderer/d3d11/shaders/Swizzle11.hlsl b/src/libGLESv2/renderer/d3d/d3d11/shaders/Swizzle11.hlsl
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/Swizzle11.hlsl
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/Swizzle11.hlsl
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_gs.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_gs.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4f.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4f.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4i.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4i.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_vs.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_vs.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11vs.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11vs.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11vs.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11vs.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11vs.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11vs.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11gs.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11gs.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11vs.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11vs.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughdepth2d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughdepth2d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum2d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum2d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum3d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum3d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2di11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2di11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2dui11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2dui11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3di11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3di11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3dui11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3dui11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2di11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2di11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2dui11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2dui11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3di11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3di11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3dui11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3dui11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2di11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2di11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2dui11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2dui11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3di11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3di11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3dui11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3dui11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2di11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2di11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2dui11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2dui11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3d11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3d11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3di11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3di11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3dui11ps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3dui11ps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2darrayps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2darrayps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2dps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2dps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef3dps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef3dps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2darrayps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2darrayps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2dps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2dps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei3dps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei3dps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2darrayps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2darrayps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2dps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2dps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui3dps.h b/src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui3dps.h
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h
diff --git a/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat b/src/libGLESv2/renderer/d3d/d3d11/shaders/generate_shaders.bat
similarity index 100%
rename from src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat
rename to src/libGLESv2/renderer/d3d/d3d11/shaders/generate_shaders.bat
diff --git a/src/libGLESv2/renderer/d3d9/Blit9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
similarity index 91%
rename from src/libGLESv2/renderer/d3d9/Blit9.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
index 80a4375..80503d5 100644
--- a/src/libGLESv2/renderer/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
@@ -7,24 +6,24 @@
 
 // Blit9.cpp: Surface copy utility class.
 
-#include "libGLESv2/renderer/d3d9/Blit9.h"
-
-#include "libGLESv2/main.h"
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d9/TextureStorage9.h"
-#include "libGLESv2/renderer/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Blit9.h"
+#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
+#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/main.h"
 
 namespace
 {
-#include "libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h"
-#include "libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h"
-#include "libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h"
-#include "libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h"
-#include "libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h"
+// 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"
+#include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/luminanceps.h"
+#include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h"
 
 const BYTE* const g_shaderCode[] =
 {
@@ -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;
 
@@ -296,7 +295,7 @@
     dest->GetDesc(&destDesc);
 
     if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
-        d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat, mRenderer->getCurrentClientVersion()))   // Can use StretchRect
+        d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat))   // Can use StretchRect
     {
         RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
         HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
diff --git a/src/libGLESv2/renderer/d3d9/Blit9.h b/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
similarity index 87%
rename from src/libGLESv2/renderer/d3d9/Blit9.h
rename to src/libGLESv2/renderer/d3d/d3d9/Blit9.h
index 3635bca..46a3ee1 100644
--- a/src/libGLESv2/renderer/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
new file mode 100644
index 0000000..c02db51
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
@@ -0,0 +1,121 @@
+//
+// 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.
+//
+
+// Buffer9.cpp Defines the Buffer9 class.
+
+#include "libGLESv2/renderer/d3d/d3d9/Buffer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+Buffer9::Buffer9(rx::Renderer9 *renderer)
+    : BufferD3D(),
+      mRenderer(renderer),
+      mSize(0)
+{}
+
+Buffer9::~Buffer9()
+{
+    mSize = 0;
+}
+
+Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(Buffer9*, buffer));
+    return static_cast<Buffer9*>(buffer);
+}
+
+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, "Failed to resize internal buffer.");
+        }
+    }
+
+    mSize = size;
+    if (data)
+    {
+        memcpy(mMemory.data(), data, size);
+    }
+
+    invalidateStaticData();
+
+    if (usage == GL_STATIC_DRAW)
+    {
+        initializeStaticData();
+    }
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+void *Buffer9::getData()
+{
+    return mMemory.data();
+}
+
+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, "Failed to resize internal buffer.");
+        }
+    }
+
+    mSize = std::max(mSize, offset + size);
+    if (data)
+    {
+        memcpy(mMemory.data() + offset, data, size);
+    }
+
+    invalidateStaticData();
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+{
+    // Note: this method is currently unreachable
+    Buffer9* sourceBuffer = makeBuffer9(source);
+    ASSERT(sourceBuffer);
+
+    memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size);
+
+    invalidateStaticData();
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+// We do not support buffer mapping in D3D9
+gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
+{
+    UNREACHABLE();
+    return gl::Error(GL_INVALID_OPERATION);
+}
+
+gl::Error Buffer9::unmap()
+{
+    UNREACHABLE();
+    return gl::Error(GL_INVALID_OPERATION);
+}
+
+void Buffer9::markTransformFeedbackUsage()
+{
+    UNREACHABLE();
+}
+
+Renderer* Buffer9::getRenderer()
+{
+    return mRenderer;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
new file mode 100644
index 0000000..e78182f
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
@@ -0,0 +1,52 @@
+//
+// 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.
+//
+
+// Buffer9.h: Defines the rx::Buffer9 class which implements rx::BufferImpl via rx::BufferD3D.
+
+#ifndef LIBGLESV2_RENDERER_BUFFER9_H_
+#define LIBGLESV2_RENDERER_BUFFER9_H_
+
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
+#include "libGLESv2/angletypes.h"
+
+namespace rx
+{
+class Renderer9;
+
+class Buffer9 : public BufferD3D
+{
+  public:
+    Buffer9(rx::Renderer9 *renderer);
+    virtual ~Buffer9();
+
+    static Buffer9 *makeBuffer9(BufferImpl *buffer);
+
+    // BufferD3D implementation
+    virtual size_t getSize() const { return mSize; }
+    virtual bool supportsDirectBinding() const { return false; }
+    virtual Renderer* getRenderer();
+
+    // BufferImpl implementation
+    virtual gl::Error setData(const void* data, size_t size, GLenum usage);
+    virtual void *getData();
+    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:
+    DISALLOW_COPY_AND_ASSIGN(Buffer9);
+
+    rx::Renderer9 *mRenderer;
+    MemoryBuffer mMemory;
+    size_t mSize;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFER9_H_
diff --git a/src/libGLESv2/renderer/d3d9/Fence9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
similarity index 88%
rename from src/libGLESv2/renderer/d3d9/Fence9.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
index 372a8a4..e352a5f 100644
--- a/src/libGLESv2/renderer/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
@@ -7,10 +6,10 @@
 
 // Fence9.cpp: Defines the rx::Fence9 class.
 
-#include "libGLESv2/renderer/d3d9/Fence9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
+#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/main.h"
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
 
 namespace rx
 {
diff --git a/src/libGLESv2/renderer/d3d9/Fence9.h b/src/libGLESv2/renderer/d3d/d3d9/Fence9.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/Fence9.h
rename to src/libGLESv2/renderer/d3d/d3d9/Fence9.h
diff --git a/src/libGLESv2/renderer/d3d9/Image9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
similarity index 80%
rename from src/libGLESv2/renderer/d3d9/Image9.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
index 001858e..18383fb 100644
--- a/src/libGLESv2/renderer/d3d9/Image9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Image9.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,17 +7,17 @@
 // Image9.cpp: Implements the rx::Image9 class, which acts as the interface to
 // the actual underlying surfaces of a Texture.
 
-#include "libGLESv2/renderer/d3d9/Image9.h"
-
+#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/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d9/TextureStorage9.h"
 
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d9/formatutils9.h"
 
 namespace rx
 {
@@ -51,8 +50,8 @@
     ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
     ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height);
 
-    MipGenerationFunction mipFunction = d3d9::GetMipGenerationFunction(sourceDesc.Format);
-    ASSERT(mipFunction != NULL);
+    const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format);
+    ASSERT(d3dFormatInfo.mipGenerationFunction != NULL);
 
     D3DLOCKED_RECT sourceLocked = {0};
     result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
@@ -62,13 +61,13 @@
     result = destSurface->LockRect(&destLocked, NULL, 0);
     ASSERT(SUCCEEDED(result));
 
-    const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(sourceLocked.pBits);
-    unsigned char *destData = reinterpret_cast<unsigned char*>(destLocked.pBits);
+    const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(sourceLocked.pBits);
+    uint8_t *destData = reinterpret_cast<uint8_t*>(destLocked.pBits);
 
     if (sourceData && destData)
     {
-        mipFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
-                    destData, destLocked.Pitch, 0);
+        d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
+                                            destData, destLocked.Pitch, 0);
     }
 
     destSurface->UnlockRect();
@@ -97,22 +96,23 @@
 {
     D3DLOCKED_RECT sourceLock = {0};
     D3DLOCKED_RECT destLock = {0};
-    
+
     source->LockRect(&sourceLock, NULL, 0);
     dest->LockRect(&destLock, NULL, 0);
-    
+
     if (sourceLock.pBits && destLock.pBits)
     {
         D3DSURFACE_DESC desc;
         source->GetDesc(&desc);
 
-        int blockHeight = d3d9::GetBlockHeight(desc.Format);
-        int rows = desc.Height / blockHeight;
+        const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+        unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
 
-        int bytes = d3d9::GetBlockSize(desc.Format, desc.Width, blockHeight);
-        ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch);
+        unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
+        ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
+               bytes <= static_cast<unsigned int>(destLock.Pitch));
 
-        for(int i = 0; i < rows; i++)
+        for(unsigned int i = 0; i < rows; i++)
         {
             memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
         }
@@ -145,12 +145,14 @@
         mInternalFormat = internalformat;
 
         // compute the d3d format that will be used
-        mD3DFormat = gl_d3d9::GetTextureFormat(internalformat, mRenderer);
-        mActualFormat = d3d9_gl::GetInternalFormat(mD3DFormat);
-        mRenderable = gl_d3d9::GetRenderFormat(internalformat, mRenderer) != D3DFMT_UNKNOWN;
+        const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+        const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat);
+        mD3DFormat = d3d9FormatInfo.texFormat;
+        mActualFormat = d3dFormatInfo.internalFormat;
+        mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN);
 
         SafeRelease(mSurface);
-        mDirty = gl_d3d9::RequiresTextureDataInitialization(mInternalFormat);
+        mDirty = (d3d9FormatInfo.dataInitializerFunction != NULL);
 
         return true;
     }
@@ -192,10 +194,9 @@
         newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
         SafeRelease(newTexture);
 
-        if (gl_d3d9::RequiresTextureDataInitialization(mInternalFormat))
+        const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
+        if (d3dFormatInfo.dataInitializerFunction != NULL)
         {
-            InitializeTextureDataFunction initializeFunc = gl_d3d9::GetTextureDataInitializationFunction(mInternalFormat);
-
             RECT entireRect;
             entireRect.left = 0;
             entireRect.right = mWidth;
@@ -206,7 +207,8 @@
             result = newSurface->LockRect(&lockedRect, &entireRect, 0);
             ASSERT(SUCCEEDED(result));
 
-            initializeFunc(mWidth, mHeight, 1, lockedRect.pBits, lockedRect.Pitch, 0);
+            d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits),
+                                                  lockedRect.Pitch, 0);
 
             result = newSurface->UnlockRect();
             ASSERT(SUCCEEDED(result));
@@ -258,7 +260,7 @@
 {
     // Make sure to that this image is marked as dirty even if the staging texture hasn't been created yet
     // if initialization is required before use.
-    return (mSurface || gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) && mDirty;
+    return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty;
 }
 
 IDirect3DSurface9 *Image9::getSurface()
@@ -268,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));
 }
 
@@ -299,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();
@@ -366,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));
@@ -385,11 +387,11 @@
     // 3D textures are not supported by the D3D9 backend.
     ASSERT(zoffset == 0 && depth == 1);
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, type, clientVersion, width, unpackAlignment);
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
+    GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
 
-    LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat, mRenderer);
-    ASSERT(loadFunction != NULL);
+    const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
+    ASSERT(d3dFormatInfo.loadFunction != NULL);
 
     RECT lockRect =
     {
@@ -404,7 +406,9 @@
         return;
     }
 
-    loadFunction(width, height, depth, input, inputRowPitch, 0, locked.pBits, locked.Pitch, 0);
+    d3dFormatInfo.loadFunction(width, height, depth,
+                               reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0,
+                               reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
 
     unlock();
 }
@@ -415,15 +419,16 @@
     // 3D textures are not supported by the D3D9 backend.
     ASSERT(zoffset == 0 && depth == 1);
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion, width, 1);
-    GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion, width, height, 1);
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
+    GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
+    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
 
-    ASSERT(xoffset % d3d9::GetBlockWidth(mD3DFormat) == 0);
-    ASSERT(yoffset % d3d9::GetBlockHeight(mD3DFormat) == 0);
+    const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
 
-    LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat, mRenderer);
-    ASSERT(loadFunction != NULL);
+    ASSERT(xoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0);
+    ASSERT(yoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0);
+
+    ASSERT(d3d9FormatInfo.loadFunction != NULL);
 
     RECT lockRect =
     {
@@ -438,8 +443,9 @@
         return;
     }
 
-    loadFunction(width, height, depth, input, inputRowPitch, inputDepthPitch,
-                 locked.pBits, locked.Pitch, 0);
+    d3d9FormatInfo.loadFunction(width, height, depth,
+                                reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
+                                reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
 
     unlock();
 }
@@ -456,9 +462,9 @@
 
     if (colorbuffer)
     {
-        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
     }
-    
+
     if (renderTarget)
     {
         surface = renderTarget->getSurface();
@@ -475,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))
@@ -511,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/d3d9/Image9.h b/src/libGLESv2/renderer/d3d/d3d9/Image9.h
similarity index 68%
rename from src/libGLESv2/renderer/d3d9/Image9.h
rename to src/libGLESv2/renderer/d3d/d3d9/Image9.h
index 8b5ba89..08d8ee3 100644
--- a/src/libGLESv2/renderer/d3d9/Image9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Image9.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -10,7 +10,7 @@
 #ifndef LIBGLESV2_RENDERER_IMAGE9_H_
 #define LIBGLESV2_RENDERER_IMAGE9_H_
 
-#include "libGLESv2/renderer/Image.h"
+#include "libGLESv2/renderer/d3d/ImageD3D.h"
 #include "common/debug.h"
 
 namespace gl
@@ -22,10 +22,8 @@
 {
 class Renderer;
 class Renderer9;
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
 
-class Image9 : public Image
+class Image9 : public ImageD3D
 {
   public:
     Image9();
@@ -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
new file mode 100644
index 0000000..1c51b9e
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp
@@ -0,0 +1,173 @@
+//
+// 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.
+//
+
+// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
+
+#include "libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+
+namespace rx
+{
+
+IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
+{
+    mIndexBuffer = NULL;
+    mBufferSize = 0;
+    mIndexType = 0;
+    mDynamic = false;
+}
+
+IndexBuffer9::~IndexBuffer9()
+{
+    SafeRelease(mIndexBuffer);
+}
+
+gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+{
+    SafeRelease(mIndexBuffer);
+
+    updateSerial();
+
+    if (bufferSize > 0)
+    {
+        D3DFORMAT format = D3DFMT_UNKNOWN;
+        if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
+        {
+            format = D3DFMT_INDEX16;
+        }
+        else if (indexType == GL_UNSIGNED_INT)
+        {
+            ASSERT(mRenderer->getRendererExtensions().elementIndexUint);
+            format = D3DFMT_INDEX32;
+        }
+        else UNREACHABLE();
+
+        DWORD usageFlags = D3DUSAGE_WRITEONLY;
+        if (dynamic)
+        {
+            usageFlags |= D3DUSAGE_DYNAMIC;
+        }
+
+        HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
+        if (FAILED(result))
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
+        }
+    }
+
+    mBufferSize = bufferSize;
+    mIndexType = indexType;
+    mDynamic = dynamic;
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer));
+    return static_cast<IndexBuffer9*>(indexBuffer);
+}
+
+gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+{
+    if (!mIndexBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
+    }
+
+    DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
+
+    void *mapPtr = NULL;
+    HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
+    if (FAILED(result))
+    {
+        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);
+}
+
+gl::Error IndexBuffer9::unmapBuffer()
+{
+    if (!mIndexBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
+    }
+
+    HRESULT 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);
+}
+
+GLenum IndexBuffer9::getIndexType() const
+{
+    return mIndexType;
+}
+
+unsigned int IndexBuffer9::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
+{
+    if (bufferSize > mBufferSize || indexType != mIndexType)
+    {
+        return initialize(bufferSize, indexType, mDynamic);
+    }
+    else
+    {
+        return gl::Error(GL_NO_ERROR);
+    }
+}
+
+gl::Error IndexBuffer9::discard()
+{
+    if (!mIndexBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
+    }
+
+    void *dummy;
+    HRESULT result;
+
+    result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+    if (FAILED(result))
+    {
+        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
+{
+    switch (mIndexType)
+    {
+      case GL_UNSIGNED_BYTE:    return D3DFMT_INDEX16;
+      case GL_UNSIGNED_SHORT:   return D3DFMT_INDEX16;
+      case GL_UNSIGNED_INT:     return D3DFMT_INDEX32;
+      default: UNREACHABLE();   return D3DFMT_UNKNOWN;
+    }
+}
+
+IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const
+{
+    return mIndexBuffer;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d9/IndexBuffer9.h b/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
similarity index 72%
rename from src/libGLESv2/renderer/d3d9/IndexBuffer9.h
rename to src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
index 6801867..d0970d6 100644
--- a/src/libGLESv2/renderer/d3d9/IndexBuffer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
@@ -9,7 +9,7 @@
 #ifndef LIBGLESV2_RENDERER_INDEXBUFFER9_H_
 #define LIBGLESV2_RENDERER_INDEXBUFFER9_H_
 
-#include "libGLESv2/renderer/IndexBuffer.h"
+#include "libGLESv2/renderer/d3d/IndexBuffer.h"
 
 namespace rx
 {
@@ -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
new file mode 100644
index 0000000..815fc01
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
@@ -0,0 +1,144 @@
+//
+// 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.
+//
+
+// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl.
+
+#include "libGLESv2/renderer/d3d/d3d9/Query9.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),
+      mResult(GL_FALSE),
+      mQueryFinished(false),
+      mRenderer(renderer),
+      mQuery(NULL)
+{
+}
+
+Query9::~Query9()
+{
+    SafeRelease(mQuery);
+}
+
+gl::Error Query9::begin()
+{
+    if (mQuery == NULL)
+    {
+        HRESULT result = mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery);
+        if (FAILED(result))
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result);
+        }
+    }
+
+    HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
+    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);
+}
+
+gl::Error Query9::end()
+{
+    ASSERT(mQuery);
+
+    HRESULT result = mQuery->Issue(D3DISSUE_END);
+    ASSERT(SUCCEEDED(result));
+    if (FAILED(result))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to end internal query, result: 0x%X.", result);
+    }
+
+    mQueryFinished = false;
+    mResult = GL_FALSE;
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Query9::getResult(GLuint *params)
+{
+    while (!mQueryFinished)
+    {
+        gl::Error error = testQuery();
+        if (error.isError())
+        {
+            return error;
+        }
+
+        if (!mQueryFinished)
+        {
+            Sleep(0);
+        }
+    }
+
+    ASSERT(mQueryFinished);
+    *params = mResult;
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Query9::isResultAvailable(GLuint *available)
+{
+    gl::Error error = testQuery();
+    if (error.isError())
+    {
+        return error;
+    }
+
+    *available = (mQueryFinished ? GL_TRUE : GL_FALSE);
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Query9::testQuery()
+{
+    if (!mQueryFinished)
+    {
+        ASSERT(mQuery);
+
+        DWORD numPixels = 0;
+
+        HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
+        if (hres == S_OK)
+        {
+            mQueryFinished = true;
+
+            switch (getType())
+            {
+              case GL_ANY_SAMPLES_PASSED_EXT:
+              case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+                mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
+                break;
+
+              default:
+                UNREACHABLE();
+                break;
+            }
+        }
+        else if (d3d9::isDeviceLostError(hres))
+        {
+            mRenderer->notifyDeviceLost();
+            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, "Failed to test get query result, device is lost.");
+        }
+    }
+
+    return gl::Error(GL_NO_ERROR);
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d9/Query9.h b/src/libGLESv2/renderer/d3d/d3d9/Query9.h
similarity index 73%
rename from src/libGLESv2/renderer/d3d9/Query9.h
rename to src/libGLESv2/renderer/d3d/d3d9/Query9.h
index 6290623..513e0ba 100644
--- a/src/libGLESv2/renderer/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/d3d9/RenderTarget9.cpp b/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
similarity index 72%
rename from src/libGLESv2/renderer/d3d9/RenderTarget9.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
index a3f2e70..13321ac 100644
--- a/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// 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
 // found in the LICENSE file.
 //
@@ -8,11 +7,10 @@
 // RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9
 // pointers retained by renderbuffers.
 
-#include "libGLESv2/renderer/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
-
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d9/formatutils9.h"
+#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"
 
 namespace rx
@@ -33,8 +31,9 @@
         mHeight = description.Height;
         mDepth = 1;
 
-        mInternalFormat = d3d9_gl::GetInternalFormat(description.Format);
-        mActualFormat = d3d9_gl::GetInternalFormat(description.Format);
+        const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format);
+        mInternalFormat = d3dFormatInfo.internalFormat;
+        mActualFormat = d3dFormatInfo.internalFormat;
         mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType);
     }
 }
@@ -44,38 +43,31 @@
     mRenderer = Renderer9::makeRenderer9(renderer);
     mRenderTarget = NULL;
 
-    D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat, mRenderer);
-    int supportedSamples = mRenderer->getNearestSupportedSamples(renderFormat, samples);
+    const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
+    const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.renderFormat);
 
-    if (supportedSamples == -1)
-    {
-        gl::error(GL_OUT_OF_MEMORY);
-
-        return;
-    }
+    const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
+    GLuint supportedSamples = textureCaps.getNearestSamples(samples);
 
     HRESULT result = D3DERR_INVALIDCALL;
 
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
     if (width > 0 && height > 0)
     {
         IDirect3DDevice9 *device = mRenderer->getDevice();
 
         bool requiresInitialization = false;
 
-        if (gl::GetDepthBits(internalFormat, clientVersion) > 0 ||
-            gl::GetStencilBits(internalFormat, clientVersion) > 0)
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+        if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
         {
-            result = device->CreateDepthStencilSurface(width, height, renderFormat,
+            result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat,
                                                        gl_d3d9::GetMultisampleType(supportedSamples),
                                                        0, FALSE, &mRenderTarget, NULL);
         }
         else
         {
-            requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat);
-
-            result = device->CreateRenderTarget(width, height, renderFormat,
+            requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
+            result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
                                                 gl_d3d9::GetMultisampleType(supportedSamples),
                                                 0, FALSE, &mRenderTarget, NULL);
         }
@@ -107,7 +99,7 @@
     mDepth = 1;
     mInternalFormat = internalFormat;
     mSamples = supportedSamples;
-    mActualFormat = d3d9_gl::GetInternalFormat(renderFormat);
+    mActualFormat = d3dFormatInfo.internalFormat;
 }
 
 RenderTarget9::~RenderTarget9()
diff --git a/src/libGLESv2/renderer/d3d9/RenderTarget9.h b/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/RenderTarget9.h
rename to src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
similarity index 72%
rename from src/libGLESv2/renderer/d3d9/Renderer9.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index 7d6dd7a..dd75048 100644
--- a/src/libGLESv2/renderer/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,35 +6,42 @@
 
 // Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer.
 
-#include "common/utilities.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/renderer/d3d/d3d9/ShaderExecutable9.h"
+#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
+#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Image9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Blit9.h"
+#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Buffer9.h"
+#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/renderer/IndexDataManager.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d9/ShaderExecutable9.h"
-#include "libGLESv2/renderer/d3d9/SwapChain9.h"
-#include "libGLESv2/renderer/d3d9/TextureStorage9.h"
-#include "libGLESv2/renderer/d3d9/Image9.h"
-#include "libGLESv2/renderer/d3d9/Blit9.h"
-#include "libGLESv2/renderer/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d9/VertexBuffer9.h"
-#include "libGLESv2/renderer/d3d9/IndexBuffer9.h"
-#include "libGLESv2/renderer/d3d9/BufferStorage9.h"
-#include "libGLESv2/renderer/d3d9/Query9.h"
-#include "libGLESv2/renderer/d3d9/Fence9.h"
 #include "libGLESv2/angletypes.h"
 
 #include "libEGL/Display.h"
 
+#include "common/utilities.h"
+
 #include "third_party/trace_event/trace_event.h"
-#include "third_party/systeminfo/SystemInfo.h"
+
+#include <sstream>
 
 // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
 #define REF_RAST 0
@@ -92,7 +98,9 @@
     MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
 };
 
-Renderer9::Renderer9(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
+Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay)
+    : Renderer(display),
+      mDc(hDc)
 {
     mD3d9Module = NULL;
 
@@ -113,13 +121,12 @@
 
     mDeviceLost = false;
 
-    mMaxSupportedSamples = 0;
-
     mMaskedClearSavedState = NULL;
 
     mVertexDataManager = NULL;
     mIndexDataManager = NULL;
     mLineLoopIB = NULL;
+    mCountingIB = NULL;
 
     mMaxNullColorbufferLRU = 0;
     for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
@@ -146,11 +153,12 @@
         }
     }
 
-    deinitialize();
+    release();
 }
 
-void Renderer9::deinitialize()
+void Renderer9::release()
 {
+    releaseShaderCompiler();
     releaseDeviceResources();
 
     SafeRelease(mDevice);
@@ -264,15 +272,6 @@
         mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
     }
 
-    // ATI cards on XP have problems with non-power-of-two textures.
-    mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
-        !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
-        !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
-        !(!isWindowsVistaOrGreater() && mAdapterIdentifier.VendorId == VENDOR_ID_AMD);
-
-    // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec
-    mSupportsTextureFilterAnisotropy = ((mDeviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) && (mDeviceCaps.MaxAnisotropy >= 2));
-
     mMinSwapInterval = 4;
     mMaxSwapInterval = 0;
 
@@ -302,17 +301,6 @@
         mMaxSwapInterval = std::max(mMaxSwapInterval, 4);
     }
 
-    mMaxSupportedSamples = 0;
-
-    const d3d9::D3DFormatSet &d3d9Formats = d3d9::GetAllUsedD3DFormats();
-    for (d3d9::D3DFormatSet::const_iterator i = d3d9Formats.begin(); i != d3d9Formats.end(); ++i)
-    {
-        TRACE_EVENT0("gpu", "getMultiSampleSupport");
-        MultisampleSupportInfo support = getMultiSampleSupport(*i);
-        mMultiSampleSupport[*i] = support;
-        mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples);
-    }
-
     static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
     static const TCHAR className[] = TEXT("STATIC");
 
@@ -358,36 +346,6 @@
         mPixelShaderCache.initialize(mDevice);
     }
 
-    // Check occlusion query support
-    IDirect3DQuery9 *occlusionQuery = NULL;
-    {
-        TRACE_EVENT0("gpu", "device_CreateQuery");
-        if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery)
-        {
-            SafeRelease(occlusionQuery);
-            mOcclusionQuerySupport = true;
-        }
-        else
-        {
-            mOcclusionQuerySupport = false;
-        }
-    }
-
-    // Check event query support
-    IDirect3DQuery9 *eventQuery = NULL;
-    {
-        TRACE_EVENT0("gpu", "device_CreateQuery2");
-        if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery)
-        {
-            SafeRelease(eventQuery);
-            mEventQuerySupport = true;
-        }
-        else
-        {
-            mEventQuerySupport = false;
-        }
-    }
-
     D3DDISPLAYMODE currentDisplayMode;
     mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
 
@@ -398,97 +356,8 @@
                             SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
                                                                D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F));
 
-    // Check RGB565 texture support
-    mRGB565TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
-                                                               D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_R5G6B5));
-
-    // Check depth texture support
-    // we use INTZ for depth textures in Direct3D9
-    // we also want NULL texture support to ensure the we can make depth-only FBOs
-    // see http://aras-p.info/texts/D3D9GPUHacks.html
-    mDepthTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
-                                                              D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ)) &&
-                           SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
-                                                              D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL));
-
-    // Check 32 bit floating point texture support
-    mFloat32FilterSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
-                                                               D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
-                            SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
-                                                               D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
-
-    mFloat32RenderSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
-                                                               D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
-                            SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
-                                                               D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
-
-    if (!mFloat32FilterSupport && !mFloat32RenderSupport)
-    {
-        mFloat32TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
-                                                                    D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
-                                 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
-                                                                    D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
-    }
-    else
-    {
-        mFloat32TextureSupport = true;
-    }
-
-    // Check 16 bit floating point texture support
-    mFloat16FilterSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
-                                                               D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
-                            SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
-                                                               D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
-
-    mFloat16RenderSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
-                                                               D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
-                            SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
-                                                               D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
-
-    if (!mFloat16FilterSupport && !mFloat16RenderSupport)
-    {
-        mFloat16TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
-                                                                    D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
-                                 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
-                                                                    D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
-    }
-    else
-    {
-        mFloat16TextureSupport = true;
-    }
-
-    D3DFORMAT rgTextureFormats[] =
-    {
-        D3DFMT_R16F,
-        D3DFMT_G16R16F,
-        D3DFMT_R32F,
-        D3DFMT_G32R32F,
-    };
-
-    mRGTextureSupport = true;
-    for (unsigned int i = 0; i < ArraySize(rgTextureFormats); i++)
-    {
-        D3DFORMAT fmt = rgTextureFormats[i];
-        mRGTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, fmt)) &&
-                            SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt)) &&
-                            SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, D3DRTYPE_CUBETEXTURE, fmt)) &&
-                            SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE, fmt));
-    }
-
-
-    // Check DXT texture support
-    mDXT1TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
-    mDXT3TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
-    mDXT5TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
-
-    // Check luminance[alpha] texture support
-    mLuminanceTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
-    mLuminanceAlphaTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
-
     initializeDevice();
 
-    d3d9::InitializeVertexTranslations(this);
-
     return EGL_SUCCESS;
 }
 
@@ -510,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;
@@ -554,40 +434,24 @@
 
     for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
     {
-        D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
-
-        HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
-
-        if (SUCCEEDED(result))
+        const d3d9::D3DFormat &renderTargetFormatInfo = d3d9::GetD3DFormatInfo(RenderTargetFormats[formatIndex]);
+        const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat);
+        if (renderTargetFormatCaps.renderable)
         {
             for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
             {
-                D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
-                HRESULT result = D3D_OK;
-
-                if(depthStencilFormat != D3DFMT_UNKNOWN)
+                const d3d9::D3DFormat &depthStencilFormatInfo = d3d9::GetD3DFormatInfo(DepthStencilFormats[depthStencilIndex]);
+                const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat);
+                if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == D3DFMT_UNKNOWN)
                 {
-                    result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
-                }
+                    ConfigDesc newConfig;
+                    newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat;
+                    newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat;
+                    newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
+                    newConfig.fastConfig = (currentDisplayMode.Format == RenderTargetFormats[formatIndex]);
+                    newConfig.es3Capable = false;
 
-                if (SUCCEEDED(result))
-                {
-                    if(depthStencilFormat != D3DFMT_UNKNOWN)
-                    {
-                        result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
-                    }
-
-                    if (SUCCEEDED(result))
-                    {
-                        ConfigDesc newConfig;
-                        newConfig.renderTargetFormat = d3d9_gl::GetInternalFormat(renderTargetFormat);
-                        newConfig.depthStencilFormat = d3d9_gl::GetInternalFormat(depthStencilFormat);
-                        newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
-                        newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat);
-                        newConfig.es3Capable = false;
-
-                        (*configDescList)[numConfigs++] = newConfig;
-                    }
+                    (*configDescList)[numConfigs++] = newConfig;
                 }
             }
         }
@@ -733,9 +597,14 @@
     return new IndexBuffer9(this);
 }
 
-BufferStorage *Renderer9::createBufferStorage()
+BufferImpl *Renderer9::createBuffer()
 {
-    return new BufferStorage9();
+    return new Buffer9(this);
+}
+
+VertexArrayImpl *Renderer9::createVertexArray()
+{
+    return new VertexArray9(this);
 }
 
 QueryImpl *Renderer9::createQuery(GLenum type)
@@ -748,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.
@@ -770,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)
     {
@@ -787,7 +661,7 @@
         mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
         mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
         mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.baseLevel);
-        if (mSupportsTextureFilterAnisotropy)
+        if (getRendererExtensions().textureFilterAnisotropic)
         {
             mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
         }
@@ -805,14 +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)
     {
-        TextureStorageInterface *texStorage = texture->getNativeTexture();
+        TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
+
+        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
@@ -820,7 +696,8 @@
         ASSERT(d3dTexture != NULL);
 
         serial = texture->getTextureSerial();
-        forceSetTexture = texture->hasDirtyImages();
+        forceSetTexture = textureImpl->hasDirtyImages();
+        textureImpl->resetDirty();
     }
 
     if (forceSetTexture || appliedSerials[index] != serial)
@@ -932,7 +809,6 @@
 
         gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer();
         GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE;
-        GLuint clientVersion = getCurrentClientVersion();
 
         // Set the color mask
         bool zeroColorMaskAllowed = getAdapterVendor() != VENDOR_ID_AMD;
@@ -942,10 +818,11 @@
         // drawing is done.
         // http://code.google.com/p/angleproject/issues/detail?id=169
 
-        DWORD colorMask = gl_d3d9::ConvertColorMask(gl::GetRedBits(internalFormat, clientVersion) > 0 && blendState.colorMaskRed,
-                                                    gl::GetGreenBits(internalFormat, clientVersion) > 0 && blendState.colorMaskGreen,
-                                                    gl::GetBlueBits(internalFormat, clientVersion) > 0 && blendState.colorMaskBlue,
-                                                    gl::GetAlphaBits(internalFormat, clientVersion) > 0 && blendState.colorMaskAlpha);
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+        DWORD colorMask = gl_d3d9::ConvertColorMask(formatInfo.redBits   > 0 && blendState.colorMaskRed,
+                                                    formatInfo.greenBits > 0 && blendState.colorMaskGreen,
+                                                    formatInfo.blueBits  > 0 && blendState.colorMaskBlue,
+                                                    formatInfo.alphaBits > 0 && blendState.colorMaskAlpha);
         if (colorMask == 0 && !zeroColorMaskAllowed)
         {
             // Enable green channel, but set blending so nothing will be drawn.
@@ -1014,13 +891,10 @@
             const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
             const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
             const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
-            if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
-                stencilRef != stencilBackRef ||
-                depthStencilState.stencilMask != depthStencilState.stencilBackMask)
-            {
-                ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
-                return gl::error(GL_INVALID_OPERATION);
-            }
+
+            ASSERT(depthStencilState.stencilWritemask == depthStencilState.stencilBackWritemask);
+            ASSERT(stencilRef == stencilBackRef);
+            ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask);
 
             // get the maximum size of the stencil ref
             unsigned int maxStencil = (1 << mCurStencilSize) - 1;
@@ -1101,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;
@@ -1125,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 ||
@@ -1182,7 +1051,6 @@
     }
 
     mForceSetViewport = false;
-    return true;
 }
 
 bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
@@ -1218,7 +1086,8 @@
         mPrimitiveCount = count - 2;
         break;
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        UNREACHABLE();
+        return false;
     }
 
     return mPrimitiveCount > 0;
@@ -1248,7 +1117,8 @@
         }
     }
 
-    gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment(this, 0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
+    gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
+    gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer);
 
     // add nullbuffer to the cache
     NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0];
@@ -1273,32 +1143,28 @@
 {
     // if there is no color attachment we must synthesize a NULL colorattachment
     // to keep the D3D runtime happy.  This should only be possible if depth texturing.
-    gl::FramebufferAttachment *renderbufferObject = NULL;
-    if (framebuffer->getColorbufferType(0) != GL_NONE)
+    gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(0);
+    if (!attachment)
     {
-        renderbufferObject = framebuffer->getColorbuffer(0);
+        attachment = getNullColorbuffer(framebuffer->getDepthbuffer());
     }
-    else
-    {
-        renderbufferObject = getNullColorbuffer(framebuffer->getDepthbuffer());
-    }
-    if (!renderbufferObject)
+    if (!attachment)
     {
         ERR("unable to locate renderbuffer for FBO.");
         return false;
     }
 
     bool renderTargetChanged = false;
-    unsigned int renderTargetSerial = renderbufferObject->getSerial();
+    unsigned int renderTargetSerial = GetAttachmentSerial(attachment);
     if (renderTargetSerial != mAppliedRenderTargetSerial)
     {
         // Apply the render target on the device
         IDirect3DSurface9 *renderTargetSurface = NULL;
 
-        RenderTarget *renderTarget = renderbufferObject->getRenderTarget();
+        RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment);
         if (renderTarget)
         {
-            renderTargetSurface = RenderTarget9::makeRenderTarget9(renderTarget)->getSurface();
+            renderTargetSurface = renderTarget->getSurface();
         }
 
         if (!renderTargetSurface)
@@ -1314,30 +1180,17 @@
         renderTargetChanged = true;
     }
 
-    gl::FramebufferAttachment *depthStencil = NULL;
+    gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer();
     unsigned int depthbufferSerial = 0;
     unsigned int stencilbufferSerial = 0;
-    if (framebuffer->getDepthbufferType() != GL_NONE)
+    if (depthStencil)
     {
-        depthStencil = framebuffer->getDepthbuffer();
-        if (!depthStencil)
-        {
-            ERR("Depth stencil pointer unexpectedly null.");
-            return false;
-        }
-
-        depthbufferSerial = depthStencil->getSerial();
+        depthbufferSerial = GetAttachmentSerial(depthStencil);
     }
-    else if (framebuffer->getStencilbufferType() != GL_NONE)
+    else if (framebuffer->getStencilbuffer())
     {
         depthStencil = framebuffer->getStencilbuffer();
-        if (!depthStencil)
-        {
-            ERR("Depth stencil pointer unexpectedly null.");
-            return false;
-        }
-
-        stencilbufferSerial = depthStencil->getSerial();
+        stencilbufferSerial = GetAttachmentSerial(depthStencil);
     }
 
     if (depthbufferSerial != mAppliedDepthbufferSerial ||
@@ -1351,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)
@@ -1398,48 +1251,49 @@
         mForceSetViewport = true;
         mForceSetBlendState = true;
 
-        mRenderTargetDesc.width = renderbufferObject->getWidth();
-        mRenderTargetDesc.height = renderbufferObject->getHeight();
-        mRenderTargetDesc.format = renderbufferObject->getActualFormat();
+        mRenderTargetDesc.width = attachment->getWidth();
+        mRenderTargetDesc.height = attachment->getHeight();
+        mRenderTargetDesc.format = attachment->getActualFormat();
         mRenderTargetDescInitialized = true;
     }
 
     return true;
 }
 
-GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], 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[])
@@ -1459,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
@@ -1492,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);
         }
     }
 }
@@ -1516,22 +1369,22 @@
     if (type != GL_NONE && elementArrayBuffer)
     {
         gl::Buffer *indexBuffer = elementArrayBuffer;
-        BufferStorage *storage = indexBuffer->getStorage();
+        BufferImpl *storage = indexBuffer->getImplementation();
         intptr_t offset = reinterpret_cast<intptr_t>(indices);
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
 
     unsigned int startIndex = 0;
 
-    if (get32BitIndexSupport())
+    if (getRendererExtensions().elementIndexUint)
     {
         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);
@@ -1547,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);
@@ -1556,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);
@@ -1598,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);
@@ -1609,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);
@@ -1629,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);
@@ -1637,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);
@@ -1679,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);
@@ -1714,7 +1573,7 @@
 
     if (elementArrayBuffer)
     {
-        BufferStorage *storage = elementArrayBuffer->getStorage();
+        BufferImpl *storage = elementArrayBuffer->getImplementation();
         intptr_t offset = reinterpret_cast<intptr_t>(indices);
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
@@ -1728,13 +1587,92 @@
     }
 }
 
-void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[])
+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)
 {
     ASSERT(!transformFeedbackActive);
     ASSERT(!rasterizerDiscard);
 
     ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
-    ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
+    ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer);
 
     IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL);
     IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL);
@@ -1864,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];
@@ -1880,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);
         }
     }
 
@@ -1890,8 +1828,7 @@
     unsigned int stencilUnmasked = 0x0;
     if (clearParams.clearStencil && frameBuffer->hasStencil())
     {
-        unsigned int stencilSize = gl::GetStencilBits(frameBuffer->getStencilbuffer()->getActualFormat(),
-                                                      getCurrentClientVersion());
+        unsigned int stencilSize = gl::GetInternalFormatInfo((frameBuffer->getStencilbuffer()->getActualFormat())).stencilBits;
         stencilUnmasked = (0x1 << stencilSize) - 1;
     }
 
@@ -1902,30 +1839,19 @@
     D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0);
     if (clearColor)
     {
-        gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer();
-        GLenum internalFormat = attachment->getInternalFormat();
-        GLenum actualFormat = attachment->getActualFormat();
+        const gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer();
+        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
+        const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
 
-        GLuint clientVersion = getCurrentClientVersion();
-        GLuint internalRedBits = gl::GetRedBits(internalFormat, clientVersion);
-        GLuint internalGreenBits = gl::GetGreenBits(internalFormat, clientVersion);
-        GLuint internalBlueBits = gl::GetBlueBits(internalFormat, clientVersion);
-        GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat, clientVersion);
+        color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
+                              gl::unorm<8>((formatInfo.redBits   == 0 && actualFormatInfo.redBits   > 0) ? 0.0f : clearParams.colorFClearValue.red),
+                              gl::unorm<8>((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
+                              gl::unorm<8>((formatInfo.blueBits  == 0 && actualFormatInfo.blueBits  > 0) ? 0.0f : clearParams.colorFClearValue.blue));
 
-        GLuint actualRedBits = gl::GetRedBits(actualFormat, clientVersion);
-        GLuint actualGreenBits = gl::GetGreenBits(actualFormat, clientVersion);
-        GLuint actualBlueBits = gl::GetBlueBits(actualFormat, clientVersion);
-        GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat, clientVersion);
-
-        color = D3DCOLOR_ARGB(gl::unorm<8>((internalAlphaBits == 0 && actualAlphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
-                              gl::unorm<8>((internalRedBits   == 0 && actualRedBits   > 0) ? 0.0f : clearParams.colorFClearValue.red),
-                              gl::unorm<8>((internalGreenBits == 0 && actualGreenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
-                              gl::unorm<8>((internalBlueBits  == 0 && actualBlueBits  > 0) ? 0.0f : clearParams.colorFClearValue.blue));
-
-        if ((internalRedBits   > 0 && !clearParams.colorMaskRed) ||
-            (internalGreenBits > 0 && !clearParams.colorMaskGreen) ||
-            (internalBlueBits  > 0 && !clearParams.colorMaskBlue) ||
-            (internalAlphaBits > 0 && !clearParams.colorMaskAlpha))
+        if ((formatInfo.redBits   > 0 && !clearParams.colorMaskRed) ||
+            (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) ||
+            (formatInfo.blueBits  > 0 && !clearParams.colorMaskBlue) ||
+            (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha))
         {
             needMaskedColorClear = true;
         }
@@ -2089,6 +2015,8 @@
 
         mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil);
     }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 void Renderer9::markAllStateDirty()
@@ -2105,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;
@@ -2142,6 +2073,7 @@
     SafeDelete(mVertexDataManager);
     SafeDelete(mIndexDataManager);
     SafeDelete(mLineLoopIB);
+    SafeDelete(mCountingIB);
 
     for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
     {
@@ -2318,7 +2250,7 @@
     // The hardware adapter has been removed. Application must destroy the device, do enumeration of
     // adapters and create another Direct3D device. If application continues rendering without
     // calling Reset, the rendering calls will succeed. Applies to Direct3D 9Ex only.
-    deinitialize();
+    release();
     return (initialize() == EGL_SUCCESS);
 }
 
@@ -2352,144 +2284,6 @@
     return mAdapterIdentifier.DeviceIdentifier;
 }
 
-Renderer9::MultisampleSupportInfo Renderer9::getMultiSampleSupport(D3DFORMAT format)
-{
-    MultisampleSupportInfo support = { 0 };
-
-    for (unsigned int multiSampleIndex = 0; multiSampleIndex < ArraySize(support.supportedSamples); multiSampleIndex++)
-    {
-        HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format, TRUE,
-                                                           (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
-
-        if (SUCCEEDED(result))
-        {
-             support.supportedSamples[multiSampleIndex] = true;
-             if (multiSampleIndex != D3DMULTISAMPLE_NONMASKABLE)
-             {
-                 support.maxSupportedSamples = std::max(support.maxSupportedSamples, multiSampleIndex);
-             }
-        }
-        else
-        {
-            support.supportedSamples[multiSampleIndex] = false;
-        }
-    }
-
-    return support;
-}
-
-bool Renderer9::getBGRATextureSupport() const
-{
-    // DirectX 9 always supports BGRA
-    return true;
-}
-
-bool Renderer9::getDXT1TextureSupport() const
-{
-    return mDXT1TextureSupport;
-}
-
-bool Renderer9::getDXT3TextureSupport() const
-{
-    return mDXT3TextureSupport;
-}
-
-bool Renderer9::getDXT5TextureSupport() const
-{
-    return mDXT5TextureSupport;
-}
-
-bool Renderer9::getDepthTextureSupport() const
-{
-    return mDepthTextureSupport;
-}
-
-bool Renderer9::getFloat32TextureSupport() const
-{
-    return mFloat32TextureSupport;
-}
-
-bool Renderer9::getFloat32TextureFilteringSupport() const
-{
-    return mFloat32FilterSupport;
-}
-
-bool Renderer9::getFloat32TextureRenderingSupport() const
-{
-    return mFloat32RenderSupport;
-}
-
-bool Renderer9::getFloat16TextureSupport() const
-{
-    return mFloat16TextureSupport;
-}
-
-bool Renderer9::getFloat16TextureFilteringSupport() const
-{
-    return mFloat16FilterSupport;
-}
-
-bool Renderer9::getFloat16TextureRenderingSupport() const
-{
-    return mFloat16RenderSupport;
-}
-
-bool Renderer9::getRGB565TextureSupport() const
-{
-    return mRGB565TextureSupport;
-}
-
-bool Renderer9::getLuminanceTextureSupport() const
-{
-    return mLuminanceTextureSupport;
-}
-
-bool Renderer9::getLuminanceAlphaTextureSupport() const
-{
-    return mLuminanceAlphaTextureSupport;
-}
-
-bool Renderer9::getRGTextureSupport() const
-{
-    return mRGTextureSupport;
-}
-
-bool Renderer9::getTextureFilterAnisotropySupport() const
-{
-    return mSupportsTextureFilterAnisotropy;
-}
-
-bool Renderer9::getPBOSupport() const
-{
-    // D3D9 cannot support PBOs
-    return false;
-}
-
-float Renderer9::getTextureMaxAnisotropy() const
-{
-    if (mSupportsTextureFilterAnisotropy)
-    {
-        return static_cast<float>(mDeviceCaps.MaxAnisotropy);
-    }
-    return 1.0f;
-}
-
-bool Renderer9::getEventQuerySupport() const
-{
-    return mEventQuerySupport;
-}
-
-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.
@@ -2500,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;
@@ -2537,116 +2304,22 @@
     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::getNonPower2TextureSupport() const
-{
-    return mSupportsNonPower2Textures;
-}
-
-bool Renderer9::getOcclusionQuerySupport() const
-{
-    return mOcclusionQuerySupport;
-}
-
-bool Renderer9::getInstancingSupport() const
-{
-    return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
-}
-
 bool Renderer9::getShareHandleSupport() const
 {
     // PIX doesn't seem to support using share handles, so disable them.
     return (mD3d9Ex != NULL) && !gl::perfActive();
 }
 
-bool Renderer9::getDerivativeInstructionSupport() const
-{
-    return (mDeviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0;
-}
-
 bool Renderer9::getPostSubBufferSupport() const
 {
     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);
 }
 
-float Renderer9::getMaxPointSize() const
-{
-    // Point size clamped at 1.0f for SM2
-    return getMajorShaderModel() == 3 ? mDeviceCaps.MaxPointSize : 1.0f;
-}
-
-int Renderer9::getMaxViewportDimension() const
-{
-    int maxTextureDimension = std::min(std::min(getMaxTextureWidth(), getMaxTextureHeight()),
-                                       (int)gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
-    return maxTextureDimension;
-}
-
-int Renderer9::getMaxTextureWidth() const
-{
-    return (int)mDeviceCaps.MaxTextureWidth;
-}
-
-int Renderer9::getMaxTextureHeight() const
-{
-    return (int)mDeviceCaps.MaxTextureHeight;
-}
-
-int Renderer9::getMaxTextureDepth() const
-{
-    // 3D textures are not available in the D3D9 backend.
-    return 1;
-}
-
-int Renderer9::getMaxTextureArrayLayers() const
-{
-    // 2D array textures are not available in the D3D9 backend.
-    return 1;
-}
-
-bool Renderer9::get32BitIndexSupport() const
-{
-    return mDeviceCaps.MaxVertexIndex >= (1 << 16);
-}
-
 DWORD Renderer9::getCapsDeclTypes() const
 {
     return mDeviceCaps.DeclTypes;
@@ -2662,145 +2335,14 @@
     return mMaxSwapInterval;
 }
 
-int Renderer9::getMaxSupportedSamples() const
-{
-    return mMaxSupportedSamples;
-}
-
-GLsizei Renderer9::getMaxSupportedFormatSamples(GLenum internalFormat) const
-{
-    D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this);
-    MultisampleSupportMap::const_iterator itr = mMultiSampleSupport.find(format);
-    return (itr != mMultiSampleSupport.end()) ? mMaxSupportedSamples : 0;
-}
-
-GLsizei Renderer9::getNumSampleCounts(GLenum internalFormat) const
-{
-    D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this);
-    MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format);
-
-    unsigned int numCounts = 0;
-    if (iter != mMultiSampleSupport.end())
-    {
-        const MultisampleSupportInfo& info = iter->second;
-        for (int i = 0; i < D3DMULTISAMPLE_16_SAMPLES; i++)
-        {
-            if (i != D3DMULTISAMPLE_NONMASKABLE && info.supportedSamples[i])
-            {
-                numCounts++;
-            }
-        }
-    }
-
-    return numCounts;
-}
-
-void Renderer9::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
-{
-    D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this);
-    MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format);
-
-    if (iter != mMultiSampleSupport.end())
-    {
-        const MultisampleSupportInfo& info = iter->second;
-        int bufPos = 0;
-        for (int i = D3DMULTISAMPLE_16_SAMPLES; i >= 0 && bufPos < bufSize; i--)
-        {
-            if (i != D3DMULTISAMPLE_NONMASKABLE && info.supportedSamples[i])
-            {
-                params[bufPos++] = i;
-            }
-        }
-    }
-}
-
-int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const
-{
-    if (requested == 0)
-    {
-        return requested;
-    }
-
-    MultisampleSupportMap::const_iterator itr = mMultiSampleSupport.find(format);
-    if (itr == mMultiSampleSupport.end())
-    {
-        if (format == D3DFMT_UNKNOWN)
-            return 0;
-        return -1;
-    }
-
-    for (unsigned int i = requested; i < ArraySize(itr->second.supportedSamples); ++i)
-    {
-        if (itr->second.supportedSamples[i] && i != D3DMULTISAMPLE_NONMASKABLE)
-        {
-            return i;
-        }
-    }
-
-    return -1;
-}
-
-unsigned int Renderer9::getMaxRenderTargets() const
-{
-    // we do not support MRT in d3d9
-    return 1;
-}
-
-D3DFORMAT Renderer9::ConvertTextureInternalFormat(GLenum internalformat)
-{
-    switch (internalformat)
-    {
-      case GL_DEPTH_COMPONENT16:
-      case GL_DEPTH_COMPONENT32_OES:
-      case GL_DEPTH24_STENCIL8_OES:
-        return D3DFMT_INTZ;
-      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-        return D3DFMT_DXT1;
-      case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
-        return D3DFMT_DXT3;
-      case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
-        return D3DFMT_DXT5;
-      case GL_RGBA32F_EXT:
-      case GL_RGB32F_EXT:
-      case GL_ALPHA32F_EXT:
-      case GL_LUMINANCE32F_EXT:
-      case GL_LUMINANCE_ALPHA32F_EXT:
-        return D3DFMT_A32B32G32R32F;
-      case GL_RGBA16F_EXT:
-      case GL_RGB16F_EXT:
-      case GL_ALPHA16F_EXT:
-      case GL_LUMINANCE16F_EXT:
-      case GL_LUMINANCE_ALPHA16F_EXT:
-        return D3DFMT_A16B16G16R16F;
-      case GL_LUMINANCE8_EXT:
-        if (getLuminanceTextureSupport())
-        {
-            return D3DFMT_L8;
-        }
-        break;
-      case GL_LUMINANCE8_ALPHA8_EXT:
-        if (getLuminanceAlphaTextureSupport())
-        {
-            return D3DFMT_A8L8;
-        }
-        break;
-      case GL_RGB8_OES:
-      case GL_RGB565:
-        return D3DFMT_X8R8G8B8;
-    }
-
-    return D3DFMT_A8R8G8B8;
-}
-
-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)
@@ -2823,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++)
         {
@@ -2855,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();
@@ -2886,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;
@@ -2895,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;
@@ -2907,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();
@@ -2944,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)
@@ -3073,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)
@@ -3110,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);
 
@@ -3121,7 +2663,7 @@
 
     if (colorbuffer)
     {
-        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
     }
 
     if (renderTarget)
@@ -3132,7 +2674,7 @@
     if (!surface)
     {
         // context must be lost
-        return;
+        return gl::Error(GL_NO_ERROR);
     }
 
     D3DSURFACE_DESC desc;
@@ -3142,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;
@@ -3154,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
@@ -3170,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.");
         }
     }
 
@@ -3186,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;
@@ -3216,46 +2757,40 @@
         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;
     }
 
-    GLuint clientVersion = getCurrentClientVersion();
-
-    GLenum sourceInternalFormat = d3d9_gl::GetInternalFormat(desc.Format);
-    GLenum sourceFormat = gl::GetFormat(sourceInternalFormat, clientVersion);
-    GLenum sourceType = gl::GetType(sourceInternalFormat, clientVersion);
-
-    GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
-
-    if (sourceFormat == format && sourceType == type)
+    const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+    const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat);
+    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) * sourcePixelSize);
+            memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes);
         }
     }
     else
     {
-        GLenum destInternalFormat = gl::GetSizedInternalFormat(format, type, clientVersion);
-        GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion);
-        GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
+        const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+        ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type);
 
-        ColorCopyFunction fastCopyFunc = d3d9::GetFastCopyFunction(desc.Format, format, type, getCurrentClientVersion());
+        const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(format, type);
+        const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat);
+
         if (fastCopyFunc)
         {
             // Fast copy is possible through some special function
@@ -3263,8 +2798,8 @@
             {
                 for (int x = 0; x < rect.right - rect.left; x++)
                 {
-                    void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize;
-                    void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
+                    uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
+                    const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
 
                     fastCopyFunc(src, dest);
                 }
@@ -3272,22 +2807,18 @@
         }
         else
         {
-            ColorReadFunction readFunc = d3d9::GetColorReadFunction(desc.Format);
-            ColorWriteFunction writeFunc = gl::GetColorWriteFunction(format, type, clientVersion);
-
-            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 * destPixelSize;
-                    void *src = source + y * inputPitch + x * sourcePixelSize;
+                    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.
-                    readFunc(src, &temp);
-                    writeFunc(&temp, dest);
+                    sourceD3DFormatInfo.colorReadFunction(src, temp);
+                    destFormatTypeInfo.colorWriteFunction(temp, dest);
                 }
             }
         }
@@ -3295,6 +2826,8 @@
 
     systemSurface->UnlockRect();
     SafeRelease(systemSurface);
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth)
@@ -3321,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)
@@ -3544,6 +3092,18 @@
     return NULL;
 }
 
+TextureImpl *Renderer9::createTexture(GLenum target)
+{
+    switch(target)
+    {
+      case GL_TEXTURE_2D:       return new TextureD3D_2D(this);
+      case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
+      default:                  UNREACHABLE();
+    }
+
+    return NULL;
+}
+
 bool Renderer9::getLUID(LUID *adapterLuid) const
 {
     adapterLuid->HighPart = 0;
@@ -3558,20 +3118,19 @@
     return false;
 }
 
-GLenum Renderer9::getNativeTextureFormat(GLenum internalFormat) const
-{
-    return d3d9_gl::GetInternalFormat(gl_d3d9::GetTextureFormat(internalFormat, this));
-}
-
 rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
 {
-    return d3d9::GetVertexConversionType(vertexFormat);
+    return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType;
 }
 
 GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const
 {
-    D3DDECLTYPE declType = d3d9::GetNativeVertexFormat(vertexFormat);
-    return d3d9::GetDeclTypeComponentType(declType);
+    return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).componentType;
+}
+
+void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const
+{
+    d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, outExtensions);
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
similarity index 62%
rename from src/libGLESv2/renderer/d3d9/Renderer9.h
rename to src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index d3ea314..87a3323 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -12,8 +12,8 @@
 #include "common/angleutils.h"
 #include "common/mathutil.h"
 #include "libGLESv2/renderer/d3d/HLSLCompiler.h"
-#include "libGLESv2/renderer/d3d9/ShaderCache.h"
-#include "libGLESv2/renderer/d3d9/VertexDeclarationCache.h"
+#include "libGLESv2/renderer/d3d/d3d9/ShaderCache.h"
+#include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/RenderTarget.h"
 
@@ -27,13 +27,14 @@
 class VertexDataManager;
 class IndexDataManager;
 class StreamingIndexBufferInterface;
+class StaticIndexBufferInterface;
 struct TranslatedAttribute;
 class Blit9;
 
 class Renderer9 : public Renderer
 {
   public:
-    Renderer9(egl::Display *display, HDC hDc);
+    Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay);
     virtual ~Renderer9();
 
     static Renderer9 *makeRenderer9(Renderer *renderer);
@@ -72,16 +73,17 @@
                                       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);
-    virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]);
+    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 bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
-    virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], 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[]);
 
@@ -89,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();
 
@@ -99,102 +101,54 @@
     virtual bool testDeviceLost(bool notify);
     virtual bool testDeviceResettable();
 
-    // Renderer capabilities
     IDirect3DDevice9 *getDevice() { return mDevice; }
     virtual DWORD getAdapterVendor() const;
     virtual std::string getRendererDescription() const;
     virtual GUID getAdapterIdentifier() const;
 
-    virtual bool getBGRATextureSupport() const;
-    virtual bool getDXT1TextureSupport() const;
-    virtual bool getDXT3TextureSupport() const;
-    virtual bool getDXT5TextureSupport() const;
-    virtual bool getEventQuerySupport() const;
-    virtual bool getFloat32TextureSupport() const;
-    virtual bool getFloat32TextureFilteringSupport() const;
-    virtual bool getFloat32TextureRenderingSupport() const;
-    virtual bool getFloat16TextureSupport() const;
-    virtual bool getFloat16TextureFilteringSupport() const;
-    virtual bool getFloat16TextureRenderingSupport() const;
-    virtual bool getRGB565TextureSupport() const;
-    virtual bool getLuminanceTextureSupport() const;
-    virtual bool getLuminanceAlphaTextureSupport() const;
-    virtual bool getRGTextureSupport() 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 getNonPower2TextureSupport() const;
-    virtual bool getDepthTextureSupport() const;
-    virtual bool getOcclusionQuerySupport() const;
-    virtual bool getInstancingSupport() const;
-    virtual bool getTextureFilterAnisotropySupport() const;
-    virtual bool getPBOSupport() const;
-    virtual float getTextureMaxAnisotropy() const;
     virtual bool getShareHandleSupport() const;
-    virtual bool getDerivativeInstructionSupport() const;
     virtual bool getPostSubBufferSupport() const;
-    virtual int getMaxRecommendedElementsIndices() const;
-    virtual int getMaxRecommendedElementsVertices() const;
 
     virtual int getMajorShaderModel() const;
-    virtual float getMaxPointSize() const;
-    virtual int getMaxViewportDimension() const;
-    virtual int getMaxTextureWidth() const;
-    virtual int getMaxTextureHeight() const;
-    virtual int getMaxTextureDepth() const;
-    virtual int getMaxTextureArrayLayers() const;
-    virtual bool get32BitIndexSupport() const;
     DWORD getCapsDeclTypes() const;
     virtual int getMinSwapInterval() const;
     virtual int getMaxSwapInterval() const;
 
-    virtual GLsizei getMaxSupportedSamples() const;
-    virtual GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const;
-    virtual GLsizei getNumSampleCounts(GLenum internalFormat) const;
-    virtual void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const;
-    int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
-    
-    virtual unsigned int getMaxRenderTargets() const;
-
-    D3DFORMAT ConvertTextureInternalFormat(GLenum internalformat);
-
     // 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);
@@ -212,15 +166,24 @@
     virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
 
+    // Texture creation
+    virtual TextureImpl *createTexture(GLenum target);
+
     // Buffer creation
+    virtual BufferImpl *createBuffer();
     virtual VertexBuffer *createVertexBuffer();
     virtual IndexBuffer *createIndexBuffer();
-    virtual BufferStorage *createBufferStorage();
+
+    // Vertex Array creation
+    virtual VertexArrayImpl *createVertexArray();
 
     // Query and Fence creation
     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,
@@ -232,14 +195,15 @@
     D3DPOOL getTexturePool(DWORD usage) const;
 
     virtual bool getLUID(LUID *adapterLuid) const;
-    virtual GLenum getNativeTextureFormat(GLenum internalFormat) const;
     virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
     virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Renderer9);
 
-    void deinitialize();
+    virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const;
+
+    void release();
 
     void applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v);
     void applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v);
@@ -248,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);
 
@@ -286,47 +252,11 @@
     GLsizei mRepeatDraw;
 
     bool mSceneStarted;
-    bool mSupportsNonPower2Textures;
-    bool mSupportsTextureFilterAnisotropy;
     int mMinSwapInterval;
     int mMaxSwapInterval;
 
-    bool mOcclusionQuerySupport;
-    bool mEventQuerySupport;
     bool mVertexTextureSupport;
 
-    bool mDepthTextureSupport;
-
-    bool mRGB565TextureSupport;
-
-    bool mFloat32TextureSupport;
-    bool mFloat32FilterSupport;
-    bool mFloat32RenderSupport;
-
-    bool mFloat16TextureSupport;
-    bool mFloat16FilterSupport;
-    bool mFloat16RenderSupport;
-
-    bool mDXT1TextureSupport;
-    bool mDXT3TextureSupport;
-    bool mDXT5TextureSupport;
-
-    bool mLuminanceTextureSupport;
-    bool mLuminanceAlphaTextureSupport;
-
-    bool mRGTextureSupport;
-
-    struct MultisampleSupportInfo
-    {
-        bool supportedSamples[D3DMULTISAMPLE_16_SAMPLES + 1];
-        unsigned int maxSupportedSamples;
-    };
-    typedef std::map<D3DFORMAT, MultisampleSupportInfo> MultisampleSupportMap;
-    MultisampleSupportMap mMultiSampleSupport;
-    unsigned int mMaxSupportedSamples;
-
-    MultisampleSupportInfo getMultiSampleSupport(D3DFORMAT format);
-
     // current render target states
     unsigned int mAppliedRenderTargetSerial;
     unsigned int mAppliedDepthbufferSerial;
@@ -365,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;
@@ -394,6 +324,7 @@
 
     IndexDataManager *mIndexDataManager;
     StreamingIndexBufferInterface *mLineLoopIB;
+    StaticIndexBufferInterface *mCountingIB;
 
     enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 };
     struct NullColorbufferCacheEntry
diff --git a/src/libGLESv2/renderer/d3d9/ShaderCache.h b/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
similarity index 97%
rename from src/libGLESv2/renderer/d3d9/ShaderCache.h
rename to src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
index a03528c..2ad3022 100644
--- a/src/libGLESv2/renderer/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/d3d9/ShaderExecutable9.cpp b/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp
similarity index 94%
rename from src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp
index 115ed08..bc71204 100644
--- a/src/libGLESv2/renderer/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
@@ -8,7 +7,7 @@
 // ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader
 // executable implementation details.
 
-#include "libGLESv2/renderer/d3d9/ShaderExecutable9.h"
+#include "libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h"
 
 #include "common/debug.h"
 
diff --git a/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h b/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/ShaderExecutable9.h
rename to src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h
diff --git a/src/libGLESv2/renderer/d3d9/SwapChain9.cpp b/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
similarity index 92%
rename from src/libGLESv2/renderer/d3d9/SwapChain9.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
index bfb3459..f702b79 100644
--- a/src/libGLESv2/renderer/d3d9/SwapChain9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
@@ -1,16 +1,15 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// 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
 // found in the LICENSE file.
 //
 
 // SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain.
 
-#include "libGLESv2/renderer/d3d9/SwapChain9.h"
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
+#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
+#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 
 namespace rx
 {
@@ -50,7 +49,7 @@
 
 static DWORD convertInterval(EGLint interval)
 {
-#if ANGLE_FORCE_VSYNC_OFF
+#ifdef ANGLE_FORCE_VSYNC_OFF
     return D3DPRESENT_INTERVAL_IMMEDIATE;
 #else
     switch(interval)
@@ -101,9 +100,10 @@
         pShareHandle = &mShareHandle;
     }
 
+    const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mBackBufferFormat);
     result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
-                                   gl_d3d9::GetTextureFormat(mBackBufferFormat, mRenderer),
-                                   D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
+                                   backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture,
+                                   pShareHandle);
     if (FAILED(result))
     {
         ERR("Could not create offscreen texture: %08lX", result);
@@ -150,12 +150,14 @@
         SafeRelease(oldRenderTarget);
     }
 
+    const d3d9::TextureFormat &depthBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mDepthBufferFormat);
+
     if (mWindow)
     {
         D3DPRESENT_PARAMETERS presentParameters = {0};
-        presentParameters.AutoDepthStencilFormat = gl_d3d9::GetRenderFormat(mDepthBufferFormat, mRenderer);
+        presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat;
         presentParameters.BackBufferCount = 1;
-        presentParameters.BackBufferFormat = gl_d3d9::GetRenderFormat(mBackBufferFormat, mRenderer);
+        presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat;
         presentParameters.EnableAutoDepthStencil = FALSE;
         presentParameters.Flags = 0;
         presentParameters.hDeviceWindow = mWindow;
@@ -207,7 +209,7 @@
     if (mDepthBufferFormat != GL_NONE)
     {
         result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight,
-                                                   gl_d3d9::GetRenderFormat(mDepthBufferFormat, mRenderer),
+                                                   depthBufferd3dFormatInfo.renderFormat,
                                                    D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL);
 
         if (FAILED(result))
diff --git a/src/libGLESv2/renderer/d3d9/SwapChain9.h b/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/SwapChain9.h
rename to src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
diff --git a/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
similarity index 70%
rename from src/libGLESv2/renderer/d3d9/TextureStorage9.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
index a8efca7..f44e33d 100644
--- a/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// 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
 // found in the LICENSE file.
 //
@@ -9,14 +8,15 @@
 // classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
 // D3D9 texture.
 
-#include "libGLESv2/main.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d9/TextureStorage9.h"
-#include "libGLESv2/renderer/d3d9/SwapChain9.h"
-#include "libGLESv2/renderer/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d9/formatutils9.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
 {
@@ -38,18 +38,17 @@
     return static_cast<TextureStorage9*>(storage);
 }
 
-DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, Renderer9 *renderer, bool renderTarget)
+DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget)
 {
-    GLuint clientVersion = renderer->getCurrentClientVersion();
-
     DWORD d3dusage = 0;
 
-    if (gl::GetDepthBits(internalformat, clientVersion) > 0 ||
-        gl::GetStencilBits(internalformat, clientVersion) > 0)
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+    const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+    if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
     {
         d3dusage |= D3DUSAGE_DEPTHSTENCIL;
     }
-    else if (renderTarget && (gl_d3d9::GetRenderFormat(internalformat, renderer) != D3DFMT_UNKNOWN))
+    else if (renderTarget && (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN))
     {
         d3dusage |= D3DUSAGE_RENDERTARGET;
     }
@@ -96,10 +95,11 @@
     mRenderTarget = NULL;
 
     initializeRenderTarget();
+    initializeSerials(1, 1);
 }
 
 TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
-    : TextureStorage9(renderer, GetTextureUsage(internalformat, Renderer9::makeRenderer9(renderer), renderTarget))
+    : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
 {
     mTexture = NULL;
     mRenderTarget = NULL;
@@ -108,11 +108,11 @@
     if (width > 0 && height > 0)
     {
         IDirect3DDevice9 *device = mRenderer->getDevice();
-        D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat, mRenderer);
-        d3d9::MakeValidSize(false, format, &width, &height, &mTopLevel);
+        const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+        d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
         UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
 
-        HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), format, getPool(), &mTexture, NULL);
+        HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
 
         if (FAILED(result))
         {
@@ -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
@@ -195,7 +201,7 @@
 }
 
 TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
-    : TextureStorage9(renderer, GetTextureUsage(internalformat, Renderer9::makeRenderer9(renderer), renderTarget))
+    : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
 {
     mTexture = NULL;
     for (int i = 0; i < 6; ++i)
@@ -209,11 +215,11 @@
     {
         IDirect3DDevice9 *device = mRenderer->getDevice();
         int height = size;
-        D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat, mRenderer);
-        d3d9::MakeValidSize(false, format, &size, &height, &mTopLevel);
+        const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+        d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
         UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
 
-        HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), format, getPool(), &mTexture, NULL);
+        HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
 
         if (FAILED(result))
         {
@@ -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::targetToIndex(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/d3d9/TextureStorage9.h b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
similarity index 78%
rename from src/libGLESv2/renderer/d3d9/TextureStorage9.h
rename to src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
index 1f4975f..e698c7d 100644
--- a/src/libGLESv2/renderer/d3d9/TextureStorage9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
@@ -11,7 +11,7 @@
 #ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
 #define LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
 
-#include "libGLESv2/renderer/TextureStorage.h"
+#include "libGLESv2/renderer/d3d/TextureStorage.h"
 #include "common/debug.h"
 
 namespace rx
@@ -28,17 +28,14 @@
 
     static TextureStorage9 *makeTextureStorage9(TextureStorage *storage);
 
-    static DWORD GetTextureUsage(GLenum internalformat, Renderer9 *renderer, bool renderTarget);
+    static DWORD GetTextureUsage(GLenum internalformat, bool renderTarget);
 
     D3DPOOL getPool() const;
     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/VertexArray9.h b/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
new file mode 100644
index 0000000..66a6c64
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+
+// VertexArray9.h: Defines the rx::VertexArray9 class which implements rx::VertexArrayImpl.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXARRAY9_H_
+#define LIBGLESV2_RENDERER_VERTEXARRAY9_H_
+
+#include "libGLESv2/renderer/VertexArrayImpl.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+
+namespace rx
+{
+class Renderer9;
+
+class VertexArray9 : public VertexArrayImpl
+{
+  public:
+    VertexArray9(rx::Renderer9 *renderer)
+        : VertexArrayImpl(),
+          mRenderer(renderer)
+    {
+    }
+
+    virtual ~VertexArray9() { }
+
+    virtual void setElementArrayBuffer(const gl::Buffer *buffer) { }
+    virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) { }
+    virtual void setAttributeDivisor(size_t idx, GLuint divisor) { }
+    virtual void enableAttribute(size_t idx, bool enabledState) { }
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexArray9);
+
+    rx::Renderer9 *mRenderer;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXARRAY9_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
new file mode 100644
index 0000000..4cf7779
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
@@ -0,0 +1,233 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// 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/Buffer.h"
+
+namespace rx
+{
+
+VertexBuffer9::VertexBuffer9(rx::Renderer9 *renderer) : mRenderer(renderer)
+{
+    mVertexBuffer = NULL;
+    mBufferSize = 0;
+    mDynamicUsage = false;
+}
+
+VertexBuffer9::~VertexBuffer9()
+{
+    SafeRelease(mVertexBuffer);
+}
+
+gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage)
+{
+    SafeRelease(mVertexBuffer);
+
+    updateSerial();
+
+    if (size > 0)
+    {
+        DWORD flags = D3DUSAGE_WRITEONLY;
+        if (dynamicUsage)
+        {
+            flags |= D3DUSAGE_DYNAMIC;
+        }
+
+        HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer);
+
+        if (FAILED(result))
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
+        }
+    }
+
+    mBufferSize = size;
+    mDynamicUsage = dynamicUsage;
+    return gl::Error(GL_NO_ERROR);
+}
+
+VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer));
+    return static_cast<VertexBuffer9*>(vertexBuffer);
+}
+
+gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                               GLint start, GLsizei count, GLsizei instances, unsigned int offset)
+{
+    if (!mVertexBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
+    }
+
+    gl::Buffer *buffer = attrib.buffer.get();
+
+    int inputStride = gl::ComputeVertexAttributeStride(attrib);
+    int elementSize = gl::ComputeVertexAttributeTypeSize(attrib);
+
+    DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
+
+    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)
+        {
+            BufferImpl *storage = buffer->getImplementation();
+            input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset);
+        }
+        else
+        {
+            input = static_cast<const uint8_t*>(attrib.pointer);
+        }
+    }
+    else
+    {
+        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);
+}
+
+gl::Error VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
+                                          unsigned int *outSpaceRequired) const
+{
+    return spaceRequired(attrib, count, instances, outSpaceRequired);
+}
+
+unsigned int VertexBuffer9::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+gl::Error VertexBuffer9::setBufferSize(unsigned int size)
+{
+    if (size > mBufferSize)
+    {
+        return initialize(size, mDynamicUsage);
+    }
+    else
+    {
+        return gl::Error(GL_NO_ERROR);
+    }
+}
+
+gl::Error VertexBuffer9::discard()
+{
+    if (!mVertexBuffer)
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized.");
+    }
+
+    void *dummy;
+    HRESULT result;
+
+    result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+    if (FAILED(result))
+    {
+        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
+{
+    return mVertexBuffer;
+}
+
+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);
+
+    if (attrib.enabled)
+    {
+        unsigned int elementCount = 0;
+        if (instances == 0 || attrib.divisor == 0)
+        {
+            elementCount = count;
+        }
+        else
+        {
+            // Round up to divisor, if possible
+            elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
+        }
+
+        if (d3d9VertexInfo.outputElementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
+        {
+            if (outSpaceRequired)
+            {
+                *outSpaceRequired = d3d9VertexInfo.outputElementSize * elementCount;
+            }
+            return gl::Error(GL_NO_ERROR);
+        }
+        else
+        {
+            return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
+        }
+    }
+    else
+    {
+        const unsigned int elementSize = 4;
+        if (outSpaceRequired)
+        {
+            *outSpaceRequired = elementSize * 4;
+        }
+        return gl::Error(GL_NO_ERROR);
+    }
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
new file mode 100644
index 0000000..bdcf4bb
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
@@ -0,0 +1,54 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
+#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
+
+#include "libGLESv2/renderer/d3d/VertexBuffer.h"
+
+namespace rx
+{
+class Renderer9;
+
+class VertexBuffer9 : public VertexBuffer
+{
+  public:
+    explicit VertexBuffer9(rx::Renderer9 *renderer);
+    virtual ~VertexBuffer9();
+
+    virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
+
+    static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer);
+
+    virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+                                            GLint start, GLsizei count, GLsizei instances, unsigned int offset);
+
+    virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const;
+
+    virtual unsigned int getBufferSize() const;
+    virtual gl::Error setBufferSize(unsigned int size);
+    virtual gl::Error discard();
+
+    IDirect3DVertexBuffer9 *getBuffer() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
+
+    rx::Renderer9 *mRenderer;
+
+    IDirect3DVertexBuffer9 *mVertexBuffer;
+    unsigned int mBufferSize;
+    bool mDynamicUsage;
+
+    gl::Error spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
+                            unsigned int *outSpaceRequired) const;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
diff --git a/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp b/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp
similarity index 80%
rename from src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp
rename to src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp
index 30c0233..cefd786 100644
--- a/src/libGLESv2/renderer/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/d3d9/VertexBuffer9.h"
-#include "libGLESv2/renderer/d3d9/VertexDeclarationCache.h"
-#include "libGLESv2/renderer/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,12 +81,14 @@
             }
         }
 
-        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;
+    device->GetDeviceCaps(&caps);
+
     D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
     D3DVERTEXELEMENT9 *element = &elements[0];
 
@@ -133,10 +148,11 @@
             }
 
             gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT);
+            const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexFormat);
 
             element->Stream = stream;
             element->Offset = 0;
-            element->Type = d3d9::GetNativeVertexFormat(vertexFormat);
+            element->Type = d3d9VertexInfo.nativeFormat;
             element->Method = D3DDECLMETHOD_DEFAULT;
             element->Usage = D3DDECLUSAGE_TEXCOORD;
             element->UsageIndex = programBinary->getSemanticIndex(i);
@@ -172,7 +188,7 @@
                 mLastSetVDecl = entry->vertexDeclaration;
             }
 
-            return GL_NO_ERROR;
+            return gl::Error(GL_NO_ERROR);
         }
     }
 
@@ -194,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/d3d9/VertexDeclarationCache.h b/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h
similarity index 82%
rename from src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h
rename to src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h
index 3fc024a..9af36e0 100644
--- a/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h
@@ -9,7 +9,8 @@
 #ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
 #define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
 
-#include "libGLESv2/renderer/VertexDataManager.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
new file mode 100644
index 0000000..f3acaf7
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp
@@ -0,0 +1,588 @@
+//
+// 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.
+//
+
+// formatutils9.cpp: Queries for GL image formats and their translations to D3D9
+// formats.
+
+#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libGLESv2/renderer/generatemip.h"
+#include "libGLESv2/renderer/loadimage.h"
+#include "libGLESv2/renderer/copyimage.h"
+#include "libGLESv2/renderer/vertexconversion.h"
+
+namespace rx
+{
+
+namespace d3d9
+{
+
+const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')));
+const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L')));
+
+struct D3D9FastCopyFormat
+{
+    GLenum destFormat;
+    GLenum destType;
+    ColorCopyFunction copyFunction;
+
+    D3D9FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction)
+        : destFormat(destFormat), destType(destType), copyFunction(copyFunction)
+    { }
+
+    bool operator<(const D3D9FastCopyFormat& other) const
+    {
+        return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0;
+    }
+};
+
+typedef std::multimap<D3DFORMAT, D3D9FastCopyFormat> D3D9FastCopyMap;
+
+static D3D9FastCopyMap BuildFastCopyMap()
+{
+    D3D9FastCopyMap map;
+
+    map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8)));
+
+    return map;
+}
+
+// A map to determine the pixel size and mip generation function of a given D3D format
+typedef std::map<D3DFORMAT, D3DFormat> D3D9FormatInfoMap;
+
+D3DFormat::D3DFormat()
+    : pixelBytes(0),
+      blockWidth(0),
+      blockHeight(0),
+      internalFormat(GL_NONE),
+      mipGenerationFunction(NULL),
+      colorReadFunction(NULL),
+      fastCopyFunctions()
+{
+}
+
+ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) const
+{
+    FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type));
+    return (iter != fastCopyFunctions.end()) ? iter->second : NULL;
+}
+
+static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth,
+                                       GLuint blockHeight, GLenum internalFormat, MipGenerationFunction mipFunc,
+                                       ColorReadFunction colorReadFunc)
+{
+    D3DFormat info;
+    info.pixelBytes = bits / 8;
+    info.blockWidth = blockWidth;
+    info.blockHeight = blockHeight;
+    info.internalFormat = internalFormat;
+    info.mipGenerationFunction = mipFunc;
+    info.colorReadFunction = colorReadFunc;
+
+    static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap();
+    std::pair<D3D9FastCopyMap::const_iterator, D3D9FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(format);
+    for (D3D9FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++)
+    {
+        info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction));
+    }
+
+    map->insert(std::make_pair(format, info));
+}
+
+static D3D9FormatInfoMap BuildD3D9FormatInfoMap()
+{
+    D3D9FormatInfoMap map;
+
+    //                       | D3DFORMAT           | S  |W |H | Internal format                   | Mip generation function   | Color read function             |
+    InsertD3DFormatInfo(&map, D3DFMT_NULL,            0, 0, 0, GL_NONE,                            NULL,                       NULL                             );
+    InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN,         0, 0, 0, GL_NONE,                            NULL,                       NULL                             );
+
+    InsertD3DFormatInfo(&map, D3DFMT_L8,              8, 1, 1, GL_LUMINANCE8_EXT,                  GenerateMip<L8>,            ReadColor<L8, GLfloat>           );
+    InsertD3DFormatInfo(&map, D3DFMT_A8,              8, 1, 1, GL_ALPHA8_EXT,                      GenerateMip<A8>,            ReadColor<A8, GLfloat>           );
+    InsertD3DFormatInfo(&map, D3DFMT_A8L8,           16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT,           GenerateMip<A8L8>,          ReadColor<A8L8, GLfloat>         );
+    InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4,       16, 1, 1, GL_BGRA4_ANGLEX,                    GenerateMip<B4G4R4A4>,      ReadColor<B4G4R4A4, GLfloat>     );
+    InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5,       16, 1, 1, GL_BGR5_A1_ANGLEX,                  GenerateMip<B5G5R5A1>,      ReadColor<B5G5R5A1, GLfloat>     );
+    InsertD3DFormatInfo(&map, D3DFMT_R5G6B5,         16, 1, 1, GL_RGB565,                          GenerateMip<R5G6B5>,        ReadColor<R5G6B5, GLfloat>       );
+    InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8,       32, 1, 1, GL_BGRA8_EXT,                       GenerateMip<B8G8R8X8>,      ReadColor<B8G8R8X8, GLfloat>     );
+    InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8,       32, 1, 1, GL_BGRA8_EXT,                       GenerateMip<B8G8R8A8>,      ReadColor<B8G8R8A8, GLfloat>     );
+    InsertD3DFormatInfo(&map, D3DFMT_R16F,           16, 1, 1, GL_R16F_EXT,                        GenerateMip<R16F>,          ReadColor<R16F, GLfloat>         );
+    InsertD3DFormatInfo(&map, D3DFMT_G16R16F,        32, 1, 1, GL_RG16F_EXT,                       GenerateMip<R16G16F>,       ReadColor<R16G16F, GLfloat>      );
+    InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F,  64, 1, 1, GL_RGBA16F_EXT,                     GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>);
+    InsertD3DFormatInfo(&map, D3DFMT_R32F,           32, 1, 1, GL_R32F_EXT,                        GenerateMip<R32F>,          ReadColor<R32F, GLfloat>         );
+    InsertD3DFormatInfo(&map, D3DFMT_G32R32F,        64, 1, 1, GL_RG32F_EXT,                       GenerateMip<R32G32F>,       ReadColor<R32G32F, GLfloat>      );
+    InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, GL_RGBA32F_EXT,                     GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>);
+
+    InsertD3DFormatInfo(&map, D3DFMT_D16,            16, 1, 1, GL_DEPTH_COMPONENT16,               NULL,                       NULL                             );
+    InsertD3DFormatInfo(&map, D3DFMT_D24S8,          32, 1, 1, GL_DEPTH24_STENCIL8_OES,            NULL,                       NULL                             );
+    InsertD3DFormatInfo(&map, D3DFMT_D24X8,          32, 1, 1, GL_DEPTH_COMPONENT16,               NULL,                       NULL                             );
+    InsertD3DFormatInfo(&map, D3DFMT_D32,            32, 1, 1, GL_DEPTH_COMPONENT32_OES,           NULL,                       NULL                             );
+
+    InsertD3DFormatInfo(&map, D3DFMT_INTZ,           32, 1, 1, GL_DEPTH24_STENCIL8_OES,            NULL,                       NULL                             );
+
+    InsertD3DFormatInfo(&map, D3DFMT_DXT1,           64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   NULL,                       NULL                             );
+    InsertD3DFormatInfo(&map, D3DFMT_DXT3,          128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL,                       NULL                             );
+    InsertD3DFormatInfo(&map, D3DFMT_DXT5,          128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL,                       NULL                             );
+
+    return map;
+}
+
+const D3DFormat &GetD3DFormatInfo(D3DFORMAT format)
+{
+    static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap();
+    D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
+    if (iter != infoMap.end())
+    {
+        return iter->second;
+    }
+    else
+    {
+        static const D3DFormat defaultInfo;
+        return defaultInfo;
+    }
+}
+
+
+
+typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair;
+typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap;
+
+static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap()
+{
+    InternalFormatInitialzerMap map;
+
+    map.insert(InternalFormatInitialzerPair(GL_RGB16F, Initialize4ComponentData<GLhalf,   0x0000,     0x0000,     0x0000,     gl::Float16One>));
+    map.insert(InternalFormatInitialzerPair(GL_RGB32F, Initialize4ComponentData<GLfloat,  0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
+
+    return map;
+}
+
+// Each GL internal format corresponds to one D3D format and data loading function.
+// Due to not all formats being available all the time, some of the function/format types are wrapped
+// in templates that perform format support queries on a Renderer9 object which is supplied
+// when requesting the function or format.
+
+typedef bool(*FallbackPredicateFunction)();
+
+template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
+static void FallbackLoad(size_t width, size_t height, size_t depth,
+                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    if (pred())
+    {
+        prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
+    }
+    else
+    {
+        fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
+    }
+}
+
+static void UnreachableLoad(size_t width, size_t height, size_t depth,
+                            const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                            uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    UNREACHABLE();
+}
+
+typedef std::pair<GLenum, TextureFormat> D3D9FormatPair;
+typedef std::map<GLenum, TextureFormat> D3D9FormatMap;
+
+TextureFormat::TextureFormat()
+    : texFormat(D3DFMT_NULL),
+      renderFormat(D3DFMT_NULL),
+      dataInitializerFunction(NULL),
+      loadFunction(UnreachableLoad)
+{
+}
+
+static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalFormat, D3DFORMAT texFormat,
+                                        D3DFORMAT renderFormat, LoadImageFunction loadFunction)
+{
+    TextureFormat info;
+    info.texFormat = texFormat;
+    info.renderFormat = renderFormat;
+
+    static const InternalFormatInitialzerMap dataInitializationMap = BuildInternalFormatInitialzerMap();
+    InternalFormatInitialzerMap::const_iterator dataInitIter = dataInitializationMap.find(internalFormat);
+    info.dataInitializerFunction = (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : NULL;
+
+    info.loadFunction = loadFunction;
+
+    map->insert(std::make_pair(internalFormat, info));
+}
+
+static D3D9FormatMap BuildD3D9FormatMap()
+{
+    D3D9FormatMap map;
+
+    //                       | 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_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?
+
+    InsertD3D9FormatInfo(&map, GL_RGBA32F_EXT,                      D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F,  LoadToNative<GLfloat, 4>                 );
+    InsertD3D9FormatInfo(&map, GL_RGB32F_EXT,                       D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F,  LoadToNative3To4<GLfloat, gl::Float32One>);
+    InsertD3D9FormatInfo(&map, GL_RG32F_EXT,                        D3DFMT_G32R32F,       D3DFMT_G32R32F,        LoadToNative<GLfloat, 2>                 );
+    InsertD3D9FormatInfo(&map, GL_R32F_EXT,                         D3DFMT_R32F,          D3DFMT_R32F,           LoadToNative<GLfloat, 1>                 );
+    InsertD3D9FormatInfo(&map, GL_ALPHA32F_EXT,                     D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN,        LoadA32FToRGBA32F                        );
+    InsertD3D9FormatInfo(&map, GL_LUMINANCE32F_EXT,                 D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN,        LoadL32FToRGBA32F                        );
+    InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT,           D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN,        LoadLA32FToRGBA32F                       );
+
+    InsertD3D9FormatInfo(&map, GL_RGBA16F_EXT,                      D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F,  LoadToNative<GLhalf, 4>                  );
+    InsertD3D9FormatInfo(&map, GL_RGB16F_EXT,                       D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F,  LoadToNative3To4<GLhalf, gl::Float16One> );
+    InsertD3D9FormatInfo(&map, GL_RG16F_EXT,                        D3DFMT_G16R16F,       D3DFMT_G16R16F,        LoadToNative<GLhalf, 2>                  );
+    InsertD3D9FormatInfo(&map, GL_R16F_EXT,                         D3DFMT_R16F,          D3DFMT_R16F,           LoadToNative<GLhalf, 1>                  );
+    InsertD3D9FormatInfo(&map, GL_ALPHA16F_EXT,                     D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN,        LoadA16FToRGBA16F                        );
+    InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT,                 D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN,        LoadL16FToRGBA16F                        );
+    InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT,           D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN,        LoadLA16FToRGBA16F                       );
+
+    InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT,                       D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       FallbackLoad<gl::supportsSSE2, LoadA8ToBGRA8_SSE2, LoadA8ToBGRA8>);
+
+    InsertD3D9FormatInfo(&map, GL_RGB8_OES,                         D3DFMT_X8R8G8B8,      D3DFMT_X8R8G8B8,       LoadRGB8ToBGRX8                           );
+    InsertD3D9FormatInfo(&map, GL_RGB565,                           D3DFMT_X8R8G8B8,      D3DFMT_X8R8G8B8,       LoadR5G6B5ToBGRA8                         );
+    InsertD3D9FormatInfo(&map, GL_RGBA8_OES,                        D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       FallbackLoad<gl::supportsSSE2, LoadRGBA8ToBGRA8_SSE2, LoadRGBA8ToBGRA8>);
+    InsertD3D9FormatInfo(&map, GL_RGBA4,                            D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadRGBA4ToBGRA8                          );
+    InsertD3D9FormatInfo(&map, GL_RGB5_A1,                          D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadRGB5A1ToBGRA8                         );
+    InsertD3D9FormatInfo(&map, GL_R8_EXT,                           D3DFMT_X8R8G8B8,      D3DFMT_X8R8G8B8,       LoadR8ToBGRX8                             );
+    InsertD3D9FormatInfo(&map, GL_RG8_EXT,                          D3DFMT_X8R8G8B8,      D3DFMT_X8R8G8B8,       LoadRG8ToBGRX8                            );
+
+    InsertD3D9FormatInfo(&map, GL_BGRA8_EXT,                        D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadToNative<GLubyte, 4>                  );
+    InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX,                     D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadBGRA4ToBGRA8                          );
+    InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX,                   D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadBGR5A1ToBGRA8                         );
+
+    InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,     D3DFMT_DXT1,          D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4,  8>          );
+    InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,    D3DFMT_DXT1,          D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4,  8>          );
+    InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,  D3DFMT_DXT3,          D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 16>          );
+    InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,  D3DFMT_DXT5,          D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 16>          );
+
+    // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
+    // then changing the format and loading function appropriately.
+    InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT,                   D3DFMT_L8,            D3DFMT_UNKNOWN,        LoadToNative<GLubyte, 1>                  );
+    InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT,            D3DFMT_A8L8,          D3DFMT_UNKNOWN,        LoadToNative<GLubyte, 2>                  );
+
+    return map;
+}
+
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat)
+{
+    static const D3D9FormatMap formatMap = BuildD3D9FormatMap();
+    D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat);
+    if (iter != formatMap.end())
+    {
+        return iter->second;
+    }
+    else
+    {
+        static const TextureFormat defaultInfo;
+        return defaultInfo;
+    }
+}
+
+static GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
+{
+    switch (declType)
+    {
+      case D3DDECLTYPE_FLOAT1:   return GL_FLOAT;
+      case D3DDECLTYPE_FLOAT2:   return GL_FLOAT;
+      case D3DDECLTYPE_FLOAT3:   return GL_FLOAT;
+      case D3DDECLTYPE_FLOAT4:   return GL_FLOAT;
+      case D3DDECLTYPE_UBYTE4:   return GL_UNSIGNED_INT;
+      case D3DDECLTYPE_SHORT2:   return GL_INT;
+      case D3DDECLTYPE_SHORT4:   return GL_INT;
+      case D3DDECLTYPE_UBYTE4N:  return GL_UNSIGNED_NORMALIZED;
+      case D3DDECLTYPE_SHORT4N:  return GL_SIGNED_NORMALIZED;
+      case D3DDECLTYPE_USHORT4N: return GL_UNSIGNED_NORMALIZED;
+      case D3DDECLTYPE_SHORT2N:  return GL_SIGNED_NORMALIZED;
+      case D3DDECLTYPE_USHORT2N: return GL_UNSIGNED_NORMALIZED;
+      default: UNREACHABLE();    return GL_NONE;
+    }
+}
+
+// Attribute format conversion
+enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
+
+struct TranslationDescription
+{
+    DWORD capsFlag;
+    VertexFormat preferredConversion;
+    VertexFormat fallbackConversion;
+};
+
+// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
+//
+// BYTE                 SHORT (Cast)
+// BYTE-norm            FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
+// UNSIGNED_BYTE        UBYTE4 (Identity) or SHORT (Cast)
+// UNSIGNED_BYTE-norm   UBYTE4N (Identity) or FLOAT (Normalize)
+// SHORT                SHORT (Identity)
+// SHORT-norm           SHORT-norm (Identity) or FLOAT (Normalize)
+// UNSIGNED_SHORT       FLOAT (Cast)
+// UNSIGNED_SHORT-norm  USHORT-norm (Identity) or FLOAT (Normalize)
+// FIXED (not in WebGL) FLOAT (FixedToFloat)
+// FLOAT                FLOAT (Identity)
+
+// GLToCType maps from GL type (as GLenum) to the C typedef.
+template <GLenum GLType> struct GLToCType { };
+
+template <> struct GLToCType<GL_BYTE>           { typedef GLbyte type;      };
+template <> struct GLToCType<GL_UNSIGNED_BYTE>  { typedef GLubyte type;     };
+template <> struct GLToCType<GL_SHORT>          { typedef GLshort type;     };
+template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type;    };
+template <> struct GLToCType<GL_FIXED>          { typedef GLuint type;      };
+template <> struct GLToCType<GL_FLOAT>          { typedef GLfloat type;     };
+
+// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
+enum D3DVertexType
+{
+    D3DVT_FLOAT,
+    D3DVT_SHORT,
+    D3DVT_SHORT_NORM,
+    D3DVT_UBYTE,
+    D3DVT_UBYTE_NORM,
+    D3DVT_USHORT_NORM
+};
+
+// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
+template <unsigned int D3DType> struct D3DToCType { };
+
+template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
+template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
+template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
+template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
+template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
+template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
+
+// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
+template <unsigned int type, int size> struct WidenRule { };
+
+template <int size> struct WidenRule<D3DVT_FLOAT, size>          : NoWiden<size> { };
+template <int size> struct WidenRule<D3DVT_SHORT, size>          : WidenToEven<size> { };
+template <int size> struct WidenRule<D3DVT_SHORT_NORM, size>     : WidenToEven<size> { };
+template <int size> struct WidenRule<D3DVT_UBYTE, size>          : WidenToFour<size> { };
+template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size>     : WidenToFour<size> { };
+template <int size> struct WidenRule<D3DVT_USHORT_NORM, size>    : WidenToEven<size> { };
+
+// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
+template <unsigned int d3dtype, int size> struct VertexTypeFlags { };
+
+template <unsigned int _capflag, unsigned int _declflag>
+struct VertexTypeFlagsHelper
+{
+    enum { capflag = _capflag };
+    enum { declflag = _declflag };
+};
+
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
+template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
+template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
+template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
+template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
+
+
+// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
+template <GLenum GLtype, bool normalized> struct VertexTypeMapping { };
+
+template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
+struct VertexTypeMappingBase
+{
+    enum { preferred = Preferred };
+    enum { fallback = Fallback };
+};
+
+template <> struct VertexTypeMapping<GL_BYTE, false>                        : VertexTypeMappingBase<D3DVT_SHORT> { };                       // Cast
+template <> struct VertexTypeMapping<GL_BYTE, true>                         : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Normalize
+template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false>               : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { };          // Identity, Cast
+template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true>                : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { };     // Identity, Normalize
+template <> struct VertexTypeMapping<GL_SHORT, false>                       : VertexTypeMappingBase<D3DVT_SHORT> { };                       // Identity
+template <> struct VertexTypeMapping<GL_SHORT, true>                        : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { };     // Cast, Normalize
+template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false>              : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Cast
+template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true>               : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { };    // Cast, Normalize
+template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized>   : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // FixedToFloat
+template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized>   : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Identity
+
+
+// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
+// The conversion rules themselves are defined in vertexconversion.h.
+
+// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
+template <GLenum fromType, bool normalized, unsigned int toType>
+struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type> { };
+
+// All conversions from normalized types to float use the Normalize operator.
+template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type> { };
+
+// Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules.
+template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT>  : FixedToFloat<GLint, 16> { };
+template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { };
+
+// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
+// whether it is normalized or not.
+template <class T, bool normalized> struct DefaultVertexValuesStage2 { };
+
+template <class T> struct DefaultVertexValuesStage2<T, true>  : NormalizedDefaultValues<T> { };
+template <class T> struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T> { };
+
+// Work out the default value rule for a D3D type (expressed as the C type) and
+template <class T, bool normalized> struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized> { };
+template <bool normalized> struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float> { };
+
+// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
+// The fallback conversion produces an output that all D3D9 devices must support.
+template <class T> struct UsePreferred { enum { type = T::preferred }; };
+template <class T> struct UseFallback { enum { type = T::fallback }; };
+
+// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
+// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
+// and the D3DDECLTYPE member needed for the vertex declaration in declflag.
+template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
+struct Converter
+    : VertexDataConverter<typename GLToCType<fromType>::type,
+                          WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
+                          ConversionRule<fromType,
+                                         normalized,
+                                         PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
+                          DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
+{
+private:
+    enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
+    enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
+
+public:
+    enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
+    enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
+};
+
+VertexFormat::VertexFormat()
+    : conversionType(VERTEX_CONVERT_NONE),
+      outputElementSize(0),
+      copyFunction(NULL),
+      nativeFormat(D3DDECLTYPE_UNUSED),
+      componentType(GL_NONE)
+{
+}
+
+// Initialize a TranslationInfo
+VertexFormat CreateVertexFormatInfo(bool identity, size_t elementSize, VertexCopyFunction copyFunc, D3DDECLTYPE nativeFormat)
+{
+    VertexFormat formatInfo;
+    formatInfo.conversionType = identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU;
+    formatInfo.outputElementSize = elementSize;
+    formatInfo.copyFunction = copyFunc;
+    formatInfo.nativeFormat = nativeFormat;
+    formatInfo.componentType = GetDeclTypeComponentType(nativeFormat);
+    return formatInfo;
+}
+
+#define TRANSLATION(type, norm, size, preferred)                                    \
+    CreateVertexFormatInfo                                                          \
+    (                                                                               \
+        Converter<type, norm, size, preferred>::identity,                           \
+        Converter<type, norm, size, preferred>::finalSize,                          \
+        Converter<type, norm, size, preferred>::convertArray,                       \
+        static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag)  \
+    )
+
+#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size)    \
+    {                                                       \
+        Converter<type, norm, size, UsePreferred>::capflag, \
+        TRANSLATION(type, norm, size, UsePreferred),        \
+        TRANSLATION(type, norm, size, UseFallback)          \
+    }
+
+#define TRANSLATIONS_FOR_TYPE(type)                                                                                                                                                                         \
+    {                                                                                                                                                                                                       \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) },     \
+    }
+
+#define TRANSLATIONS_FOR_TYPE_NO_NORM(type)                                                                                                                                                                 \
+    {                                                                                                                                                                                                       \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+    }
+
+static inline unsigned int ComputeTypeIndex(GLenum type)
+{
+    switch (type)
+    {
+      case GL_BYTE:           return 0;
+      case GL_UNSIGNED_BYTE:  return 1;
+      case GL_SHORT:          return 2;
+      case GL_UNSIGNED_SHORT: return 3;
+      case GL_FIXED:          return 4;
+      case GL_FLOAT:          return 5;
+
+      default: UNREACHABLE(); return 5;
+    }
+}
+
+const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat)
+{
+    static bool initialized = false;
+    static DWORD intializedDeclTypes = 0;
+    static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
+    if (!initialized)
+    {
+        const TranslationDescription translations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
+        {
+            TRANSLATIONS_FOR_TYPE(GL_BYTE),
+            TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
+            TRANSLATIONS_FOR_TYPE(GL_SHORT),
+            TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
+            TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED),
+            TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)
+        };
+        for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
+        {
+            for (unsigned int j = 0; j < 2; j++)
+            {
+                for (unsigned int k = 0; k < 4; k++)
+                {
+                    if (translations[i][j][k].capsFlag == 0 || (supportedDeclTypes & translations[i][j][k].capsFlag) != 0)
+                    {
+                        formatConverters[i][j][k] = translations[i][j][k].preferredConversion;
+                    }
+                    else
+                    {
+                        formatConverters[i][j][k] = translations[i][j][k].fallbackConversion;
+                    }
+                }
+            }
+        }
+        initialized = true;
+        intializedDeclTypes = supportedDeclTypes;
+    }
+
+    ASSERT(intializedDeclTypes == supportedDeclTypes);
+
+    // Pure integer attributes only supported in ES3.0
+    ASSERT(!vertexFormat.mPureInteger);
+    return formatConverters[ComputeTypeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1];
+}
+
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h b/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h
new file mode 100644
index 0000000..f26fe43
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h
@@ -0,0 +1,74 @@
+//
+// 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.
+//
+
+// formatutils9.h: Queries for GL image formats and their translations to D3D9
+// formats.
+
+#ifndef LIBGLESV2_RENDERER_FORMATUTILS9_H_
+#define LIBGLESV2_RENDERER_FORMATUTILS9_H_
+
+#include "libGLESv2/formatutils.h"
+
+#include <map>
+
+namespace rx
+{
+
+class Renderer9;
+
+namespace d3d9
+{
+
+typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
+
+struct D3DFormat
+{
+    D3DFormat();
+
+    GLuint pixelBytes;
+    GLuint blockWidth;
+    GLuint blockHeight;
+
+    GLenum internalFormat;
+
+    MipGenerationFunction mipGenerationFunction;
+    ColorReadFunction colorReadFunction;
+
+    FastCopyFunctionMap fastCopyFunctions;
+    ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
+};
+const D3DFormat &GetD3DFormatInfo(D3DFORMAT format);
+
+struct VertexFormat
+{
+    VertexFormat();
+
+    VertexConversionType conversionType;
+    size_t outputElementSize;
+    VertexCopyFunction copyFunction;
+    D3DDECLTYPE nativeFormat;
+    GLenum componentType;
+};
+const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat);
+
+struct TextureFormat
+{
+    TextureFormat();
+
+    D3DFORMAT texFormat;
+    D3DFORMAT renderFormat;
+
+    InitializeTextureDataFunction dataInitializerFunction;
+
+    LoadImageFunction loadFunction;
+};
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat);
+
+}
+
+}
+
+#endif // LIBGLESV2_RENDERER_FORMATUTILS9_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
new file mode 100644
index 0000000..7d7396a
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -0,0 +1,544 @@
+//
+// 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.
+//
+
+// renderer9_utils.cpp: Conversion functions and other utility routines
+// specific to the D3D9 renderer.
+
+#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
+#include "libGLESv2/formatutils.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"
+
+namespace rx
+{
+
+namespace gl_d3d9
+{
+
+D3DCMPFUNC ConvertComparison(GLenum comparison)
+{
+    D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
+    switch (comparison)
+    {
+      case GL_NEVER:    d3dComp = D3DCMP_NEVER;        break;
+      case GL_ALWAYS:   d3dComp = D3DCMP_ALWAYS;       break;
+      case GL_LESS:     d3dComp = D3DCMP_LESS;         break;
+      case GL_LEQUAL:   d3dComp = D3DCMP_LESSEQUAL;    break;
+      case GL_EQUAL:    d3dComp = D3DCMP_EQUAL;        break;
+      case GL_GREATER:  d3dComp = D3DCMP_GREATER;      break;
+      case GL_GEQUAL:   d3dComp = D3DCMP_GREATEREQUAL; break;
+      case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL;     break;
+      default: UNREACHABLE();
+    }
+
+    return d3dComp;
+}
+
+D3DCOLOR ConvertColor(gl::ColorF color)
+{
+    return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
+                         gl::unorm<8>(color.green),
+                         gl::unorm<8>(color.blue),
+                         gl::unorm<8>(color.alpha));
+}
+
+D3DBLEND ConvertBlendFunc(GLenum blend)
+{
+    D3DBLEND d3dBlend = D3DBLEND_ZERO;
+
+    switch (blend)
+    {
+      case GL_ZERO:                     d3dBlend = D3DBLEND_ZERO;           break;
+      case GL_ONE:                      d3dBlend = D3DBLEND_ONE;            break;
+      case GL_SRC_COLOR:                d3dBlend = D3DBLEND_SRCCOLOR;       break;
+      case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = D3DBLEND_INVSRCCOLOR;    break;
+      case GL_DST_COLOR:                d3dBlend = D3DBLEND_DESTCOLOR;      break;
+      case GL_ONE_MINUS_DST_COLOR:      d3dBlend = D3DBLEND_INVDESTCOLOR;   break;
+      case GL_SRC_ALPHA:                d3dBlend = D3DBLEND_SRCALPHA;       break;
+      case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3DBLEND_INVSRCALPHA;    break;
+      case GL_DST_ALPHA:                d3dBlend = D3DBLEND_DESTALPHA;      break;
+      case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3DBLEND_INVDESTALPHA;   break;
+      case GL_CONSTANT_COLOR:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
+      case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
+      case GL_CONSTANT_ALPHA:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
+      case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
+      case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3DBLEND_SRCALPHASAT;    break;
+      default: UNREACHABLE();
+    }
+
+    return d3dBlend;
+}
+
+D3DBLENDOP ConvertBlendOp(GLenum blendOp)
+{
+    D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
+
+    switch (blendOp)
+    {
+      case GL_FUNC_ADD:              d3dBlendOp = D3DBLENDOP_ADD;         break;
+      case GL_FUNC_SUBTRACT:         d3dBlendOp = D3DBLENDOP_SUBTRACT;    break;
+      case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
+      case GL_MIN_EXT:               d3dBlendOp = D3DBLENDOP_MIN;         break;
+      case GL_MAX_EXT:               d3dBlendOp = D3DBLENDOP_MAX;         break;
+      default: UNREACHABLE();
+    }
+
+    return d3dBlendOp;
+}
+
+D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
+{
+    D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
+
+    switch (stencilOp)
+    {
+      case GL_ZERO:      d3dStencilOp = D3DSTENCILOP_ZERO;    break;
+      case GL_KEEP:      d3dStencilOp = D3DSTENCILOP_KEEP;    break;
+      case GL_REPLACE:   d3dStencilOp = D3DSTENCILOP_REPLACE; break;
+      case GL_INCR:      d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
+      case GL_DECR:      d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
+      case GL_INVERT:    d3dStencilOp = D3DSTENCILOP_INVERT;  break;
+      case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR;    break;
+      case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR;    break;
+      default: UNREACHABLE();
+    }
+
+    return d3dStencilOp;
+}
+
+D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
+{
+    D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
+
+    switch (wrap)
+    {
+      case GL_REPEAT:            d3dWrap = D3DTADDRESS_WRAP;   break;
+      case GL_CLAMP_TO_EDGE:     d3dWrap = D3DTADDRESS_CLAMP;  break;
+      case GL_MIRRORED_REPEAT:   d3dWrap = D3DTADDRESS_MIRROR; break;
+      default: UNREACHABLE();
+    }
+
+    return d3dWrap;
+}
+
+D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
+{
+    D3DCULL cull = D3DCULL_CCW;
+    switch (cullFace)
+    {
+      case GL_FRONT:
+        cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
+        break;
+      case GL_BACK:
+        cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
+        break;
+      case GL_FRONT_AND_BACK:
+        cull = D3DCULL_NONE; // culling will be handled during draw
+        break;
+      default: UNREACHABLE();
+    }
+
+    return cull;
+}
+
+D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
+{
+    D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
+
+    switch (cubeFace)
+    {
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+        face = D3DCUBEMAP_FACE_POSITIVE_X;
+        break;
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+        face = D3DCUBEMAP_FACE_NEGATIVE_X;
+        break;
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+        face = D3DCUBEMAP_FACE_POSITIVE_Y;
+        break;
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+        face = D3DCUBEMAP_FACE_NEGATIVE_Y;
+        break;
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+        face = D3DCUBEMAP_FACE_POSITIVE_Z;
+        break;
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        face = D3DCUBEMAP_FACE_NEGATIVE_Z;
+        break;
+      default: UNREACHABLE();
+    }
+
+    return face;
+}
+
+DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+{
+    return (red   ? D3DCOLORWRITEENABLE_RED   : 0) |
+           (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
+           (blue  ? D3DCOLORWRITEENABLE_BLUE  : 0) |
+           (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
+}
+
+D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
+{
+    if (maxAnisotropy > 1.0f)
+    {
+        return D3DTEXF_ANISOTROPIC;
+    }
+
+    D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
+    switch (magFilter)
+    {
+      case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT;  break;
+      case GL_LINEAR:  d3dMagFilter = D3DTEXF_LINEAR; break;
+      default: UNREACHABLE();
+    }
+
+    return d3dMagFilter;
+}
+
+void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy)
+{
+    switch (minFilter)
+    {
+      case GL_NEAREST:
+        *d3dMinFilter = D3DTEXF_POINT;
+        *d3dMipFilter = D3DTEXF_NONE;
+        break;
+      case GL_LINEAR:
+        *d3dMinFilter = D3DTEXF_LINEAR;
+        *d3dMipFilter = D3DTEXF_NONE;
+        break;
+      case GL_NEAREST_MIPMAP_NEAREST:
+        *d3dMinFilter = D3DTEXF_POINT;
+        *d3dMipFilter = D3DTEXF_POINT;
+        break;
+      case GL_LINEAR_MIPMAP_NEAREST:
+        *d3dMinFilter = D3DTEXF_LINEAR;
+        *d3dMipFilter = D3DTEXF_POINT;
+        break;
+      case GL_NEAREST_MIPMAP_LINEAR:
+        *d3dMinFilter = D3DTEXF_POINT;
+        *d3dMipFilter = D3DTEXF_LINEAR;
+        break;
+      case GL_LINEAR_MIPMAP_LINEAR:
+        *d3dMinFilter = D3DTEXF_LINEAR;
+        *d3dMipFilter = D3DTEXF_LINEAR;
+        break;
+      default:
+        *d3dMinFilter = D3DTEXF_POINT;
+        *d3dMipFilter = D3DTEXF_NONE;
+        UNREACHABLE();
+    }
+
+    if (maxAnisotropy > 1.0f)
+    {
+        *d3dMinFilter = D3DTEXF_ANISOTROPIC;
+    }
+}
+
+D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples)
+{
+    return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE;
+}
+
+}
+
+namespace d3d9_gl
+{
+
+GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type)
+{
+    return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0;
+}
+
+bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
+{
+    GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).internalFormat;
+    GLenum convertedFormat = gl::GetInternalFormatInfo(internalFormat).format;
+    return convertedFormat == format;
+}
+
+static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3D9 *d3d9, D3DDEVTYPE deviceType,
+                                                 UINT adapter, D3DFORMAT adapterFormat)
+{
+    gl::TextureCaps textureCaps;
+
+    const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+    if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+    {
+        textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
+        textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
+        textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)) ||
+                                 SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
+    }
+    else
+    {
+        textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) &&
+                                 SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, d3dFormatInfo.texFormat));
+        textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
+        textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) ||
+                                 SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
+    }
+
+    textureCaps.sampleCounts.insert(1);
+    for (size_t i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++)
+    {
+        D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i);
+
+        HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, NULL);
+        if (SUCCEEDED(result))
+        {
+            textureCaps.sampleCounts.insert(i);
+        }
+    }
+
+    return textureCaps;
+}
+
+void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps,
+                  gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
+{
+    D3DCAPS9 deviceCaps;
+    if (FAILED(d3d9->GetDeviceCaps(adapter, deviceType, &deviceCaps)))
+    {
+        // Can't continue with out device caps
+        return;
+    }
+
+    D3DDISPLAYMODE currentDisplayMode;
+    d3d9->GetAdapterDisplayMode(adapter, &currentDisplayMode);
+
+    GLuint maxSamples = 0;
+    const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
+    for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat)
+    {
+        gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, d3d9, deviceType, adapter,
+                                                                currentDisplayMode.Format);
+        textureCapsMap->insert(*internalFormat, textureCaps);
+
+        maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());
+
+        if (gl::GetInternalFormatInfo(*internalFormat).compressed)
+        {
+            caps->compressedTextureFormats.push_back(*internalFormat);
+        }
+    }
+
+    // GL core feature limits
+    caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
+
+    // 3D textures are unimplemented in D3D9
+    caps->max3DTextureSize = 1;
+
+    // Only one limit in GL, use the minimum dimension
+    caps->max2DTextureSize = std::min(deviceCaps.MaxTextureWidth, deviceCaps.MaxTextureHeight);
+
+    // D3D treats cube maps as a special case of 2D textures
+    caps->maxCubeMapTextureSize = caps->max2DTextureSize;
+
+    // Array textures are not available in D3D9
+    caps->maxArrayTextureLayers = 1;
+
+    // ES3-only feature
+    caps->maxLODBias = 0.0f;
+
+    // No specific limits on render target size, maximum 2D texture size is equivalent
+    caps->maxRenderbufferSize = caps->max2DTextureSize;
+
+    // Draw buffers are not supported in D3D9
+    caps->maxDrawBuffers = 1;
+    caps->maxColorAttachments = 1;
+
+    // No specific limits on viewport size, maximum 2D texture size is equivalent
+    caps->maxViewportWidth = caps->max2DTextureSize;
+    caps->maxViewportHeight = caps->maxViewportWidth;
+
+    // Point size is clamped to 1.0f when the shader model is less than 3
+    caps->minAliasedPointSize = 1.0f;
+    caps->maxAliasedPointSize = ((D3DSHADER_VERSION_MAJOR(deviceCaps.PixelShaderVersion) >= 3) ? deviceCaps.MaxPointSize : 1.0f);
+
+    // Wide lines not supported
+    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);
+    extensions->packedDepthStencil = true;
+    extensions->getProgramBinary = true;
+    extensions->rgb8rgba8 = true;
+    extensions->readFormatBGRA = true;
+    extensions->pixelBufferObject = false;
+    extensions->mapBuffer = false;
+    extensions->mapBufferRange = false;
+
+    // ATI cards on XP have problems with non-power-of-two textures.
+    D3DADAPTER_IDENTIFIER9 adapterId = { 0 };
+    if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId)))
+    {
+        extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
+                                      !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
+                                      !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
+                                      !(!isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD);
+    }
+    else
+    {
+        extensions->textureNPOT = false;
+    }
+
+    extensions->drawBuffers = false;
+    extensions->textureStorage = true;
+
+    // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec
+    extensions->textureFilterAnisotropic = (deviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && deviceCaps.MaxAnisotropy >= 2;
+    extensions->maxTextureAnisotropy = static_cast<GLfloat>(deviceCaps.MaxAnisotropy);
+
+    // Check occlusion query support by trying to create one
+    IDirect3DQuery9 *occlusionQuery = NULL;
+    extensions->occlusionQueryBoolean = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery;
+    SafeRelease(occlusionQuery);
+
+    // Check event query support by trying to create one
+    IDirect3DQuery9 *eventQuery = NULL;
+    extensions->fence = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery;
+    SafeRelease(eventQuery);
+
+    extensions->timerQuery = false; // Unimplemented
+    extensions->robustness = true;
+    extensions->blendMinMax = true;
+    extensions->framebufferBlit = true;
+    extensions->framebufferMultisample = true;
+    extensions->maxSamples = maxSamples;
+    extensions->instancedArrays = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
+    extensions->packReverseRowOrder = true;
+    extensions->standardDerivatives = (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0;
+    extensions->shaderTextureLOD = true;
+    extensions->fragDepth = true;
+    extensions->textureUsage = true;
+    extensions->translatedShaderSource = true;
+    extensions->colorBufferFloat = false;
+}
+
+}
+
+namespace d3d9
+{
+
+GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height)
+{
+    const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format);
+    GLuint numBlocksWide = (width + d3dFormatInfo.blockWidth - 1) / d3dFormatInfo.blockWidth;
+    GLuint numBlocksHight = (height + d3dFormatInfo.blockHeight - 1) / d3dFormatInfo.blockHeight;
+    return (d3dFormatInfo.pixelBytes * numBlocksWide * numBlocksHight);
+}
+
+void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
+{
+    const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format);
+
+    int upsampleCount = 0;
+    // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
+    if (isImage || *requestWidth < static_cast<GLsizei>(d3dFormatInfo.blockWidth) ||
+        *requestHeight < static_cast<GLsizei>(d3dFormatInfo.blockHeight))
+    {
+        while (*requestWidth % d3dFormatInfo.blockWidth != 0 || *requestHeight % d3dFormatInfo.blockHeight != 0)
+        {
+            *requestWidth <<= 1;
+            *requestHeight <<= 1;
+            upsampleCount++;
+        }
+    }
+    *levelOffset = upsampleCount;
+}
+
+RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+{
+    RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
+    return RenderTarget9::makeRenderTarget9(renderTarget);
+}
+
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d9/renderer9_utils.h b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
similarity index 62%
rename from src/libGLESv2/renderer/d3d9/renderer9_utils.h
rename to src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
index a115f9e..b0a940e 100644
--- a/src/libGLESv2/renderer/d3d9/renderer9_utils.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
@@ -1,19 +1,26 @@
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 
-// 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
 #define LIBGLESV2_RENDERER_RENDERER9_UTILS_H
 
 #include "libGLESv2/angletypes.h"
+#include "libGLESv2/Caps.h"
+
+namespace gl
+{
+class FramebufferAttachment;
+}
 
 namespace rx
 {
+class RenderTarget9;
 
 namespace gl_d3d9
 {
@@ -30,11 +37,29 @@
 D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
 void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy);
 
+D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples);
+
+}
+
+namespace d3d9_gl
+{
+
+GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type);
+
+bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
+
+void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps,
+                  gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions);
+
 }
 
 namespace d3d9
 {
 
+GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height);
+
+void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
+
 inline bool isDeviceLostError(HRESULT errorCode)
 {
     switch (errorCode)
@@ -49,6 +74,8 @@
     }
 }
 
+RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+
 }
 
 }
diff --git a/src/libGLESv2/renderer/d3d9/shaders/Blit.ps b/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/shaders/Blit.ps
rename to src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps
diff --git a/src/libGLESv2/renderer/d3d9/shaders/Blit.vs b/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/shaders/Blit.vs
rename to src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs
diff --git a/src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h b/src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h
rename to src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h
diff --git a/src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h b/src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/flipyvs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h
rename to src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/flipyvs.h
diff --git a/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h b/src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/luminanceps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h
rename to src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/luminanceps.h
diff --git a/src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h b/src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/passthroughps.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h
rename to src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/passthroughps.h
diff --git a/src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h b/src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/standardvs.h
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h
rename to src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/standardvs.h
diff --git a/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat b/src/libGLESv2/renderer/d3d/d3d9/shaders/generate_shaders.bat
similarity index 100%
rename from src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat
rename to src/libGLESv2/renderer/d3d/d3d9/shaders/generate_shaders.bat
diff --git a/src/libGLESv2/renderer/d3d11/BufferStorage11.h b/src/libGLESv2/renderer/d3d11/BufferStorage11.h
deleted file mode 100644
index 7934de1..0000000
--- a/src/libGLESv2/renderer/d3d11/BufferStorage11.h
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// 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.
-//
-
-// BufferStorage11.h Defines the BufferStorage11 class.
-
-#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
-#define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
-
-#include "libGLESv2/renderer/BufferStorage.h"
-#include "libGLESv2/angletypes.h"
-
-namespace rx
-{
-class Renderer;
-class Renderer11;
-
-enum BufferUsage
-{
-    BUFFER_USAGE_STAGING,
-    BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
-    BUFFER_USAGE_INDEX,
-    BUFFER_USAGE_PIXEL_UNPACK,
-    BUFFER_USAGE_PIXEL_PACK,
-    BUFFER_USAGE_UNIFORM,
-};
-
-struct PackPixelsParams
-{
-    PackPixelsParams();
-    PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch,
-                     const gl::PixelPackState &pack, ptrdiff_t offset);
-
-    gl::Rectangle area;
-    GLenum format;
-    GLenum type;
-    GLuint outputPitch;
-    gl::Buffer *packBuffer;
-    gl::PixelPackState pack;
-    ptrdiff_t offset;
-};
-
-typedef size_t DataRevision;
-
-class BufferStorage11 : public BufferStorage
-{
-  public:
-    explicit BufferStorage11(Renderer11 *renderer);
-    virtual ~BufferStorage11();
-
-    static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage);
-
-    virtual void *getData();
-    virtual void setData(const void* data, size_t size, size_t offset);
-    virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset);
-    virtual void clear();
-    virtual void markTransformFeedbackUsage();
-    virtual size_t getSize() const;
-    virtual bool supportsDirectBinding() const;
-
-    ID3D11Buffer *getBuffer(BufferUsage usage);
-    ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
-    void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
-
-    virtual bool isMapped() const;
-    virtual void *map(GLbitfield access);
-    virtual void unmap();
-
-  private:
-    class TypedBufferStorage11;
-    class NativeBuffer11;
-    class PackStorage11;
-
-    Renderer11 *mRenderer;
-    TypedBufferStorage11 *mMappedStorage;
-
-    std::map<BufferUsage, TypedBufferStorage11*> mTypedBuffers;
-
-    typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
-    std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
-
-    std::vector<unsigned char> mResolvedData;
-    DataRevision mResolvedDataRevision;
-    unsigned int mReadUsageCount;
-
-    size_t mSize;
-
-    void markBufferUsage();
-    NativeBuffer11 *getStagingBuffer();
-    PackStorage11 *getPackStorage();
-
-    TypedBufferStorage11 *getStorage(BufferUsage usage);
-    TypedBufferStorage11 *getLatestStorage() const;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
diff --git a/src/libGLESv2/renderer/d3d11/Image11.cpp b/src/libGLESv2/renderer/d3d11/Image11.cpp
deleted file mode 100644
index aa9260d..0000000
--- a/src/libGLESv2/renderer/d3d11/Image11.cpp
+++ /dev/null
@@ -1,461 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// Image11.h: Implements the rx::Image11 class, which acts as the interface to
-// the actual underlying resources of a Texture
-
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/Image11.h"
-#include "libGLESv2/renderer/d3d11/TextureStorage11.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
-
-#include "libGLESv2/main.h"
-#include "common/utilities.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-
-namespace rx
-{
-
-Image11::Image11()
-{
-    mStagingTexture = NULL;
-    mRenderer = NULL;
-    mDXGIFormat = DXGI_FORMAT_UNKNOWN;
-}
-
-Image11::~Image11()
-{
-    SafeRelease(mStagingTexture);
-}
-
-Image11 *Image11::makeImage11(Image *img)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
-    return static_cast<rx::Image11*>(img);
-}
-
-void Image11::generateMipmap(GLuint clientVersion, Image11 *dest, Image11 *src)
-{
-    ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
-    ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
-    ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight());
-
-    MipGenerationFunction mipFunction = d3d11::GetMipGenerationFunction(src->getDXGIFormat());
-    ASSERT(mipFunction != NULL);
-
-    D3D11_MAPPED_SUBRESOURCE destMapped;
-    HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped);
-    if (FAILED(destMapResult))
-    {
-        ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult);
-        return;
-    }
-
-    D3D11_MAPPED_SUBRESOURCE srcMapped;
-    HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped);
-    if (FAILED(srcMapResult))
-    {
-        ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult);
-
-        dest->unmap();
-        return;
-    }
-
-    const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(srcMapped.pData);
-    unsigned char *destData = reinterpret_cast<unsigned char*>(destMapped.pData);
-
-    mipFunction(src->getWidth(), src->getHeight(), src->getDepth(), sourceData, srcMapped.RowPitch, srcMapped.DepthPitch,
-                destData, destMapped.RowPitch, destMapped.DepthPitch);
-
-    dest->unmap();
-    src->unmap();
-
-    dest->markDirty();
-}
-
-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 || gl_d3d11::RequiresTextureDataInitialization(mInternalFormat)));
-}
-
-bool Image11::copyToStorage(TextureStorageInterface2D *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);
-}
-
-bool Image11::copyToStorage(TextureStorageInterfaceCube *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);
-}
-
-bool Image11::copyToStorage(TextureStorageInterface3D *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);
-}
-
-bool Image11::copyToStorage(TextureStorageInterface2DArray *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);
-}
-
-bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
-{
-    if (mWidth != width ||
-        mHeight != height ||
-        mInternalFormat != internalformat ||
-        forceRelease)
-    {
-        mRenderer = Renderer11::makeRenderer11(renderer);
-        GLuint clientVersion = mRenderer->getCurrentClientVersion();
-
-        mWidth = width;
-        mHeight = height;
-        mDepth = depth;
-        mInternalFormat = internalformat;
-        mTarget = target;
-
-        // compute the d3d format that will be used
-        mDXGIFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion);
-        mActualFormat = d3d11_gl::GetInternalFormat(mDXGIFormat, clientVersion);
-        mRenderable = gl_d3d11::GetRTVFormat(internalformat, clientVersion) != DXGI_FORMAT_UNKNOWN;
-
-        SafeRelease(mStagingTexture);
-        mDirty = gl_d3d11::RequiresTextureDataInitialization(mInternalFormat);
-
-        return true;
-    }
-
-    return false;
-}
-
-DXGI_FORMAT Image11::getDXGIFormat() const
-{
-    // this should only happen if the image hasn't been redefined first
-    // which would be a bug by the caller
-    ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN);
-
-    return mDXGIFormat;
-}
-
-// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
-// into the target pixel rectangle.
-void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                       GLint unpackAlignment, GLenum type, const void *input)
-{
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, type, clientVersion, width, unpackAlignment);
-    GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, type, clientVersion, width, height, unpackAlignment);
-    GLuint outputPixelSize = d3d11::GetFormatPixelBytes(mDXGIFormat);
-
-    LoadImageFunction loadFunction = d3d11::GetImageLoadFunction(mInternalFormat, type, clientVersion);
-    ASSERT(loadFunction != NULL);
-
-    D3D11_MAPPED_SUBRESOURCE mappedImage;
-    HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
-    if (FAILED(result))
-    {
-        ERR("Could not map image for loading.");
-        return;
-    }
-
-    void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch));
-    loadFunction(width, height, depth, input, inputRowPitch, inputDepthPitch, offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
-
-    unmap();
-}
-
-void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                                 const void *input)
-{
-    GLuint clientVersion = mRenderer->getCurrentClientVersion();
-    GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion, width, 1);
-    GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion, width, height, 1);
-
-    GLuint outputPixelSize = d3d11::GetFormatPixelBytes(mDXGIFormat);
-    GLuint outputBlockWidth = d3d11::GetBlockWidth(mDXGIFormat);
-    GLuint outputBlockHeight = d3d11::GetBlockHeight(mDXGIFormat);
-
-    ASSERT(xoffset % outputBlockWidth == 0);
-    ASSERT(yoffset % outputBlockHeight == 0);
-
-    LoadImageFunction loadFunction = d3d11::GetImageLoadFunction(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion);
-    ASSERT(loadFunction != NULL);
-
-    D3D11_MAPPED_SUBRESOURCE mappedImage;
-    HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
-    if (FAILED(result))
-    {
-        ERR("Could not map image for loading.");
-        return;
-    }
-
-    void* offsetMappedData = (void*)((BYTE*)mappedImage.pData + ((yoffset / outputBlockHeight) * mappedImage.RowPitch +
-                                                                 (xoffset / outputBlockWidth) * outputPixelSize +
-                                                                 zoffset * mappedImage.DepthPitch));
-
-    loadFunction(width, height, depth, input, inputRowPitch, inputDepthPitch,
-                 offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
-
-    unmap();
-}
-
-void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
-{
-    gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
-
-    if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat)
-    {
-        // No conversion needed-- use copyback fastpath
-        ID3D11Texture2D *colorBufferTexture = NULL;
-        unsigned int subresourceIndex = 0;
-
-        if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
-        {
-            D3D11_TEXTURE2D_DESC textureDesc;
-            colorBufferTexture->GetDesc(&textureDesc);
-
-            ID3D11Device *device = mRenderer->getDevice();
-            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
-
-            ID3D11Texture2D* srcTex = NULL;
-            if (textureDesc.SampleDesc.Count > 1)
-            {
-                D3D11_TEXTURE2D_DESC resolveDesc;
-                resolveDesc.Width = textureDesc.Width;
-                resolveDesc.Height = textureDesc.Height;
-                resolveDesc.MipLevels = 1;
-                resolveDesc.ArraySize = 1;
-                resolveDesc.Format = textureDesc.Format;
-                resolveDesc.SampleDesc.Count = 1;
-                resolveDesc.SampleDesc.Quality = 0;
-                resolveDesc.Usage = D3D11_USAGE_DEFAULT;
-                resolveDesc.BindFlags = 0;
-                resolveDesc.CPUAccessFlags = 0;
-                resolveDesc.MiscFlags = 0;
-
-                HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
-                if (FAILED(result))
-                {
-                    ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
-                    return;
-                }
-
-                deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
-                subresourceIndex = 0;
-            }
-            else
-            {
-                srcTex = colorBufferTexture;
-                srcTex->AddRef();
-            }
-
-            D3D11_BOX srcBox;
-            srcBox.left = x;
-            srcBox.right = x + width;
-            srcBox.top = y;
-            srcBox.bottom = y + height;
-            srcBox.front = 0;
-            srcBox.back = 1;
-
-            deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox);
-
-            SafeRelease(srcTex);
-            SafeRelease(colorBufferTexture);
-        }
-    }
-    else
-    {
-        // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
-        D3D11_MAPPED_SUBRESOURCE mappedImage;
-        HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
-        if (FAILED(result))
-        {
-            ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result);
-            return;
-        }
-
-        // determine the offset coordinate into the destination buffer
-        GLuint clientVersion = mRenderer->getCurrentClientVersion();
-        GLsizei rowOffset = gl::GetPixelBytes(mActualFormat, clientVersion) * xoffset;
-        void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch;
-
-        GLenum format = gl::GetFormat(mInternalFormat, clientVersion);
-        GLenum type = gl::GetType(mInternalFormat, clientVersion);
-
-        mRenderer->readPixels(source, x, y, width, height, format, type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
-
-        unmap();
-    }
-}
-
-ID3D11Resource *Image11::getStagingTexture()
-{
-    createStagingTexture();
-
-    return mStagingTexture;
-}
-
-unsigned int Image11::getStagingSubresource()
-{
-    createStagingTexture();
-
-    return mStagingSubresource;
-}
-
-void Image11::createStagingTexture()
-{
-    if (mStagingTexture)
-    {
-        return;
-    }
-
-    const DXGI_FORMAT dxgiFormat = getDXGIFormat();
-
-    if (mWidth > 0 && mHeight > 0 && mDepth > 0)
-    {
-        ID3D11Device *device = mRenderer->getDevice();
-        HRESULT result;
-
-        int lodOffset = 1;
-        GLsizei width = mWidth;
-        GLsizei height = mHeight;
-
-        // adjust size if needed for compressed textures
-        d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
-
-        if (mTarget == GL_TEXTURE_3D)
-        {
-            ID3D11Texture3D *newTexture = NULL;
-
-            D3D11_TEXTURE3D_DESC desc;
-            desc.Width = width;
-            desc.Height = height;
-            desc.Depth = mDepth;
-            desc.MipLevels = lodOffset + 1;
-            desc.Format = dxgiFormat;
-            desc.Usage = D3D11_USAGE_STAGING;
-            desc.BindFlags = 0;
-            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
-            desc.MiscFlags = 0;
-
-            if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat))
-            {
-                std::vector<D3D11_SUBRESOURCE_DATA> initialData;
-                std::vector< std::vector<BYTE> > textureData;
-                d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getCurrentClientVersion(), width, height,
-                                                  mDepth, lodOffset + 1, &initialData, &textureData);
-
-                result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
-            }
-            else
-            {
-                result = device->CreateTexture3D(&desc, NULL, &newTexture);
-            }
-
-            if (FAILED(result))
-            {
-                ASSERT(result == E_OUTOFMEMORY);
-                ERR("Creating image failed.");
-                return gl::error(GL_OUT_OF_MEMORY);
-            }
-
-            mStagingTexture = newTexture;
-            mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
-        }
-        else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
-        {
-            ID3D11Texture2D *newTexture = NULL;
-
-            D3D11_TEXTURE2D_DESC desc;
-            desc.Width = width;
-            desc.Height = height;
-            desc.MipLevels = lodOffset + 1;
-            desc.ArraySize = 1;
-            desc.Format = dxgiFormat;
-            desc.SampleDesc.Count = 1;
-            desc.SampleDesc.Quality = 0;
-            desc.Usage = D3D11_USAGE_STAGING;
-            desc.BindFlags = 0;
-            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
-            desc.MiscFlags = 0;
-
-            if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat))
-            {
-                std::vector<D3D11_SUBRESOURCE_DATA> initialData;
-                std::vector< std::vector<BYTE> > textureData;
-                d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getCurrentClientVersion(), width, height,
-                                                  1, lodOffset + 1, &initialData, &textureData);
-
-                result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
-            }
-            else
-            {
-                result = device->CreateTexture2D(&desc, NULL, &newTexture);
-            }
-
-            if (FAILED(result))
-            {
-                ASSERT(result == E_OUTOFMEMORY);
-                ERR("Creating image failed.");
-                return gl::error(GL_OUT_OF_MEMORY);
-            }
-
-            mStagingTexture = newTexture;
-            mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
-        }
-        else
-        {
-            UNREACHABLE();
-        }
-    }
-
-    mDirty = false;
-}
-
-HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
-{
-    createStagingTexture();
-
-    HRESULT result = E_FAIL;
-
-    if (mStagingTexture)
-    {
-        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
-        result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map);
-
-        // this can fail if the device is removed (from TDR)
-        if (d3d11::isDeviceLostError(result))
-        {
-            mRenderer->notifyDeviceLost();
-        }
-        else if (SUCCEEDED(result))
-        {
-            mDirty = true;
-        }
-    }
-
-    return result;
-}
-
-void Image11::unmap()
-{
-    if (mStagingTexture)
-    {
-        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
-        deviceContext->Unmap(mStagingTexture, mStagingSubresource);
-    }
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d11/Image11.h b/src/libGLESv2/renderer/d3d11/Image11.h
deleted file mode 100644
index 300774c..0000000
--- a/src/libGLESv2/renderer/d3d11/Image11.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-// 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
-// found in the LICENSE file.
-//
-
-// Image11.h: Defines the rx::Image11 class, which acts as the interface to
-// the actual underlying resources of a Texture
-
-#ifndef LIBGLESV2_RENDERER_IMAGE11_H_
-#define LIBGLESV2_RENDERER_IMAGE11_H_
-
-#include "libGLESv2/renderer/Image.h"
-
-#include "common/debug.h"
-
-namespace gl
-{
-class Framebuffer;
-}
-
-namespace rx
-{
-class Renderer;
-class Renderer11;
-class TextureStorageInterface2D;
-class TextureStorageInterfaceCube;
-
-class Image11 : public Image
-{
-  public:
-    Image11();
-    virtual ~Image11();
-
-    static Image11 *makeImage11(Image *img);
-
-    static void generateMipmap(GLuint clientVersion, Image11 *dest, Image11 *src);
-
-    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 redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease);
-
-    DXGI_FORMAT getDXGIFormat() const;
-    
-    virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                          GLint unpackAlignment, GLenum type, const void *input);
-    virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                                    const void *input);
-
-    virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
-
-  protected:
-    HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
-    void unmap();
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Image11);
-
-    ID3D11Resource *getStagingTexture();
-    unsigned int getStagingSubresource();
-    void createStagingTexture();
-
-    Renderer11 *mRenderer;
-
-    DXGI_FORMAT mDXGIFormat;
-    ID3D11Resource *mStagingTexture;
-    unsigned int mStagingSubresource;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_IMAGE11_H_
diff --git a/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp b/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp
deleted file mode 100644
index afceac7..0000000
--- a/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
-
-#include "libGLESv2/renderer/d3d11/IndexBuffer11.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-
-namespace rx
-{
-
-IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
-{
-    mBuffer = NULL;
-    mBufferSize = 0;
-    mDynamicUsage = false;
-}
-
-IndexBuffer11::~IndexBuffer11()
-{
-    SafeRelease(mBuffer);
-}
-
-bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
-{
-    SafeRelease(mBuffer);
-
-    updateSerial();
-
-    if (bufferSize > 0)
-    {
-        ID3D11Device* dxDevice = mRenderer->getDevice();
-
-        D3D11_BUFFER_DESC bufferDesc;
-        bufferDesc.ByteWidth = bufferSize;
-        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
-        bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
-        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
-        bufferDesc.MiscFlags = 0;
-        bufferDesc.StructureByteStride = 0;
-
-        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
-        if (FAILED(result))
-        {
-            return false;
-        }
-    }
-
-    mBufferSize = bufferSize;
-    mIndexType = indexType;
-    mDynamicUsage = dynamic;
-
-    return true;
-}
-
-IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer));
-    return static_cast<IndexBuffer11*>(indexBuffer);
-}
-
-bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
-{
-    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;
-    }
-    else
-    {
-        ERR("Index buffer not initialized.");
-        return false;
-    }
-}
-
-bool IndexBuffer11::unmapBuffer()
-{
-    if (mBuffer)
-    {
-        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
-        dxContext->Unmap(mBuffer, 0);
-        return true;
-    }
-    else
-    {
-        ERR("Index buffer not initialized.");
-        return false;
-    }
-}
-
-GLenum IndexBuffer11::getIndexType() const
-{
-    return mIndexType;
-}
-
-unsigned int IndexBuffer11::getBufferSize() const
-{
-    return mBufferSize;
-}
-
-bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
-{
-    if (bufferSize > mBufferSize || indexType != mIndexType)
-    {
-        return initialize(bufferSize, indexType, mDynamicUsage);
-    }
-    else
-    {
-        return true;
-    }
-}
-
-bool IndexBuffer11::discard()
-{
-    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;
-    }
-    else
-    {
-        ERR("Index buffer not initialized.");
-        return false;
-    }
-}
-
-DXGI_FORMAT IndexBuffer11::getIndexFormat() const
-{
-    switch (mIndexType)
-    {
-      case GL_UNSIGNED_BYTE:    return DXGI_FORMAT_R16_UINT;
-      case GL_UNSIGNED_SHORT:   return DXGI_FORMAT_R16_UINT;
-      case GL_UNSIGNED_INT:     return DXGI_FORMAT_R32_UINT;
-      default: UNREACHABLE();   return DXGI_FORMAT_UNKNOWN;
-    }
-}
-
-ID3D11Buffer *IndexBuffer11::getBuffer() const
-{
-    return mBuffer;
-}
-
-}
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/d3d11/Query11.cpp b/src/libGLESv2/renderer/d3d11/Query11.cpp
deleted file mode 100644
index 203f61f..0000000
--- a/src/libGLESv2/renderer/d3d11/Query11.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl.
-
-#include "libGLESv2/renderer/d3d11/Query11.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/main.h"
-
-namespace rx
-{
-
-static bool checkOcclusionQuery(ID3D11DeviceContext *context, ID3D11Query *query, UINT64 *numPixels)
-{
-    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()
-{
-    SafeRelease(mQuery);
-}
-
-void Query11::begin()
-{
-    if (mQuery == NULL)
-    {
-        D3D11_QUERY_DESC queryDesc;
-        queryDesc.Query = gl_d3d11::ConvertQueryType(getType());
-        queryDesc.MiscFlags = 0;
-
-        if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery)))
-        {
-            return gl::error(GL_OUT_OF_MEMORY);
-        }
-    }
-
-    mRenderer->getDeviceContext()->Begin(mQuery);
-}
-
-void Query11::end()
-{
-    ASSERT(mQuery);
-    mRenderer->getDeviceContext()->End(mQuery);
-
-    mStatus = GL_FALSE;
-    mResult = GL_FALSE;
-}
-
-GLuint Query11::getResult()
-{
-    if (mQuery != NULL)
-    {
-        while (!testQuery())
-        {
-            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;
-}
-
-GLboolean Query11::isResultAvailable()
-{
-    if (mQuery != NULL)
-    {
-        testQuery();
-    }
-
-    return mStatus;
-}
-
-GLboolean Query11::testQuery()
-{
-    if (mQuery != NULL && mStatus != GL_TRUE)
-    {
-        ID3D11DeviceContext *context = mRenderer->getDeviceContext();
-
-        bool queryFinished = false;
-        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)
-                {
-                    mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
-                }
-            }
-            break;
-
-          case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
-            {
-                UINT64 numPrimitives = 0;
-                queryFinished = checkStreamOutPrimitivesWritten(context, mQuery, &numPrimitives);
-                if (queryFinished)
-                {
-                    mResult = static_cast<GLuint>(numPrimitives);
-                }
-            }
-            break;
-
-        default:
-            UNREACHABLE();
-            break;
-        }
-
-        if (queryFinished)
-        {
-            mStatus = GL_TRUE;
-        }
-        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);
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp b/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp
deleted file mode 100644
index d69668d..0000000
--- a/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
-
-#include "libGLESv2/renderer/d3d11/VertexBuffer11.h"
-#include "libGLESv2/renderer/BufferStorage.h"
-
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/renderer/d3d11/Renderer11.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
-
-namespace rx
-{
-
-VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer)
-{
-    mBuffer = NULL;
-    mBufferSize = 0;
-    mDynamicUsage = false;
-}
-
-VertexBuffer11::~VertexBuffer11()
-{
-    SafeRelease(mBuffer);
-}
-
-bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
-{
-    SafeRelease(mBuffer);
-
-    updateSerial();
-
-    if (size > 0)
-    {
-        ID3D11Device* dxDevice = mRenderer->getDevice();
-
-        D3D11_BUFFER_DESC bufferDesc;
-        bufferDesc.ByteWidth = size;
-        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
-        bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
-        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
-        bufferDesc.MiscFlags = 0;
-        bufferDesc.StructureByteStride = 0;
-
-        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
-        if (FAILED(result))
-        {
-            return false;
-        }
-    }
-
-    mBufferSize = size;
-    mDynamicUsage = dynamicUsage;
-    return true;
-}
-
-VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer));
-    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)
-{
-    if (mBuffer)
-    {
-        gl::Buffer *buffer = attrib.mBoundBuffer.get();
-        int inputStride = attrib.stride();
-        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("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.mArrayEnabled)
-        {
-            if (buffer)
-            {
-                BufferStorage *storage = buffer->getStorage();
-                input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset);
-            }
-            else
-            {
-                input = static_cast<const char*>(attrib.mPointer);
-            }
-        }
-        else
-        {
-            input = reinterpret_cast<const char*>(currentValue.FloatValues);
-        }
-
-        if (instances == 0 || attrib.mDivisor == 0)
-        {
-            input += inputStride * start;
-        }
-
-        gl::VertexFormat vertexFormat(attrib, currentValue.Type);
-        VertexCopyFunction conversionFunc = gl_d3d11::GetVertexCopyFunction(vertexFormat);
-        ASSERT(conversionFunc != NULL);
-        conversionFunc(input, inputStride, count, output);
-
-        dxContext->Unmap(mBuffer, 0);
-
-        return true;
-    }
-    else
-    {
-        ERR("Vertex buffer not initialized.");
-        return false;
-    }
-}
-
-bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
-                                      GLsizei instances, unsigned int *outSpaceRequired) const
-{
-    unsigned int elementCount = 0;
-    if (attrib.mArrayEnabled)
-    {
-        if (instances == 0 || attrib.mDivisor == 0)
-        {
-            elementCount = count;
-        }
-        else
-        {
-            if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1))
-            {
-                // Round up
-                elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.mDivisor);
-            }
-            else
-            {
-                elementCount = instances / attrib.mDivisor;
-            }
-        }
-
-        gl::VertexFormat vertexFormat(attrib);
-        unsigned int elementSize = static_cast<unsigned int>(gl_d3d11::GetVertexElementSize(vertexFormat));
-        if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
-        {
-            if (outSpaceRequired)
-            {
-                *outSpaceRequired = elementSize * elementCount;
-            }
-            return true;
-        }
-        else
-        {
-            return false;
-        }
-    }
-    else
-    {
-        const unsigned int elementSize = 4;
-        if (outSpaceRequired)
-        {
-            *outSpaceRequired = elementSize * 4;
-        }
-        return true;
-    }
-}
-
-unsigned int VertexBuffer11::getBufferSize() const
-{
-    return mBufferSize;
-}
-
-bool VertexBuffer11::setBufferSize(unsigned int size)
-{
-    if (size > mBufferSize)
-    {
-        return initialize(size, mDynamicUsage);
-    }
-    else
-    {
-        return true;
-    }
-}
-
-bool VertexBuffer11::discard()
-{
-    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;
-    }
-    else
-    {
-        ERR("Vertex buffer not initialized.");
-        return false;
-    }
-}
-
-ID3D11Buffer *VertexBuffer11::getBuffer() const
-{
-    return mBuffer;
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d11/VertexBuffer11.h b/src/libGLESv2/renderer/d3d11/VertexBuffer11.h
deleted file mode 100644
index 191791a..0000000
--- a/src/libGLESv2/renderer/d3d11/VertexBuffer11.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// 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
-// found in the LICENSE file.
-//
-
-// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation.
-
-#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
-#define LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
-
-#include "libGLESv2/renderer/VertexBuffer.h"
-
-namespace rx
-{
-class Renderer11;
-
-class VertexBuffer11 : public VertexBuffer
-{
-  public:
-    explicit VertexBuffer11(rx::Renderer11 *const renderer);
-    virtual ~VertexBuffer11();
-
-    virtual bool 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 bool 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();
-
-    ID3D11Buffer *getBuffer() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(VertexBuffer11);
-
-    rx::Renderer11 *const mRenderer;
-
-    ID3D11Buffer *mBuffer;
-    unsigned int mBufferSize;
-    bool mDynamicUsage;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
diff --git a/src/libGLESv2/renderer/d3d11/formatutils11.cpp b/src/libGLESv2/renderer/d3d11/formatutils11.cpp
deleted file mode 100644
index 695e168..0000000
--- a/src/libGLESv2/renderer/d3d11/formatutils11.cpp
+++ /dev/null
@@ -1,1665 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// formatutils11.cpp: Queries for GL image formats and their translations to D3D11
-// formats.
-
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/generatemip.h"
-#include "libGLESv2/renderer/loadimage.h"
-#include "libGLESv2/renderer/copyimage.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/copyvertex.h"
-
-namespace rx
-{
-
-struct D3D11ES3FormatInfo
-{
-    DXGI_FORMAT mTexFormat;
-    DXGI_FORMAT mSRVFormat;
-    DXGI_FORMAT mRTVFormat;
-    DXGI_FORMAT mDSVFormat;
-
-    D3D11ES3FormatInfo()
-        : mTexFormat(DXGI_FORMAT_UNKNOWN), mDSVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN)
-    { }
-
-    D3D11ES3FormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
-        : mTexFormat(texFormat), mDSVFormat(dsvFormat), mRTVFormat(rtvFormat), mSRVFormat(srvFormat)
-    { }
-};
-
-// For sized GL internal formats, there is only one corresponding D3D11 format. This map type allows
-// querying for the DXGI texture formats to use for textures, SRVs, RTVs and DSVs given a GL internal
-// format.
-typedef std::pair<GLenum, D3D11ES3FormatInfo> D3D11ES3FormatPair;
-typedef std::map<GLenum, D3D11ES3FormatInfo> D3D11ES3FormatMap;
-
-static D3D11ES3FormatMap BuildD3D11ES3FormatMap()
-{
-    D3D11ES3FormatMap map;
-
-    //                           | GL internal format  |                  | D3D11 texture format            | D3D11 SRV format               | D3D11 RTV format               | D3D11 DSV format   |
-    map.insert(D3D11ES3FormatPair(GL_NONE,              D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,              DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R8,                D3D11ES3FormatInfo(DXGI_FORMAT_R8_UNORM,             DXGI_FORMAT_R8_UNORM,            DXGI_FORMAT_R8_UNORM,            DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R8_SNORM,          D3D11ES3FormatInfo(DXGI_FORMAT_R8_SNORM,             DXGI_FORMAT_R8_SNORM,            DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG8,               D3D11ES3FormatInfo(DXGI_FORMAT_R8G8_UNORM,           DXGI_FORMAT_R8G8_UNORM,          DXGI_FORMAT_R8G8_UNORM,          DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG8_SNORM,         D3D11ES3FormatInfo(DXGI_FORMAT_R8G8_SNORM,           DXGI_FORMAT_R8G8_SNORM,          DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB8,              D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB8_SNORM,        D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM,       DXGI_FORMAT_R8G8B8A8_SNORM,      DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB565,            D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA4,             D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB5_A1,           D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA8,             D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA8_SNORM,       D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM,       DXGI_FORMAT_R8G8B8A8_SNORM,      DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB10_A2,          D3D11ES3FormatInfo(DXGI_FORMAT_R10G10B10A2_UNORM,    DXGI_FORMAT_R10G10B10A2_UNORM,   DXGI_FORMAT_R10G10B10A2_UNORM,   DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB10_A2UI,        D3D11ES3FormatInfo(DXGI_FORMAT_R10G10B10A2_UINT,     DXGI_FORMAT_R10G10B10A2_UINT,    DXGI_FORMAT_R10G10B10A2_UINT,    DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_SRGB8,             D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,  DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_SRGB8_ALPHA8,      D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,  DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R16F,              D3D11ES3FormatInfo(DXGI_FORMAT_R16_FLOAT,            DXGI_FORMAT_R16_FLOAT,           DXGI_FORMAT_R16_FLOAT,           DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG16F,             D3D11ES3FormatInfo(DXGI_FORMAT_R16G16_FLOAT,         DXGI_FORMAT_R16G16_FLOAT,        DXGI_FORMAT_R16G16_FLOAT,        DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB16F,            D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT,   DXGI_FORMAT_R16G16B16A16_FLOAT,  DXGI_FORMAT_R16G16B16A16_FLOAT,  DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA16F,           D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT,   DXGI_FORMAT_R16G16B16A16_FLOAT,  DXGI_FORMAT_R16G16B16A16_FLOAT,  DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R32F,              D3D11ES3FormatInfo(DXGI_FORMAT_R32_FLOAT,            DXGI_FORMAT_R32_FLOAT,           DXGI_FORMAT_R32_FLOAT,           DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG32F,             D3D11ES3FormatInfo(DXGI_FORMAT_R32G32_FLOAT,         DXGI_FORMAT_R32G32_FLOAT,        DXGI_FORMAT_R32G32_FLOAT,        DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB32F,            D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT,   DXGI_FORMAT_R32G32B32A32_FLOAT,  DXGI_FORMAT_R32G32B32A32_FLOAT,  DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA32F,           D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT,   DXGI_FORMAT_R32G32B32A32_FLOAT,  DXGI_FORMAT_R32G32B32A32_FLOAT,  DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R11F_G11F_B10F,    D3D11ES3FormatInfo(DXGI_FORMAT_R11G11B10_FLOAT,      DXGI_FORMAT_R11G11B10_FLOAT,     DXGI_FORMAT_R11G11B10_FLOAT,     DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB9_E5,           D3D11ES3FormatInfo(DXGI_FORMAT_R9G9B9E5_SHAREDEXP,   DXGI_FORMAT_R9G9B9E5_SHAREDEXP,  DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R8I,               D3D11ES3FormatInfo(DXGI_FORMAT_R8_SINT,              DXGI_FORMAT_R8_SINT,             DXGI_FORMAT_R8_SINT,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R8UI,              D3D11ES3FormatInfo(DXGI_FORMAT_R8_UINT,              DXGI_FORMAT_R8_UINT,             DXGI_FORMAT_R8_UINT,             DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R16I,              D3D11ES3FormatInfo(DXGI_FORMAT_R16_SINT,             DXGI_FORMAT_R16_SINT,            DXGI_FORMAT_R16_SINT,            DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R16UI,             D3D11ES3FormatInfo(DXGI_FORMAT_R16_UINT,             DXGI_FORMAT_R16_UINT,            DXGI_FORMAT_R16_UINT,            DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R32I,              D3D11ES3FormatInfo(DXGI_FORMAT_R32_SINT,             DXGI_FORMAT_R32_SINT,            DXGI_FORMAT_R32_SINT,            DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_R32UI,             D3D11ES3FormatInfo(DXGI_FORMAT_R32_UINT,             DXGI_FORMAT_R32_UINT,            DXGI_FORMAT_R32_UINT,            DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG8I,              D3D11ES3FormatInfo(DXGI_FORMAT_R8G8_SINT,            DXGI_FORMAT_R8G8_SINT,           DXGI_FORMAT_R8G8_SINT,           DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG8UI,             D3D11ES3FormatInfo(DXGI_FORMAT_R8G8_UINT,            DXGI_FORMAT_R8G8_UINT,           DXGI_FORMAT_R8G8_UINT,           DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG16I,             D3D11ES3FormatInfo(DXGI_FORMAT_R16G16_SINT,          DXGI_FORMAT_R16G16_SINT,         DXGI_FORMAT_R16G16_SINT,         DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG16UI,            D3D11ES3FormatInfo(DXGI_FORMAT_R16G16_UINT,          DXGI_FORMAT_R16G16_UINT,         DXGI_FORMAT_R16G16_UINT,         DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG32I,             D3D11ES3FormatInfo(DXGI_FORMAT_R32G32_SINT,          DXGI_FORMAT_R32G32_SINT,         DXGI_FORMAT_R32G32_SINT,         DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RG32UI,            D3D11ES3FormatInfo(DXGI_FORMAT_R32G32_UINT,          DXGI_FORMAT_R32G32_UINT,         DXGI_FORMAT_R32G32_UINT,         DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB8I,             D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_SINT,        DXGI_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB8UI,            D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UINT,        DXGI_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB16I,            D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_SINT,    DXGI_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB16UI,           D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_UINT,    DXGI_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB32I,            D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_SINT,    DXGI_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB32UI,           D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_UINT,    DXGI_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA8I,            D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_SINT,        DXGI_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA8UI,           D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UINT,        DXGI_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA16I,           D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_SINT,    DXGI_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA16UI,          D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_UINT,    DXGI_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA32I,           D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_SINT,    DXGI_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA32UI,          D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_UINT,    DXGI_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_UNKNOWN)));
-
-    // Unsized formats, TODO: Are types of float and half float allowed for the unsized types? Would it change the DXGI format?
-    map.insert(D3D11ES3FormatPair(GL_ALPHA,             D3D11ES3FormatInfo(DXGI_FORMAT_A8_UNORM,             DXGI_FORMAT_A8_UNORM,            DXGI_FORMAT_A8_UNORM,            DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_LUMINANCE,         D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA,   D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGB,               D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_RGBA,              D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,       DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_BGRA_EXT,          D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM,       DXGI_FORMAT_B8G8R8A8_UNORM,      DXGI_FORMAT_B8G8R8A8_UNORM,      DXGI_FORMAT_UNKNOWN)));
-
-    // From GL_EXT_texture_storage
-    //                           | GL internal format       |                  | D3D11 texture format          | D3D11 SRV format                    | D3D11 RTV format              | D3D11 DSV format               |
-    map.insert(D3D11ES3FormatPair(GL_ALPHA8_EXT,             D3D11ES3FormatInfo(DXGI_FORMAT_A8_UNORM,           DXGI_FORMAT_A8_UNORM,                 DXGI_FORMAT_A8_UNORM,           DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_EXT,         D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,           DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_ALPHA32F_EXT,           D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,       DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_LUMINANCE32F_EXT,       D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,       DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_ALPHA16F_EXT,           D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,       DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_LUMINANCE16F_EXT,       D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,       DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_ALPHA8_EXT,  D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,           DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,       DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,       DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_BGRA8_EXT,              D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,           DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_BGRA4_ANGLEX,           D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,           DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN             )));
-    map.insert(D3D11ES3FormatPair(GL_BGR5_A1_ANGLEX,         D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,           DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN             )));
-
-    // Depth stencil formats
-    map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT16,     D3D11ES3FormatInfo(DXGI_FORMAT_R16_TYPELESS,        DXGI_FORMAT_R16_UNORM,                DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D16_UNORM           )));
-    map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT24,     D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS,      DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D24_UNORM_S8_UINT   )));
-    map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32F,    D3D11ES3FormatInfo(DXGI_FORMAT_R32_TYPELESS,        DXGI_FORMAT_R32_FLOAT,                DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D32_FLOAT           )));
-    map.insert(D3D11ES3FormatPair(GL_DEPTH24_STENCIL8,      D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS,      DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D24_UNORM_S8_UINT   )));
-    map.insert(D3D11ES3FormatPair(GL_DEPTH32F_STENCIL8,     D3D11ES3FormatInfo(DXGI_FORMAT_R32G8X24_TYPELESS,   DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D32_FLOAT_S8X24_UINT)));
-    map.insert(D3D11ES3FormatPair(GL_STENCIL_INDEX8,        D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS,      DXGI_FORMAT_X24_TYPELESS_G8_UINT,     DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D24_UNORM_S8_UINT   )));
-
-    // From GL_ANGLE_depth_texture
-    map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32_OES, D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS,      DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    DXGI_FORMAT_UNKNOWN,             DXGI_FORMAT_D24_UNORM_S8_UINT  )));
-
-    // Compressed formats, From ES 3.0.1 spec, table 3.16
-    //                           | GL internal format                          |                  | D3D11 texture format | D3D11 SRV format     | D3D11 RTV format   | D3D11 DSV format  |
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_R11_EAC,                        D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_R11_EAC,                 D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RG11_EAC,                       D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_RG11_EAC,                D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_ETC2,                      D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ETC2,                     D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA8_ETC2_EAC,                 D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN,   DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-
-    // From GL_EXT_texture_compression_dxt1
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              D3D11ES3FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             D3D11ES3FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-
-    // From GL_ANGLE_texture_compression_dxt3
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           D3D11ES3FormatInfo(DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-
-    // From GL_ANGLE_texture_compression_dxt5
-    map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           D3D11ES3FormatInfo(DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
-
-    return map;
-}
-
-static bool GetD3D11ES3FormatInfo(GLenum internalFormat, GLuint clientVersion, D3D11ES3FormatInfo *outFormatInfo)
-{
-    static const D3D11ES3FormatMap formatMap = BuildD3D11ES3FormatMap();
-    D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat);
-    if (iter != formatMap.end())
-    {
-        if (outFormatInfo)
-        {
-            *outFormatInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-// ES3 image loading functions vary based on the internal format and data type given,
-// this map type determines the loading function from the internal format and type supplied
-// to glTex*Image*D and the destination DXGI_FORMAT. Source formats and types are taken from
-// Tables 3.2 and 3.3 of the ES 3 spec.
-typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
-typedef std::pair<InternalFormatTypePair, LoadImageFunction> D3D11LoadFunctionPair;
-typedef std::map<InternalFormatTypePair, LoadImageFunction> D3D11LoadFunctionMap;
-
-static void UnimplementedLoadFunction(int width, int height, int depth,
-                                      const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                      void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    UNIMPLEMENTED();
-}
-
-static void UnreachableLoadFunction(int width, int height, int depth,
-                                    const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                    void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    UNREACHABLE();
-}
-
-// A helper function to insert data into the D3D11LoadFunctionMap with fewer characters.
-static inline void insertLoadFunction(D3D11LoadFunctionMap *map, GLenum internalFormat, GLenum type,
-                                      LoadImageFunction loadFunc)
-{
-    map->insert(D3D11LoadFunctionPair(InternalFormatTypePair(internalFormat, type), loadFunc));
-}
-
-D3D11LoadFunctionMap buildD3D11LoadFunctionMap()
-{
-    D3D11LoadFunctionMap map;
-
-    //                      | Internal format      | Type                             | Load function                       |
-    insertLoadFunction(&map, GL_RGBA8,              GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 4>             );
-    insertLoadFunction(&map, GL_RGB5_A1,            GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 4>             );
-    insertLoadFunction(&map, GL_RGBA4,              GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 4>             );
-    insertLoadFunction(&map, GL_SRGB8_ALPHA8,       GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 4>             );
-    insertLoadFunction(&map, GL_RGBA8_SNORM,        GL_BYTE,                           loadToNative<GLbyte, 4>              );
-    insertLoadFunction(&map, GL_RGBA4,              GL_UNSIGNED_SHORT_4_4_4_4,         loadRGBA4444DataToRGBA               );
-    insertLoadFunction(&map, GL_RGB10_A2,           GL_UNSIGNED_INT_2_10_10_10_REV,    loadToNative<GLuint, 1>              );
-    insertLoadFunction(&map, GL_RGB5_A1,            GL_UNSIGNED_SHORT_5_5_5_1,         loadRGBA5551DataToRGBA               );
-    insertLoadFunction(&map, GL_RGB5_A1,            GL_UNSIGNED_INT_2_10_10_10_REV,    loadRGBA2101010ToRGBA                );
-    insertLoadFunction(&map, GL_RGBA16F,            GL_HALF_FLOAT,                     loadToNative<GLhalf, 4>              );
-    insertLoadFunction(&map, GL_RGBA32F,            GL_FLOAT,                          loadToNative<GLfloat, 4>             );
-    insertLoadFunction(&map, GL_RGBA16F,            GL_FLOAT,                          loadFloatDataToHalfFloat<4>          );
-    insertLoadFunction(&map, GL_RGBA8UI,            GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 4>             );
-    insertLoadFunction(&map, GL_RGBA8I,             GL_BYTE,                           loadToNative<GLbyte, 4>              );
-    insertLoadFunction(&map, GL_RGBA16UI,           GL_UNSIGNED_SHORT,                 loadToNative<GLushort, 4>            );
-    insertLoadFunction(&map, GL_RGBA16I,            GL_SHORT,                          loadToNative<GLshort, 4>             );
-    insertLoadFunction(&map, GL_RGBA32UI,           GL_UNSIGNED_INT,                   loadToNative<GLuint, 4>              );
-    insertLoadFunction(&map, GL_RGBA32I,            GL_INT,                            loadToNative<GLint, 4>               );
-    insertLoadFunction(&map, GL_RGB10_A2UI,         GL_UNSIGNED_INT_2_10_10_10_REV,    loadToNative<GLuint, 1>              );
-    insertLoadFunction(&map, GL_RGB8,               GL_UNSIGNED_BYTE,                  loadRGBUByteDataToRGBA               );
-    insertLoadFunction(&map, GL_RGB565,             GL_UNSIGNED_BYTE,                  loadToNative3To4<GLubyte, 0xFF>      );
-    insertLoadFunction(&map, GL_SRGB8,              GL_UNSIGNED_BYTE,                  loadToNative3To4<GLubyte, 0xFF>      );
-    insertLoadFunction(&map, GL_RGB8_SNORM,         GL_BYTE,                           loadRGBSByteDataToRGBA               );
-    insertLoadFunction(&map, GL_RGB565,             GL_UNSIGNED_SHORT_5_6_5,           loadRGB565DataToRGBA                 );
-    insertLoadFunction(&map, GL_R11F_G11F_B10F,     GL_UNSIGNED_INT_10F_11F_11F_REV,   loadToNative<GLuint, 1>              );
-    insertLoadFunction(&map, GL_RGB9_E5,            GL_UNSIGNED_INT_5_9_9_9_REV,       loadToNative<GLuint, 1>              );
-    insertLoadFunction(&map, GL_RGB16F,             GL_HALF_FLOAT,                     loadToNative3To4<GLhalf, gl::Float16One>);
-    insertLoadFunction(&map, GL_R11F_G11F_B10F,     GL_HALF_FLOAT,                     loadRGBHalfFloatDataTo111110Float    );
-    insertLoadFunction(&map, GL_RGB9_E5,            GL_HALF_FLOAT,                     loadRGBHalfFloatDataTo999E5          );
-    insertLoadFunction(&map, GL_RGB32F,             GL_FLOAT,                          loadToNative3To4<GLfloat, gl::Float32One>);
-    insertLoadFunction(&map, GL_RGB16F,             GL_FLOAT,                          loadFloatRGBDataToHalfFloatRGBA      );
-    insertLoadFunction(&map, GL_R11F_G11F_B10F,     GL_FLOAT,                          loadRGBFloatDataTo111110Float        );
-    insertLoadFunction(&map, GL_RGB9_E5,            GL_FLOAT,                          loadRGBFloatDataTo999E5              );
-    insertLoadFunction(&map, GL_RGB8UI,             GL_UNSIGNED_BYTE,                  loadToNative3To4<GLubyte, 0x01>      );
-    insertLoadFunction(&map, GL_RGB8I,              GL_BYTE,                           loadToNative3To4<GLbyte, 0x01>       );
-    insertLoadFunction(&map, GL_RGB16UI,            GL_UNSIGNED_SHORT,                 loadToNative3To4<GLushort, 0x0001>   );
-    insertLoadFunction(&map, GL_RGB16I,             GL_SHORT,                          loadToNative3To4<GLshort, 0x0001>    );
-    insertLoadFunction(&map, GL_RGB32UI,            GL_UNSIGNED_INT,                   loadToNative3To4<GLuint, 0x00000001> );
-    insertLoadFunction(&map, GL_RGB32I,             GL_INT,                            loadToNative3To4<GLint, 0x00000001>  );
-    insertLoadFunction(&map, GL_RG8,                GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 2>             );
-    insertLoadFunction(&map, GL_RG8_SNORM,          GL_BYTE,                           loadToNative<GLbyte, 2>              );
-    insertLoadFunction(&map, GL_RG16F,              GL_HALF_FLOAT,                     loadToNative<GLhalf, 2>              );
-    insertLoadFunction(&map, GL_RG32F,              GL_FLOAT,                          loadToNative<GLfloat, 2>             );
-    insertLoadFunction(&map, GL_RG16F,              GL_FLOAT,                          loadFloatDataToHalfFloat<2>          );
-    insertLoadFunction(&map, GL_RG8UI,              GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 2>             );
-    insertLoadFunction(&map, GL_RG8I,               GL_BYTE,                           loadToNative<GLbyte, 2>              );
-    insertLoadFunction(&map, GL_RG16UI,             GL_UNSIGNED_SHORT,                 loadToNative<GLushort, 2>            );
-    insertLoadFunction(&map, GL_RG16I,              GL_SHORT,                          loadToNative<GLshort, 2>             );
-    insertLoadFunction(&map, GL_RG32UI,             GL_UNSIGNED_INT,                   loadToNative<GLuint, 2>              );
-    insertLoadFunction(&map, GL_RG32I,              GL_INT,                            loadToNative<GLint, 2>               );
-    insertLoadFunction(&map, GL_R8,                 GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 1>             );
-    insertLoadFunction(&map, GL_R8_SNORM,           GL_BYTE,                           loadToNative<GLbyte, 1>              );
-    insertLoadFunction(&map, GL_R16F,               GL_HALF_FLOAT,                     loadToNative<GLhalf, 1>              );
-    insertLoadFunction(&map, GL_R32F,               GL_FLOAT,                          loadToNative<GLfloat, 1>             );
-    insertLoadFunction(&map, GL_R16F,               GL_FLOAT,                          loadFloatDataToHalfFloat<1>          );
-    insertLoadFunction(&map, GL_R8UI,               GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 1>             );
-    insertLoadFunction(&map, GL_R8I,                GL_BYTE,                           loadToNative<GLbyte, 1>              );
-    insertLoadFunction(&map, GL_R16UI,              GL_UNSIGNED_SHORT,                 loadToNative<GLushort, 1>            );
-    insertLoadFunction(&map, GL_R16I,               GL_SHORT,                          loadToNative<GLshort, 1>             );
-    insertLoadFunction(&map, GL_R32UI,              GL_UNSIGNED_INT,                   loadToNative<GLuint, 1>              );
-    insertLoadFunction(&map, GL_R32I,               GL_INT,                            loadToNative<GLint, 1>               );
-    insertLoadFunction(&map, GL_DEPTH_COMPONENT16,  GL_UNSIGNED_SHORT,                 loadToNative<GLushort, 1>            );
-    insertLoadFunction(&map, GL_DEPTH_COMPONENT24,  GL_UNSIGNED_INT,                   loadG8R24DataToR24G8                 );
-    insertLoadFunction(&map, GL_DEPTH_COMPONENT16,  GL_UNSIGNED_INT,                   loadUintDataToUshort                 );
-    insertLoadFunction(&map, GL_DEPTH_COMPONENT32F, GL_FLOAT,                          loadToNative<GLfloat, 1>             );
-    insertLoadFunction(&map, GL_DEPTH24_STENCIL8,   GL_UNSIGNED_INT_24_8,              loadG8R24DataToR24G8                 );
-    insertLoadFunction(&map, GL_DEPTH32F_STENCIL8,  GL_FLOAT_32_UNSIGNED_INT_24_8_REV, loadToNative<GLuint, 2>              );
-
-    // Unsized formats
-    // Load functions are unreachable because they are converted to sized internal formats based on
-    // the format and type before loading takes place.
-    insertLoadFunction(&map, GL_RGBA,               GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
-    insertLoadFunction(&map, GL_RGBA,               GL_UNSIGNED_SHORT_4_4_4_4,         UnreachableLoadFunction              );
-    insertLoadFunction(&map, GL_RGBA,               GL_UNSIGNED_SHORT_5_5_5_1,         UnreachableLoadFunction              );
-    insertLoadFunction(&map, GL_RGB,                GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
-    insertLoadFunction(&map, GL_RGB,                GL_UNSIGNED_SHORT_5_6_5,           UnreachableLoadFunction              );
-    insertLoadFunction(&map, GL_LUMINANCE_ALPHA,    GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
-    insertLoadFunction(&map, GL_LUMINANCE,          GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
-    insertLoadFunction(&map, GL_ALPHA,              GL_UNSIGNED_BYTE,                  UnreachableLoadFunction              );
-
-    // From GL_OES_texture_float
-    insertLoadFunction(&map, GL_LUMINANCE_ALPHA,    GL_FLOAT,                          loadLuminanceAlphaFloatDataToRGBA    );
-    insertLoadFunction(&map, GL_LUMINANCE,          GL_FLOAT,                          loadLuminanceFloatDataToRGB          );
-    insertLoadFunction(&map, GL_ALPHA,              GL_FLOAT,                          loadAlphaFloatDataToRGBA             );
-
-    // From GL_OES_texture_half_float
-    insertLoadFunction(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT,                     loadLuminanceAlphaHalfFloatDataToRGBA);
-    insertLoadFunction(&map, GL_LUMINANCE,          GL_HALF_FLOAT,                     loadLuminanceHalfFloatDataToRGBA     );
-    insertLoadFunction(&map, GL_ALPHA,              GL_HALF_FLOAT,                     loadAlphaHalfFloatDataToRGBA         );
-
-    // From GL_EXT_texture_storage
-    insertLoadFunction(&map, GL_ALPHA8_EXT,             GL_UNSIGNED_BYTE,              loadToNative<GLubyte, 1>             );
-    insertLoadFunction(&map, GL_LUMINANCE8_EXT,         GL_UNSIGNED_BYTE,              loadLuminanceDataToBGRA              );
-    insertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT,  GL_UNSIGNED_BYTE,              loadLuminanceAlphaDataToBGRA         );
-    insertLoadFunction(&map, GL_ALPHA32F_EXT,           GL_FLOAT,                      loadAlphaFloatDataToRGBA             );
-    insertLoadFunction(&map, GL_LUMINANCE32F_EXT,       GL_FLOAT,                      loadLuminanceFloatDataToRGB          );
-    insertLoadFunction(&map, GL_LUMINANCE_ALPHA32F_EXT, GL_FLOAT,                      loadLuminanceAlphaFloatDataToRGBA    );
-    insertLoadFunction(&map, GL_ALPHA16F_EXT,           GL_HALF_FLOAT,                 loadAlphaHalfFloatDataToRGBA         );
-    insertLoadFunction(&map, GL_LUMINANCE16F_EXT,       GL_HALF_FLOAT,                 loadLuminanceHalfFloatDataToRGBA     );
-    insertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT,                 loadLuminanceAlphaHalfFloatDataToRGBA);
-
-    insertLoadFunction(&map, GL_BGRA8_EXT,              GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 4>         );
-    insertLoadFunction(&map, GL_BGRA4_ANGLEX,           GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, loadRGBA4444DataToRGBA           );
-    insertLoadFunction(&map, GL_BGRA4_ANGLEX,           GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 4>         );
-    insertLoadFunction(&map, GL_BGR5_A1_ANGLEX,         GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, loadRGBA5551DataToRGBA           );
-    insertLoadFunction(&map, GL_BGR5_A1_ANGLEX,         GL_UNSIGNED_BYTE,                  loadToNative<GLubyte, 4>         );
-
-    // Compressed formats
-    // From ES 3.0.1 spec, table 3.16
-    //                      | Internal format                             | Type            | Load function                     |
-    insertLoadFunction(&map, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-    insertLoadFunction(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE, UnimplementedLoadFunction          );
-
-    // From GL_EXT_texture_compression_dxt1
-    insertLoadFunction(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4,  8>);
-    insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4,  8>);
-
-    // From GL_ANGLE_texture_compression_dxt3
-    insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 16>);
-
-    // From GL_ANGLE_texture_compression_dxt5
-    insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 16>);
-
-    return map;
-}
-
-struct D3D11ES2FormatInfo
-{
-    DXGI_FORMAT mTexFormat;
-    DXGI_FORMAT mSRVFormat;
-    DXGI_FORMAT mRTVFormat;
-    DXGI_FORMAT mDSVFormat;
-
-    LoadImageFunction mLoadImageFunction;
-
-    D3D11ES2FormatInfo()
-        : mTexFormat(DXGI_FORMAT_UNKNOWN), mDSVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN),
-        mSRVFormat(DXGI_FORMAT_UNKNOWN), mLoadImageFunction(NULL)
-    { }
-
-    D3D11ES2FormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat,
-        LoadImageFunction loadFunc)
-        : mTexFormat(texFormat), mDSVFormat(dsvFormat), mRTVFormat(rtvFormat), mSRVFormat(srvFormat),
-        mLoadImageFunction(loadFunc)
-    { }
-};
-
-// ES2 internal formats can map to DXGI formats and loading functions
-typedef std::pair<GLenum, D3D11ES2FormatInfo> D3D11ES2FormatPair;
-typedef std::map<GLenum, D3D11ES2FormatInfo> D3D11ES2FormatMap;
-
-static D3D11ES2FormatMap BuildD3D11ES2FormatMap()
-{
-    D3D11ES2FormatMap map;
-
-    //                           | Internal format                   |                  | Texture format                | SRV format                       | RTV format                    | DSV format                   | Load function                           |
-    map.insert(D3D11ES2FormatPair(GL_NONE,                            D3D11ES2FormatInfo(DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,           UnreachableLoadFunction                  )));
-    map.insert(D3D11ES2FormatPair(GL_DEPTH_COMPONENT16,               D3D11ES2FormatInfo(DXGI_FORMAT_R16_TYPELESS,       DXGI_FORMAT_R16_UNORM,             DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D16_UNORM,         UnreachableLoadFunction                  )));
-    map.insert(D3D11ES2FormatPair(GL_DEPTH_COMPONENT32_OES,           D3D11ES2FormatInfo(DXGI_FORMAT_R32_TYPELESS,       DXGI_FORMAT_R32_FLOAT,             DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D32_FLOAT,         UnreachableLoadFunction                  )));
-    map.insert(D3D11ES2FormatPair(GL_DEPTH24_STENCIL8_OES,            D3D11ES2FormatInfo(DXGI_FORMAT_R24G8_TYPELESS,     DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D24_UNORM_S8_UINT, UnreachableLoadFunction                  )));
-    map.insert(D3D11ES2FormatPair(GL_STENCIL_INDEX8,                  D3D11ES2FormatInfo(DXGI_FORMAT_R24G8_TYPELESS,     DXGI_FORMAT_X24_TYPELESS_G8_UINT,  DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_D24_UNORM_S8_UINT, UnreachableLoadFunction                  )));
-
-    map.insert(D3D11ES2FormatPair(GL_RGBA32F_EXT,                     D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,    DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN,           loadRGBAFloatDataToRGBA                  )));
-    map.insert(D3D11ES2FormatPair(GL_RGB32F_EXT,                      D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,    DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN,           loadRGBFloatDataToRGBA                   )));
-    map.insert(D3D11ES2FormatPair(GL_ALPHA32F_EXT,                    D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,    DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN,           loadAlphaFloatDataToRGBA                 )));
-    map.insert(D3D11ES2FormatPair(GL_LUMINANCE32F_EXT,                D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,    DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN,           loadLuminanceFloatDataToRGBA             )));
-    map.insert(D3D11ES2FormatPair(GL_LUMINANCE_ALPHA32F_EXT,          D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,    DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN,           loadLuminanceAlphaFloatDataToRGBA        )));
-
-    map.insert(D3D11ES2FormatPair(GL_RGBA16F_EXT,                     D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,    DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN,           loadRGBAHalfFloatDataToRGBA              )));
-    map.insert(D3D11ES2FormatPair(GL_RGB16F_EXT,                      D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,    DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN,           loadRGBHalfFloatDataToRGBA               )));
-    map.insert(D3D11ES2FormatPair(GL_ALPHA16F_EXT,                    D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,    DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN,           loadAlphaHalfFloatDataToRGBA             )));
-    map.insert(D3D11ES2FormatPair(GL_LUMINANCE16F_EXT,                D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,    DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN,           loadLuminanceHalfFloatDataToRGBA         )));
-    map.insert(D3D11ES2FormatPair(GL_LUMINANCE_ALPHA16F_EXT,          D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,    DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN,           loadLuminanceAlphaHalfFloatDataToRGBA    )));
-
-    map.insert(D3D11ES2FormatPair(GL_ALPHA8_EXT,                      D3D11ES2FormatInfo(DXGI_FORMAT_A8_UNORM,           DXGI_FORMAT_A8_UNORM,              DXGI_FORMAT_A8_UNORM,           DXGI_FORMAT_UNKNOWN,           loadAlphaDataToNative                    )));
-    map.insert(D3D11ES2FormatPair(GL_LUMINANCE8_EXT,                  D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,        DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadLuminanceDataToBGRA                  )));
-    map.insert(D3D11ES2FormatPair(GL_LUMINANCE8_ALPHA8_EXT,           D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,        DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadLuminanceAlphaDataToBGRA             )));
-
-    map.insert(D3D11ES2FormatPair(GL_RGB8_OES,                        D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,        DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadRGBUByteDataToRGBA                   )));
-    map.insert(D3D11ES2FormatPair(GL_RGB565,                          D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,        DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadRGB565DataToRGBA                     )));
-    map.insert(D3D11ES2FormatPair(GL_RGBA8_OES,                       D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,        DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadRGBAUByteDataToNative                )));
-    map.insert(D3D11ES2FormatPair(GL_RGBA4,                           D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,        DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadRGBA4444DataToRGBA                   )));
-    map.insert(D3D11ES2FormatPair(GL_RGB5_A1,                         D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,        DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadRGBA5551DataToRGBA                   )));
-    map.insert(D3D11ES2FormatPair(GL_BGRA8_EXT,                       D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,        DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadBGRADataToBGRA                       )));
-    map.insert(D3D11ES2FormatPair(GL_BGRA4_ANGLEX,                    D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,        DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadRGBA4444DataToRGBA                   )));
-    map.insert(D3D11ES2FormatPair(GL_BGR5_A1_ANGLEX,                  D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,        DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_UNKNOWN,           loadRGBA5551DataToRGBA                   )));
-
-    // From GL_EXT_texture_rg
-    map.insert(D3D11ES2FormatPair(GL_R8_EXT,                          D3D11ES2FormatInfo(DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8_UNORM,              DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_UNKNOWN,           loadToNative<GLubyte, 1>                 )));
-    map.insert(D3D11ES2FormatPair(GL_R32F_EXT,                        D3D11ES2FormatInfo(DXGI_FORMAT_R32_FLOAT,          DXGI_FORMAT_R32_FLOAT,             DXGI_FORMAT_R32_FLOAT,          DXGI_FORMAT_UNKNOWN,           loadToNative<GLfloat, 1>                 )));
-    map.insert(D3D11ES2FormatPair(GL_R16F_EXT,                        D3D11ES2FormatInfo(DXGI_FORMAT_R16_FLOAT,          DXGI_FORMAT_R16_FLOAT,             DXGI_FORMAT_R16_FLOAT,          DXGI_FORMAT_UNKNOWN,           loadToNative<GLhalf, 1>                  )));
-    map.insert(D3D11ES2FormatPair(GL_RG8_EXT,                         D3D11ES2FormatInfo(DXGI_FORMAT_R8G8_UNORM,         DXGI_FORMAT_R8G8_UNORM,            DXGI_FORMAT_R8G8_UNORM,         DXGI_FORMAT_UNKNOWN,           loadToNative<GLubyte, 2>                 )));
-    map.insert(D3D11ES2FormatPair(GL_RG32F_EXT,                       D3D11ES2FormatInfo(DXGI_FORMAT_R32G32_FLOAT,       DXGI_FORMAT_R32G32_FLOAT,          DXGI_FORMAT_R32G32_FLOAT,       DXGI_FORMAT_UNKNOWN,           loadToNative<GLfloat, 2>                 )));
-    map.insert(D3D11ES2FormatPair(GL_RG16F_EXT,                       D3D11ES2FormatInfo(DXGI_FORMAT_R16G16_FLOAT,       DXGI_FORMAT_R16G16_FLOAT,          DXGI_FORMAT_R16G16_FLOAT,       DXGI_FORMAT_UNKNOWN,           loadToNative<GLhalf, 2>                  )));
-
-    map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    D3D11ES2FormatInfo(DXGI_FORMAT_BC1_UNORM,          DXGI_FORMAT_BC1_UNORM,             DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,           loadCompressedBlockDataToNative<4, 4,  8>)));
-    map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   D3D11ES2FormatInfo(DXGI_FORMAT_BC1_UNORM,          DXGI_FORMAT_BC1_UNORM,             DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,           loadCompressedBlockDataToNative<4, 4,  8>)));
-    map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D11ES2FormatInfo(DXGI_FORMAT_BC2_UNORM,          DXGI_FORMAT_BC2_UNORM,             DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,           loadCompressedBlockDataToNative<4, 4, 16>)));
-    map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D11ES2FormatInfo(DXGI_FORMAT_BC3_UNORM,          DXGI_FORMAT_BC3_UNORM,             DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,           loadCompressedBlockDataToNative<4, 4, 16>)));
-
-    return map;
-}
-
-static bool GetD3D11ES2FormatInfo(GLenum internalFormat, GLuint clientVersion, D3D11ES2FormatInfo *outFormatInfo)
-{
-    static const D3D11ES2FormatMap formatMap = BuildD3D11ES2FormatMap();
-    D3D11ES2FormatMap::const_iterator iter = formatMap.find(internalFormat);
-    if (iter != formatMap.end())
-    {
-        if (outFormatInfo)
-        {
-            *outFormatInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-// A map to determine the pixel size and mipmap generation function of a given DXGI format
-struct DXGIFormatInfo
-{
-    GLuint mPixelBits;
-    GLuint mBlockWidth;
-    GLuint mBlockHeight;
-    GLenum mComponentType;
-
-    MipGenerationFunction mMipGenerationFunction;
-    ColorReadFunction mColorReadFunction;
-
-    DXGIFormatInfo()
-        : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mComponentType(GL_NONE), mMipGenerationFunction(NULL),
-          mColorReadFunction(NULL)
-    { }
-
-    DXGIFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLenum componentType,
-                   MipGenerationFunction mipFunc, ColorReadFunction readFunc)
-        : mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mComponentType(componentType),
-          mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc)
-    { }
-};
-
-typedef std::map<DXGI_FORMAT, DXGIFormatInfo> DXGIFormatInfoMap;
-
-void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight,
-                   GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc)
-{
-    map->insert(std::make_pair(dxgiFormat, DXGIFormatInfo(pixelBits, blockWidth, blockHeight, componentType, mipFunc, readFunc)));
-}
-
-static DXGIFormatInfoMap BuildDXGIFormatInfoMap()
-{
-    DXGIFormatInfoMap map;
-
-    //                | DXGI format                          |S   |W |H |Component Type        | Mip generation function   | Color read function
-    AddDXGIFormat(&map, DXGI_FORMAT_UNKNOWN,                  0,   0, 0, GL_NONE,                NULL,                       NULL);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_A8_UNORM,                 8,   1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<A8>,            ReadColor<A8, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8_UNORM,                 8,   1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8>,            ReadColor<R8, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UNORM,               16,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8>,          ReadColor<R8G8, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM,           32,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>,      ReadColor<R8G8B8A8, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,      32,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>,      ReadColor<R8G8B8A8, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_B8G8R8A8_UNORM,           32,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<B8G8R8A8>,      ReadColor<B8G8R8A8, GLfloat>);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_R8_SNORM,                 8,   1, 1, GL_SIGNED_NORMALIZED,   GenerateMip<R8S>,           ReadColor<R8S, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SNORM,               16,  1, 1, GL_SIGNED_NORMALIZED,   GenerateMip<R8G8S>,         ReadColor<R8G8S, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SNORM,           32,  1, 1, GL_SIGNED_NORMALIZED,   GenerateMip<R8G8B8A8S>,     ReadColor<R8G8B8A8S, GLfloat>);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_R8_UINT,                  8,   1, 1, GL_UNSIGNED_INT,        GenerateMip<R8>,            ReadColor<R8, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16_UINT,                 16,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R16>,           ReadColor<R16, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32_UINT,                 32,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R32>,           ReadColor<R32, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UINT,                16,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R8G8>,          ReadColor<R8G8, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UINT,              32,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R16G16>,        ReadColor<R16G16, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32_UINT,              64,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R32G32>,        ReadColor<R32G32, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_UINT,           96,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R32G32B32>,     ReadColor<R32G32B32, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UINT,            32,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R8G8B8A8>,      ReadColor<R8G8B8A8, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UINT,        64,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R16G16B16A16>,  ReadColor<R16G16B16A16, GLuint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_UINT,        128, 1, 1, GL_UNSIGNED_INT,        GenerateMip<R32G32B32A32>,  ReadColor<R32G32B32A32, GLuint>);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_R8_SINT,                  8,   1, 1, GL_INT,                 GenerateMip<R8S>,           ReadColor<R8S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16_SINT,                 16,  1, 1, GL_INT,                 GenerateMip<R16S>,          ReadColor<R16S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32_SINT,                 32,  1, 1, GL_INT,                 GenerateMip<R32S>,          ReadColor<R32S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SINT,                16,  1, 1, GL_INT,                 GenerateMip<R8G8S>,         ReadColor<R8G8S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SINT,              32,  1, 1, GL_INT,                 GenerateMip<R16G16S>,       ReadColor<R16G16S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32_SINT,              64,  1, 1, GL_INT,                 GenerateMip<R32G32S>,       ReadColor<R32G32S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_SINT,           96,  1, 1, GL_INT,                 GenerateMip<R32G32B32S>,    ReadColor<R32G32B32S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SINT,            32,  1, 1, GL_INT,                 GenerateMip<R8G8B8A8S>,     ReadColor<R8G8B8A8S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SINT,        64,  1, 1, GL_INT,                 GenerateMip<R16G16B16A16S>, ReadColor<R16G16B16A16S, GLint>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_SINT,        128, 1, 1, GL_INT,                 GenerateMip<R32G32B32A32S>, ReadColor<R32G32B32A32S, GLint>);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UNORM,        32,  1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R10G10B10A2>,   ReadColor<R10G10B10A2, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UINT,         32,  1, 1, GL_UNSIGNED_INT,        GenerateMip<R10G10B10A2>,   ReadColor<R10G10B10A2, GLuint>);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_R16_FLOAT,                16,  1, 1, GL_FLOAT,               GenerateMip<R16F>,          ReadColor<R16F, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_FLOAT,             32,  1, 1, GL_FLOAT,               GenerateMip<R16G16F>,       ReadColor<R16G16F, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_FLOAT,       64,  1, 1, GL_FLOAT,               GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT,                32,  1, 1, GL_FLOAT,               GenerateMip<R32F>,          ReadColor<R32F, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32_FLOAT,             64,  1, 1, GL_FLOAT,               GenerateMip<R32G32F>,       ReadColor<R32G32F, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_FLOAT,          96,  1, 1, GL_FLOAT,               NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_FLOAT,       128, 1, 1, GL_FLOAT,               GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP,       32,  1, 1, GL_FLOAT,               GenerateMip<R9G9B9E5>,      ReadColor<R9G9B9E5, GLfloat>);
-    AddDXGIFormat(&map, DXGI_FORMAT_R11G11B10_FLOAT,          32,  1, 1, GL_FLOAT,               GenerateMip<R11G11B10F>,    ReadColor<R11G11B10F, GLfloat>);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_R16_TYPELESS,             16,  1, 1, GL_NONE,                NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM,                16,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_D16_UNORM,                16,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R24G8_TYPELESS,           32,  1, 1, GL_NONE,                NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    32,  1, 1, GL_NONE,                NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_D24_UNORM_S8_UINT,        32,  1, 1, GL_UNSIGNED_INT,        NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32G8X24_TYPELESS,        64,  1, 1, GL_NONE,                NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 64,  1, 1, GL_NONE,                NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT,     64,  1, 1, GL_UNSIGNED_INT,        NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R32_TYPELESS,             32,  1, 1, GL_NONE,                NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT,                32,  1, 1, GL_FLOAT,               NULL,                       NULL);
-
-    AddDXGIFormat(&map, DXGI_FORMAT_BC1_UNORM,                64,  4, 4, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_BC2_UNORM,                128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_BC3_UNORM,                128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
-
-    // Useful formats for vertex buffers
-    AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM,                16,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16_SNORM,                16,  1, 1, GL_SIGNED_NORMALIZED,   NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UNORM,             32,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SNORM,             32,  1, 1, GL_SIGNED_NORMALIZED,   NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UNORM,       64,  1, 1, GL_UNSIGNED_NORMALIZED, NULL,                       NULL);
-    AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SNORM,       64,  1, 1, GL_SIGNED_NORMALIZED,   NULL,                       NULL);
-
-    return map;
-}
-
-typedef std::map<DXGI_FORMAT, GLenum> DXGIToESFormatMap;
-
-inline void AddDXGIToESEntry(DXGIToESFormatMap *map, DXGI_FORMAT key, GLenum value)
-{
-    map->insert(std::make_pair(key, value));
-}
-
-static DXGIToESFormatMap BuildCommonDXGIToESFormatMap()
-{
-    DXGIToESFormatMap map;
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_UNKNOWN,                  GL_NONE);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_A8_UNORM,                 GL_ALPHA8_EXT);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UNORM,                 GL_R8);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UNORM,               GL_RG8);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM,           GL_RGBA8);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,      GL_SRGB8_ALPHA8);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_B8G8R8A8_UNORM,           GL_BGRA8_EXT);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SNORM,                 GL_R8_SNORM);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SNORM,               GL_RG8_SNORM);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SNORM,           GL_RGBA8_SNORM);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UINT,                  GL_R8UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UINT,                 GL_R16UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_UINT,                 GL_R32UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UINT,                GL_RG8UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_UINT,              GL_RG16UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_UINT,              GL_RG32UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_UINT,           GL_RGB32UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UINT,            GL_RGBA8UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_UINT,        GL_RGBA16UI);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_UINT,        GL_RGBA32UI);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SINT,                  GL_R8I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_SINT,                 GL_R16I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_SINT,                 GL_R32I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SINT,                GL_RG8I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_SINT,              GL_RG16I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_SINT,              GL_RG32I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_SINT,           GL_RGB32I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SINT,            GL_RGBA8I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_SINT,        GL_RGBA16I);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_SINT,        GL_RGBA32I);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UNORM,        GL_RGB10_A2);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UINT,         GL_RGB10_A2UI);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_FLOAT,                GL_R16F);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_FLOAT,             GL_RG16F);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_FLOAT,       GL_RGBA16F);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT,                GL_R32F);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_FLOAT,             GL_RG32F);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_FLOAT,          GL_RGB32F);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_FLOAT,       GL_RGBA32F);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP,       GL_RGB9_E5);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R11G11B10_FLOAT,          GL_R11F_G11F_B10F);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_TYPELESS,             GL_DEPTH_COMPONENT16);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UNORM,                GL_DEPTH_COMPONENT16);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_D16_UNORM,                GL_DEPTH_COMPONENT16);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R24G8_TYPELESS,           GL_DEPTH24_STENCIL8_OES);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    GL_DEPTH24_STENCIL8_OES);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_D24_UNORM_S8_UINT,        GL_DEPTH24_STENCIL8_OES);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32G8X24_TYPELESS,        GL_DEPTH32F_STENCIL8);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, GL_DEPTH32F_STENCIL8);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT,     GL_DEPTH32F_STENCIL8);
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_BC1_UNORM,                GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_BC2_UNORM,                GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_BC3_UNORM,                GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
-
-    return map;
-}
-
-static DXGIToESFormatMap BuildDXGIToES2FormatMap()
-{
-    DXGIToESFormatMap map = BuildCommonDXGIToESFormatMap();
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS, GL_DEPTH_COMPONENT32_OES);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT,    GL_DEPTH_COMPONENT32_OES);
-
-    return map;
-}
-
-static DXGIToESFormatMap BuildDXGIToES3FormatMap()
-{
-    DXGIToESFormatMap map = BuildCommonDXGIToESFormatMap();
-
-    AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS, GL_DEPTH_COMPONENT32F);
-    AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT,    GL_DEPTH_COMPONENT32F);
-
-    return map;
-}
-
-static const DXGIFormatInfoMap &GetDXGIFormatInfoMap()
-{
-    static const DXGIFormatInfoMap infoMap = BuildDXGIFormatInfoMap();
-    return infoMap;
-}
-
-static bool GetDXGIFormatInfo(DXGI_FORMAT format, DXGIFormatInfo *outFormatInfo)
-{
-    const DXGIFormatInfoMap &infoMap = GetDXGIFormatInfoMap();
-    DXGIFormatInfoMap::const_iterator iter = infoMap.find(format);
-    if (iter != infoMap.end())
-    {
-        if (outFormatInfo)
-        {
-            *outFormatInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-static d3d11::DXGIFormatSet BuildAllDXGIFormatSet()
-{
-    d3d11::DXGIFormatSet set;
-
-    const DXGIFormatInfoMap &infoMap = GetDXGIFormatInfoMap();
-    for (DXGIFormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i)
-    {
-        set.insert(i->first);
-    }
-
-    return set;
-}
-
-struct D3D11FastCopyFormat
-{
-    DXGI_FORMAT mSourceFormat;
-    GLenum mDestFormat;
-    GLenum mDestType;
-
-    D3D11FastCopyFormat(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType)
-        : mSourceFormat(sourceFormat), mDestFormat(destFormat), mDestType(destType)
-    { }
-
-    bool operator<(const D3D11FastCopyFormat& other) const
-    {
-        return memcmp(this, &other, sizeof(D3D11FastCopyFormat)) < 0;
-    }
-};
-
-typedef std::map<D3D11FastCopyFormat, ColorCopyFunction> D3D11FastCopyMap;
-typedef std::pair<D3D11FastCopyFormat, ColorCopyFunction> D3D11FastCopyPair;
-
-static D3D11FastCopyMap BuildFastCopyMap()
-{
-    D3D11FastCopyMap map;
-
-    map.insert(D3D11FastCopyPair(D3D11FastCopyFormat(DXGI_FORMAT_B8G8R8A8_UNORM, GL_RGBA, GL_UNSIGNED_BYTE), CopyBGRAUByteToRGBAUByte));
-
-    return map;
-}
-
-struct DXGIDepthStencilInfo
-{
-    unsigned int mDepthBits;
-    unsigned int mDepthOffset;
-    unsigned int mStencilBits;
-    unsigned int mStencilOffset;
-
-    DXGIDepthStencilInfo()
-        : mDepthBits(0), mDepthOffset(0), mStencilBits(0), mStencilOffset(0)
-    { }
-
-    DXGIDepthStencilInfo(unsigned int depthBits, unsigned int depthOffset, unsigned int stencilBits, unsigned int stencilOffset)
-        : mDepthBits(depthBits), mDepthOffset(depthOffset), mStencilBits(stencilBits), mStencilOffset(stencilOffset)
-    { }
-};
-
-typedef std::map<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoMap;
-typedef std::pair<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoPair;
-
-static DepthStencilInfoMap BuildDepthStencilInfoMap()
-{
-    DepthStencilInfoMap map;
-
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_R16_TYPELESS,             DXGIDepthStencilInfo(16, 0, 0,  0)));
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_R16_UNORM,                DXGIDepthStencilInfo(16, 0, 0,  0)));
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_D16_UNORM,                DXGIDepthStencilInfo(16, 0, 0,  0)));
-
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_R24G8_TYPELESS,           DXGIDepthStencilInfo(24, 0, 8, 24)));
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    DXGIDepthStencilInfo(24, 0, 8, 24)));
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_D24_UNORM_S8_UINT,        DXGIDepthStencilInfo(24, 0, 8, 24)));
-
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_TYPELESS,             DXGIDepthStencilInfo(32, 0, 0,  0)));
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_FLOAT,                DXGIDepthStencilInfo(32, 0, 0,  0)));
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_D32_FLOAT,                DXGIDepthStencilInfo(32, 0, 0,  0)));
-
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32G8X24_TYPELESS,        DXGIDepthStencilInfo(32, 0, 8, 32)));
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGIDepthStencilInfo(32, 0, 8, 32)));
-    map.insert(DepthStencilInfoPair(DXGI_FORMAT_D32_FLOAT_S8X24_UINT,     DXGIDepthStencilInfo(32, 0, 8, 32)));
-
-    return map;
-}
-
-static const DepthStencilInfoMap &GetDepthStencilInfoMap()
-{
-    static const DepthStencilInfoMap infoMap = BuildDepthStencilInfoMap();
-    return infoMap;
-}
-
-bool GetDepthStencilInfo(DXGI_FORMAT format, DXGIDepthStencilInfo *outDepthStencilInfo)
-{
-    const DepthStencilInfoMap& infoMap = GetDepthStencilInfoMap();
-    DepthStencilInfoMap::const_iterator iter = infoMap.find(format);
-    if (iter != infoMap.end())
-    {
-        if (outDepthStencilInfo)
-        {
-            *outDepthStencilInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-struct SwizzleSizeType
-{
-    unsigned int mMaxComponentSize;
-    GLenum mComponentType;
-
-    SwizzleSizeType()
-        : mMaxComponentSize(0), mComponentType(GL_NONE)
-    { }
-
-    SwizzleSizeType(unsigned int maxComponentSize, GLenum componentType)
-        : mMaxComponentSize(maxComponentSize), mComponentType(componentType)
-    { }
-
-    bool operator<(const SwizzleSizeType& other) const
-    {
-        return (mMaxComponentSize != other.mMaxComponentSize) ? (mMaxComponentSize < other.mMaxComponentSize)
-                                                              : (mComponentType < other.mComponentType);
-    }
-};
-
-struct SwizzleFormatInfo
-{
-    DXGI_FORMAT mTexFormat;
-    DXGI_FORMAT mSRVFormat;
-    DXGI_FORMAT mRTVFormat;
-
-    SwizzleFormatInfo()
-        : mTexFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN)
-    { }
-
-    SwizzleFormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat)
-        : mTexFormat(texFormat), mSRVFormat(srvFormat), mRTVFormat(rtvFormat)
-    { }
-};
-
-typedef std::map<SwizzleSizeType, SwizzleFormatInfo> SwizzleInfoMap;
-typedef std::pair<SwizzleSizeType, SwizzleFormatInfo> SwizzleInfoPair;
-
-static SwizzleInfoMap BuildSwizzleInfoMap()
-{
-    SwizzleInfoMap map;
-
-    map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM    )));
-    map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM)));
-    map.insert(SwizzleInfoPair(SwizzleSizeType(24, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
-    map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
-
-    map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_SIGNED_NORMALIZED  ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM,     DXGI_FORMAT_R8G8B8A8_SNORM,     DXGI_FORMAT_R8G8B8A8_SNORM    )));
-
-    map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_FLOAT              ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT)));
-    map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_FLOAT              ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT)));
-
-    map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_INT       ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UINT     )));
-    map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_INT       ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UINT,  DXGI_FORMAT_R16G16B16A16_UINT,  DXGI_FORMAT_R16G16B16A16_UINT )));
-    map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_INT       ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_UINT,  DXGI_FORMAT_R32G32B32A32_UINT,  DXGI_FORMAT_R32G32B32A32_UINT )));
-
-    map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_INT                ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SINT,      DXGI_FORMAT_R8G8B8A8_SINT,      DXGI_FORMAT_R8G8B8A8_SINT     )));
-    map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_INT                ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_SINT,  DXGI_FORMAT_R16G16B16A16_SINT,  DXGI_FORMAT_R16G16B16A16_SINT )));
-    map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_INT                ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_SINT,  DXGI_FORMAT_R32G32B32A32_SINT,  DXGI_FORMAT_R32G32B32A32_SINT )));
-
-    return map;
-}
-typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitializerPair;
-typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitializerMap;
-
-static InternalFormatInitializerMap BuildInternalFormatInitializerMap()
-{
-    InternalFormatInitializerMap map;
-
-    map.insert(InternalFormatInitializerPair(GL_RGB8,    initialize4ComponentData<GLubyte,  0x00,       0x00,       0x00,       0xFF>          ));
-    map.insert(InternalFormatInitializerPair(GL_RGB565,  initialize4ComponentData<GLubyte,  0x00,       0x00,       0x00,       0xFF>          ));
-    map.insert(InternalFormatInitializerPair(GL_SRGB8,   initialize4ComponentData<GLubyte,  0x00,       0x00,       0x00,       0xFF>          ));
-    map.insert(InternalFormatInitializerPair(GL_RGB16F,  initialize4ComponentData<GLhalf,   0x0000,     0x0000,     0x0000,     gl::Float16One>));
-    map.insert(InternalFormatInitializerPair(GL_RGB32F,  initialize4ComponentData<GLfloat,  0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
-    map.insert(InternalFormatInitializerPair(GL_RGB8UI,  initialize4ComponentData<GLubyte,  0x00,       0x00,       0x00,       0x01>          ));
-    map.insert(InternalFormatInitializerPair(GL_RGB8I,   initialize4ComponentData<GLbyte,   0x00,       0x00,       0x00,       0x01>          ));
-    map.insert(InternalFormatInitializerPair(GL_RGB16UI, initialize4ComponentData<GLushort, 0x0000,     0x0000,     0x0000,     0x0001>        ));
-    map.insert(InternalFormatInitializerPair(GL_RGB16I,  initialize4ComponentData<GLshort,  0x0000,     0x0000,     0x0000,     0x0001>        ));
-    map.insert(InternalFormatInitializerPair(GL_RGB32UI, initialize4ComponentData<GLuint,   0x00000000, 0x00000000, 0x00000000, 0x00000001>    ));
-    map.insert(InternalFormatInitializerPair(GL_RGB32I,  initialize4ComponentData<GLint,    0x00000000, 0x00000000, 0x00000000, 0x00000001>    ));
-
-    return map;
-}
-
-static const SwizzleInfoMap &GetSwizzleInfoMap()
-{
-    static const SwizzleInfoMap map = BuildSwizzleInfoMap();
-    return map;
-}
-
-static const SwizzleFormatInfo GetSwizzleFormatInfo(GLint internalFormat, GLuint clientVersion)
-{
-    // Get the maximum sized component
-    unsigned int maxBits = 1;
-
-    if (gl::IsFormatCompressed(internalFormat, clientVersion))
-    {
-        unsigned int compressedBitsPerBlock = gl::GetPixelBytes(internalFormat, clientVersion) * 8;
-        unsigned int blockSize = gl::GetCompressedBlockWidth(internalFormat, clientVersion) *
-                                 gl::GetCompressedBlockHeight(internalFormat, clientVersion);
-        maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits);
-    }
-    else
-    {
-        maxBits = std::max(maxBits, gl::GetAlphaBits(    internalFormat, clientVersion));
-        maxBits = std::max(maxBits, gl::GetRedBits(      internalFormat, clientVersion));
-        maxBits = std::max(maxBits, gl::GetGreenBits(    internalFormat, clientVersion));
-        maxBits = std::max(maxBits, gl::GetBlueBits(     internalFormat, clientVersion));
-        maxBits = std::max(maxBits, gl::GetLuminanceBits(internalFormat, clientVersion));
-        maxBits = std::max(maxBits, gl::GetDepthBits(    internalFormat, clientVersion));
-    }
-
-    maxBits = roundUp(maxBits, 8U);
-
-    GLenum componentType = gl::GetComponentType(internalFormat, clientVersion);
-
-    const SwizzleInfoMap &map = GetSwizzleInfoMap();
-    SwizzleInfoMap::const_iterator iter = map.find(SwizzleSizeType(maxBits, componentType));
-
-    if (iter != map.end())
-    {
-        return iter->second;
-    }
-    else
-    {
-        UNREACHABLE();
-        static const SwizzleFormatInfo defaultFormatInfo;
-        return defaultFormatInfo;
-    }
-}
-
-static const InternalFormatInitializerMap &GetInternalFormatInitializerMap()
-{
-    static const InternalFormatInitializerMap map = BuildInternalFormatInitializerMap();
-    return map;
-}
-
-namespace d3d11
-{
-
-MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format)
-{
-    DXGIFormatInfo formatInfo;
-    if (GetDXGIFormatInfo(format, &formatInfo))
-    {
-        return formatInfo.mMipGenerationFunction;
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-LoadImageFunction GetImageLoadFunction(GLenum internalFormat, GLenum type, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        D3D11ES2FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mLoadImageFunction;
-        }
-        else
-        {
-            UNREACHABLE();
-            return NULL;
-        }
-    }
-    else if (clientVersion == 3)
-    {
-        static const D3D11LoadFunctionMap loadImageMap = buildD3D11LoadFunctionMap();
-        D3D11LoadFunctionMap::const_iterator iter = loadImageMap.find(InternalFormatTypePair(internalFormat, type));
-        if (iter != loadImageMap.end())
-        {
-            return iter->second;
-        }
-        else
-        {
-            UNREACHABLE();
-            return NULL;
-        }
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-GLuint GetFormatPixelBytes(DXGI_FORMAT format)
-{
-    DXGIFormatInfo dxgiFormatInfo;
-    if (GetDXGIFormatInfo(format, &dxgiFormatInfo))
-    {
-        return dxgiFormatInfo.mPixelBits / 8;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetBlockWidth(DXGI_FORMAT format)
-{
-    DXGIFormatInfo dxgiFormatInfo;
-    if (GetDXGIFormatInfo(format, &dxgiFormatInfo))
-    {
-        return dxgiFormatInfo.mBlockWidth;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetBlockHeight(DXGI_FORMAT format)
-{
-    DXGIFormatInfo dxgiFormatInfo;
-    if (GetDXGIFormatInfo(format, &dxgiFormatInfo))
-    {
-        return dxgiFormatInfo.mBlockHeight;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLenum GetComponentType(DXGI_FORMAT format)
-{
-    DXGIFormatInfo dxgiFormatInfo;
-    if (GetDXGIFormatInfo(format, &dxgiFormatInfo))
-    {
-        return dxgiFormatInfo.mComponentType;
-    }
-    else
-    {
-        UNREACHABLE();
-        return GL_NONE;
-    }
-}
-
-GLuint GetDepthBits(DXGI_FORMAT format)
-{
-    DXGIDepthStencilInfo dxgiDSInfo;
-    if (GetDepthStencilInfo(format, &dxgiDSInfo))
-    {
-        return dxgiDSInfo.mDepthBits;
-    }
-    else
-    {
-        // Since the depth stencil info map does not contain all used DXGI formats,
-        // we should not assert that the format exists
-        return 0;
-    }
-}
-
-GLuint GetDepthOffset(DXGI_FORMAT format)
-{
-    DXGIDepthStencilInfo dxgiDSInfo;
-    if (GetDepthStencilInfo(format, &dxgiDSInfo))
-    {
-        return dxgiDSInfo.mDepthOffset;
-    }
-    else
-    {
-        // Since the depth stencil info map does not contain all used DXGI formats,
-        // we should not assert that the format exists
-        return 0;
-    }
-}
-
-GLuint GetStencilBits(DXGI_FORMAT format)
-{
-    DXGIDepthStencilInfo dxgiDSInfo;
-    if (GetDepthStencilInfo(format, &dxgiDSInfo))
-    {
-        return dxgiDSInfo.mStencilBits;
-    }
-    else
-    {
-        // Since the depth stencil info map does not contain all used DXGI formats,
-        // we should not assert that the format exists
-        return 0;
-    }
-}
-
-GLuint GetStencilOffset(DXGI_FORMAT format)
-{
-    DXGIDepthStencilInfo dxgiDSInfo;
-    if (GetDepthStencilInfo(format, &dxgiDSInfo))
-    {
-        return dxgiDSInfo.mStencilOffset;
-    }
-    else
-    {
-        // Since the depth stencil info map does not contain all used DXGI formats,
-        // we should not assert that the format exists
-        return 0;
-    }
-}
-
-void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
-{
-    DXGIFormatInfo dxgiFormatInfo;
-    if (GetDXGIFormatInfo(format, &dxgiFormatInfo))
-    {
-        int upsampleCount = 0;
-
-        GLsizei blockWidth = dxgiFormatInfo.mBlockWidth;
-        GLsizei blockHeight = dxgiFormatInfo.mBlockHeight;
-
-        // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
-        if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight)
-        {
-            while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0)
-            {
-                *requestWidth <<= 1;
-                *requestHeight <<= 1;
-                upsampleCount++;
-            }
-        }
-        *levelOffset = upsampleCount;
-    }
-    else
-    {
-        UNREACHABLE();
-    }
-}
-
-const DXGIFormatSet &GetAllUsedDXGIFormats()
-{
-    static DXGIFormatSet formatSet = BuildAllDXGIFormatSet();
-    return formatSet;
-}
-
-ColorReadFunction GetColorReadFunction(DXGI_FORMAT format)
-{
-    DXGIFormatInfo dxgiFormatInfo;
-    if (GetDXGIFormatInfo(format, &dxgiFormatInfo))
-    {
-        return dxgiFormatInfo.mColorReadFunction;
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-ColorCopyFunction GetFastCopyFunction(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType)
-{
-    static const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap();
-    D3D11FastCopyMap::const_iterator iter = fastCopyMap.find(D3D11FastCopyFormat(sourceFormat, destFormat, destType));
-    return (iter != fastCopyMap.end()) ? iter->second : NULL;
-}
-
-}
-
-namespace gl_d3d11
-{
-
-DXGI_FORMAT GetTexFormat(GLenum internalFormat, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        D3D11ES2FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mTexFormat;
-        }
-        else
-        {
-            UNREACHABLE();
-            return DXGI_FORMAT_UNKNOWN;
-        }
-    }
-    else if (clientVersion == 3)
-    {
-        D3D11ES3FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mTexFormat;
-        }
-        else
-        {
-            UNREACHABLE();
-            return DXGI_FORMAT_UNKNOWN;
-        }
-    }
-    else
-    {
-        UNREACHABLE();
-        return DXGI_FORMAT_UNKNOWN;
-    }
-}
-
-DXGI_FORMAT GetSRVFormat(GLenum internalFormat, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        D3D11ES2FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mSRVFormat;
-        }
-        else
-        {
-            UNREACHABLE();
-            return DXGI_FORMAT_UNKNOWN;
-        }
-    }
-    else if (clientVersion == 3)
-    {
-        D3D11ES3FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mSRVFormat;
-        }
-        else
-        {
-            UNREACHABLE();
-            return DXGI_FORMAT_UNKNOWN;
-        }
-    }
-    else
-    {
-        UNREACHABLE();
-        return DXGI_FORMAT_UNKNOWN;
-    }
-}
-
-DXGI_FORMAT GetRTVFormat(GLenum internalFormat, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        D3D11ES2FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mRTVFormat;
-        }
-        else
-        {
-            UNREACHABLE();
-            return DXGI_FORMAT_UNKNOWN;
-        }
-    }
-    else if (clientVersion == 3)
-    {
-        D3D11ES3FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mRTVFormat;
-        }
-        else
-        {
-            UNREACHABLE();
-            return DXGI_FORMAT_UNKNOWN;
-        }
-    }
-    else
-    {
-        UNREACHABLE();
-        return DXGI_FORMAT_UNKNOWN;
-    }
-}
-
-DXGI_FORMAT GetDSVFormat(GLenum internalFormat, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        D3D11ES2FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mDSVFormat;
-        }
-        else
-        {
-            return DXGI_FORMAT_UNKNOWN;
-        }
-    }
-    else if (clientVersion == 3)
-    {
-        D3D11ES3FormatInfo d3d11FormatInfo;
-        if (GetD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
-        {
-            return d3d11FormatInfo.mDSVFormat;
-        }
-        else
-        {
-            return DXGI_FORMAT_UNKNOWN;
-        }
-    }
-    else
-    {
-        UNREACHABLE();
-        return DXGI_FORMAT_UNKNOWN;
-    }
-}
-
-// Given a GL internal format, this function returns the DSV format if it is depth- or stencil-renderable,
-// the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise.
-DXGI_FORMAT GetRenderableFormat(GLenum internalFormat, GLuint clientVersion)
-{
-    DXGI_FORMAT targetFormat = GetDSVFormat(internalFormat, clientVersion);
-    if (targetFormat == DXGI_FORMAT_UNKNOWN)
-        targetFormat = GetRTVFormat(internalFormat, clientVersion);
-    if (targetFormat == DXGI_FORMAT_UNKNOWN)
-        targetFormat = GetTexFormat(internalFormat, clientVersion);
-
-    return targetFormat;
-}
-
-DXGI_FORMAT GetSwizzleTexFormat(GLint internalFormat, const Renderer *renderer)
-{
-    GLuint clientVersion = renderer->getCurrentClientVersion();
-    if (gl::GetComponentCount(internalFormat, clientVersion) != 4 || !gl::IsColorRenderingSupported(internalFormat, renderer))
-    {
-        const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat, clientVersion);
-        return swizzleInfo.mTexFormat;
-    }
-    else
-    {
-        return GetTexFormat(internalFormat, clientVersion);
-    }
-}
-
-DXGI_FORMAT GetSwizzleSRVFormat(GLint internalFormat, const Renderer *renderer)
-{
-    GLuint clientVersion = renderer->getCurrentClientVersion();
-    if (gl::GetComponentCount(internalFormat, clientVersion) != 4 || !gl::IsColorRenderingSupported(internalFormat, renderer))
-    {
-        const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat, clientVersion);
-        return swizzleInfo.mSRVFormat;
-    }
-    else
-    {
-        return GetTexFormat(internalFormat, clientVersion);
-    }
-}
-
-DXGI_FORMAT GetSwizzleRTVFormat(GLint internalFormat, const Renderer *renderer)
-{
-    GLuint clientVersion = renderer->getCurrentClientVersion();
-    if (gl::GetComponentCount(internalFormat, clientVersion) != 4 || !gl::IsColorRenderingSupported(internalFormat, renderer))
-    {
-        const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat, clientVersion);
-        return swizzleInfo.mRTVFormat;
-    }
-    else
-    {
-        return GetTexFormat(internalFormat, clientVersion);
-    }
-}
-
-bool RequiresTextureDataInitialization(GLint internalFormat)
-{
-    const InternalFormatInitializerMap &map = GetInternalFormatInitializerMap();
-    return map.find(internalFormat) != map.end();
-}
-
-InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat)
-{
-    const InternalFormatInitializerMap &map = GetInternalFormatInitializerMap();
-    InternalFormatInitializerMap::const_iterator iter = map.find(internalFormat);
-    if (iter != map.end())
-    {
-        return iter->second;
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-struct D3D11VertexFormatInfo
-{
-    rx::VertexConversionType mConversionType;
-    DXGI_FORMAT mNativeFormat;
-    VertexCopyFunction mCopyFunction;
-
-    D3D11VertexFormatInfo()
-        : mConversionType(VERTEX_CONVERT_NONE),
-          mNativeFormat(DXGI_FORMAT_UNKNOWN),
-          mCopyFunction(NULL)
-    {}
-
-    D3D11VertexFormatInfo(VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction)
-        : mConversionType(conversionType),
-          mNativeFormat(nativeFormat),
-          mCopyFunction(copyFunction)
-    {}
-};
-
-typedef std::map<gl::VertexFormat, D3D11VertexFormatInfo> D3D11VertexFormatInfoMap;
-
-typedef std::pair<gl::VertexFormat, D3D11VertexFormatInfo> D3D11VertexFormatPair;
-
-static void addVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLboolean normalized, GLuint componentCount,
-                                VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction)
-{
-    gl::VertexFormat inputFormat(inputType, normalized, componentCount, false);
-    map->insert(D3D11VertexFormatPair(inputFormat, D3D11VertexFormatInfo(conversionType, nativeFormat, copyFunction)));
-}
-
-static void addIntegerVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLuint componentCount,
-                                       VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction)
-{
-    gl::VertexFormat inputFormat(inputType, GL_FALSE, componentCount, true);
-    map->insert(D3D11VertexFormatPair(inputFormat, D3D11VertexFormatInfo(conversionType, nativeFormat, copyFunction)));
-}
-
-static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap()
-{
-    D3D11VertexFormatInfoMap map;
-
-    // TODO: column legend
-
-    //
-    // Float formats
-    //
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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);
-
-    //
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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>);
-
-    // 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);
-
-    return map;
-}
-
-static bool GetD3D11VertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D11VertexFormatInfo *outVertexFormatInfo)
-{
-    static const D3D11VertexFormatInfoMap vertexFormatMap = BuildD3D11VertexFormatInfoMap();
-
-    D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMap.find(vertexFormat);
-    if (iter != vertexFormatMap.end())
-    {
-        if (outVertexFormatInfo)
-        {
-            *outVertexFormatInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat)
-{
-    D3D11VertexFormatInfo vertexFormatInfo;
-    if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo))
-    {
-        return vertexFormatInfo.mCopyFunction;
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat)
-{
-    D3D11VertexFormatInfo vertexFormatInfo;
-    if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo))
-    {
-        // FIXME: should not need a client version, and is not a pixel!
-        return d3d11::GetFormatPixelBytes(vertexFormatInfo.mNativeFormat);
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-rx::VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat)
-{
-    D3D11VertexFormatInfo vertexFormatInfo;
-    if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo))
-    {
-        return vertexFormatInfo.mConversionType;
-    }
-    else
-    {
-        UNREACHABLE();
-        return VERTEX_CONVERT_NONE;
-    }
-}
-
-DXGI_FORMAT GetNativeVertexFormat(const gl::VertexFormat &vertexFormat)
-{
-    D3D11VertexFormatInfo vertexFormatInfo;
-    if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo))
-    {
-        return vertexFormatInfo.mNativeFormat;
-    }
-    else
-    {
-        UNREACHABLE();
-        return DXGI_FORMAT_UNKNOWN;
-    }
-}
-
-}
-
-namespace d3d11_gl
-{
-
-GLenum GetInternalFormat(DXGI_FORMAT format, GLuint clientVersion)
-{
-    if (clientVersion == 2)
-    {
-        static DXGIToESFormatMap es2FormatMap = BuildDXGIToES2FormatMap();
-        auto formatIt = es2FormatMap.find(format);
-        if (formatIt != es2FormatMap.end())
-        {
-            return formatIt->second;
-        }
-    }
-    else if (clientVersion == 3)
-    {
-        static DXGIToESFormatMap es3FormatMap = BuildDXGIToES3FormatMap();
-        auto formatIt = es3FormatMap.find(format);
-        if (formatIt != es3FormatMap.end())
-        {
-            return formatIt->second;
-        }
-    }
-
-    UNREACHABLE();
-    return GL_NONE;
-}
-
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d11/formatutils11.h b/src/libGLESv2/renderer/d3d11/formatutils11.h
deleted file mode 100644
index d7ae4e0..0000000
--- a/src/libGLESv2/renderer/d3d11/formatutils11.h
+++ /dev/null
@@ -1,79 +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.
-//
-
-// formatutils11.h: Queries for GL image formats and their translations to D3D11
-// formats.
-
-#ifndef LIBGLESV2_RENDERER_FORMATUTILS11_H_
-#define LIBGLESV2_RENDERER_FORMATUTILS11_H_
-
-#include "libGLESv2/formatutils.h"
-
-namespace rx
-{
-
-class Renderer;
-
-namespace d3d11
-{
-
-typedef std::set<DXGI_FORMAT> DXGIFormatSet;
-
-MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format);
-LoadImageFunction GetImageLoadFunction(GLenum internalFormat, GLenum type, GLuint clientVersion);
-
-GLuint GetFormatPixelBytes(DXGI_FORMAT format);
-GLuint GetBlockWidth(DXGI_FORMAT format);
-GLuint GetBlockHeight(DXGI_FORMAT format);
-GLenum GetComponentType(DXGI_FORMAT format);
-
-GLuint GetDepthBits(DXGI_FORMAT format);
-GLuint GetDepthOffset(DXGI_FORMAT format);
-GLuint GetStencilBits(DXGI_FORMAT format);
-GLuint GetStencilOffset(DXGI_FORMAT format);
-
-void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
-
-const DXGIFormatSet &GetAllUsedDXGIFormats();
-
-ColorReadFunction GetColorReadFunction(DXGI_FORMAT format);
-ColorCopyFunction GetFastCopyFunction(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType);
-
-}
-
-namespace gl_d3d11
-{
-
-DXGI_FORMAT GetTexFormat(GLenum internalFormat, GLuint clientVersion);
-DXGI_FORMAT GetSRVFormat(GLenum internalFormat, GLuint clientVersion);
-DXGI_FORMAT GetRTVFormat(GLenum internalFormat, GLuint clientVersion);
-DXGI_FORMAT GetDSVFormat(GLenum internalFormat, GLuint clientVersion);
-DXGI_FORMAT GetRenderableFormat(GLenum internalFormat, GLuint clientVersion);
-
-DXGI_FORMAT GetSwizzleTexFormat(GLint internalFormat, const Renderer *renderer);
-DXGI_FORMAT GetSwizzleSRVFormat(GLint internalFormat, const Renderer *renderer);
-DXGI_FORMAT GetSwizzleRTVFormat(GLint internalFormat, const Renderer *renderer);
-
-bool RequiresTextureDataInitialization(GLint internalFormat);
-InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat);
-
-VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat);
-size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat);
-VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat);
-DXGI_FORMAT GetNativeVertexFormat(const gl::VertexFormat &vertexFormat);
-
-}
-
-namespace d3d11_gl
-{
-
-GLenum GetInternalFormat(DXGI_FORMAT format, GLuint clientVersion);
-
-}
-
-}
-
-#endif // LIBGLESV2_RENDERER_FORMATUTILS11_H_
diff --git a/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp b/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp
deleted file mode 100644
index 327d2f0..0000000
--- a/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// renderer11_utils.cpp: Conversion functions and other utility routines
-// specific to the D3D11 renderer.
-
-#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d11/formatutils11.h"
-#include "common/debug.h"
-
-namespace rx
-{
-
-namespace gl_d3d11
-{
-
-D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
-{
-    D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
-
-    switch (glBlend)
-    {
-      case GL_ZERO:                     d3dBlend = D3D11_BLEND_ZERO;                break;
-      case GL_ONE:                      d3dBlend = D3D11_BLEND_ONE;                 break;
-      case GL_SRC_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR);           break;
-      case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR);   break;
-      case GL_DST_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR);         break;
-      case GL_ONE_MINUS_DST_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break;
-      case GL_SRC_ALPHA:                d3dBlend = D3D11_BLEND_SRC_ALPHA;           break;
-      case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3D11_BLEND_INV_SRC_ALPHA;       break;
-      case GL_DST_ALPHA:                d3dBlend = D3D11_BLEND_DEST_ALPHA;          break;
-      case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3D11_BLEND_INV_DEST_ALPHA;      break;
-      case GL_CONSTANT_COLOR:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
-      case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
-      case GL_CONSTANT_ALPHA:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
-      case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
-      case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;       break;
-      default: UNREACHABLE();
-    }
-
-    return d3dBlend;
-}
-
-D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
-{
-    D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
-
-    switch (glBlendOp)
-    {
-      case GL_FUNC_ADD:              d3dBlendOp = D3D11_BLEND_OP_ADD;           break;
-      case GL_FUNC_SUBTRACT:         d3dBlendOp = D3D11_BLEND_OP_SUBTRACT;      break;
-      case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT;  break;
-      case GL_MIN:                   d3dBlendOp = D3D11_BLEND_OP_MIN;           break;
-      case GL_MAX:                   d3dBlendOp = D3D11_BLEND_OP_MAX;           break;
-      default: UNREACHABLE();
-    }
-
-    return d3dBlendOp;
-}
-
-UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
-{
-    UINT8 mask = 0;
-    if (red)
-    {
-        mask |= D3D11_COLOR_WRITE_ENABLE_RED;
-    }
-    if (green)
-    {
-        mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
-    }
-    if (blue)
-    {
-        mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
-    }
-    if (alpha)
-    {
-        mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
-    }
-    return mask;
-}
-
-D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
-{
-    D3D11_CULL_MODE cull = D3D11_CULL_NONE;
-
-    if (cullEnabled)
-    {
-        switch (cullMode)
-        {
-          case GL_FRONT:            cull = D3D11_CULL_FRONT;    break;
-          case GL_BACK:             cull = D3D11_CULL_BACK;     break;
-          case GL_FRONT_AND_BACK:   cull = D3D11_CULL_NONE;     break;
-          default: UNREACHABLE();
-        }
-    }
-    else
-    {
-        cull = D3D11_CULL_NONE;
-    }
-
-    return cull;
-}
-
-D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
-{
-    D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
-    switch (comparison)
-    {
-      case GL_NEVER:    d3dComp = D3D11_COMPARISON_NEVER;           break;
-      case GL_ALWAYS:   d3dComp = D3D11_COMPARISON_ALWAYS;          break;
-      case GL_LESS:     d3dComp = D3D11_COMPARISON_LESS;            break;
-      case GL_LEQUAL:   d3dComp = D3D11_COMPARISON_LESS_EQUAL;      break;
-      case GL_EQUAL:    d3dComp = D3D11_COMPARISON_EQUAL;           break;
-      case GL_GREATER:  d3dComp = D3D11_COMPARISON_GREATER;         break;
-      case GL_GEQUAL:   d3dComp = D3D11_COMPARISON_GREATER_EQUAL;   break;
-      case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL;       break;
-      default: UNREACHABLE();
-    }
-
-    return d3dComp;
-}
-
-D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
-{
-    return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
-}
-
-UINT8 ConvertStencilMask(GLuint stencilmask)
-{
-    return static_cast<UINT8>(stencilmask);
-}
-
-D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
-{
-    D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
-
-    switch (stencilOp)
-    {
-      case GL_ZERO:      d3dStencilOp = D3D11_STENCIL_OP_ZERO;      break;
-      case GL_KEEP:      d3dStencilOp = D3D11_STENCIL_OP_KEEP;      break;
-      case GL_REPLACE:   d3dStencilOp = D3D11_STENCIL_OP_REPLACE;   break;
-      case GL_INCR:      d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT;  break;
-      case GL_DECR:      d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT;  break;
-      case GL_INVERT:    d3dStencilOp = D3D11_STENCIL_OP_INVERT;    break;
-      case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR;      break;
-      case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR;      break;
-      default: UNREACHABLE();
-    }
-
-    return d3dStencilOp;
-}
-
-D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode)
-{
-    bool comparison = comparisonMode != GL_NONE;
-
-    if (maxAnisotropy > 1.0f)
-    {
-        return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison));
-    }
-    else
-    {
-        D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
-        D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
-        switch (minFilter)
-        {
-          case GL_NEAREST:                dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
-          case GL_LINEAR:                 dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
-          case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
-          case GL_LINEAR_MIPMAP_NEAREST:  dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
-          case GL_NEAREST_MIPMAP_LINEAR:  dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_LINEAR; break;
-          case GL_LINEAR_MIPMAP_LINEAR:   dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
-          default:                        UNREACHABLE();
-        }
-
-        D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
-        switch (magFilter)
-        {
-          case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT;  break;
-          case GL_LINEAR:  dxMag = D3D11_FILTER_TYPE_LINEAR; break;
-          default:         UNREACHABLE();
-        }
-
-        return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, static_cast<D3D11_COMPARISON_FUNC>(comparison));
-    }
-}
-
-D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
-{
-    switch (wrap)
-    {
-      case GL_REPEAT:          return D3D11_TEXTURE_ADDRESS_WRAP;
-      case GL_CLAMP_TO_EDGE:   return D3D11_TEXTURE_ADDRESS_CLAMP;
-      case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR;
-      default:                 UNREACHABLE();
-    }
-
-    return D3D11_TEXTURE_ADDRESS_WRAP;
-}
-
-D3D11_QUERY ConvertQueryType(GLenum queryType)
-{
-    switch (queryType)
-    {
-      case GL_ANY_SAMPLES_PASSED_EXT:
-      case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   return D3D11_QUERY_OCCLUSION;
-      case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS;
-      default: UNREACHABLE();                        return D3D11_QUERY_EVENT;
-    }
-}
-
-}
-
-namespace d3d11
-{
-
-void GenerateInitialTextureData(GLint internalFormat, GLuint clientVersion, GLuint width, GLuint height, GLuint depth,
-                                GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
-                                std::vector< std::vector<BYTE> > *outData)
-{
-    InitializeTextureDataFunction initializeFunc = gl_d3d11::GetTextureDataInitializationFunction(internalFormat);
-    DXGI_FORMAT dxgiFormat = gl_d3d11::GetTexFormat(internalFormat, clientVersion);
-
-    outSubresourceData->resize(mipLevels);
-    outData->resize(mipLevels);
-
-    for (unsigned int i = 0; i < mipLevels; i++)
-    {
-        unsigned int mipWidth = std::max(width >> i, 1U);
-        unsigned int mipHeight = std::max(height >> i, 1U);
-        unsigned int mipDepth = std::max(depth >> i, 1U);
-
-        unsigned int rowWidth = d3d11::GetFormatPixelBytes(dxgiFormat) * mipWidth;
-        unsigned int imageSize = rowWidth * height;
-
-        outData->at(i).resize(rowWidth * mipHeight * mipDepth);
-        initializeFunc(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize);
-
-        outSubresourceData->at(i).pSysMem = outData->at(i).data();
-        outSubresourceData->at(i).SysMemPitch = rowWidth;
-        outSubresourceData->at(i).SysMemSlicePitch = imageSize;
-    }
-}
-
-void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
-{
-    vertex->x = x;
-    vertex->y = y;
-    vertex->u = u;
-    vertex->v = v;
-}
-
-void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y,
-                                      unsigned int layer, float u, float v, float s)
-{
-    vertex->x = x;
-    vertex->y = y;
-    vertex->l = layer;
-    vertex->u = u;
-    vertex->v = v;
-    vertex->s = s;
-}
-
-HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
-{
-#if defined(_DEBUG)
-    return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
-#else
-    return S_OK;
-#endif
-}
-
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp b/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp
deleted file mode 100644
index 489a040..0000000
--- a/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// BufferStorage9.cpp Defines the BufferStorage9 class.
-
-#include "libGLESv2/renderer/d3d9/BufferStorage9.h"
-#include "common/debug.h"
-#include "libGLESv2/main.h"
-
-namespace rx
-{
-
-BufferStorage9::BufferStorage9()
-    : mSize(0)
-{
-}
-
-BufferStorage9::~BufferStorage9()
-{
-}
-
-BufferStorage9 *BufferStorage9::makeBufferStorage9(BufferStorage *bufferStorage)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(BufferStorage9*, bufferStorage));
-    return static_cast<BufferStorage9*>(bufferStorage);
-}
-
-void *BufferStorage9::getData()
-{
-    return mMemory.data();
-}
-
-void BufferStorage9::setData(const void* data, size_t size, size_t offset)
-{
-    if (offset + size > mMemory.size())
-    {
-        mMemory.resize(offset + size);
-    }
-
-    mSize = std::max(mSize, offset + size);
-    if (data)
-    {
-        memcpy(mMemory.data() + offset, data, size);
-    }
-}
-
-void BufferStorage9::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset)
-{
-    BufferStorage9* source = makeBufferStorage9(sourceStorage);
-    if (source)
-    {
-        memcpy(mMemory.data() + destOffset, source->mMemory.data() + sourceOffset, size);
-    }
-}
-
-void BufferStorage9::clear()
-{
-    mSize = 0;
-}
-
-void BufferStorage9::markTransformFeedbackUsage()
-{
-    UNREACHABLE();
-}
-
-size_t BufferStorage9::getSize() const
-{
-    return mSize;
-}
-
-bool BufferStorage9::supportsDirectBinding() const
-{
-    return false;
-}
-
-// We do not suppot buffer mapping facility in D3D9
-bool BufferStorage9::isMapped() const
-{
-    UNREACHABLE();
-    return false;
-}
-
-void *BufferStorage9::map(GLbitfield access)
-{
-    UNREACHABLE();
-    return NULL;
-}
-
-void BufferStorage9::unmap()
-{
-    UNREACHABLE();
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d9/BufferStorage9.h b/src/libGLESv2/renderer/d3d9/BufferStorage9.h
deleted file mode 100644
index dd61624..0000000
--- a/src/libGLESv2/renderer/d3d9/BufferStorage9.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// 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.
-//
-
-// BufferStorage9.h Defines the BufferStorage9 class.
-
-#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
-#define LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
-
-#include "libGLESv2/renderer/BufferStorage.h"
-
-namespace rx
-{
-
-class BufferStorage9 : public BufferStorage
-{
-  public:
-    BufferStorage9();
-    virtual ~BufferStorage9();
-
-    static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage);
-
-    virtual void *getData();
-    virtual void setData(const void* data, size_t size, size_t offset);
-    virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset);
-    virtual void clear();
-    virtual void markTransformFeedbackUsage();
-    virtual size_t getSize() const;
-    virtual bool supportsDirectBinding() const;
-
-    virtual bool isMapped() const;
-    virtual void *map(GLbitfield access);
-    virtual void unmap();
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(BufferStorage9);
-
-    std::vector<char> mMemory;
-    size_t mSize;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
diff --git a/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp b/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp
deleted file mode 100644
index bc2e6a8..0000000
--- a/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
-
-#include "libGLESv2/renderer/d3d9/IndexBuffer9.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
-
-namespace rx
-{
-
-IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
-{
-    mIndexBuffer = NULL;
-    mBufferSize = 0;
-    mIndexType = 0;
-    mDynamic = false;
-}
-
-IndexBuffer9::~IndexBuffer9()
-{
-    SafeRelease(mIndexBuffer);
-}
-
-bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
-{
-    SafeRelease(mIndexBuffer);
-
-    updateSerial();
-
-    if (bufferSize > 0)
-    {
-        D3DFORMAT format;
-        if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
-        {
-            format = D3DFMT_INDEX16;
-        }
-        else if (indexType == GL_UNSIGNED_INT)
-        {
-            if (mRenderer->get32BitIndexSupport())
-            {
-                format = D3DFMT_INDEX32;
-            }
-            else
-            {
-                ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices.");
-                return false;
-            }
-        }
-        else
-        {
-            ERR("Invalid index type %u.", indexType);
-            return false;
-        }
-
-        DWORD usageFlags = D3DUSAGE_WRITEONLY;
-        if (dynamic)
-        {
-            usageFlags |= D3DUSAGE_DYNAMIC;
-        }
-
-        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;
-        }
-    }
-
-    mBufferSize = bufferSize;
-    mIndexType = indexType;
-    mDynamic = dynamic;
-
-    return true;
-}
-
-IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer));
-    return static_cast<IndexBuffer9*>(indexBuffer);
-}
-
-bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
-{
-    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;
-    }
-    else
-    {
-        ERR("Index buffer not initialized.");
-        return false;
-    }
-}
-
-bool IndexBuffer9::unmapBuffer()
-{
-    if (mIndexBuffer)
-    {
-        HRESULT result = mIndexBuffer->Unlock();
-        if (FAILED(result))
-        {
-            ERR("Index buffer unlock failed with error 0x%08x", result);
-            return false;
-        }
-
-        return true;
-    }
-    else
-    {
-        ERR("Index buffer not initialized.");
-        return false;
-    }
-}
-
-GLenum IndexBuffer9::getIndexType() const
-{
-    return mIndexType;
-}
-
-unsigned int IndexBuffer9::getBufferSize() const
-{
-    return mBufferSize;
-}
-
-bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
-{
-    if (bufferSize > mBufferSize || indexType != mIndexType)
-    {
-        return initialize(bufferSize, indexType, mDynamic);
-    }
-    else
-    {
-        return true;
-    }
-}
-
-bool IndexBuffer9::discard()
-{
-    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;
-    }
-    else
-    {
-        ERR("Index buffer not initialized.");
-        return false;
-    }
-}
-
-D3DFORMAT IndexBuffer9::getIndexFormat() const
-{
-    switch (mIndexType)
-    {
-      case GL_UNSIGNED_BYTE:    return D3DFMT_INDEX16;
-      case GL_UNSIGNED_SHORT:   return D3DFMT_INDEX16;
-      case GL_UNSIGNED_INT:     return D3DFMT_INDEX32;
-      default: UNREACHABLE();   return D3DFMT_UNKNOWN;
-    }
-}
-
-IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const
-{
-    return mIndexBuffer;
-}
-
-}
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/d3d9/Query9.cpp b/src/libGLESv2/renderer/d3d9/Query9.cpp
deleted file mode 100644
index bc3f58f..0000000
--- a/src/libGLESv2/renderer/d3d9/Query9.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl.
-
-
-#include "libGLESv2/renderer/d3d9/Query9.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
-
-namespace rx
-{
-
-Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type)
-{
-    mRenderer = renderer;
-    mQuery = NULL;
-}
-
-Query9::~Query9()
-{
-    SafeRelease(mQuery);
-}
-
-void Query9::begin()
-{
-    if (mQuery == NULL)
-    {
-        if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
-        {
-            return gl::error(GL_OUT_OF_MEMORY);
-        }
-    }
-
-    HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
-    UNUSED_ASSERTION_VARIABLE(result);
-    ASSERT(SUCCEEDED(result));
-}
-
-void Query9::end()
-{
-    ASSERT(mQuery);
-
-    HRESULT result = mQuery->Issue(D3DISSUE_END);
-    UNUSED_ASSERTION_VARIABLE(result);
-    ASSERT(SUCCEEDED(result));
-
-    mStatus = GL_FALSE;
-    mResult = GL_FALSE;
-}
-
-GLuint Query9::getResult()
-{
-    if (mQuery != NULL)
-    {
-        while (!testQuery())
-        {
-            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;
-}
-
-GLboolean Query9::isResultAvailable()
-{
-    if (mQuery != NULL)
-    {
-        testQuery();
-    }
-
-    return mStatus;
-}
-
-GLboolean Query9::testQuery()
-{
-    if (mQuery != NULL && mStatus != GL_TRUE)
-    {
-        DWORD numPixels = 0;
-
-        HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
-        if (hres == S_OK)
-        {
-            mStatus =  GL_TRUE;
-
-            switch (getType())
-            {
-              case GL_ANY_SAMPLES_PASSED_EXT:
-              case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
-                mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
-                break;
-              default:
-                ASSERT(false);
-            }
-        }
-        else if (d3d9::isDeviceLostError(hres))
-        {
-            mRenderer->notifyDeviceLost();
-            return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
-        }
-
-        return mStatus;
-    }
-
-    return GL_TRUE; // prevent blocking when query is null
-}
-
-bool Query9::isStarted() const
-{
-    return (mQuery != NULL);
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp b/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp
deleted file mode 100644
index 42ddfca..0000000
--- a/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation.
-
-#include "libGLESv2/renderer/d3d9/VertexBuffer9.h"
-#include "libGLESv2/renderer/vertexconversion.h"
-#include "libGLESv2/renderer/BufferStorage.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d9/formatutils9.h"
-
-#include "libGLESv2/Buffer.h"
-
-namespace rx
-{
-
-VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer)
-{
-    mVertexBuffer = NULL;
-    mBufferSize = 0;
-    mDynamicUsage = false;
-}
-
-VertexBuffer9::~VertexBuffer9()
-{
-    SafeRelease(mVertexBuffer);
-}
-
-bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage)
-{
-    SafeRelease(mVertexBuffer);
-
-    updateSerial();
-
-    if (size > 0)
-    {
-        DWORD flags = D3DUSAGE_WRITEONLY;
-        if (dynamicUsage)
-        {
-            flags |= D3DUSAGE_DYNAMIC;
-        }
-
-        HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer);
-
-        if (FAILED(result))
-        {
-            ERR("Out of memory allocating a vertex buffer of size %lu.", size);
-            return false;
-        }
-    }
-
-    mBufferSize = size;
-    mDynamicUsage = dynamicUsage;
-    return true;
-}
-
-VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer));
-    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)
-{
-    if (mVertexBuffer)
-    {
-        gl::Buffer *buffer = attrib.mBoundBuffer.get();
-
-        int inputStride = attrib.stride();
-        int elementSize = attrib.typeSize();
-
-        DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
-
-        void *mapPtr = NULL;
-
-        unsigned int mapSize;
-        if (!spaceRequired(attrib, count, instances, &mapSize))
-        {
-            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.mArrayEnabled)
-        {
-            if (buffer)
-            {
-                BufferStorage *storage = buffer->getStorage();
-                input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset);
-            }
-            else
-            {
-                input = static_cast<const char*>(attrib.mPointer);
-            }
-        }
-        else
-        {
-            input = reinterpret_cast<const char*>(currentValue.FloatValues);
-        }
-
-        if (instances == 0 || attrib.mDivisor == 0)
-        {
-            input += inputStride * start;
-        }
-
-        gl::VertexFormat vertexFormat(attrib, currentValue.Type);
-        bool needsConversion = (d3d9::GetVertexConversionType(vertexFormat) & 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
-        {
-            VertexCopyFunction copyFunction = d3d9::GetVertexCopyFunction(vertexFormat);
-            copyFunction(input, inputStride, count, mapPtr);
-        }
-
-        mVertexBuffer->Unlock();
-
-        return true;
-    }
-    else
-    {
-        ERR("Vertex buffer not initialized.");
-        return false;
-    }
-}
-
-bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
-                                     unsigned int *outSpaceRequired) const
-{
-    return spaceRequired(attrib, count, instances, outSpaceRequired);
-}
-
-unsigned int VertexBuffer9::getBufferSize() const
-{
-    return mBufferSize;
-}
-
-bool VertexBuffer9::setBufferSize(unsigned int size)
-{
-    if (size > mBufferSize)
-    {
-        return initialize(size, mDynamicUsage);
-    }
-    else
-    {
-        return true;
-    }
-}
-
-bool VertexBuffer9::discard()
-{
-    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;
-    }
-    else
-    {
-        ERR("Vertex buffer not initialized.");
-        return false;
-    }
-}
-
-IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const
-{
-    return mVertexBuffer;
-}
-
-bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
-                                  unsigned int *outSpaceRequired)
-{
-    gl::VertexFormat vertexFormat(attrib, GL_FLOAT);
-    unsigned int elementSize = d3d9::GetVertexElementSize(vertexFormat);
-
-    if (attrib.mArrayEnabled)
-    {
-        unsigned int elementCount = 0;
-        if (instances == 0 || attrib.mDivisor == 0)
-        {
-            elementCount = count;
-        }
-        else
-        {
-            if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1))
-            {
-                // Round up
-                elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor;
-            }
-            else
-            {
-                elementCount = static_cast<unsigned int>(instances) / attrib.mDivisor;
-            }
-        }
-
-        if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
-        {
-            if (outSpaceRequired)
-            {
-                *outSpaceRequired = elementSize * elementCount;
-            }
-            return true;
-        }
-        else
-        {
-            return false;
-        }
-    }
-    else
-    {
-        const unsigned int elementSize = 4;
-        if (outSpaceRequired)
-        {
-            *outSpaceRequired = elementSize * 4;
-        }
-        return true;
-    }
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d9/VertexBuffer9.h b/src/libGLESv2/renderer/d3d9/VertexBuffer9.h
deleted file mode 100644
index 2fb5a36..0000000
--- a/src/libGLESv2/renderer/d3d9/VertexBuffer9.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation.
-
-#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
-#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
-
-#include "libGLESv2/renderer/VertexBuffer.h"
-
-namespace rx
-{
-class Renderer9;
-
-class VertexBuffer9 : public VertexBuffer
-{
-  public:
-    explicit VertexBuffer9(rx::Renderer9 *const renderer);
-    virtual ~VertexBuffer9();
-
-    virtual bool 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 bool 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();
-
-    IDirect3DVertexBuffer9 *getBuffer() const;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
-
-    rx::Renderer9 *const mRenderer;
-
-    IDirect3DVertexBuffer9 *mVertexBuffer;
-    unsigned int mBufferSize;
-    bool mDynamicUsage;
-
-    static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
-                              unsigned int *outSpaceRequired);
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
diff --git a/src/libGLESv2/renderer/d3d9/formatutils9.cpp b/src/libGLESv2/renderer/d3d9/formatutils9.cpp
deleted file mode 100644
index 141bcc7..0000000
--- a/src/libGLESv2/renderer/d3d9/formatutils9.cpp
+++ /dev/null
@@ -1,864 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// formatutils9.cpp: Queries for GL image formats and their translations to D3D9
-// formats.
-
-#include "libGLESv2/renderer/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/generatemip.h"
-#include "libGLESv2/renderer/loadimage.h"
-#include "libGLESv2/renderer/copyimage.h"
-#include "libGLESv2/renderer/vertexconversion.h"
-
-namespace rx
-{
-
-// Each GL internal format corresponds to one D3D format and data loading function.
-// Due to not all formats being available all the time, some of the function/format types are wrapped
-// in templates that perform format support queries on a Renderer9 object which is supplied
-// when requesting the function or format.
-
-typedef bool ((Renderer9::*Renderer9FormatCheckFunction)(void) const);
-typedef LoadImageFunction (*RendererCheckLoadFunction)(const Renderer9 *renderer);
-
-template <Renderer9FormatCheckFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
-LoadImageFunction RendererCheckLoad(const Renderer9 *renderer)
-{
-    return ((renderer->*pred)()) ? prefered : fallback;
-}
-
-template <LoadImageFunction loadFunc>
-LoadImageFunction SimpleLoad(const Renderer9 *renderer)
-{
-    return loadFunc;
-}
-
-LoadImageFunction UnreachableLoad(const Renderer9 *renderer)
-{
-    UNREACHABLE();
-    return NULL;
-}
-
-typedef bool (*FallbackPredicateFunction)(void);
-
-template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
-LoadImageFunction FallbackLoadFunction(const Renderer9 *renderer)
-{
-    return pred() ? prefered : fallback;
-}
-
-typedef D3DFORMAT (*FormatQueryFunction)(const rx::Renderer9 *renderer);
-
-template <Renderer9FormatCheckFunction pred, D3DFORMAT prefered, D3DFORMAT fallback>
-D3DFORMAT CheckFormatSupport(const rx::Renderer9 *renderer)
-{
-    return (renderer->*pred)() ? prefered : fallback;
-}
-
-template <D3DFORMAT format>
-D3DFORMAT D3D9Format(const rx::Renderer9 *renderer)
-{
-    return format;
-}
-
-struct D3D9FormatInfo
-{
-    FormatQueryFunction mTexFormat;
-    FormatQueryFunction mRenderFormat;
-    RendererCheckLoadFunction mLoadFunction;
-
-    D3D9FormatInfo()
-        : mTexFormat(NULL), mRenderFormat(NULL), mLoadFunction(NULL)
-    { }
-
-    D3D9FormatInfo(FormatQueryFunction textureFormat, FormatQueryFunction renderFormat, RendererCheckLoadFunction loadFunc)
-        : mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc)
-    { }
-};
-
-const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')));
-const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')));
-
-typedef std::pair<GLenum, D3D9FormatInfo> D3D9FormatPair;
-typedef std::map<GLenum, D3D9FormatInfo> D3D9FormatMap;
-
-static D3D9FormatMap BuildD3D9FormatMap()
-{
-    D3D9FormatMap map;
-
-    //                       | Internal format                                   | Texture format                  | Render format                    | Load function                                   |
-    map.insert(D3D9FormatPair(GL_NONE,                             D3D9FormatInfo(D3D9Format<D3DFMT_NULL>,          D3D9Format<D3DFMT_NULL>,           UnreachableLoad                                  )));
-
-    map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT16,                D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>,          D3D9Format<D3DFMT_D24S8>,          UnreachableLoad                                  )));
-    map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT32_OES,            D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>,          D3D9Format<D3DFMT_D32>,            UnreachableLoad                                  )));
-    map.insert(D3D9FormatPair(GL_DEPTH24_STENCIL8_OES,             D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>,          D3D9Format<D3DFMT_D24S8>,          UnreachableLoad                                  )));
-    map.insert(D3D9FormatPair(GL_STENCIL_INDEX8,                   D3D9FormatInfo(D3D9Format<D3DFMT_UNKNOWN>,       D3D9Format<D3DFMT_D24S8>,          UnreachableLoad                                  ))); // TODO: What's the texture format?
-
-    map.insert(D3D9FormatPair(GL_RGBA32F_EXT,                      D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>,  SimpleLoad<loadToNative<GLfloat, 4> >            )));
-    map.insert(D3D9FormatPair(GL_RGB32F_EXT,                       D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>,  SimpleLoad<loadToNative3To4<GLfloat, gl::Float32One> >)));
-    map.insert(D3D9FormatPair(GL_RG32F_EXT,                        D3D9FormatInfo(D3D9Format<D3DFMT_G32R32F>,       D3D9Format<D3DFMT_G32R32F>,        SimpleLoad<loadToNative<GLfloat, 2> >            )));
-    map.insert(D3D9FormatPair(GL_R32F_EXT,                         D3D9FormatInfo(D3D9Format<D3DFMT_R32F>,          D3D9Format<D3DFMT_R32F>,           SimpleLoad<loadToNative<GLfloat, 1> >            )));
-    map.insert(D3D9FormatPair(GL_ALPHA32F_EXT,                     D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadAlphaFloatDataToRGBA>             )));
-    map.insert(D3D9FormatPair(GL_LUMINANCE32F_EXT,                 D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadLuminanceFloatDataToRGBA>         )));
-    map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA32F_EXT,           D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadLuminanceAlphaFloatDataToRGBA>    )));
-
-    map.insert(D3D9FormatPair(GL_RGBA16F_EXT,                      D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>,  SimpleLoad<loadToNative<GLhalf, 4> >             )));
-    map.insert(D3D9FormatPair(GL_RGB16F_EXT,                       D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>,  SimpleLoad<loadToNative3To4<GLhalf, gl::Float16One> >)));
-    map.insert(D3D9FormatPair(GL_RG16F_EXT,                        D3D9FormatInfo(D3D9Format<D3DFMT_G16R16F>,       D3D9Format<D3DFMT_G16R16F>,        SimpleLoad<loadToNative<GLhalf, 2> >             )));
-    map.insert(D3D9FormatPair(GL_R16F_EXT,                         D3D9FormatInfo(D3D9Format<D3DFMT_R16F>,          D3D9Format<D3DFMT_R16F>,           SimpleLoad<loadToNative<GLhalf, 1> >             )));
-    map.insert(D3D9FormatPair(GL_ALPHA16F_EXT,                     D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadAlphaHalfFloatDataToRGBA>         )));
-    map.insert(D3D9FormatPair(GL_LUMINANCE16F_EXT,                 D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadLuminanceHalfFloatDataToRGBA>     )));
-    map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA16F_EXT,           D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadLuminanceAlphaHalfFloatDataToRGBA>)));
-
-    map.insert(D3D9FormatPair(GL_ALPHA8_EXT,                       D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>,      D3D9Format<D3DFMT_A8R8G8B8>,       FallbackLoadFunction<gl::supportsSSE2, loadAlphaDataToBGRASSE2, loadAlphaDataToBGRA>)));
-
-    map.insert(D3D9FormatPair(GL_RGB8_OES,                         D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>,      D3D9Format<D3DFMT_X8R8G8B8>,       SimpleLoad<loadRGBUByteDataToBGRX>                )));
-    map.insert(D3D9FormatPair(GL_RGB565,                           D3D9FormatInfo(CheckFormatSupport<&Renderer9::getRGB565TextureSupport, D3DFMT_R5G6B5, D3DFMT_X8R8G8B8>, CheckFormatSupport<&Renderer9::getRGB565TextureSupport, D3DFMT_R5G6B5, D3DFMT_X8R8G8B8>, RendererCheckLoad<&Renderer9::getRGB565TextureSupport, loadToNative<GLushort, 1>, loadRGB565DataToBGRA>)));
-    map.insert(D3D9FormatPair(GL_RGBA8_OES,                        D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>,      D3D9Format<D3DFMT_A8R8G8B8>,       FallbackLoadFunction<gl::supportsSSE2, loadRGBAUByteDataToBGRASSE2, loadRGBAUByteDataToBGRA>)));
-    map.insert(D3D9FormatPair(GL_RGBA4,                            D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>,      D3D9Format<D3DFMT_A8R8G8B8>,       SimpleLoad<loadRGBA4444DataToBGRA>                )));
-    map.insert(D3D9FormatPair(GL_RGB5_A1,                          D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>,      D3D9Format<D3DFMT_A8R8G8B8>,       SimpleLoad<loadRGBA5551DataToBGRA>                )));
-    map.insert(D3D9FormatPair(GL_R8_EXT,                           D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>,      D3D9Format<D3DFMT_X8R8G8B8>,       SimpleLoad<loadRUByteDataToBGRX>                  )));
-    map.insert(D3D9FormatPair(GL_RG8_EXT,                          D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>,      D3D9Format<D3DFMT_X8R8G8B8>,       SimpleLoad<loadRGUByteDataToBGRX>                 )));
-
-    map.insert(D3D9FormatPair(GL_BGRA8_EXT,                        D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>,      D3D9Format<D3DFMT_A8R8G8B8>,       SimpleLoad<loadToNative<GLubyte, 4> >             )));
-    map.insert(D3D9FormatPair(GL_BGRA4_ANGLEX,                     D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>,      D3D9Format<D3DFMT_A8R8G8B8>,       SimpleLoad<loadRGBA4444DataToRGBA>                )));
-    map.insert(D3D9FormatPair(GL_BGR5_A1_ANGLEX,                   D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>,      D3D9Format<D3DFMT_A8R8G8B8>,       SimpleLoad<loadRGBA5551DataToRGBA>                )));
-
-    map.insert(D3D9FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,     D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>,          D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadCompressedBlockDataToNative<4, 4,  8> >)));
-    map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,    D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>,          D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadCompressedBlockDataToNative<4, 4,  8> >)));
-    map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,  D3D9FormatInfo(D3D9Format<D3DFMT_DXT3>,          D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >)));
-    map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,  D3D9FormatInfo(D3D9Format<D3DFMT_DXT5>,          D3D9Format<D3DFMT_UNKNOWN>,        SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >)));
-
-    // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
-    // then changing the format and loading function appropriately.
-    map.insert(D3D9FormatPair(GL_LUMINANCE8_EXT,                   D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceTextureSupport, D3DFMT_L8, D3DFMT_A8R8G8B8>,        D3D9Format<D3DFMT_UNKNOWN>,  RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadToNative<GLubyte, 1>, loadLuminanceDataToBGRA>)));
-    map.insert(D3D9FormatPair(GL_LUMINANCE8_ALPHA8_EXT,            D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceAlphaTextureSupport, D3DFMT_A8L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>,  RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadToNative<GLubyte, 2>, loadLuminanceAlphaDataToBGRA>)));
-
-    return map;
-}
-
-static bool GetD3D9FormatInfo(GLenum internalFormat, D3D9FormatInfo *outFormatInfo)
-{
-    static const D3D9FormatMap formatMap = BuildD3D9FormatMap();
-    D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat);
-    if (iter != formatMap.end())
-    {
-        if (outFormatInfo)
-        {
-            *outFormatInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-// A map to determine the pixel size and mip generation function of a given D3D format
-struct D3DFormatInfo
-{
-    GLuint mPixelBits;
-    GLuint mBlockWidth;
-    GLuint mBlockHeight;
-    GLenum mInternalFormat;
-
-    MipGenerationFunction mMipGenerationFunction;
-    ColorReadFunction mColorReadFunction;
-
-    D3DFormatInfo()
-        : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE), mMipGenerationFunction(NULL),
-          mColorReadFunction(NULL)
-    { }
-
-    D3DFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLenum internalFormat,
-                  MipGenerationFunction mipFunc, ColorReadFunction readFunc)
-        : mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat),
-          mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc)
-    { }
-};
-
-typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair;
-typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap;
-
-static D3D9FormatInfoMap BuildD3D9FormatInfoMap()
-{
-    D3D9FormatInfoMap map;
-
-    //                           | D3DFORMAT           |             | S  |W |H | Internal format                   | Mip generation function   | Color read function             |
-    map.insert(D3D9FormatInfoPair(D3DFMT_NULL,          D3DFormatInfo(  0, 0, 0, GL_NONE,                            NULL,                       NULL                             )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_UNKNOWN,       D3DFormatInfo(  0, 0, 0, GL_NONE,                            NULL,                       NULL                             )));
-
-    map.insert(D3D9FormatInfoPair(D3DFMT_L8,            D3DFormatInfo(  8, 1, 1, GL_LUMINANCE8_EXT,                  GenerateMip<L8>,            ReadColor<L8, GLfloat>           )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_A8,            D3DFormatInfo(  8, 1, 1, GL_ALPHA8_EXT,                      GenerateMip<A8>,            ReadColor<A8, GLfloat>           )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_A8L8,          D3DFormatInfo( 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT,           GenerateMip<A8L8>,          ReadColor<A8L8, GLfloat>         )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_A4R4G4B4,      D3DFormatInfo( 16, 1, 1, GL_BGRA4_ANGLEX,                    GenerateMip<B4G4R4A4>,      ReadColor<B4G4R4A4, GLfloat>     )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_A1R5G5B5,      D3DFormatInfo( 16, 1, 1, GL_BGR5_A1_ANGLEX,                  GenerateMip<B5G5R5A1>,      ReadColor<B5G5R5A1, GLfloat>     )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_R5G6B5,        D3DFormatInfo( 16, 1, 1, GL_RGB565,                          GenerateMip<R5G6B5>,        ReadColor<R5G6B5, GLfloat>       )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_X8R8G8B8,      D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT,                       GenerateMip<B8G8R8X8>,      ReadColor<B8G8R8X8, GLfloat>     )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_A8R8G8B8,      D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT,                       GenerateMip<B8G8R8A8>,      ReadColor<B8G8R8A8, GLfloat>     )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_R16F,          D3DFormatInfo( 16, 1, 1, GL_R16F_EXT,                        GenerateMip<R16F>,          ReadColor<R16F, GLfloat>         )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_G16R16F,       D3DFormatInfo( 32, 1, 1, GL_RG16F_EXT,                       GenerateMip<R16G16F>,       ReadColor<R16G16F, GLfloat>      )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_A16B16G16R16F, D3DFormatInfo( 64, 1, 1, GL_RGBA16F_EXT,                     GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>)));
-    map.insert(D3D9FormatInfoPair(D3DFMT_R32F,          D3DFormatInfo( 32, 1, 1, GL_R32F_EXT,                        GenerateMip<R32F>,          ReadColor<R32F, GLfloat>         )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_G32R32F,       D3DFormatInfo( 64, 1, 1, GL_RG32F_EXT,                       GenerateMip<R32G32F>,       ReadColor<R32G32F, GLfloat>      )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_A32B32G32R32F, D3DFormatInfo(128, 1, 1, GL_RGBA32F_EXT,                     GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>)));
-
-    map.insert(D3D9FormatInfoPair(D3DFMT_D16,           D3DFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16,               NULL,                       NULL                             )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_D24S8,         D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES,            NULL,                       NULL                             )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_D24X8,         D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT16,               NULL,                       NULL                             )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_D32,           D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES,           NULL,                       NULL                             )));
-
-    map.insert(D3D9FormatInfoPair(D3DFMT_INTZ,          D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES,            NULL,                       NULL                             )));
-
-    map.insert(D3D9FormatInfoPair(D3DFMT_DXT1,          D3DFormatInfo( 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   NULL,                       NULL                             )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_DXT3,          D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL,                       NULL                             )));
-    map.insert(D3D9FormatInfoPair(D3DFMT_DXT5,          D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL,                       NULL                             )));
-
-    return map;
-}
-
-static const D3D9FormatInfoMap &GetD3D9FormatInfoMap()
-{
-    static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap();
-    return infoMap;
-}
-
-static bool GetD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo)
-{
-    const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap();
-    D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
-    if (iter != infoMap.end())
-    {
-        if (outFormatInfo)
-        {
-            *outFormatInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-static d3d9::D3DFormatSet BuildAllD3DFormatSet()
-{
-    d3d9::D3DFormatSet set;
-
-    const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap();
-    for (D3D9FormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i)
-    {
-        set.insert(i->first);
-    }
-
-    return set;
-}
-
-struct D3D9FastCopyFormat
-{
-    D3DFORMAT mSourceFormat;
-    GLenum mDestFormat;
-    GLenum mDestType;
-
-    D3D9FastCopyFormat(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType)
-        : mSourceFormat(sourceFormat), mDestFormat(destFormat), mDestType(destType)
-    { }
-
-    bool operator<(const D3D9FastCopyFormat& other) const
-    {
-        return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0;
-    }
-};
-
-typedef std::map<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyMap;
-typedef std::pair<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyPair;
-
-static D3D9FastCopyMap BuildFastCopyMap()
-{
-    D3D9FastCopyMap map;
-
-    map.insert(D3D9FastCopyPair(D3D9FastCopyFormat(D3DFMT_A8R8G8B8, GL_RGBA, GL_UNSIGNED_BYTE), CopyBGRAUByteToRGBAUByte));
-
-    return map;
-}
-
-typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair;
-typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap;
-
-static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap()
-{
-    InternalFormatInitialzerMap map;
-
-    map.insert(InternalFormatInitialzerPair(GL_RGB16F,  initialize4ComponentData<GLhalf,   0x0000,     0x0000,     0x0000,     gl::Float16One>));
-    map.insert(InternalFormatInitialzerPair(GL_RGB32F,  initialize4ComponentData<GLfloat,  0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
-
-    return map;
-}
-
-static const InternalFormatInitialzerMap &GetInternalFormatInitialzerMap()
-{
-    static const InternalFormatInitialzerMap map = BuildInternalFormatInitialzerMap();
-    return map;
-}
-
-namespace d3d9
-{
-
-MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format)
-{
-    D3DFormatInfo d3dFormatInfo;
-    if (GetD3D9FormatInfo(format, &d3dFormatInfo))
-    {
-        return d3dFormatInfo.mMipGenerationFunction;
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-LoadImageFunction GetImageLoadFunction(GLenum internalFormat, const Renderer9 *renderer)
-{
-    if (!renderer)
-    {
-        return NULL;
-    }
-
-    ASSERT(renderer->getCurrentClientVersion() == 2);
-
-    D3D9FormatInfo d3d9FormatInfo;
-    if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
-    {
-        return d3d9FormatInfo.mLoadFunction(renderer);
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-GLuint GetFormatPixelBytes(D3DFORMAT format)
-{
-    D3DFormatInfo d3dFormatInfo;
-    if (GetD3D9FormatInfo(format, &d3dFormatInfo))
-    {
-        return d3dFormatInfo.mPixelBits / 8;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetBlockWidth(D3DFORMAT format)
-{
-    D3DFormatInfo d3dFormatInfo;
-    if (GetD3D9FormatInfo(format, &d3dFormatInfo))
-    {
-        return d3dFormatInfo.mBlockWidth;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetBlockHeight(D3DFORMAT format)
-{
-    D3DFormatInfo d3dFormatInfo;
-    if (GetD3D9FormatInfo(format, &d3dFormatInfo))
-    {
-        return d3dFormatInfo.mBlockHeight;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height)
-{
-    D3DFormatInfo d3dFormatInfo;
-    if (GetD3D9FormatInfo(format, &d3dFormatInfo))
-    {
-        GLuint numBlocksWide = (width + d3dFormatInfo.mBlockWidth - 1) / d3dFormatInfo.mBlockWidth;
-        GLuint numBlocksHight = (height + d3dFormatInfo.mBlockHeight - 1) / d3dFormatInfo.mBlockHeight;
-
-        return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
-{
-    D3DFormatInfo d3dFormatInfo;
-    if (GetD3D9FormatInfo(format, &d3dFormatInfo))
-    {
-        int upsampleCount = 0;
-
-        GLsizei blockWidth = d3dFormatInfo.mBlockWidth;
-        GLsizei blockHeight = d3dFormatInfo.mBlockHeight;
-
-        // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
-        if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight)
-        {
-            while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0)
-            {
-                *requestWidth <<= 1;
-                *requestHeight <<= 1;
-                upsampleCount++;
-            }
-        }
-        *levelOffset = upsampleCount;
-    }
-}
-
-const D3DFormatSet &GetAllUsedD3DFormats()
-{
-    static const D3DFormatSet formatSet = BuildAllD3DFormatSet();
-    return formatSet;
-}
-
-ColorReadFunction GetColorReadFunction(D3DFORMAT format)
-{
-    D3DFormatInfo d3dFormatInfo;
-    if (GetD3D9FormatInfo(format, &d3dFormatInfo))
-    {
-        return d3dFormatInfo.mColorReadFunction;
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType, GLuint clientVersion)
-{
-    static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap();
-    D3D9FastCopyMap::const_iterator iter = fastCopyMap.find(D3D9FastCopyFormat(sourceFormat, destFormat, destType));
-    return (iter != fastCopyMap.end()) ? iter->second : NULL;
-}
-
-GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
-{
-    switch (declType)
-    {
-      case D3DDECLTYPE_FLOAT1:   return GL_FLOAT;
-      case D3DDECLTYPE_FLOAT2:   return GL_FLOAT;
-      case D3DDECLTYPE_FLOAT3:   return GL_FLOAT;
-      case D3DDECLTYPE_FLOAT4:   return GL_FLOAT;
-      case D3DDECLTYPE_UBYTE4:   return GL_UNSIGNED_INT;
-      case D3DDECLTYPE_SHORT2:   return GL_INT;
-      case D3DDECLTYPE_SHORT4:   return GL_INT;
-      case D3DDECLTYPE_UBYTE4N:  return GL_UNSIGNED_NORMALIZED;
-      case D3DDECLTYPE_SHORT4N:  return GL_SIGNED_NORMALIZED;
-      case D3DDECLTYPE_USHORT4N: return GL_UNSIGNED_NORMALIZED;
-      case D3DDECLTYPE_SHORT2N:  return GL_SIGNED_NORMALIZED;
-      case D3DDECLTYPE_USHORT2N: return GL_UNSIGNED_NORMALIZED;
-      default: UNREACHABLE();    return GL_NONE;
-    }
-}
-
-// Attribute format conversion
-enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
-
-struct FormatConverter
-{
-    bool identity;
-    std::size_t outputElementSize;
-    void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
-    D3DDECLTYPE d3dDeclType;
-};
-
-struct TranslationDescription
-{
-    DWORD capsFlag;
-    FormatConverter preferredConversion;
-    FormatConverter fallbackConversion;
-};
-
-static unsigned int typeIndex(GLenum type);
-static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute);
-
-bool mTranslationsInitialized = false;
-FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
-
-// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
-//
-// BYTE                 SHORT (Cast)
-// BYTE-norm            FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
-// UNSIGNED_BYTE        UBYTE4 (Identity) or SHORT (Cast)
-// UNSIGNED_BYTE-norm   UBYTE4N (Identity) or FLOAT (Normalize)
-// SHORT                SHORT (Identity)
-// SHORT-norm           SHORT-norm (Identity) or FLOAT (Normalize)
-// UNSIGNED_SHORT       FLOAT (Cast)
-// UNSIGNED_SHORT-norm  USHORT-norm (Identity) or FLOAT (Normalize)
-// FIXED (not in WebGL) FLOAT (FixedToFloat)
-// FLOAT                FLOAT (Identity)
-
-// GLToCType maps from GL type (as GLenum) to the C typedef.
-template <GLenum GLType> struct GLToCType { };
-
-template <> struct GLToCType<GL_BYTE>           { typedef GLbyte type;      };
-template <> struct GLToCType<GL_UNSIGNED_BYTE>  { typedef GLubyte type;     };
-template <> struct GLToCType<GL_SHORT>          { typedef GLshort type;     };
-template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type;    };
-template <> struct GLToCType<GL_FIXED>          { typedef GLuint type;      };
-template <> struct GLToCType<GL_FLOAT>          { typedef GLfloat type;     };
-
-// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
-enum D3DVertexType
-{
-    D3DVT_FLOAT,
-    D3DVT_SHORT,
-    D3DVT_SHORT_NORM,
-    D3DVT_UBYTE,
-    D3DVT_UBYTE_NORM,
-    D3DVT_USHORT_NORM
-};
-
-// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
-template <unsigned int D3DType> struct D3DToCType { };
-
-template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
-template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
-template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
-template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
-template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
-template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
-
-// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
-template <unsigned int type, int size> struct WidenRule { };
-
-template <int size> struct WidenRule<D3DVT_FLOAT, size>          : NoWiden<size> { };
-template <int size> struct WidenRule<D3DVT_SHORT, size>          : WidenToEven<size> { };
-template <int size> struct WidenRule<D3DVT_SHORT_NORM, size>     : WidenToEven<size> { };
-template <int size> struct WidenRule<D3DVT_UBYTE, size>          : WidenToFour<size> { };
-template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size>     : WidenToFour<size> { };
-template <int size> struct WidenRule<D3DVT_USHORT_NORM, size>    : WidenToEven<size> { };
-
-// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
-template <unsigned int d3dtype, int size> struct VertexTypeFlags { };
-
-template <unsigned int _capflag, unsigned int _declflag>
-struct VertexTypeFlagsHelper
-{
-    enum { capflag = _capflag };
-    enum { declflag = _declflag };
-};
-
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
-template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
-template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
-template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
-template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
-
-
-// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
-template <GLenum GLtype, bool normalized> struct VertexTypeMapping { };
-
-template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
-struct VertexTypeMappingBase
-{
-    enum { preferred = Preferred };
-    enum { fallback = Fallback };
-};
-
-template <> struct VertexTypeMapping<GL_BYTE, false>                        : VertexTypeMappingBase<D3DVT_SHORT> { };                       // Cast
-template <> struct VertexTypeMapping<GL_BYTE, true>                         : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Normalize
-template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false>               : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { };          // Identity, Cast
-template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true>                : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { };     // Identity, Normalize
-template <> struct VertexTypeMapping<GL_SHORT, false>                       : VertexTypeMappingBase<D3DVT_SHORT> { };                       // Identity
-template <> struct VertexTypeMapping<GL_SHORT, true>                        : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { };     // Cast, Normalize
-template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false>              : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Cast
-template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true>               : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { };    // Cast, Normalize
-template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized>   : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // FixedToFloat
-template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized>   : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Identity
-
-
-// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
-// The conversion rules themselves are defined in vertexconversion.h.
-
-// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
-template <GLenum fromType, bool normalized, unsigned int toType>
-struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type> { };
-
-// All conversions from normalized types to float use the Normalize operator.
-template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type> { };
-
-// Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules.
-template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT>  : FixedToFloat<GLint, 16> { };
-template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { };
-
-// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
-// whether it is normalized or not.
-template <class T, bool normalized> struct DefaultVertexValuesStage2 { };
-
-template <class T> struct DefaultVertexValuesStage2<T, true>  : NormalizedDefaultValues<T> { };
-template <class T> struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T> { };
-
-// Work out the default value rule for a D3D type (expressed as the C type) and
-template <class T, bool normalized> struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized> { };
-template <bool normalized> struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float> { };
-
-// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
-// The fallback conversion produces an output that all D3D9 devices must support.
-template <class T> struct UsePreferred { enum { type = T::preferred }; };
-template <class T> struct UseFallback { enum { type = T::fallback }; };
-
-// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
-// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
-// and the D3DDECLTYPE member needed for the vertex declaration in declflag.
-template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
-struct Converter
-    : VertexDataConverter<typename GLToCType<fromType>::type,
-                          WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
-                          ConversionRule<fromType,
-                                         normalized,
-                                         PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
-                          DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
-{
-private:
-    enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
-    enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
-
-public:
-    enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
-    enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
-};
-
-// Initialize a TranslationInfo
-#define TRANSLATION(type, norm, size, preferred)                                    \
-    {                                                                               \
-        Converter<type, norm, size, preferred>::identity,                           \
-        Converter<type, norm, size, preferred>::finalSize,                          \
-        Converter<type, norm, size, preferred>::convertArray,                       \
-        static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag)  \
-    }
-
-#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size)    \
-    {                                                       \
-        Converter<type, norm, size, UsePreferred>::capflag, \
-        TRANSLATION(type, norm, size, UsePreferred),        \
-        TRANSLATION(type, norm, size, UseFallback)          \
-    }
-
-#define TRANSLATIONS_FOR_TYPE(type)                                                                                                                                                                         \
-    {                                                                                                                                                                                                       \
-        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
-        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) },     \
-    }
-
-#define TRANSLATIONS_FOR_TYPE_NO_NORM(type)                                                                                                                                                                 \
-    {                                                                                                                                                                                                       \
-        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
-        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
-    }
-
-const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
-{
-    TRANSLATIONS_FOR_TYPE(GL_BYTE),
-    TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
-    TRANSLATIONS_FOR_TYPE(GL_SHORT),
-    TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
-    TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED),
-    TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)
-};
-
-void InitializeVertexTranslations(const rx::Renderer9 *renderer)
-{
-    DWORD declTypes = renderer->getCapsDeclTypes();
-
-    for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
-    {
-        for (unsigned int j = 0; j < 2; j++)
-        {
-            for (unsigned int k = 0; k < 4; k++)
-            {
-                if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0)
-                {
-                    mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
-                }
-                else
-                {
-                    mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
-                }
-            }
-        }
-    }
-}
-
-unsigned int typeIndex(GLenum type)
-{
-    switch (type)
-    {
-      case GL_BYTE: return 0;
-      case GL_UNSIGNED_BYTE: return 1;
-      case GL_SHORT: return 2;
-      case GL_UNSIGNED_SHORT: return 3;
-      case GL_FIXED: return 4;
-      case GL_FLOAT: return 5;
-
-      default: UNREACHABLE(); return 5;
-    }
-}
-
-const FormatConverter &formatConverter(const gl::VertexFormat &vertexFormat)
-{
-    // Pure integer attributes only supported in ES3.0
-    ASSERT(!vertexFormat.mPureInteger);
-    return mFormatConverters[typeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1];
-}
-
-VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat)
-{
-    return formatConverter(vertexFormat).convertArray;
-}
-
-size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat)
-{
-    return formatConverter(vertexFormat).outputElementSize;
-}
-
-VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat)
-{
-    return (formatConverter(vertexFormat).identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU);
-}
-
-D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat)
-{
-    return formatConverter(vertexFormat).d3dDeclType;
-}
-
-}
-
-namespace gl_d3d9
-{
-
-D3DFORMAT GetTextureFormat(GLenum internalFormat, const Renderer9 *renderer)
-{
-    if (!renderer)
-    {
-        UNREACHABLE();
-        return D3DFMT_UNKNOWN;
-    }
-
-    ASSERT(renderer->getCurrentClientVersion() == 2);
-
-    D3D9FormatInfo d3d9FormatInfo;
-    if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
-    {
-        return d3d9FormatInfo.mTexFormat(renderer);
-    }
-    else
-    {
-        UNREACHABLE();
-        return D3DFMT_UNKNOWN;
-    }
-}
-
-D3DFORMAT GetRenderFormat(GLenum internalFormat, const Renderer9 *renderer)
-{
-    if (!renderer)
-    {
-        UNREACHABLE();
-        return D3DFMT_UNKNOWN;
-    }
-
-    ASSERT(renderer->getCurrentClientVersion() == 2);
-
-    D3D9FormatInfo d3d9FormatInfo;
-    if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
-    {
-        return d3d9FormatInfo.mRenderFormat(renderer);
-    }
-    else
-    {
-        UNREACHABLE();
-        return D3DFMT_UNKNOWN;
-    }
-}
-
-D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples)
-{
-    return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE;
-}
-
-bool RequiresTextureDataInitialization(GLint internalFormat)
-{
-    const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap();
-    return map.find(internalFormat) != map.end();
-}
-
-InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat)
-{
-    const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap();
-    InternalFormatInitialzerMap::const_iterator iter = map.find(internalFormat);
-    if (iter != map.end())
-    {
-        return iter->second;
-    }
-    else
-    {
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-}
-
-namespace d3d9_gl
-{
-
-GLenum GetInternalFormat(D3DFORMAT format)
-{
-    static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap();
-    D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
-    if (iter != infoMap.end())
-    {
-        return iter->second.mInternalFormat;
-    }
-    else
-    {
-        UNREACHABLE();
-        return GL_NONE;
-    }
-}
-
-GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type)
-{
-    return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0;
-}
-
-bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format, GLuint clientVersion)
-{
-    GLenum internalFormat = d3d9_gl::GetInternalFormat(d3dformat);
-    GLenum convertedFormat = gl::GetFormat(internalFormat, clientVersion);
-    return convertedFormat == format;
-}
-
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d9/formatutils9.h b/src/libGLESv2/renderer/d3d9/formatutils9.h
deleted file mode 100644
index 5b40c10..0000000
--- a/src/libGLESv2/renderer/d3d9/formatutils9.h
+++ /dev/null
@@ -1,77 +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.
-//
-
-// formatutils9.h: Queries for GL image formats and their translations to D3D9
-// formats.
-
-#ifndef LIBGLESV2_RENDERER_FORMATUTILS9_H_
-#define LIBGLESV2_RENDERER_FORMATUTILS9_H_
-
-#include "libGLESv2/formatutils.h"
-
-namespace rx
-{
-
-class Renderer9;
-
-namespace d3d9
-{
-
-typedef std::set<D3DFORMAT> D3DFormatSet;
-
-MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format);
-LoadImageFunction GetImageLoadFunction(GLenum internalFormat, const Renderer9 *renderer);
-
-GLuint GetFormatPixelBytes(D3DFORMAT format);
-GLuint GetBlockWidth(D3DFORMAT format);
-GLuint GetBlockHeight(D3DFORMAT format);
-GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height);
-
-void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
-
-const D3DFormatSet &GetAllUsedD3DFormats();
-
-ColorReadFunction GetColorReadFunction(D3DFORMAT format);
-ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType, GLuint clientVersion);
-
-VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat);
-size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat);
-VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat);
-D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat);
-
-GLenum GetDeclTypeComponentType(D3DDECLTYPE declType);
-int GetDeclTypeComponentCount(D3DDECLTYPE declType);
-bool IsDeclTypeNormalized(D3DDECLTYPE declType);
-
-void InitializeVertexTranslations(const rx::Renderer9 *renderer);
-
-}
-
-namespace gl_d3d9
-{
-
-D3DFORMAT GetTextureFormat(GLenum internalFormat, const Renderer9 *renderer);
-D3DFORMAT GetRenderFormat(GLenum internalFormat, const Renderer9 *renderer);
-
-D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples);
-
-bool RequiresTextureDataInitialization(GLint internalFormat);
-InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat);
-
-}
-
-namespace d3d9_gl
-{
-
-GLenum GetInternalFormat(D3DFORMAT format);
-GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type);
-bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format, GLuint clientVersion);
-
-}
-
-}
-
-#endif // LIBGLESV2_RENDERER_FORMATUTILS9_H_
diff --git a/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp b/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp
deleted file mode 100644
index 48c3788..0000000
--- a/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-#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
-// found in the LICENSE file.
-//
-
-// renderer9_utils.cpp: Conversion functions and other utility routines
-// specific to the D3D9 renderer.
-
-#include "libGLESv2/renderer/d3d9/renderer9_utils.h"
-#include "common/mathutil.h"
-#include "libGLESv2/Context.h"
-
-#include "common/debug.h"
-
-namespace rx
-{
-
-namespace gl_d3d9
-{
-
-D3DCMPFUNC ConvertComparison(GLenum comparison)
-{
-    D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
-    switch (comparison)
-    {
-      case GL_NEVER:    d3dComp = D3DCMP_NEVER;        break;
-      case GL_ALWAYS:   d3dComp = D3DCMP_ALWAYS;       break;
-      case GL_LESS:     d3dComp = D3DCMP_LESS;         break;
-      case GL_LEQUAL:   d3dComp = D3DCMP_LESSEQUAL;    break;
-      case GL_EQUAL:    d3dComp = D3DCMP_EQUAL;        break;
-      case GL_GREATER:  d3dComp = D3DCMP_GREATER;      break;
-      case GL_GEQUAL:   d3dComp = D3DCMP_GREATEREQUAL; break;
-      case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL;     break;
-      default: UNREACHABLE();
-    }
-
-    return d3dComp;
-}
-
-D3DCOLOR ConvertColor(gl::ColorF color)
-{
-    return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
-                         gl::unorm<8>(color.green),
-                         gl::unorm<8>(color.blue),
-                         gl::unorm<8>(color.alpha));
-}
-
-D3DBLEND ConvertBlendFunc(GLenum blend)
-{
-    D3DBLEND d3dBlend = D3DBLEND_ZERO;
-
-    switch (blend)
-    {
-      case GL_ZERO:                     d3dBlend = D3DBLEND_ZERO;           break;
-      case GL_ONE:                      d3dBlend = D3DBLEND_ONE;            break;
-      case GL_SRC_COLOR:                d3dBlend = D3DBLEND_SRCCOLOR;       break;
-      case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = D3DBLEND_INVSRCCOLOR;    break;
-      case GL_DST_COLOR:                d3dBlend = D3DBLEND_DESTCOLOR;      break;
-      case GL_ONE_MINUS_DST_COLOR:      d3dBlend = D3DBLEND_INVDESTCOLOR;   break;
-      case GL_SRC_ALPHA:                d3dBlend = D3DBLEND_SRCALPHA;       break;
-      case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3DBLEND_INVSRCALPHA;    break;
-      case GL_DST_ALPHA:                d3dBlend = D3DBLEND_DESTALPHA;      break;
-      case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3DBLEND_INVDESTALPHA;   break;
-      case GL_CONSTANT_COLOR:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
-      case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
-      case GL_CONSTANT_ALPHA:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
-      case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
-      case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3DBLEND_SRCALPHASAT;    break;
-      default: UNREACHABLE();
-    }
-
-    return d3dBlend;
-}
-
-D3DBLENDOP ConvertBlendOp(GLenum blendOp)
-{
-    D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
-
-    switch (blendOp)
-    {
-      case GL_FUNC_ADD:              d3dBlendOp = D3DBLENDOP_ADD;         break;
-      case GL_FUNC_SUBTRACT:         d3dBlendOp = D3DBLENDOP_SUBTRACT;    break;
-      case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
-      case GL_MIN_EXT:               d3dBlendOp = D3DBLENDOP_MIN;         break;
-      case GL_MAX_EXT:               d3dBlendOp = D3DBLENDOP_MAX;         break;
-      default: UNREACHABLE();
-    }
-
-    return d3dBlendOp;
-}
-
-D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
-{
-    D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
-
-    switch (stencilOp)
-    {
-      case GL_ZERO:      d3dStencilOp = D3DSTENCILOP_ZERO;    break;
-      case GL_KEEP:      d3dStencilOp = D3DSTENCILOP_KEEP;    break;
-      case GL_REPLACE:   d3dStencilOp = D3DSTENCILOP_REPLACE; break;
-      case GL_INCR:      d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
-      case GL_DECR:      d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
-      case GL_INVERT:    d3dStencilOp = D3DSTENCILOP_INVERT;  break;
-      case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR;    break;
-      case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR;    break;
-      default: UNREACHABLE();
-    }
-
-    return d3dStencilOp;
-}
-
-D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
-{
-    D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
-
-    switch (wrap)
-    {
-      case GL_REPEAT:            d3dWrap = D3DTADDRESS_WRAP;   break;
-      case GL_CLAMP_TO_EDGE:     d3dWrap = D3DTADDRESS_CLAMP;  break;
-      case GL_MIRRORED_REPEAT:   d3dWrap = D3DTADDRESS_MIRROR; break;
-      default: UNREACHABLE();
-    }
-
-    return d3dWrap;
-}
-
-D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
-{
-    D3DCULL cull = D3DCULL_CCW;
-    switch (cullFace)
-    {
-      case GL_FRONT:
-        cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
-        break;
-      case GL_BACK:
-        cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
-        break;
-      case GL_FRONT_AND_BACK:
-        cull = D3DCULL_NONE; // culling will be handled during draw
-        break;
-      default: UNREACHABLE();
-    }
-
-    return cull;
-}
-
-D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
-{
-    D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
-
-    switch (cubeFace)
-    {
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-        face = D3DCUBEMAP_FACE_POSITIVE_X;
-        break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-        face = D3DCUBEMAP_FACE_NEGATIVE_X;
-        break;
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-        face = D3DCUBEMAP_FACE_POSITIVE_Y;
-        break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-        face = D3DCUBEMAP_FACE_NEGATIVE_Y;
-        break;
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-        face = D3DCUBEMAP_FACE_POSITIVE_Z;
-        break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-        face = D3DCUBEMAP_FACE_NEGATIVE_Z;
-        break;
-      default: UNREACHABLE();
-    }
-
-    return face;
-}
-
-DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
-{
-    return (red   ? D3DCOLORWRITEENABLE_RED   : 0) |
-           (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
-           (blue  ? D3DCOLORWRITEENABLE_BLUE  : 0) |
-           (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
-}
-
-D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
-{
-    if (maxAnisotropy > 1.0f)
-    {
-        return D3DTEXF_ANISOTROPIC;
-    }
-
-    D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
-    switch (magFilter)
-    {
-      case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT;  break;
-      case GL_LINEAR:  d3dMagFilter = D3DTEXF_LINEAR; break;
-      default: UNREACHABLE();
-    }
-
-    return d3dMagFilter;
-}
-
-void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy)
-{
-    switch (minFilter)
-    {
-      case GL_NEAREST:
-        *d3dMinFilter = D3DTEXF_POINT;
-        *d3dMipFilter = D3DTEXF_NONE;
-        break;
-      case GL_LINEAR:
-        *d3dMinFilter = D3DTEXF_LINEAR;
-        *d3dMipFilter = D3DTEXF_NONE;
-        break;
-      case GL_NEAREST_MIPMAP_NEAREST:
-        *d3dMinFilter = D3DTEXF_POINT;
-        *d3dMipFilter = D3DTEXF_POINT;
-        break;
-      case GL_LINEAR_MIPMAP_NEAREST:
-        *d3dMinFilter = D3DTEXF_LINEAR;
-        *d3dMipFilter = D3DTEXF_POINT;
-        break;
-      case GL_NEAREST_MIPMAP_LINEAR:
-        *d3dMinFilter = D3DTEXF_POINT;
-        *d3dMipFilter = D3DTEXF_LINEAR;
-        break;
-      case GL_LINEAR_MIPMAP_LINEAR:
-        *d3dMinFilter = D3DTEXF_LINEAR;
-        *d3dMipFilter = D3DTEXF_LINEAR;
-        break;
-      default:
-        *d3dMinFilter = D3DTEXF_POINT;
-        *d3dMipFilter = D3DTEXF_NONE;
-        UNREACHABLE();
-    }
-
-    if (maxAnisotropy > 1.0f)
-    {
-        *d3dMinFilter = D3DTEXF_ANISOTROPIC;
-    }
-}
-
-}
-
-}
diff --git a/src/libGLESv2/renderer/generatemip.h b/src/libGLESv2/renderer/generatemip.h
index 3177a2b..a57b00d 100644
--- a/src/libGLESv2/renderer/generatemip.h
+++ b/src/libGLESv2/renderer/generatemip.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
@@ -10,260 +10,19 @@
 #ifndef LIBGLESV2_RENDERER_GENERATEMIP_H_
 #define LIBGLESV2_RENDERER_GENERATEMIP_H_
 
-#include "common/mathutil.h"
-#include "imageformats.h"
+#include "libGLESv2/renderer/imageformats.h"
+#include "libGLESv2/angletypes.h"
 
 namespace rx
 {
 
-namespace priv
-{
-
 template <typename T>
-static inline T *GetPixel(void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch)
-{
-    return reinterpret_cast<T*>(reinterpret_cast<unsigned char*>(data) + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
-}
-
-template <typename T>
-static inline const T *GetPixel(const void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch)
-{
-    return reinterpret_cast<const T*>(reinterpret_cast<const unsigned char*>(data) + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
-}
-
-template <typename T>
-static void GenerateMip_Y(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                          const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                          unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
-                          unsigned char *destData, int destRowPitch, int destDepthPitch)
-{
-    ASSERT(sourceWidth == 1);
-    ASSERT(sourceHeight > 1);
-    ASSERT(sourceDepth == 1);
-
-    for (unsigned int y = 0; y < destHeight; y++)
-    {
-        const T *src0 = GetPixel<T>(sourceData, 0, y * 2, 0, sourceRowPitch, sourceDepthPitch);
-        const T *src1 = GetPixel<T>(sourceData, 0, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
-        T *dst = GetPixel<T>(destData, 0, y, 0, destRowPitch, destDepthPitch);
-
-        T::average(dst, src0, src1);
-    }
-}
-
-template <typename T>
-static void GenerateMip_X(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                          const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                          unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
-                          unsigned char *destData, int destRowPitch, int destDepthPitch)
-{
-    ASSERT(sourceWidth > 1);
-    ASSERT(sourceHeight == 1);
-    ASSERT(sourceDepth == 1);
-
-    for (unsigned int x = 0; x < destWidth; x++)
-    {
-        const T *src0 = GetPixel<T>(sourceData, x * 2, 0, 0, sourceRowPitch, sourceDepthPitch);
-        const T *src1 = GetPixel<T>(sourceData, x * 2 + 1, 0, 0, sourceRowPitch, sourceDepthPitch);
-        T *dst = GetPixel<T>(destData, x, 0, 0, destRowPitch, destDepthPitch);
-
-        T::average(dst, src0, src1);
-    }
-}
-
-template <typename T>
-static void GenerateMip_Z(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                          const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                          unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
-                          unsigned char *destData, int destRowPitch, int destDepthPitch)
-{
-    ASSERT(sourceWidth == 1);
-    ASSERT(sourceHeight == 1);
-    ASSERT(sourceDepth > 1);
-
-    for (unsigned int z = 0; z < destDepth; z++)
-    {
-        const T *src0 = GetPixel<T>(sourceData, 0, 0, z * 2, sourceRowPitch, sourceDepthPitch);
-        const T *src1 = GetPixel<T>(sourceData, 0, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-        T *dst = GetPixel<T>(destData, 0, 0, z, destRowPitch, destDepthPitch);
-
-        T::average(dst, src0, src1);
-    }
-}
-
-template <typename T>
-static void GenerateMip_XY(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                           const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                           unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
-                           unsigned char *destData, int destRowPitch, int destDepthPitch)
-{
-    ASSERT(sourceWidth > 1);
-    ASSERT(sourceHeight > 1);
-    ASSERT(sourceDepth == 1);
-
-    for (unsigned int y = 0; y < destHeight; y++)
-    {
-        for (unsigned int x = 0; x < destWidth; x++)
-        {
-            const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, 0, sourceRowPitch, sourceDepthPitch);
-            const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
-            const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, 0, sourceRowPitch, sourceDepthPitch);
-            const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
-            T *dst = GetPixel<T>(destData, x, y, 0, destRowPitch, destDepthPitch);
-
-            T tmp0, tmp1;
-
-            T::average(&tmp0, src0, src1);
-            T::average(&tmp1, src2, src3);
-            T::average(dst, &tmp0, &tmp1);
-        }
-    }
-}
-
-template <typename T>
-static void GenerateMip_YZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                           const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                           unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
-                           unsigned char *destData, int destRowPitch, int destDepthPitch)
-{
-    ASSERT(sourceWidth == 1);
-    ASSERT(sourceHeight > 1);
-    ASSERT(sourceDepth > 1);
-
-    for (unsigned int z = 0; z < destDepth; z++)
-    {
-        for (unsigned int y = 0; y < destHeight; y++)
-        {
-            const T *src0 = GetPixel<T>(sourceData, 0, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
-            const T *src1 = GetPixel<T>(sourceData, 0, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-            const T *src2 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
-            const T *src3 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-            T *dst = GetPixel<T>(destData, 0, y, z, destRowPitch, destDepthPitch);
-
-            T tmp0, tmp1;
-
-            T::average(&tmp0, src0, src1);
-            T::average(&tmp1, src2, src3);
-            T::average(dst, &tmp0, &tmp1);
-        }
-    }
-}
-
-template <typename T>
-static void GenerateMip_XZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                           const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                           unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
-                           unsigned char *destData, int destRowPitch, int destDepthPitch)
-{
-    ASSERT(sourceWidth > 1);
-    ASSERT(sourceHeight == 1);
-    ASSERT(sourceDepth > 1);
-
-    for (unsigned int z = 0; z < destDepth; z++)
-    {
-        for (unsigned int x = 0; x < destWidth; x++)
-        {
-            const T *src0 = GetPixel<T>(sourceData, x * 2, 0, z * 2, sourceRowPitch, sourceDepthPitch);
-            const T *src1 = GetPixel<T>(sourceData, x * 2, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-            const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2, sourceRowPitch, sourceDepthPitch);
-            const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-            T *dst = GetPixel<T>(destData, x, 0, z, destRowPitch, destDepthPitch);
-
-            T tmp0, tmp1;
-
-            T::average(&tmp0, src0, src1);
-            T::average(&tmp1, src2, src3);
-            T::average(dst, &tmp0, &tmp1);
-        }
-    }
-}
-
-template <typename T>
-static void GenerateMip_XYZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                            const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                            unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
-                            unsigned char *destData, int destRowPitch, int destDepthPitch)
-{
-    ASSERT(sourceWidth > 1);
-    ASSERT(sourceHeight > 1);
-    ASSERT(sourceDepth > 1);
-
-    for (unsigned int z = 0; z < destDepth; z++)
-    {
-        for (unsigned int y = 0; y < destHeight; y++)
-        {
-            for (unsigned int x = 0; x < destWidth; x++)
-            {
-                const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
-                const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-                const T *src2 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
-                const T *src3 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-                const T *src4 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
-                const T *src5 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-                const T *src6 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
-                const T *src7 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
-                T *dst = GetPixel<T>(destData, x, y, z, destRowPitch, destDepthPitch);
-
-                T tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
-
-                T::average(&tmp0, src0, src1);
-                T::average(&tmp1, src2, src3);
-                T::average(&tmp2, src4, src5);
-                T::average(&tmp3, src6, src7);
-
-                T::average(&tmp4, &tmp0, &tmp1);
-                T::average(&tmp5, &tmp2, &tmp3);
-
-                T::average(dst, &tmp4, &tmp5);
-            }
-        }
-    }
-}
-
-
-typedef void (*MipGenerationFunction)(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                                      const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                                      unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
-                                      unsigned char *destData, int destRowPitch, int destDepthPitch);
-
-template <typename T>
-static MipGenerationFunction GetMipGenerationFunction(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth)
-{
-    unsigned char index = ((sourceWidth > 1)  ? 1 : 0) |
-                          ((sourceHeight > 1) ? 2 : 0) |
-                          ((sourceDepth > 1)  ? 4 : 0);
-
-    switch (index)
-    {
-      case 1:  return GenerateMip_X<T>;   // W x 1 x 1
-      case 2:  return GenerateMip_Y<T>;   // 1 x H x 1
-      case 3:  return GenerateMip_XY<T>;  // W x H x 1
-      case 4:  return GenerateMip_Z<T>;   // 1 x 1 x D
-      case 5:  return GenerateMip_XZ<T>;  // W x 1 x D
-      case 6:  return GenerateMip_YZ<T>;  // 1 x H x D
-      case 7:  return GenerateMip_XYZ<T>; // W x H x D
-      default: return NULL;
-    }
-}
+inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                        const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                        uint8_t *destData, size_t destRowPitch, size_t destDepthPitch);
 
 }
 
-template <typename T>
-static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
-                        const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
-                        unsigned char *destData, int destRowPitch, int destDepthPitch)
-{
-    unsigned int mipWidth = std::max(1U, sourceWidth >> 1);
-    unsigned int mipHeight = std::max(1U, sourceHeight >> 1);
-    unsigned int mipDepth = std::max(1U, sourceDepth >> 1);
-
-    priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth);
-    ASSERT(generationFunction != NULL);
-
-    generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch,
-                       mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch);
-}
-
-}
+#include "generatemip.inl"
 
 #endif // LIBGLESV2_RENDERER_GENERATEMIP_H_
diff --git a/src/libGLESv2/renderer/generatemip.inl b/src/libGLESv2/renderer/generatemip.inl
new file mode 100644
index 0000000..6788a42
--- /dev/null
+++ b/src/libGLESv2/renderer/generatemip.inl
@@ -0,0 +1,266 @@
+//
+// 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.
+//
+
+// generatemip.inl: Defines the GenerateMip function, templated on the format
+// type of the image for which mip levels are being generated.
+
+#include "common/mathutil.h"
+
+namespace rx
+{
+
+namespace priv
+{
+
+template <typename T>
+static inline T *GetPixel(uint8_t *data, size_t x, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
+{
+    return reinterpret_cast<T*>(data + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
+}
+
+template <typename T>
+static inline const T *GetPixel(const uint8_t *data, size_t x, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
+{
+    return reinterpret_cast<const T*>(data + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
+}
+
+template <typename T>
+static void GenerateMip_Y(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                          const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                          size_t destWidth, size_t destHeight, size_t destDepth,
+                          uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+    ASSERT(sourceWidth == 1);
+    ASSERT(sourceHeight > 1);
+    ASSERT(sourceDepth == 1);
+
+    for (size_t y = 0; y < destHeight; y++)
+    {
+        const T *src0 = GetPixel<T>(sourceData, 0, y * 2, 0, sourceRowPitch, sourceDepthPitch);
+        const T *src1 = GetPixel<T>(sourceData, 0, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
+        T *dst = GetPixel<T>(destData, 0, y, 0, destRowPitch, destDepthPitch);
+
+        T::average(dst, src0, src1);
+    }
+}
+
+template <typename T>
+static void GenerateMip_X(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                          const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                          size_t destWidth, size_t destHeight, size_t destDepth,
+                          uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+    ASSERT(sourceWidth > 1);
+    ASSERT(sourceHeight == 1);
+    ASSERT(sourceDepth == 1);
+
+    for (size_t x = 0; x < destWidth; x++)
+    {
+        const T *src0 = GetPixel<T>(sourceData, x * 2, 0, 0, sourceRowPitch, sourceDepthPitch);
+        const T *src1 = GetPixel<T>(sourceData, x * 2 + 1, 0, 0, sourceRowPitch, sourceDepthPitch);
+        T *dst = GetPixel<T>(destData, x, 0, 0, destRowPitch, destDepthPitch);
+
+        T::average(dst, src0, src1);
+    }
+}
+
+template <typename T>
+static void GenerateMip_Z(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                          const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                          size_t destWidth, size_t destHeight, size_t destDepth,
+                          uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+    ASSERT(sourceWidth == 1);
+    ASSERT(sourceHeight == 1);
+    ASSERT(sourceDepth > 1);
+
+    for (size_t z = 0; z < destDepth; z++)
+    {
+        const T *src0 = GetPixel<T>(sourceData, 0, 0, z * 2, sourceRowPitch, sourceDepthPitch);
+        const T *src1 = GetPixel<T>(sourceData, 0, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+        T *dst = GetPixel<T>(destData, 0, 0, z, destRowPitch, destDepthPitch);
+
+        T::average(dst, src0, src1);
+    }
+}
+
+template <typename T>
+static void GenerateMip_XY(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                           const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                           size_t destWidth, size_t destHeight, size_t destDepth,
+                           uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+    ASSERT(sourceWidth > 1);
+    ASSERT(sourceHeight > 1);
+    ASSERT(sourceDepth == 1);
+
+    for (size_t y = 0; y < destHeight; y++)
+    {
+        for (size_t x = 0; x < destWidth; x++)
+        {
+            const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, 0, sourceRowPitch, sourceDepthPitch);
+            const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
+            const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, 0, sourceRowPitch, sourceDepthPitch);
+            const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
+            T *dst = GetPixel<T>(destData, x, y, 0, destRowPitch, destDepthPitch);
+
+            T tmp0, tmp1;
+
+            T::average(&tmp0, src0, src1);
+            T::average(&tmp1, src2, src3);
+            T::average(dst, &tmp0, &tmp1);
+        }
+    }
+}
+
+template <typename T>
+static void GenerateMip_YZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                           const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                           size_t destWidth, size_t destHeight, size_t destDepth,
+                           uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+    ASSERT(sourceWidth == 1);
+    ASSERT(sourceHeight > 1);
+    ASSERT(sourceDepth > 1);
+
+    for (size_t z = 0; z < destDepth; z++)
+    {
+        for (size_t y = 0; y < destHeight; y++)
+        {
+            const T *src0 = GetPixel<T>(sourceData, 0, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
+            const T *src1 = GetPixel<T>(sourceData, 0, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+            const T *src2 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
+            const T *src3 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+            T *dst = GetPixel<T>(destData, 0, y, z, destRowPitch, destDepthPitch);
+
+            T tmp0, tmp1;
+
+            T::average(&tmp0, src0, src1);
+            T::average(&tmp1, src2, src3);
+            T::average(dst, &tmp0, &tmp1);
+        }
+    }
+}
+
+template <typename T>
+static void GenerateMip_XZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                           const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                           size_t destWidth, size_t destHeight, size_t destDepth,
+                           uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+    ASSERT(sourceWidth > 1);
+    ASSERT(sourceHeight == 1);
+    ASSERT(sourceDepth > 1);
+
+    for (size_t z = 0; z < destDepth; z++)
+    {
+        for (size_t x = 0; x < destWidth; x++)
+        {
+            const T *src0 = GetPixel<T>(sourceData, x * 2, 0, z * 2, sourceRowPitch, sourceDepthPitch);
+            const T *src1 = GetPixel<T>(sourceData, x * 2, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+            const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2, sourceRowPitch, sourceDepthPitch);
+            const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+            T *dst = GetPixel<T>(destData, x, 0, z, destRowPitch, destDepthPitch);
+
+            T tmp0, tmp1;
+
+            T::average(&tmp0, src0, src1);
+            T::average(&tmp1, src2, src3);
+            T::average(dst, &tmp0, &tmp1);
+        }
+    }
+}
+
+template <typename T>
+static void GenerateMip_XYZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                            const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                            size_t destWidth, size_t destHeight, size_t destDepth,
+                            uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+    ASSERT(sourceWidth > 1);
+    ASSERT(sourceHeight > 1);
+    ASSERT(sourceDepth > 1);
+
+    for (size_t z = 0; z < destDepth; z++)
+    {
+        for (size_t y = 0; y < destHeight; y++)
+        {
+            for (size_t x = 0; x < destWidth; x++)
+            {
+                const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
+                const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+                const T *src2 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
+                const T *src3 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+                const T *src4 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
+                const T *src5 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+                const T *src6 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
+                const T *src7 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+                T *dst = GetPixel<T>(destData, x, y, z, destRowPitch, destDepthPitch);
+
+                T tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
+
+                T::average(&tmp0, src0, src1);
+                T::average(&tmp1, src2, src3);
+                T::average(&tmp2, src4, src5);
+                T::average(&tmp3, src6, src7);
+
+                T::average(&tmp4, &tmp0, &tmp1);
+                T::average(&tmp5, &tmp2, &tmp3);
+
+                T::average(dst, &tmp4, &tmp5);
+            }
+        }
+    }
+}
+
+
+typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                                      const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                                      size_t destWidth, size_t destHeight, size_t destDepth,
+                                      uint8_t *destData, size_t destRowPitch, size_t destDepthPitch);
+
+template <typename T>
+static MipGenerationFunction GetMipGenerationFunction(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth)
+{
+    uint8_t index = ((sourceWidth > 1)  ? 1 : 0) |
+                    ((sourceHeight > 1) ? 2 : 0) |
+                    ((sourceDepth > 1)  ? 4 : 0);
+
+    switch (index)
+    {
+      case 0: return NULL;
+      case 1: return GenerateMip_X<T>;   // W x 1 x 1
+      case 2: return GenerateMip_Y<T>;   // 1 x H x 1
+      case 3: return GenerateMip_XY<T>;  // W x H x 1
+      case 4: return GenerateMip_Z<T>;   // 1 x 1 x D
+      case 5: return GenerateMip_XZ<T>;  // W x 1 x D
+      case 6: return GenerateMip_YZ<T>;  // 1 x H x D
+      case 7: return GenerateMip_XYZ<T>; // W x H x D
+    }
+
+    UNREACHABLE();
+    return NULL;
+}
+
+}
+
+template <typename T>
+inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+                        const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+                        uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+    size_t mipWidth = std::max<size_t>(1, sourceWidth >> 1);
+    size_t mipHeight = std::max<size_t>(1, sourceHeight >> 1);
+    size_t mipDepth = std::max<size_t>(1, sourceDepth >> 1);
+
+    priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth);
+    ASSERT(generationFunction != NULL);
+
+    generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch,
+                       mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch);
+}
+
+}
diff --git a/src/libGLESv2/renderer/imageformats.h b/src/libGLESv2/renderer/imageformats.h
index 1fd93fe..2140a9e 100644
--- a/src/libGLESv2/renderer/imageformats.h
+++ b/src/libGLESv2/renderer/imageformats.h
@@ -10,7 +10,7 @@
 #ifndef LIBGLESV2_RENDERER_IMAGEFORMATS_H_
 #define LIBGLESV2_RENDERER_IMAGEFORMATS_H_
 
-#include "libGLESv2/angletypes.h"
+#include "common/mathutil.h"
 
 namespace rx
 {
diff --git a/src/libGLESv2/renderer/loadimage.cpp b/src/libGLESv2/renderer/loadimage.cpp
index 6e2d246..1986191 100644
--- a/src/libGLESv2/renderer/loadimage.cpp
+++ b/src/libGLESv2/renderer/loadimage.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// Copyright (c) 0013 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,20 +11,64 @@
 namespace rx
 {
 
-void loadAlphaDataToBGRA(int width, int height, int depth,
-                         const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                         void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadA8ToRGBA8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
+            {
+                dest[x] = static_cast<uint32_t>(source[x]) << 24;
+            }
+        }
+    }
+}
+
+void LoadA8ToBGRA8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    // Same as loading to RGBA
+    LoadA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
+}
+
+void LoadA32FToRGBA32F(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    for (size_t z = 0; z < depth; z++)
+    {
+        for (size_t y = 0; y < height; y++)
+        {
+            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
+            float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
+            {
+                dest[4 * x + 0] = 0.0f;
+                dest[4 * x + 1] = 0.0f;
+                dest[4 * x + 2] = 0.0f;
+                dest[4 * x + 3] = source[x];
+            }
+        }
+    }
+}
+
+void LoadA16FToRGBA16F(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    for (size_t z = 0; z < depth; z++)
+    {
+        for (size_t y = 0; y < height; y++)
+        {
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[4 * x + 0] = 0;
                 dest[4 * x + 1] = 0;
@@ -36,104 +79,17 @@
     }
 }
 
-void loadAlphaDataToNative(int width, int height, int depth,
-                           const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                           void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadL8ToRGBA8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            memcpy(dest, source, width);
-        }
-    }
-}
-
-void loadAlphaFloatDataToRGBA(int width, int height, int depth,
-                              const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                              void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const float *source = NULL;
-    float *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
-            {
-                dest[4 * x + 0] = 0;
-                dest[4 * x + 1] = 0;
-                dest[4 * x + 2] = 0;
-                dest[4 * x + 3] = source[x];
-            }
-        }
-    }
-}
-
-void loadAlphaHalfFloatDataToRGBA(int width, int height, int depth,
-                                  const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                  void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned short *source = NULL;
-    unsigned short *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
-            {
-                dest[4 * x + 0] = 0;
-                dest[4 * x + 1] = 0;
-                dest[4 * x + 2] = 0;
-                dest[4 * x + 3] = source[x];
-            }
-        }
-    }
-}
-
-void loadLuminanceDataToNative(int width, int height, int depth,
-                               const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                               void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            memcpy(dest, source, width);
-        }
-    }
-}
-
-void loadLuminanceDataToBGRA(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[4 * x + 0] = source[x];
                 dest[4 * x + 1] = source[x];
@@ -144,20 +100,25 @@
     }
 }
 
-void loadLuminanceFloatDataToRGBA(int width, int height, int depth,
-                                  const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                  void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadL8ToBGRA8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const float *source = NULL;
-    float *dest = NULL;
+    // Same as loading to RGBA
+    LoadL8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
+}
 
-    for (int z = 0; z < depth; z++)
+void LoadL32FToRGBA32F(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
+            float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[4 * x + 0] = source[x];
                 dest[4 * x + 1] = source[x];
@@ -168,43 +129,17 @@
     }
 }
 
-void loadLuminanceFloatDataToRGB(int width, int height, int depth,
-                                 const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                 void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadL16FToRGBA16F(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const float *source = NULL;
-    float *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
-            {
-                dest[3 * x + 0] = source[x];
-                dest[3 * x + 1] = source[x];
-                dest[3 * x + 2] = source[x];
-            }
-        }
-    }
-}
-
-void loadLuminanceHalfFloatDataToRGBA(int width, int height, int depth,
-                                      const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                      void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned short *source = NULL;
-    unsigned short *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[4 * x + 0] = source[x];
                 dest[4 * x + 1] = source[x];
@@ -215,112 +150,88 @@
     }
 }
 
-void loadLuminanceAlphaDataToNative(int width, int height, int depth,
-                                    const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                    void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadLA8ToRGBA8(size_t width, size_t height, size_t depth,
+                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            memcpy(dest, source, width * 2);
-        }
-    }
-}
-
-void loadLuminanceAlphaDataToBGRA(int width, int height, int depth,
-                                  const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                  void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                dest[4 * x + 0] = source[2*x+0];
-                dest[4 * x + 1] = source[2*x+0];
-                dest[4 * x + 2] = source[2*x+0];
-                dest[4 * x + 3] = source[2*x+1];
+                dest[4 * x + 0] = source[2 * x + 0];
+                dest[4 * x + 1] = source[2 * x + 0];
+                dest[4 * x + 2] = source[2 * x + 0];
+                dest[4 * x + 3] = source[2 * x + 1];
             }
         }
     }
 }
 
-void loadLuminanceAlphaFloatDataToRGBA(int width, int height, int depth,
-                                       const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                       void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadLA8ToBGRA8(size_t width, size_t height, size_t depth,
+                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const float *source = NULL;
-    float *dest = NULL;
+    // Same as loading to RGBA
+    LoadLA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
+}
 
-    for (int z = 0; z < depth; z++)
+void LoadLA32FToRGBA32F(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
+            float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                dest[4 * x + 0] = source[2*x+0];
-                dest[4 * x + 1] = source[2*x+0];
-                dest[4 * x + 2] = source[2*x+0];
-                dest[4 * x + 3] = source[2*x+1];
+                dest[4 * x + 0] = source[2 * x + 0];
+                dest[4 * x + 1] = source[2 * x + 0];
+                dest[4 * x + 2] = source[2 * x + 0];
+                dest[4 * x + 3] = source[2 * x + 1];
             }
         }
     }
 }
 
-void loadLuminanceAlphaHalfFloatDataToRGBA(int width, int height, int depth,
-                                           const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                           void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadLA16FToRGBA16F(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned short *source = NULL;
-    unsigned short *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                dest[4 * x + 0] = source[2*x+0];
-                dest[4 * x + 1] = source[2*x+0];
-                dest[4 * x + 2] = source[2*x+0];
-                dest[4 * x + 3] = source[2*x+1];
+                dest[4 * x + 0] = source[2 * x + 0];
+                dest[4 * x + 1] = source[2 * x + 0];
+                dest[4 * x + 2] = source[2 * x + 0];
+                dest[4 * x + 3] = source[2 * x + 1];
             }
         }
     }
 }
 
-void loadRGBUByteDataToBGRX(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth,
+                     const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[4 * x + 0] = source[x * 3 + 2];
                 dest[4 * x + 1] = source[x * 3 + 1];
@@ -331,20 +242,17 @@
     }
 }
 
-void loadRGUByteDataToBGRX(int width, int height, int depth,
-                           const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                           void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRG8ToBGRX8(size_t width, size_t height, size_t depth,
+                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[4 * x + 0] = 0x00;
                 dest[4 * x + 1] = source[x * 2 + 1];
@@ -355,20 +263,17 @@
     }
 }
 
-void loadRUByteDataToBGRX(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadR8ToBGRX8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[4 * x + 0] = 0x00;
                 dest[4 * x + 1] = 0x00;
@@ -379,228 +284,82 @@
     }
 }
 
-void loadRGBUByteDataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                dest[4 * x + 0] = source[x * 3 + 0];
-                dest[4 * x + 1] = source[x * 3 + 1];
-                dest[4 * x + 2] = source[x * 3 + 2];
+                uint16_t rgb = source[x];
+                dest[4 * x + 0] = ((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2);
+                dest[4 * x + 1] = ((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9);
+                dest[4 * x + 2] = ((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13);
                 dest[4 * x + 3] = 0xFF;
             }
         }
     }
 }
 
-void loadRGBSByteDataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadR5G6B5ToRGBA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const char *source = NULL;
-    char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                dest[4 * x + 0] = source[x * 3 + 0];
-                dest[4 * x + 1] = source[x * 3 + 1];
-                dest[4 * x + 2] = source[x * 3 + 2];
-                dest[4 * x + 3] = 0x7F;
-            }
-        }
-    }
-}
-
-void loadRGB565DataToBGRA(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned short *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
-            {
-                unsigned short rgba = source[x];
-                dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
-                dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
-                dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+                uint16_t rgb = source[x];
+                dest[4 * x + 0] = ((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13);
+                dest[4 * x + 1] = ((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9);
+                dest[4 * x + 2] = ((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2);
                 dest[4 * x + 3] = 0xFF;
             }
         }
     }
 }
 
-void loadRGB565DataToRGBA(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned short *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                unsigned short rgba = source[x];
-                dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
-                dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
-                dest[4 * x + 2] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
-                dest[4 * x + 3] = 0xFF;
-            }
-        }
-    }
-}
-
-void loadRGBFloatDataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const float *source = NULL;
-    float *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
-            {
-                dest[4 * x + 0] = source[x * 3 + 0];
-                dest[4 * x + 1] = source[x * 3 + 1];
-                dest[4 * x + 2] = source[x * 3 + 2];
-                dest[4 * x + 3] = 1.0f;
-            }
-        }
-    }
-}
-
-void loadRGBFloatDataToNative(int width, int height, int depth,
-                              const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                              void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const float *source = NULL;
-    float *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
-            memcpy(dest, source, width * 12);
-        }
-    }
-}
-
-void loadRGBHalfFloatDataToRGBA(int width, int height, int depth,
-                                const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned short *source = NULL;
-    unsigned short *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
-            {
-                dest[4 * x + 0] = source[x * 3 + 0];
-                dest[4 * x + 1] = source[x * 3 + 1];
-                dest[4 * x + 2] = source[x * 3 + 2];
-                dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
-            }
-        }
-    }
-}
-
-void loadRGBAUByteDataToBGRA(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned int *source = NULL;
-    unsigned int *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
-            {
-                unsigned int rgba = source[x];
+                uint32_t rgba = source[x];
                 dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
             }
         }
     }
 }
 
-void loadRGBAUByteDataToNative(int width, int height, int depth,
-                               const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                               void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGBA4ToBGRA8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned int *source = NULL;
-    unsigned int *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            memcpy(dest, source, width * 4);
-        }
-    }
-}
-
-void loadRGBA4444DataToBGRA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned short *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                unsigned short rgba = source[x];
+                uint16_t rgba = source[x];
                 dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
                 dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
                 dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
@@ -610,22 +369,19 @@
     }
 }
 
-void loadRGBA4444DataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGBA4ToRGBA8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned short *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                unsigned short rgba = source[x];
+                uint16_t rgba = source[x];
                 dest[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
                 dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
                 dest[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
@@ -635,22 +391,41 @@
     }
 }
 
-void loadRGBA5551DataToBGRA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned short *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                unsigned short rgba = source[x];
+                uint16_t bgra = source[x];
+                dest[4 * x + 0] = ((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12);
+                dest[4 * x + 1] = ((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8);
+                dest[4 * x + 2] = ((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4);
+                dest[4 * x + 3] = ((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0);
+            }
+        }
+    }
+}
+
+void LoadRGB5A1ToBGRA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    for (size_t z = 0; z < depth; z++)
+    {
+        for (size_t y = 0; y < height; y++)
+        {
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
+            {
+                uint16_t rgba = source[x];
                 dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
                 dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
                 dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
@@ -659,22 +434,20 @@
         }
     }
 }
-void loadRGBA5551DataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned short *source = NULL;
-    unsigned char *dest = NULL;
 
-    for (int z = 0; z < depth; z++)
+void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                unsigned short rgba = source[x];
+                uint16_t rgba = source[x];
                 dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
                 dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
                 dest[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
@@ -684,95 +457,42 @@
     }
 }
 
-void loadRGBAFloatDataToRGBA(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+
+void LoadBGR5A1ToBGRA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const float *source = NULL;
-    float *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
-            memcpy(dest, source, width * 16);
-        }
-    }
-}
-
-void loadRGBAHalfFloatDataToRGBA(int width, int height, int depth,
-                                 const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                 void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            memcpy(dest, source, width * 8);
-        }
-    }
-}
-
-void loadBGRADataToBGRA(int width, int height, int depth,
-                        const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                        void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned char *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-            memcpy(dest, source, width*4);
-        }
-    }
-}
-
-void loadRGBA2101010ToNative(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned int *source = NULL;
-    unsigned int *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
-            memcpy(dest, source, width * sizeof(unsigned int));
-        }
-    }
-}
-
-void loadRGBA2101010ToRGBA(int width, int height, int depth,
-                           const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                           void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned int *source = NULL;
-    unsigned char *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                unsigned int rgba = source[x];
+                uint16_t bgra = source[x];
+                dest[4 * x + 0] = ((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13);
+                dest[4 * x + 1] = ((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8);
+                dest[4 * x + 2] = ((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3);
+                dest[4 * x + 3] = (bgra & 0x0001) ? 0xFF : 0;
+            }
+        }
+    }
+}
+
+void LoadRGB10A2ToRGBA8(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    for (size_t z = 0; z < depth; z++)
+    {
+        for (size_t y = 0; y < height; y++)
+        {
+            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
+            {
+                uint32_t rgba = source[x];
                 dest[4 * x + 0] = (rgba & 0x000003FF) >>  2;
                 dest[4 * x + 1] = (rgba & 0x000FFC00) >> 12;
                 dest[4 * x + 2] = (rgba & 0x3FF00000) >> 22;
@@ -782,21 +502,17 @@
     }
 }
 
-void loadRGBHalfFloatDataTo999E5(int width, int height, int depth,
-                                 const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                 void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGB16FToRGB9E5(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned short *source = NULL;
-    unsigned int *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]),
                                                       gl::float16ToFloat32(source[x * 3 + 1]),
@@ -806,21 +522,17 @@
     }
 }
 
-void loadRGBFloatDataTo999E5(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGB32FToRGB9E5(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const float *source = NULL;
-    unsigned int *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1], source[x * 3 + 2]);
             }
@@ -828,21 +540,17 @@
     }
 }
 
-void loadRGBHalfFloatDataTo111110Float(int width, int height, int depth,
-                                       const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                       void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGB16FToRG11B10F(size_t width, size_t height, size_t depth,
+                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned short *source = NULL;
-    unsigned int *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) <<  0) |
                           (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) |
@@ -852,21 +560,17 @@
     }
 }
 
-void loadRGBFloatDataTo111110Float(int width, int height, int depth,
-                                   const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                   void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGB32FToRG11B10F(size_t width, size_t height, size_t depth,
+                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const float *source = NULL;
-    unsigned int *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) <<  0) |
                           (gl::float32ToFloat11(source[x * 3 + 1]) << 11) |
@@ -876,46 +580,37 @@
     }
 }
 
-
-void loadG8R24DataToR24G8(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadG8R24ToR24G8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned int *source = NULL;
-    unsigned int *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<const unsigned int>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
-                unsigned int d = source[x] >> 8;
-                unsigned int s = source[x] & 0xFF;
+                uint32_t d = source[x] >> 8;
+                uint8_t  s = source[x] & 0xFF;
                 dest[x] = d | (s << 24);
             }
         }
     }
 }
 
-void loadFloatRGBDataToHalfFloatRGBA(int width, int height, int depth,
-                                     const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                     void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGB32FToRGBA16F(size_t width, size_t height, size_t depth,
+                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const float *source = NULL;
-    unsigned short *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]);
                 dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]);
@@ -926,21 +621,17 @@
     }
 }
 
-void loadUintDataToUshort(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadR32ToR16(size_t width, size_t height, size_t depth,
+                  const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                  uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
 {
-    const unsigned int *source = NULL;
-    unsigned short *dest = NULL;
-
-    for (int z = 0; z < depth; z++)
+    for (size_t z = 0; z < depth; z++)
     {
-        for (int y = 0; y < height; y++)
+        for (size_t y = 0; y < height; y++)
         {
-            source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
+            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
             {
                 dest[x] = source[x] >> 16;
             }
@@ -948,4 +639,23 @@
     }
 }
 
+void LoadR32ToR24G8(size_t width, size_t height, size_t depth,
+                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    for (size_t z = 0; z < depth; z++)
+    {
+        for (size_t y = 0; y < height; y++)
+        {
+            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+            for (size_t x = 0; x < width; x++)
+            {
+                dest[x] = source[x] >> 8;
+            }
+        }
+    }
+}
+
 }
diff --git a/src/libGLESv2/renderer/loadimage.h b/src/libGLESv2/renderer/loadimage.h
index 537a5e4..bcdff24 100644
--- a/src/libGLESv2/renderer/loadimage.h
+++ b/src/libGLESv2/renderer/loadimage.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.
 //
@@ -9,335 +9,185 @@
 #ifndef LIBGLESV2_RENDERER_LOADIMAGE_H_
 #define LIBGLESV2_RENDERER_LOADIMAGE_H_
 
-#include "common/mathutil.h"
+#include "libGLESv2/angletypes.h"
+
+#include <cstdint>
 
 namespace rx
 {
 
-template <typename T>
-inline static T *offsetDataPointer(void *data, int y, int z, int rowPitch, int depthPitch)
-{
-    return reinterpret_cast<T*>(reinterpret_cast<unsigned char*>(data) + (y * rowPitch) + (z * depthPitch));
-}
+void LoadA8ToRGBA8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadA8ToBGRA8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadA32FToRGBA32F(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadA16FToRGBA16F(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadL8ToRGBA8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadL8ToBGRA8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadL32FToRGBA32F(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadL16FToRGBA16F(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadLA8ToRGBA8(size_t width, size_t height, size_t depth,
+                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadLA8ToBGRA8(size_t width, size_t height, size_t depth,
+                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadLA32FToRGBA32F(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadLA16FToRGBA16F(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth,
+                     const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRG8ToBGRX8(size_t width, size_t height, size_t depth,
+                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadR8ToBGRX8(size_t width, size_t height, size_t depth,
+                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadR5G6B5ToRGBA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
+                           const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                           uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGBA4ToBGRA8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGBA4ToRGBA8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB5A1ToBGRA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadBGR5A1ToBGRA8(size_t width, size_t height, size_t depth,
+                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB10A2ToRGBA8(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB16FToRGB9E5(size_t width, size_t height, size_t depth,
+                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB32FToRGB9E5(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB16FToRG11B10F(size_t width, size_t height, size_t depth,
+                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB32FToRG11B10F(size_t width, size_t height, size_t depth,
+                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadG8R24ToR24G8(size_t width, size_t height, size_t depth,
+                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+template <typename type, size_t componentCount>
+inline void LoadToNative(size_t width, size_t height, size_t depth,
+                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+template <typename type, uint32_t fourthComponentBits>
+inline void LoadToNative3To4(size_t width, size_t height, size_t depth,
+                             const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                             uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+template <size_t componentCount>
+inline void Load32FTo16F(size_t width, size_t height, size_t depth,
+                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadRGB32FToRGBA16F(size_t width, size_t height, size_t depth,
+                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+template <size_t blockWidth, size_t blockHeight, size_t blockSize>
+inline void LoadCompressedToNative(size_t width, size_t height, size_t depth,
+                                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadR32ToR16(size_t width, size_t height, size_t depth,
+                  const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                  uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+template <typename type, uint32_t firstBits, uint32_t secondBits, uint32_t thirdBits, uint32_t fourthBits>
+inline void Initialize4ComponentData(size_t width, size_t height, size_t depth,
+                                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+void LoadR32ToR24G8(size_t width, size_t height, size_t depth,
+                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
 
 template <typename T>
-inline static const T *offsetDataPointer(const void *data, int y, int z, int rowPitch, int depthPitch)
-{
-    return reinterpret_cast<const T*>(reinterpret_cast<const unsigned char*>(data) + (y * rowPitch) + (z * depthPitch));
-}
+inline T *OffsetDataPointer(uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch);
 
-void loadAlphaDataToBGRA(int width, int height, int depth,
-                         const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                         void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadAlphaDataToNative(int width, int height, int depth,
-                           const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                           void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadAlphaDataToBGRASSE2(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadAlphaFloatDataToRGBA(int width, int height, int depth,
-                              const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                              void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadAlphaHalfFloatDataToRGBA(int width, int height, int depth,
-                                  const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                  void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceDataToNative(int width, int height, int depth,
-                               const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                               void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceDataToBGRA(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceFloatDataToRGBA(int width, int height, int depth,
-                                  const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                  void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceFloatDataToRGB(int width, int height, int depth,
-                                 const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                 void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceHalfFloatDataToRGBA(int width, int height, int depth,
-                                      const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                      void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceAlphaDataToNative(int width, int height, int depth,
-                                    const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                    void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceAlphaDataToBGRA(int width, int height, int depth,
-                                  const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                  void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceAlphaFloatDataToRGBA(int width, int height, int depth,
-                                       const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                       void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadLuminanceAlphaHalfFloatDataToRGBA(int width, int height, int depth,
-                                           const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                           void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBUByteDataToBGRX(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGUByteDataToBGRX(int width, int height, int depth,
-                           const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                           void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRUByteDataToBGRX(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBUByteDataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBSByteDataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGB565DataToBGRA(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGB565DataToRGBA(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBFloatDataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBFloatDataToNative(int width, int height, int depth,
-                              const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                              void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBHalfFloatDataToRGBA(int width, int height, int depth,
-                                const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBAUByteDataToBGRASSE2(int width, int height, int depth,
-                                 const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                 void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBAUByteDataToBGRA(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBAUByteDataToNative(int width, int height, int depth,
-                               const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                               void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBA4444DataToBGRA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBA4444DataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBA5551DataToBGRA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBA5551DataToRGBA(int width, int height, int depth,
-                            const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                            void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBAFloatDataToRGBA(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBAHalfFloatDataToRGBA(int width, int height, int depth,
-                                 const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                 void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadBGRADataToBGRA(int width, int height, int depth,
-                        const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                        void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBA2101010ToNative(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBA2101010ToRGBA(int width, int height, int depth,
-                           const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                           void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBHalfFloatDataTo999E5(int width, int height, int depth,
-                                 const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                 void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBFloatDataTo999E5(int width, int height, int depth,
-                             const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                             void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBHalfFloatDataTo111110Float(int width, int height, int depth,
-                                       const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                       void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadRGBFloatDataTo111110Float(int width, int height, int depth,
-                                   const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                   void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-void loadG8R24DataToR24G8(int width, int height, int depth,
-                        const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                        void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-template <typename type, unsigned int componentCount>
-void loadToNative(int width, int height, int depth,
-                  const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                  void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const unsigned int rowSize = width * sizeof(type) * componentCount;
-    const unsigned int layerSize = rowSize * height;
-    const unsigned int imageSize = layerSize * depth;
-
-    if (layerSize == inputDepthPitch && layerSize == outputDepthPitch)
-    {
-        ASSERT(rowSize == inputRowPitch && rowSize == outputRowPitch);
-        memcpy(output, input, imageSize);
-    }
-    else if (rowSize == inputRowPitch && rowSize == outputRowPitch)
-    {
-        for (int z = 0; z < depth; z++)
-        {
-            const type *source = offsetDataPointer<type>(input, 0, z, inputRowPitch, inputDepthPitch);
-            type *dest = offsetDataPointer<type>(output, 0, z, outputRowPitch, outputDepthPitch);
-
-            memcpy(dest, source, layerSize);
-        }
-    }
-    else
-    {
-        for (int z = 0; z < depth; z++)
-        {
-            for (int y = 0; y < height; y++)
-            {
-                const type *source = offsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch);
-                type *dest = offsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
-                memcpy(dest, source, width * sizeof(type) * componentCount);
-            }
-        }
-    }
-}
-
-template <typename type, unsigned int fourthComponentBits>
-void loadToNative3To4(int width, int height, int depth,
-                      const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                      void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const type *source = NULL;
-    type *dest = NULL;
-
-    const unsigned int fourthBits = fourthComponentBits;
-    const type fourthValue = *reinterpret_cast<const type*>(&fourthBits);
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
-            {
-                dest[x * 4 + 0] = source[x * 3 + 0];
-                dest[x * 4 + 1] = source[x * 3 + 1];
-                dest[x * 4 + 2] = source[x * 3 + 2];
-                dest[x * 4 + 3] = fourthValue;
-            }
-        }
-    }
-}
-
-template <unsigned int componentCount>
-void loadFloatDataToHalfFloat(int width, int height, int depth,
-                              const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                              void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    const float *source = NULL;
-    unsigned short *dest = NULL;
-
-    const int elementWidth = componentCount * width;
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
-            dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < elementWidth; x++)
-            {
-                dest[x] = gl::float32ToFloat16(source[x]);
-            }
-        }
-    }
-}
-
-void loadFloatRGBDataToHalfFloatRGBA(int width, int height, int depth,
-                                     const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                     void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-template <unsigned int blockWidth, unsigned int blockHeight, unsigned int blockSize>
-void loadCompressedBlockDataToNative(int width, int height, int depth,
-                                     const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                                     void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    int columns = (width + (blockWidth - 1)) / blockWidth;
-    int rows = (height + (blockHeight - 1)) / blockHeight;
-
-    for (int z = 0; z < depth; ++z)
-    {
-        for (int y = 0; y < rows; ++y)
-        {
-            void *source = (void*)((char*)input + y * inputRowPitch + z * inputDepthPitch);
-            void *dest = (void*)((char*)output + y * outputRowPitch + z * outputDepthPitch);
-
-            memcpy(dest, source, columns * blockSize);
-        }
-    }
-}
-
-void loadUintDataToUshort(int width, int height, int depth,
-                          const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-                          void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
-
-template <typename type, unsigned int firstBits, unsigned int secondBits, unsigned int thirdBits, unsigned int fourthBits>
-void initialize4ComponentData(int width, int height, int depth,
-                              void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
-{
-    unsigned int writeBits[4] = { firstBits, secondBits, thirdBits, fourthBits };
-    type writeValues[4] = { *reinterpret_cast<const type*>(&writeBits[0]),
-                            *reinterpret_cast<const type*>(&writeBits[1]),
-                            *reinterpret_cast<const type*>(&writeBits[2]),
-                            *reinterpret_cast<const type*>(&writeBits[3]) };
-
-    for (int z = 0; z < depth; z++)
-    {
-        for (int y = 0; y < height; y++)
-        {
-            type* destRow = offsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
-
-            for (int x = 0; x < width; x++)
-            {
-                type* destPixel = destRow + x * 4;
-
-                // This could potentially be optimized by generating an entire row of initialization
-                // data and copying row by row instead of pixel by pixel.
-                memcpy(destPixel, writeValues, sizeof(type) * 4);
-            }
-        }
-    }
-}
+template <typename T>
+inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch);
 
 }
 
+#include "loadimage.inl"
+
 #endif // LIBGLESV2_RENDERER_LOADIMAGE_H_
diff --git a/src/libGLESv2/renderer/loadimage.inl b/src/libGLESv2/renderer/loadimage.inl
new file mode 100644
index 0000000..abd0a36
--- /dev/null
+++ b/src/libGLESv2/renderer/loadimage.inl
@@ -0,0 +1,156 @@
+//
+// 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/mathutil.h"
+
+namespace rx
+{
+
+template <typename T>
+inline T *OffsetDataPointer(uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
+{
+    return reinterpret_cast<T*>(data + (y * rowPitch) + (z * depthPitch));
+}
+
+template <typename T>
+inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
+{
+    return reinterpret_cast<const T*>(data + (y * rowPitch) + (z * depthPitch));
+}
+
+template <typename type, size_t componentCount>
+inline void LoadToNative(size_t width, size_t height, size_t depth,
+                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    const size_t rowSize = width * sizeof(type) * componentCount;
+    const size_t layerSize = rowSize * height;
+    const size_t imageSize = layerSize * depth;
+
+    if (layerSize == inputDepthPitch && layerSize == outputDepthPitch)
+    {
+        ASSERT(rowSize == inputRowPitch && rowSize == outputRowPitch);
+        memcpy(output, input, imageSize);
+    }
+    else if (rowSize == inputRowPitch && rowSize == outputRowPitch)
+    {
+        for (size_t z = 0; z < depth; z++)
+        {
+            const type *source = OffsetDataPointer<type>(input, 0, z, inputRowPitch, inputDepthPitch);
+            type *dest = OffsetDataPointer<type>(output, 0, z, outputRowPitch, outputDepthPitch);
+
+            memcpy(dest, source, layerSize);
+        }
+    }
+    else
+    {
+        for (size_t z = 0; z < depth; z++)
+        {
+            for (size_t y = 0; y < height; y++)
+            {
+                const type *source = OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch);
+                type *dest = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
+                memcpy(dest, source, width * sizeof(type) * componentCount);
+            }
+        }
+    }
+}
+
+template <typename type, uint32_t fourthComponentBits>
+inline void LoadToNative3To4(size_t width, size_t height, size_t depth,
+                             const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                             uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    const type fourthValue = gl::bitCast<type>(fourthComponentBits);
+
+    for (size_t z = 0; z < depth; z++)
+    {
+        for (size_t y = 0; y < height; y++)
+        {
+            const type *source = OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch);
+            type *dest = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
+            {
+                dest[x * 4 + 0] = source[x * 3 + 0];
+                dest[x * 4 + 1] = source[x * 3 + 1];
+                dest[x * 4 + 2] = source[x * 3 + 2];
+                dest[x * 4 + 3] = fourthValue;
+            }
+        }
+    }
+}
+
+template <size_t componentCount>
+inline void Load32FTo16F(size_t width, size_t height, size_t depth,
+                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    const size_t elementWidth = componentCount * width;
+
+    for (size_t z = 0; z < depth; z++)
+    {
+        for (size_t y = 0; y < height; y++)
+        {
+            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+            for (size_t x = 0; x < elementWidth; x++)
+            {
+                dest[x] = gl::float32ToFloat16(source[x]);
+            }
+        }
+    }
+}
+
+template <size_t blockWidth, size_t blockHeight, size_t blockSize>
+inline void LoadCompressedToNative(size_t width, size_t height, size_t depth,
+                                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    const size_t columns = (width + (blockWidth - 1)) / blockWidth;
+    const size_t rows = (height + (blockHeight - 1)) / blockHeight;
+
+    for (size_t z = 0; z < depth; ++z)
+    {
+        for (size_t y = 0; y < rows; ++y)
+        {
+            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+            memcpy(dest, source, columns * blockSize);
+        }
+    }
+}
+
+template <typename type, uint32_t firstBits, uint32_t secondBits, uint32_t thirdBits, uint32_t fourthBits>
+inline void Initialize4ComponentData(size_t width, size_t height, size_t depth,
+                                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    type writeValues[4] =
+    {
+        gl::bitCast<type>(firstBits),
+        gl::bitCast<type>(secondBits),
+        gl::bitCast<type>(thirdBits),
+        gl::bitCast<type>(fourthBits),
+    };
+
+    for (size_t z = 0; z < depth; z++)
+    {
+        for (size_t y = 0; y < height; y++)
+        {
+            type *destRow = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
+            for (size_t x = 0; x < width; x++)
+            {
+                type* destPixel = destRow + x * 4;
+
+                // This could potentially be optimized by generating an entire row of initialization
+                // data and copying row by row instead of pixel by pixel.
+                memcpy(destPixel, writeValues, sizeof(type) * 4);
+            }
+        }
+    }
+}
+
+}
diff --git a/src/libGLESv2/renderer/loadimageSSE2.cpp b/src/libGLESv2/renderer/loadimageSSE2.cpp
index 129e39b..cc20d94 100644
--- a/src/libGLESv2/renderer/loadimageSSE2.cpp
+++ b/src/libGLESv2/renderer/loadimageSSE2.cpp
@@ -1,11 +1,10 @@
-#include "precompiled.h"
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// 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.
 //
 
-// loadimage.cpp: Defines image loading functions. It's
+// loadimageSSE2.cpp: Defines image loading functions. It's
 // in a separated file for GCC, which can enable SSE usage only per-file,
 // not for code blocks that use SSE2 explicitly.
 
@@ -14,94 +13,92 @@
 namespace rx
 {
 
-    void loadAlphaDataToBGRASSE2(int width, int height, int depth,
-        const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-        void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
+                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    __m128i zeroWide = _mm_setzero_si128();
+
+    for (size_t z = 0; z < depth; z++)
     {
-        const unsigned char *source = NULL;
-        unsigned int *dest = NULL;
-        __m128i zeroWide = _mm_setzero_si128();
-
-        for (int z = 0; z < depth; z++)
+        for (size_t y = 0; y < height; y++)
         {
-            for (int y = 0; y < height; y++)
+            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+            size_t x = 0;
+
+            // Make output writes aligned
+            for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++)
             {
-                source = static_cast<const unsigned char*>(input) + y * inputRowPitch + z * inputDepthPitch;
-                dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputRowPitch + z * outputDepthPitch);
+                dest[x] = static_cast<uint32_t>(source[x]) << 24;
+            }
 
-                int x;
-                // Make output writes aligned
-                for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++)
-                {
-                    dest[x] = static_cast<unsigned int>(source[x]) << 24;
-                }
+            for (; x + 7 < width; x += 8)
+            {
+                __m128i sourceData = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&source[x]));
+                // Interleave each byte to 16bit, make the lower byte to zero
+                sourceData = _mm_unpacklo_epi8(zeroWide, sourceData);
+                // Interleave each 16bit to 32bit, make the lower 16bit to zero
+                __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData);
+                __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData);
 
-                for (; x + 7 < width; x += 8)
-                {
-                    __m128i sourceData = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&source[x]));
-                    // Interleave each byte to 16bit, make the lower byte to zero
-                    sourceData = _mm_unpacklo_epi8(zeroWide, sourceData);
-                    // Interleave each 16bit to 32bit, make the lower 16bit to zero
-                    __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData);
-                    __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData);
+                _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), lo);
+                _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x + 4]), hi);
+            }
 
-                    _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), lo);
-                    _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x + 4]), hi);
-                }
-
-                // Handle the remainder
-                for (; x < width; x++)
-                {
-                    dest[x] = static_cast<unsigned int>(source[x]) << 24;
-                }
+            // Handle the remainder
+            for (; x < width; x++)
+            {
+                dest[x] = static_cast<uint32_t>(source[x]) << 24;
             }
         }
     }
+}
 
-    void loadRGBAUByteDataToBGRASSE2(int width, int height, int depth,
-        const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
-        void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
+void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
+                           const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+                           uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+    __m128i brMask = _mm_set1_epi32(0x00ff00ff);
+
+    for (size_t z = 0; z < depth; z++)
     {
-        const unsigned int *source = NULL;
-        unsigned int *dest = NULL;
-        __m128i brMask = _mm_set1_epi32(0x00ff00ff);
-
-        for (int z = 0; z < depth; z++)
+        for (size_t y = 0; y < height; y++)
         {
-            for (int y = 0; y < height; y++)
+            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
+            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+            size_t x = 0;
+
+            // Make output writes aligned
+            for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++)
             {
-                source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputRowPitch + z * inputDepthPitch);
-                dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputRowPitch + z * outputDepthPitch);
-                int x = 0;
+                uint32_t rgba = source[x];
+                dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
+            }
 
-                // Make output writes aligned
-                for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++)
-                {
-                    unsigned int rgba = source[x];
-                    dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
-                }
+            for (; x + 3 < width; x += 4)
+            {
+                __m128i sourceData = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&source[x]));
+                // Mask out g and a, which don't change
+                __m128i gaComponents = _mm_andnot_si128(brMask, sourceData);
+                // Mask out b and r
+                __m128i brComponents = _mm_and_si128(sourceData, brMask);
+                // Swap b and r
+                __m128i brSwapped = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1));
+                __m128i result = _mm_or_si128(gaComponents, brSwapped);
+                _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), result);
+            }
 
-                for (; x + 3 < width; x += 4)
-                {
-                    __m128i sourceData = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&source[x]));
-                    // Mask out g and a, which don't change
-                    __m128i gaComponents = _mm_andnot_si128(brMask, sourceData);
-                    // Mask out b and r
-                    __m128i brComponents = _mm_and_si128(sourceData, brMask);
-                    // Swap b and r
-                    __m128i brSwapped = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1));
-                    __m128i result = _mm_or_si128(gaComponents, brSwapped);
-                    _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), result);
-                }
-
-                // Perform leftover writes
-                for (; x < width; x++)
-                {
-                    unsigned int rgba = source[x];
-                    dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
-                }
+            // Perform leftover writes
+            for (; x < width; x++)
+            {
+                uint32_t rgba = source[x];
+                dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
             }
         }
     }
+}
 
 }
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 03b8f71..9a5fa31 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// 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.
 //
@@ -13,11 +12,14 @@
 #include "libGLESv2/Context.h"
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/main.h"
 #include "libGLESv2/Query.h"
 #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"
@@ -111,7 +113,7 @@
 
       case GL_PIXEL_PACK_BUFFER:
       case GL_PIXEL_UNPACK_BUFFER:
-        return context->supportsPBOs();
+        return context->getExtensions().pixelBufferObject;
 
       case GL_COPY_READ_BUFFER:
       case GL_COPY_WRITE_BUFFER:
@@ -147,26 +149,26 @@
 
 bool ValidMipLevel(const Context *context, GLenum target, GLint level)
 {
-    int maxLevel = 0;
+    size_t maxDimension = 0;
     switch (target)
     {
-      case GL_TEXTURE_2D:                  maxLevel = context->getMaximum2DTextureLevel();      break;
+      case GL_TEXTURE_2D:                  maxDimension = context->getCaps().max2DTextureSize;       break;
       case GL_TEXTURE_CUBE_MAP:
       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: maxLevel = context->getMaximumCubeTextureLevel();    break;
-      case GL_TEXTURE_3D:                  maxLevel = context->getMaximum3DTextureLevel();      break;
-      case GL_TEXTURE_2D_ARRAY:            maxLevel = context->getMaximum2DArrayTextureLevel(); break;
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: maxDimension = context->getCaps().maxCubeMapTextureSize;  break;
+      case GL_TEXTURE_3D:                  maxDimension = context->getCaps().max3DTextureSize;       break;
+      case GL_TEXTURE_2D_ARRAY:            maxDimension = context->getCaps().max2DTextureSize;       break;
       default: UNREACHABLE();
     }
 
-    return level < maxLevel;
+    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)
@@ -174,7 +176,7 @@
         return false;
     }
 
-    if (!context->supportsNonPower2Texture() &&
+    if (!context->getExtensions().textureNPOT &&
         (level != 0 && (!gl::isPow2(width) || !gl::isPow2(height) || !gl::isPow2(depth))))
     {
         return false;
@@ -188,18 +190,16 @@
     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)
 {
-    GLuint clientVersion = context->getClientVersion();
-    if (!IsFormatCompressed(internalFormat, clientVersion))
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+    if (!formatInfo.compressed)
     {
         return false;
     }
 
-    GLint blockWidth = GetCompressedBlockWidth(internalFormat, clientVersion);
-    GLint blockHeight = GetCompressedBlockHeight(internalFormat, clientVersion);
-    if (width  < 0 || (width  > blockWidth  && width  % blockWidth  != 0) ||
-        height < 0 || (height > blockHeight && height % blockHeight != 0))
+    if (width  < 0 || (static_cast<GLuint>(width)  > formatInfo.compressedBlockWidth  && width  % formatInfo.compressedBlockWidth != 0) ||
+        height < 0 || (static_cast<GLuint>(height) > formatInfo.compressedBlockHeight && height % formatInfo.compressedBlockHeight != 0))
     {
         return false;
     }
@@ -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,55 @@
     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 ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples,
+bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
+{
+    if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+    {
+        const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+
+        if (colorAttachment >= context->getCaps().maxColorAttachments)
+        {
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
+        }
+    }
+    else
+    {
+        switch (attachment)
+        {
+          case GL_DEPTH_ATTACHMENT:
+          case GL_STENCIL_ATTACHMENT:
+            break;
+
+          case GL_DEPTH_STENCIL_ATTACHMENT:
+            if (context->getClientVersion() < 3)
+            {
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
+            }
+            break;
+
+          default:
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool ValidateRenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples,
                                            GLenum internalformat, GLsizei width, GLsizei height,
                                            bool angleExtension)
 {
@@ -255,44 +294,50 @@
       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;
     }
 
-    if (!gl::IsValidInternalFormat(internalformat, context))
+    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
     // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains
     // only sized internal formats. The ES3 spec (section 4.4.2) does, however, state that the
     // internal format must be sized and not an integer format if samples is greater than zero.
-    if (!gl::IsSizedInternalFormat(internalformat, context->getClientVersion()))
+    if (formatInfo.pixelBytes == 0)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
-    GLenum componentType = gl::GetComponentType(internalformat, context->getClientVersion());
-    if ((componentType == GL_UNSIGNED_INT || componentType == GL_INT) && samples > 0)
+    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;
     }
 
-    if (!gl::IsColorRenderingSupported(internalformat, context) &&
-        !gl::IsDepthRenderingSupported(internalformat, context) &&
-        !gl::IsStencilRenderingSupported(internalformat, context))
+    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 (std::max(width, height) > context->getMaximumRenderbufferDimension())
+    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
@@ -301,23 +346,34 @@
     // internal format.
     if (angleExtension)
     {
-        if (samples > context->getMaxSupportedSamples())
+        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())
+        {
+            context->recordError(Error(GL_OUT_OF_MEMORY));
+            return false;
         }
     }
     else
     {
-        if (samples > context->getMaxSupportedFormatSamples(internalformat))
+        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->getRenderbufferHandle();
+    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;
@@ -326,40 +382,24 @@
 bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment,
                                                GLenum renderbuffertarget, GLuint renderbuffer)
 {
-    gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
-    GLuint framebufferHandle = context->getTargetFramebufferHandle(target);
+    if (!ValidFramebufferTarget(target))
+    {
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
+    }
+
+    gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+    GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id();
 
     if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
-    if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+    if (!ValidateAttachmentTarget(context, attachment))
     {
-        const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
-
-        if (colorAttachment >= context->getMaximumRenderTargets())
-        {
-            return gl::error(GL_INVALID_VALUE, false);
-        }
-    }
-    else
-    {
-        switch (attachment)
-        {
-          case GL_DEPTH_ATTACHMENT:
-            break;
-          case GL_STENCIL_ATTACHMENT:
-            break;
-          case GL_DEPTH_STENCIL_ATTACHMENT:
-            if (context->getClientVersion() < 3)
-            {
-                return gl::error(GL_INVALID_ENUM, false);
-            }
-            break;
-          default:
-            return gl::error(GL_INVALID_ENUM, false);
-        }
+        return false;
     }
 
     // [OpenGL ES 2.0.25] Section 4.4.3 page 112
@@ -370,7 +410,8 @@
     {
         if (!context->getRenderbuffer(renderbuffer))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -387,14 +428,13 @@
     {
         return true;
     }
-    else if (context->isScissorTestEnabled())
+    else if (context->getState().isScissorTestEnabled())
     {
-        int scissorX, scissorY, scissorWidth, scissorHeight;
-        context->getScissorParams(&scissorX, &scissorY, &scissorWidth, &scissorHeight);
+        const Rectangle &scissor = context->getState().getScissor();
 
-        return scissorX > 0 || scissorY > 0 ||
-               scissorWidth < writeBuffer->getWidth() ||
-               scissorHeight < writeBuffer->getHeight();
+        return scissor.x > 0 || scissor.y > 0 ||
+               scissor.width < writeBuffer->getWidth() ||
+               scissor.height < writeBuffer->getHeight();
     }
     else
     {
@@ -413,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)
@@ -435,43 +478,46 @@
     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->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
+    if (context->getState().getReadFramebuffer()->id() == context->getState().getDrawFramebuffer()->id())
     {
         if (fromAngleExtension)
         {
             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->getReadFramebuffer();
-    gl::Framebuffer *drawFramebuffer = context->getDrawFramebuffer();
+    gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
+    gl::Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
     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;
 
-    GLuint clientVersion = context->getClientVersion();
-
     if (mask & GL_COLOR_BUFFER_BIT)
     {
         gl::FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
@@ -480,45 +526,50 @@
         if (readColorBuffer && drawColorBuffer)
         {
             GLenum readInternalFormat = readColorBuffer->getActualFormat();
-            GLenum readComponentType = gl::GetComponentType(readInternalFormat, clientVersion);
+            const InternalFormat &readFormatInfo = GetInternalFormatInfo(readInternalFormat);
 
             for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
             {
                 if (drawFramebuffer->isEnabledColorAttachment(i))
                 {
                     GLenum drawInternalFormat = drawFramebuffer->getColorbuffer(i)->getActualFormat();
-                    GLenum drawComponentType = gl::GetComponentType(drawInternalFormat, clientVersion);
+                    const InternalFormat &drawFormatInfo = GetInternalFormatInfo(drawInternalFormat);
 
                     // The GL ES 3.0.2 spec (pg 193) states that:
                     // 1) If the read buffer is fixed point format, the draw buffer must be as well
                     // 2) If the read buffer is an unsigned integer format, the draw buffer must be as well
                     // 3) If the read buffer is a signed integer format, the draw buffer must be as well
-                    if ( (readComponentType == GL_UNSIGNED_NORMALIZED || readComponentType == GL_SIGNED_NORMALIZED) &&
-                        !(drawComponentType == GL_UNSIGNED_NORMALIZED || drawComponentType == GL_SIGNED_NORMALIZED))
+                    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 (readComponentType == GL_UNSIGNED_INT && drawComponentType != GL_UNSIGNED_INT)
+                    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 (readComponentType == GL_INT && drawComponentType != GL_INT)
+                    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 ((readComponentType == GL_INT || readComponentType == GL_UNSIGNED_INT) && filter == GL_LINEAR)
+            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)
@@ -526,22 +577,27 @@
                 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++)
                 {
                     if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
                     {
-                        if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
-                            drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
+                        FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(colorAttachment);
+                        ASSERT(attachment);
+
+                        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 (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
+                        if (attachment->getActualFormat() != readColorBuffer->getActualFormat())
                         {
-                            return gl::error(GL_INVALID_OPERATION, false);
+                            context->recordError(Error(GL_INVALID_OPERATION));
+                            return false;
                         }
                     }
                 }
@@ -549,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;
                 }
             }
         }
@@ -564,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)
@@ -578,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;
                 }
             }
         }
@@ -598,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)
@@ -612,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;
                 }
             }
         }
@@ -626,7 +691,7 @@
     return true;
 }
 
-bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion)
+bool ValidateGetVertexAttribParameters(Context *context, GLenum pname)
 {
     switch (pname)
     {
@@ -646,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;
     }
 }
 
@@ -670,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;
 
@@ -689,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:
@@ -703,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;
 
@@ -714,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;
 
@@ -725,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->supportsTextureFilterAnisotropy())
+        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;
 
@@ -755,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;
 
@@ -773,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;
 
@@ -791,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;
 
@@ -799,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)
     {
@@ -824,33 +907,37 @@
         return true;
 
       default:
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 }
 
 bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
                                   GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels)
 {
-    gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+    gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
     ASSERT(framebuffer);
 
     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->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
+    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;
-    int clientVersion = context->getClientVersion();
+    GLuint clientVersion = context->getClientVersion();
 
     context->getCurrentReadFormatType(&currentInternalFormat, &currentFormat, &currentType);
 
@@ -859,20 +946,22 @@
 
     if (!(currentFormat == format && currentType == type) && !validReadFormat)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
-    GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format :
-                                 GetSizedInternalFormat(format, type, clientVersion);
+    GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+    const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
 
-    GLsizei outputPitch = GetRowPitch(sizedInternalFormat, type, clientVersion, width, context->getPackAlignment());
+    GLsizei outputPitch = sizedFormatInfo.computeRowPitch(type, width, context->getState().getPackAlignment());
     // sized query sanity check
     if (bufSize)
     {
         int requiredSize = outputPitch * height;
         if (requiredSize > *bufSize)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -883,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>
@@ -906,9 +997,10 @@
     //    b) There are no active queries for the requested target (and in the case
     //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
     //       no query may be active for either if glBeginQuery targets either.
-    if (context->isQueryActive())
+    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);
@@ -916,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;
@@ -932,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->getActiveQuery(target);
+    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;
@@ -955,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->getCurrentProgramBinary();
+    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)
@@ -972,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);
@@ -980,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;
@@ -990,9 +1085,10 @@
 bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count)
 {
     // Check for ES3 uniform entry points
-    if (UniformComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3)
+    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;
@@ -1001,11 +1097,12 @@
         return false;
     }
 
-    GLenum targetBoolType = UniformBoolVectorType(uniformType);
+    GLenum targetBoolType = VariableBoolVectorType(uniformType);
     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;
@@ -1019,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;
@@ -1035,7 +1134,8 @@
 
     if (uniform->type != matrixType)
     {
-        return gl::error(GL_INVALID_OPERATION, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
     return true;
@@ -1045,16 +1145,18 @@
 {
     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)
     {
         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
 
-        if (colorAttachment >= context->getMaximumRenderTargets())
+        if (colorAttachment >= context->getCaps().maxDrawBuffers)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -1064,26 +1166,29 @@
       case GL_TEXTURE_BINDING_CUBE_MAP:
       case GL_TEXTURE_BINDING_3D:
       case GL_TEXTURE_BINDING_2D_ARRAY:
-        if (context->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;
 
       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
         {
-            Framebuffer *framebuffer = context->getReadFramebuffer();
+            Framebuffer *framebuffer = context->getState().getReadFramebuffer();
             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;
@@ -1108,48 +1213,55 @@
 
     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->getReadFramebuffer();
+    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->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
+    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();
+
     gl::Texture *texture = NULL;
     GLenum textureInternalFormat = GL_NONE;
-    bool textureCompressed = false;
-    bool textureIsDepth = false;
     GLint textureLevelWidth = 0;
     GLint textureLevelHeight = 0;
     GLint textureLevelDepth = 0;
-    int maxDimension = 0;
+    GLuint maxDimension = 0;
 
     switch (target)
     {
@@ -1159,13 +1271,11 @@
             if (texture2d)
             {
                 textureInternalFormat = texture2d->getInternalFormat(level);
-                textureCompressed = texture2d->isCompressed(level);
-                textureIsDepth = texture2d->isDepth(level);
                 textureLevelWidth = texture2d->getWidth(level);
                 textureLevelHeight = texture2d->getHeight(level);
                 textureLevelDepth = 1;
                 texture = texture2d;
-                maxDimension = context->getMaximum2DTextureDimension();
+                maxDimension = caps.max2DTextureSize;
             }
         }
         break;
@@ -1181,13 +1291,11 @@
             if (textureCube)
             {
                 textureInternalFormat = textureCube->getInternalFormat(target, level);
-                textureCompressed = textureCube->isCompressed(target, level);
-                textureIsDepth = false;
                 textureLevelWidth = textureCube->getWidth(target, level);
                 textureLevelHeight = textureCube->getHeight(target, level);
                 textureLevelDepth = 1;
                 texture = textureCube;
-                maxDimension = context->getMaximumCubeTextureDimension();
+                maxDimension = caps.maxCubeMapTextureSize;
             }
         }
         break;
@@ -1198,13 +1306,11 @@
             if (texture2dArray)
             {
                 textureInternalFormat = texture2dArray->getInternalFormat(level);
-                textureCompressed = texture2dArray->isCompressed(level);
-                textureIsDepth = texture2dArray->isDepth(level);
                 textureLevelWidth = texture2dArray->getWidth(level);
                 textureLevelHeight = texture2dArray->getHeight(level);
                 textureLevelDepth = texture2dArray->getLayers(level);
                 texture = texture2dArray;
-                maxDimension = context->getMaximum2DTextureDimension();
+                maxDimension = caps.max2DTextureSize;
             }
         }
         break;
@@ -1215,46 +1321,47 @@
             if (texture3d)
             {
                 textureInternalFormat = texture3d->getInternalFormat(level);
-                textureCompressed = texture3d->isCompressed(level);
-                textureIsDepth = texture3d->isDepth(level);
                 textureLevelWidth = texture3d->getWidth(level);
                 textureLevelHeight = texture3d->getHeight(level);
                 textureLevelDepth = texture3d->getDepth(level);
                 texture = texture3d;
-                maxDimension = context->getMaximum3DTextureDimension();
+                maxDimension = caps.max3DTextureSize;
             }
         }
         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;
     }
 
-    if (textureIsDepth)
+    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 (textureCompressed)
+    if (formatInfo.compressed)
     {
-        int clientVersion = context->getClientVersion();
-        GLint blockWidth = GetCompressedBlockWidth(textureInternalFormat, clientVersion);
-        GLint blockHeight = GetCompressedBlockHeight(textureInternalFormat, clientVersion);
-
-        if (((width % blockWidth) != 0 && width != textureLevelWidth) ||
-            ((height % blockHeight) != 0 && height != textureLevelHeight))
+        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;
         }
     }
 
@@ -1264,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 (!IsValidInternalFormat(internalformat, context))
+        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;
         }
     }
 
@@ -1290,4 +1401,526 @@
     return true;
 }
 
+static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsizei maxVertex, GLsizei primcount)
+{
+    switch (mode)
+    {
+      case GL_POINTS:
+      case GL_LINES:
+      case GL_LINE_LOOP:
+      case GL_LINE_STRIP:
+      case GL_TRIANGLES:
+      case GL_TRIANGLE_STRIP:
+      case GL_TRIANGLE_FAN:
+        break;
+      default:
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
+    }
+
+    if (count < 0)
+    {
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
+    }
+
+    const State &state = context->getState();
+
+    // Check for mapped buffers
+    if (state.hasMappedBuffer(GL_ARRAY_BUFFER))
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
+    if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
+        state.getStencilRef() != state.getStencilBackRef() ||
+        depthStencilState.stencilMask != depthStencilState.stencilBackMask)
+    {
+        // Note: these separate values are not supported in WebGL, due to D3D's limitations.
+        // 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.");
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    const gl::Framebuffer *fbo = state.getDrawFramebuffer();
+    if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
+    {
+        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+        return false;
+    }
+
+    if (state.getCurrentProgramId() == 0)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
+    if (!programBinary->validateSamplers(NULL, context->getCaps()))
+    {
+        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(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+    if (first < 0)
+    {
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
+    }
+
+    const State &state = context->getState();
+    gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+    if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
+        curTransformFeedback->getDrawMode() != mode)
+    {
+        // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
+        // that does not match the current transform feedback object's draw mode (if transform feedback
+        // is active), (3.0.2, section 2.14, pg 86)
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    if (!ValidateDrawBase(context, mode, count, count, primcount))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+    if (primcount < 0)
+    {
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
+    }
+
+    if (!ValidateDrawArrays(context, mode, first, count, primcount))
+    {
+        return false;
+    }
+
+    // No-op if zero primitive count
+    return (primcount > 0);
+}
+
+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)
+    {
+      case GL_UNSIGNED_BYTE:
+      case GL_UNSIGNED_SHORT:
+        break;
+      case GL_UNSIGNED_INT:
+        if (!context->getExtensions().elementIndexUint)
+        {
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
+        }
+        break;
+      default:
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
+    }
+
+    const State &state = context->getState();
+
+    gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+    if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
+    {
+        // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
+        // while transform feedback is active, (3.0.2, section 2.14, pg 86)
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    // Check for mapped buffers
+    if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    const gl::VertexArray *vao = state.getVertexArray();
+    const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+    if (!indices && !elementArrayBuffer)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    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;
+    }
+
+    return true;
+}
+
+bool ValidateDrawElementsInstanced(Context *context,
+                                   GLenum mode, GLsizei count, GLenum type,
+                                   const GLvoid *indices, GLsizei primcount,
+                                   rx::RangeUI *indexRangeOut)
+{
+    if (primcount < 0)
+    {
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
+    }
+
+    if (!ValidateDrawElements(context, mode, count, type, indices, primcount, indexRangeOut))
+    {
+        return false;
+    }
+
+    // No-op zero primitive count
+    return (primcount > 0);
+}
+
+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))
+    {
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
+    }
+
+    if (!ValidateAttachmentTarget(context, attachment))
+    {
+        return false;
+    }
+
+    if (texture != 0)
+    {
+        gl::Texture *tex = context->getTexture(texture);
+
+        if (tex == NULL)
+        {
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
+        }
+
+        if (level < 0)
+        {
+            context->recordError(Error(GL_INVALID_VALUE));
+            return false;
+        }
+    }
+
+    const gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+    GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id();
+
+    if (framebufferHandle == 0 || !framebuffer)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    return true;
+}
+
+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)
+    {
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
+    }
+
+    if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
+    {
+        return false;
+    }
+
+    if (texture != 0)
+    {
+        gl::Texture *tex = context->getTexture(texture);
+        ASSERT(tex);
+
+        const gl::Caps &caps = context->getCaps();
+
+        switch (textarget)
+        {
+          case GL_TEXTURE_2D:
+            {
+                if (level > gl::log2(caps.max2DTextureSize))
+                {
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
+                }
+                if (tex->getTarget() != GL_TEXTURE_2D)
+                {
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
+                }
+                gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
+                if (tex2d->isCompressed(level))
+                {
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
+                }
+            }
+            break;
+
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+            {
+                if (level > gl::log2(caps.maxCubeMapTextureSize))
+                {
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
+                }
+                if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
+                {
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
+                }
+                gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
+                if (texcube->isCompressed(textarget, level))
+                {
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
+                }
+            }
+            break;
+
+          default:
+            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 2bce2d7..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,43 +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 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(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 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(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 a0ef855..f950454 100644
--- a/src/libGLESv2/validationES2.cpp
+++ b/src/libGLESv2/validationES2.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// 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.
 //
@@ -15,6 +14,7 @@
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/main.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "common/mathutil.h"
 #include "common/utilities.h"
@@ -22,26 +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)
     {
-        GLenum internalformat = gl::GetSizedInternalFormat(format, type, 2);
-        if (internalformat != texture->getInternalFormat(level))
+        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,39 +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)
     {
-        GLenum internalformat = gl::GetSizedInternalFormat(format, type, 2);
-        if (internalformat != texture->getInternalFormat(target, level))
+        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;
         }
     }
 
@@ -91,45 +97,53 @@
         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();
+
     gl::Texture *texture = NULL;
     bool textureCompressed = false;
     GLenum textureInternalFormat = GL_NONE;
@@ -139,10 +153,11 @@
     {
       case GL_TEXTURE_2D:
         {
-            if (width > (context->getMaximum2DTextureDimension() >> level) ||
-                height > (context->getMaximum2DTextureDimension() >> level))
+            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();
@@ -155,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;
@@ -174,13 +189,15 @@
         {
             if (!isSubImage && width != height)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
-            if (width > (context->getMaximumCubeTextureDimension() >> level) ||
-                height > (context->getMaximumCubeTextureDimension() >> level))
+            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();
@@ -193,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;
@@ -202,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;
@@ -226,32 +247,37 @@
     {
         if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         switch (actualInternalFormat)
         {
           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-            if (!context->supportsDXT1Textures())
+            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->supportsDXT3Textures())
+            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->supportsDXT5Textures())
+            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
@@ -270,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
@@ -287,14 +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:
-              if (!context->supportsRGTextures())
+          case GL_RG:
+              if (!context->getExtensions().textureRG)
               {
-                  return gl::error(GL_INVALID_ENUM, false);
+                  context->recordError(Error(GL_INVALID_ENUM));
+                  return false;
               }
               switch (type)
               {
@@ -303,22 +333,8 @@
                 case GL_HALF_FLOAT_OES:
                   break;
                 default:
-                  return gl::error(GL_INVALID_OPERATION, false);
-              }
-              break;
-          case GL_RG:
-              if (!context->supportsRGTextures())
-              {
-                  return gl::error(GL_INVALID_ENUM, false);
-              }
-              switch (type)
-              {
-              case GL_UNSIGNED_BYTE:
-              case GL_FLOAT:
-              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:
@@ -330,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:
@@ -343,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:
@@ -352,7 +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)
+            {
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
+            }
+            switch (type)
+            {
+              case GL_UNSIGNED_BYTE:
+                break;
+              default:
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
             }
             break;
           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below
@@ -367,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:
@@ -376,61 +412,72 @@
               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)
         {
           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-            if (context->supportsDXT1Textures())
+            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->supportsDXT3Textures())
+            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->supportsDXT5Textures())
+            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->supportsDepthTextures())
+            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:
@@ -439,16 +486,18 @@
 
         if (type == GL_FLOAT)
         {
-            if (!context->supportsFloat32Textures())
+            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->supportsFloat16Textures())
+            if (!context->getExtensions().textureHalfFloat)
             {
-                return gl::error(GL_INVALID_ENUM, false);
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
             }
         }
     }
@@ -458,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)
 {
@@ -470,9 +519,9 @@
         return false;
     }
 
-    gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+    gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
     GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
-    GLenum textureFormat = gl::GetFormat(textureInternalFormat, context->getClientVersion());
+    GLenum textureFormat = gl::GetInternalFormatInfo(textureInternalFormat).format;
 
     // [OpenGL ES 2.0.24] table 3.9
     if (isSubImage)
@@ -485,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:
@@ -497,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:
@@ -509,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:
@@ -520,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:
@@ -530,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:
@@ -539,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
@@ -565,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:
@@ -578,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:
@@ -591,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:
@@ -603,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:
@@ -614,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:
@@ -624,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->supportsDXT1Textures())
+            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->supportsDXT3Textures())
+            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->supportsDXT5Textures())
+            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:
@@ -663,16 +733,19 @@
           case GL_DEPTH_COMPONENT32_OES:
           case GL_DEPTH_STENCIL_OES:
           case GL_DEPTH24_STENCIL8_OES:
-            if (context->supportsDepthTextures())
+            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;
         }
     }
 
@@ -680,62 +753,71 @@
     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;
     }
 
-    GLenum format = gl::GetFormat(internalformat, context->getClientVersion());
-    GLenum type = gl::GetType(internalformat, context->getClientVersion());
-
-    if (format == GL_NONE || type == GL_NONE)
+    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();
+
     switch (target)
     {
       case GL_TEXTURE_2D:
-        if (width > context->getMaximum2DTextureDimension() ||
-            height > context->getMaximum2DTextureDimension())
+        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 (width > context->getMaximumCubeTextureDimension() ||
-            height > context->getMaximumCubeTextureDimension())
+        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->supportsNonPower2Texture())
+    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;
         }
     }
 
@@ -743,21 +825,24 @@
     {
       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-        if (!context->supportsDXT1Textures())
+        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->supportsDXT3Textures())
+        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->supportsDXT5Textures())
+        if (!context->getExtensions().textureCompressionDXT5)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_RGBA32F_EXT:
@@ -765,9 +850,10 @@
       case GL_ALPHA32F_EXT:
       case GL_LUMINANCE32F_EXT:
       case GL_LUMINANCE_ALPHA32F_EXT:
-        if (!context->supportsFloat32Textures())
+        if (!context->getExtensions().textureFloat)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_RGBA16F_EXT:
@@ -775,9 +861,10 @@
       case GL_ALPHA16F_EXT:
       case GL_LUMINANCE16F_EXT:
       case GL_LUMINANCE_ALPHA16F_EXT:
-        if (!context->supportsFloat16Textures())
+        if (!context->getExtensions().textureHalfFloat)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_R8_EXT:
@@ -786,26 +873,30 @@
       case GL_RG16F_EXT:
       case GL_R32F_EXT:
       case GL_RG32F_EXT:
-        if (!context->supportsRGTextures())
+        if (!context->getExtensions().textureRG)
         {
-            return gl::error(GL_INVALID_ENUM, false);
+            context->recordError(Error(GL_INVALID_ENUM));
+            return false;
         }
         break;
       case GL_DEPTH_COMPONENT16:
       case GL_DEPTH_COMPONENT32_OES:
       case GL_DEPTH24_STENCIL8_OES:
-        if (!context->supportsDepthTextures())
+        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:
@@ -827,124 +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);
-    }
-
-    return true;
-}
-
-bool ValidateES2FramebufferTextureParameters(gl::Context *context, GLenum target, GLenum attachment,
-                                             GLenum textarget, GLuint texture, GLint level)
-{
-    META_ASSERT(GL_DRAW_FRAMEBUFFER == GL_DRAW_FRAMEBUFFER_ANGLE && GL_READ_FRAMEBUFFER == GL_READ_FRAMEBUFFER_ANGLE);
-
-    if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
-    {
-        return gl::error(GL_INVALID_ENUM, false);
-    }
-
-    if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
-    {
-        const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0);
-        if (colorAttachment >= context->getMaximumRenderTargets())
-        {
-            return gl::error(GL_INVALID_VALUE, false);
-        }
-    }
-    else
-    {
-        switch (attachment)
-        {
-          case GL_DEPTH_ATTACHMENT:
-          case GL_STENCIL_ATTACHMENT:
-            break;
-          default:
-            return gl::error(GL_INVALID_ENUM, false);
-        }
-    }
-
-    if (texture != 0)
-    {
-        gl::Texture *tex = context->getTexture(texture);
-
-        if (tex == NULL)
-        {
-            return gl::error(GL_INVALID_OPERATION, false);
-        }
-
-        switch (textarget)
-        {
-          case GL_TEXTURE_2D:
-            {
-                if (tex->getTarget() != GL_TEXTURE_2D)
-                {
-                    return gl::error(GL_INVALID_OPERATION, false);
-                }
-                gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
-                if (tex2d->isCompressed(level))
-                {
-                    return gl::error(GL_INVALID_OPERATION, false);
-                }
-                break;
-            }
-
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            {
-                if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
-                {
-                    return gl::error(GL_INVALID_OPERATION, false);
-                }
-                gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
-                if (texcube->isCompressed(textarget, level))
-                {
-                    return gl::error(GL_INVALID_OPERATION, false);
-                }
-                break;
-            }
-
-          default:
-            return gl::error(GL_INVALID_ENUM, false);
-        }
-
-        if (level != 0)
-        {
-            return gl::error(GL_INVALID_VALUE, false);
-        }
-    }
-
-    gl::Framebuffer *framebuffer = NULL;
-    GLuint framebufferHandle = 0;
-    if (target == GL_READ_FRAMEBUFFER)
-    {
-        framebuffer = context->getReadFramebuffer();
-        framebufferHandle = context->getReadFramebufferHandle();
-    }
-    else
-    {
-        framebuffer = context->getDrawFramebuffer();
-        framebufferHandle = context->getDrawFramebufferHandle();
-    }
-
-    if (framebufferHandle == 0 || !framebuffer)
-    {
-        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)
     {
@@ -970,7 +958,7 @@
         break;
       case GL_RG_EXT:
       case GL_RED_EXT:
-        if (!context->supportsRGTextures())
+        if (!context->getExtensions().textureRG)
         {
             return false;
         }
diff --git a/src/libGLESv2/validationES2.h b/src/libGLESv2/validationES2.h
index 02775ff..53a0b63 100644
--- a/src/libGLESv2/validationES2.h
+++ b/src/libGLESv2/validationES2.h
@@ -9,26 +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 ValidateES2FramebufferTextureParameters(gl::Context *context, GLenum target, GLenum attachment,
-                                             GLenum textarget, GLuint texture, GLint level);
-
-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 a45a5a3..251c6ad 100644
--- a/src/libGLESv2/validationES3.cpp
+++ b/src/libGLESv2/validationES3.cpp
@@ -1,6 +1,5 @@
-#include "precompiled.h"
 //
-// 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.
 //
@@ -15,31 +14,290 @@
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/main.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "common/mathutil.h"
 
 namespace gl
 {
 
-bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+struct ES3FormatCombination
+{
+    GLenum internalFormat;
+    GLenum format;
+    GLenum type;
+};
+
+bool operator<(const ES3FormatCombination& a, const ES3FormatCombination& b)
+{
+    return memcmp(&a, &b, sizeof(ES3FormatCombination)) < 0;
+}
+
+typedef std::set<ES3FormatCombination> ES3FormatCombinationSet;
+
+static inline void InsertES3FormatCombo(ES3FormatCombinationSet *set, GLenum internalFormat, GLenum format, GLenum type)
+{
+    ES3FormatCombination info;
+    info.internalFormat = internalFormat;
+    info.format = format;
+    info.type = type;
+    set->insert(info);
+}
+
+ES3FormatCombinationSet BuildES3FormatSet()
+{
+    ES3FormatCombinationSet set;
+
+    // Format combinations from ES 3.0.1 spec, table 3.2
+
+    //                        | Internal format      | Format            | Type                            |
+    //                        |                      |                   |                                 |
+    InsertES3FormatCombo(&set, GL_RGBA8,              GL_RGBA,            GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_SRGB8_ALPHA8,       GL_RGBA,            GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGBA8_SNORM,        GL_RGBA,            GL_BYTE                          );
+    InsertES3FormatCombo(&set, GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        );
+    InsertES3FormatCombo(&set, GL_RGB10_A2,           GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   );
+    InsertES3FormatCombo(&set, GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   );
+    InsertES3FormatCombo(&set, GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        );
+    InsertES3FormatCombo(&set, GL_RGBA16F,            GL_RGBA,            GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_RGBA16F,            GL_RGBA,            GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_RGBA32F,            GL_RGBA,            GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_RGBA16F,            GL_RGBA,            GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_RGBA8UI,            GL_RGBA_INTEGER,    GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGBA8I,             GL_RGBA_INTEGER,    GL_BYTE                          );
+    InsertES3FormatCombo(&set, GL_RGBA16UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_SHORT                );
+    InsertES3FormatCombo(&set, GL_RGBA16I,            GL_RGBA_INTEGER,    GL_SHORT                         );
+    InsertES3FormatCombo(&set, GL_RGBA32UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_INT                  );
+    InsertES3FormatCombo(&set, GL_RGBA32I,            GL_RGBA_INTEGER,    GL_INT                           );
+    InsertES3FormatCombo(&set, GL_RGB10_A2UI,         GL_RGBA_INTEGER,    GL_UNSIGNED_INT_2_10_10_10_REV   );
+    InsertES3FormatCombo(&set, GL_RGB8,               GL_RGB,             GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGB565,             GL_RGB,             GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_SRGB8,              GL_RGB,             GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGB8_SNORM,         GL_RGB,             GL_BYTE                          );
+    InsertES3FormatCombo(&set, GL_RGB565,             GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          );
+    InsertES3FormatCombo(&set, GL_R11F_G11F_B10F,     GL_RGB,             GL_UNSIGNED_INT_10F_11F_11F_REV  );
+    InsertES3FormatCombo(&set, GL_RGB9_E5,            GL_RGB,             GL_UNSIGNED_INT_5_9_9_9_REV      );
+    InsertES3FormatCombo(&set, GL_RGB16F,             GL_RGB,             GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_RGB16F,             GL_RGB,             GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_R11F_G11F_B10F,     GL_RGB,             GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_R11F_G11F_B10F,     GL_RGB,             GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_RGB9_E5,            GL_RGB,             GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_RGB9_E5,            GL_RGB,             GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_RGB32F,             GL_RGB,             GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_RGB16F,             GL_RGB,             GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_R11F_G11F_B10F,     GL_RGB,             GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_RGB9_E5,            GL_RGB,             GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_RGB8UI,             GL_RGB_INTEGER,     GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGB8I,              GL_RGB_INTEGER,     GL_BYTE                          );
+    InsertES3FormatCombo(&set, GL_RGB16UI,            GL_RGB_INTEGER,     GL_UNSIGNED_SHORT                );
+    InsertES3FormatCombo(&set, GL_RGB16I,             GL_RGB_INTEGER,     GL_SHORT                         );
+    InsertES3FormatCombo(&set, GL_RGB32UI,            GL_RGB_INTEGER,     GL_UNSIGNED_INT                  );
+    InsertES3FormatCombo(&set, GL_RGB32I,             GL_RGB_INTEGER,     GL_INT                           );
+    InsertES3FormatCombo(&set, GL_RG8,                GL_RG,              GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RG8_SNORM,          GL_RG,              GL_BYTE                          );
+    InsertES3FormatCombo(&set, GL_RG16F,              GL_RG,              GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_RG16F,              GL_RG,              GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_RG32F,              GL_RG,              GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_RG16F,              GL_RG,              GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_RG8UI,              GL_RG_INTEGER,      GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RG8I,               GL_RG_INTEGER,      GL_BYTE                          );
+    InsertES3FormatCombo(&set, GL_RG16UI,             GL_RG_INTEGER,      GL_UNSIGNED_SHORT                );
+    InsertES3FormatCombo(&set, GL_RG16I,              GL_RG_INTEGER,      GL_SHORT                         );
+    InsertES3FormatCombo(&set, GL_RG32UI,             GL_RG_INTEGER,      GL_UNSIGNED_INT                  );
+    InsertES3FormatCombo(&set, GL_RG32I,              GL_RG_INTEGER,      GL_INT                           );
+    InsertES3FormatCombo(&set, GL_R8,                 GL_RED,             GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_R8_SNORM,           GL_RED,             GL_BYTE                          );
+    InsertES3FormatCombo(&set, GL_R16F,               GL_RED,             GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_R16F,               GL_RED,             GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_R32F,               GL_RED,             GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_R16F,               GL_RED,             GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_R8UI,               GL_RED_INTEGER,     GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_R8I,                GL_RED_INTEGER,     GL_BYTE                          );
+    InsertES3FormatCombo(&set, GL_R16UI,              GL_RED_INTEGER,     GL_UNSIGNED_SHORT                );
+    InsertES3FormatCombo(&set, GL_R16I,               GL_RED_INTEGER,     GL_SHORT                         );
+    InsertES3FormatCombo(&set, GL_R32UI,              GL_RED_INTEGER,     GL_UNSIGNED_INT                  );
+    InsertES3FormatCombo(&set, GL_R32I,               GL_RED_INTEGER,     GL_INT                           );
+
+    // Unsized formats
+    InsertES3FormatCombo(&set, GL_RGBA,               GL_RGBA,            GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        );
+    InsertES3FormatCombo(&set, GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        );
+    InsertES3FormatCombo(&set, GL_RGB,                GL_RGB,             GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_RGB,                GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          );
+    InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_LUMINANCE,          GL_LUMINANCE,       GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_ALPHA,              GL_ALPHA,           GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_SRGB_ALPHA_EXT,     GL_SRGB_ALPHA_EXT,  GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_SRGB_EXT,           GL_SRGB_EXT,        GL_UNSIGNED_BYTE                 );
+
+    // Depth stencil formats
+    InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT                );
+    InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT24,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  );
+    InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  );
+    InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_DEPTH24_STENCIL8,   GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8             );
+    InsertES3FormatCombo(&set, GL_DEPTH32F_STENCIL8,  GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+
+    // From GL_EXT_sRGB
+    InsertES3FormatCombo(&set, GL_SRGB8_ALPHA8_EXT,   GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE                  );
+    InsertES3FormatCombo(&set, GL_SRGB8,              GL_SRGB_EXT,       GL_UNSIGNED_BYTE                  );
+
+    // From GL_OES_texture_float
+    InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_LUMINANCE,          GL_LUMINANCE,       GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_ALPHA,              GL_ALPHA,           GL_FLOAT                         );
+
+    // From GL_OES_texture_half_float
+    InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_LUMINANCE,          GL_LUMINANCE,       GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_LUMINANCE,          GL_LUMINANCE,       GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_ALPHA,              GL_ALPHA,           GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_ALPHA,              GL_ALPHA,           GL_HALF_FLOAT_OES                );
+
+    // From GL_EXT_texture_format_BGRA8888
+    InsertES3FormatCombo(&set, GL_BGRA_EXT,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 );
+
+    // From GL_EXT_texture_storage
+    //                    | Internal format          | Format            | Type                            |
+    //                    |                          |                   |                                 |
+    InsertES3FormatCombo(&set, GL_ALPHA8_EXT,             GL_ALPHA,           GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_LUMINANCE8_EXT,         GL_LUMINANCE,       GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_LUMINANCE8_ALPHA8_EXT,  GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_ALPHA32F_EXT,           GL_ALPHA,           GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_LUMINANCE32F_EXT,       GL_LUMINANCE,       GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT                         );
+    InsertES3FormatCombo(&set, GL_ALPHA16F_EXT,           GL_ALPHA,           GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_ALPHA16F_EXT,           GL_ALPHA,           GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_LUMINANCE16F_EXT,       GL_LUMINANCE,       GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_LUMINANCE16F_EXT,       GL_LUMINANCE,       GL_HALF_FLOAT_OES                );
+    InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    );
+    InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES                );
+
+    // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888
+    InsertES3FormatCombo(&set, GL_BGRA8_EXT,              GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT);
+    InsertES3FormatCombo(&set, GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 );
+    InsertES3FormatCombo(&set, GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT);
+    InsertES3FormatCombo(&set, GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 );
+
+    // From GL_ANGLE_depth_texture
+    InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32_OES,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES         );
+
+    // Compressed formats
+    // From ES 3.0.1 spec, table 3.16
+    //                    | Internal format                             | Format                                      | Type           |
+    //                    |                                             |                                             |                |
+    InsertES3FormatCombo(&set, GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_RG11_EAC,                       GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_RGB8_ETC2,                      GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_ETC2,                     GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE);
+
+
+    // From GL_EXT_texture_compression_dxt1
+    InsertES3FormatCombo(&set, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_UNSIGNED_BYTE);
+    InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_UNSIGNED_BYTE);
+
+    // From GL_ANGLE_texture_compression_dxt3
+    InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_UNSIGNED_BYTE);
+
+    // From GL_ANGLE_texture_compression_dxt5
+    InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_UNSIGNED_BYTE);
+
+    return set;
+}
+
+static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type)
+{
+    // Note: dEQP 2013.4 expects an INVALID_VALUE error for TexImage3D with an invalid
+    // internal format. (dEQP-GLES3.functional.negative_api.texture.teximage3d)
+    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+    if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
+    {
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
+    }
+
+    // The type and format are valid if any supported internal format has that type and format
+    bool formatSupported = false;
+    bool typeSupported = false;
+
+    static const ES3FormatCombinationSet es3FormatSet = BuildES3FormatSet();
+    for (ES3FormatCombinationSet::const_iterator i = es3FormatSet.begin(); i != es3FormatSet.end(); i++)
+    {
+        if (i->format == format || i->type == type)
+        {
+            const gl::InternalFormat &info = gl::GetInternalFormatInfo(i->internalFormat);
+            bool supported = info.textureSupport(context->getClientVersion(), context->getExtensions());
+            if (supported && i->type == type)
+            {
+                typeSupported = true;
+            }
+            if (supported && i->format == format)
+            {
+                formatSupported = true;
+            }
+
+            // Early-out if both type and format are supported now
+            if (typeSupported && formatSupported)
+            {
+                break;
+            }
+        }
+    }
+
+    if (!typeSupported || !formatSupported)
+    {
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
+    }
+
+    // Check if this is a valid format combination to load texture data
+    ES3FormatCombination searchFormat;
+    searchFormat.internalFormat = internalFormat;
+    searchFormat.format = format;
+    searchFormat.type = type;
+
+    if (es3FormatSet.find(searchFormat) == es3FormatSet.end())
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    return true;
+}
+
+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 ||
@@ -47,9 +305,12 @@
         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();
+
     gl::Texture *texture = NULL;
     bool textureCompressed = false;
     GLenum textureInternalFormat = GL_NONE;
@@ -60,10 +321,11 @@
     {
       case GL_TEXTURE_2D:
         {
-            if (width > (context->getMaximum2DTextureDimension() >> level) ||
-                height > (context->getMaximum2DTextureDimension() >> level))
+            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();
@@ -88,12 +350,14 @@
         {
             if (!isSubImage && width != height)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
-            if (width > (context->getMaximumCubeTextureDimension() >> level))
+            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();
@@ -111,11 +375,12 @@
 
       case GL_TEXTURE_3D:
         {
-            if (width > (context->getMaximum3DTextureDimension() >> level) ||
-                height > (context->getMaximum3DTextureDimension() >> level) ||
-                depth > (context->getMaximum3DTextureDimension() >> level))
+            if (static_cast<GLuint>(width) > (caps.max3DTextureSize >> level) ||
+                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();
@@ -133,11 +398,12 @@
 
         case GL_TEXTURE_2D_ARRAY:
           {
-              if (width > (context->getMaximum2DTextureDimension() >> level) ||
-                  height > (context->getMaximum2DTextureDimension() >> level) ||
-                  depth > (context->getMaximum2DArrayTextureLayers() >> level))
+              if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
+                  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();
@@ -154,58 +420,56 @@
           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
     GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
-    int clientVersion = context->getClientVersion();
+    const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(actualInternalFormat);
     if (isCompressed)
     {
         if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
-        if (!gl::IsFormatCompressed(actualInternalFormat, clientVersion))
+        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
     {
-        // Note: dEQP 2013.4 expects an INVALID_VALUE error for TexImage3D with an invalid
-        // internal format. (dEQP-GLES3.functional.negative_api.texture.teximage3d)
-        if (!gl::IsValidInternalFormat(actualInternalFormat, context) ||
-            !gl::IsValidFormat(format, clientVersion) ||
-            !gl::IsValidType(type, clientVersion))
+        if (!ValidateTexImageFormatCombination(context, actualInternalFormat, format, type))
         {
-            return gl::error(GL_INVALID_ENUM, false);
-        }
-
-        if (!gl::IsValidFormatCombination(actualInternalFormat, format, type, clientVersion))
-        {
-            return gl::error(GL_INVALID_OPERATION, false);
+            return false;
         }
 
         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;
         }
     }
 
@@ -214,7 +478,8 @@
     {
         if (isCompressed != textureCompressed)
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
 
         if (isCompressed)
@@ -222,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;
             }
         }
 
@@ -233,26 +499,29 @@
 
         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;
         }
     }
 
     // Check for pixel unpack buffer related API errors
-    gl::Buffer *pixelUnpackBuffer = context->getPixelUnpackBuffer();
+    gl::Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
     if (pixelUnpackBuffer != NULL)
     {
         // ...the data would be unpacked from the buffer object such that the memory reads required
@@ -260,50 +529,336 @@
         size_t widthSize = static_cast<size_t>(width);
         size_t heightSize = static_cast<size_t>(height);
         size_t depthSize = static_cast<size_t>(depth);
-        GLenum sizedFormat = gl::IsSizedInternalFormat(actualInternalFormat, clientVersion) ?
-                             actualInternalFormat :
-                             gl::GetSizedInternalFormat(actualInternalFormat, type, clientVersion);
+        GLenum sizedFormat = GetSizedInternalFormat(actualInternalFormat, type);
 
-        size_t pixelBytes = static_cast<size_t>(gl::GetPixelBytes(sizedFormat, clientVersion));
+        size_t pixelBytes = static_cast<size_t>(gl::GetInternalFormatInfo(sizedFormat).pixelBytes);
 
         if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) ||
             !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) ||
             !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;
         size_t offset = reinterpret_cast<size_t>(pixels);
 
         if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) ||
-            ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->size())))
+            ((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
         // indicated by type.
-        size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeBytes(type));
+        size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
 
         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->mapped())
+        if (pixelUnpackBuffer->isMapped())
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
     return true;
 }
 
-bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat,
+struct EffectiveInternalFormatInfo
+{
+    GLenum mEffectiveFormat;
+    GLenum mDestFormat;
+    GLuint mMinRedBits;
+    GLuint mMaxRedBits;
+    GLuint mMinGreenBits;
+    GLuint mMaxGreenBits;
+    GLuint mMinBlueBits;
+    GLuint mMaxBlueBits;
+    GLuint mMinAlphaBits;
+    GLuint mMaxAlphaBits;
+
+    EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
+                                GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
+                                GLuint minAlphaBits, GLuint maxAlphaBits)
+        : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
+          mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
+          mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
+          mMaxAlphaBits(maxAlphaBits) {};
+};
+
+typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
+
+static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
+{
+    EffectiveInternalFormatList list;
+
+    // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
+    //                                                    linear source buffer component sizes.
+    //                                                                            | Source channel min/max sizes |
+    //                                         Effective Internal Format |  N/A   |  R   |  G   |  B   |  A      |
+    list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_NONE, 0,  0, 0,  0, 0,  0, 1, 8));
+    list.push_back(EffectiveInternalFormatInfo(GL_R8,                      GL_NONE, 1,  8, 0,  0, 0,  0, 0, 0));
+    list.push_back(EffectiveInternalFormatInfo(GL_RG8,                     GL_NONE, 1,  8, 1,  8, 0,  0, 0, 0));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_NONE, 1,  5, 1,  6, 1,  5, 0, 0));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_NONE, 6,  8, 7,  8, 6,  8, 0, 0));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_NONE, 1,  4, 1,  4, 1,  4, 1, 4));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_NONE, 5,  5, 5,  5, 5,  5, 1, 1));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_NONE, 5,  8, 5,  8, 5,  8, 2, 8));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2,                GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
+
+    return list;
+}
+
+static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
+{
+    EffectiveInternalFormatList list;
+
+    // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
+    //                                                    linear source buffer component sizes.
+    //                                                                                        |          Source channel min/max sizes            |
+    //                                         Effective Internal Format |    Dest Format     |     R     |      G     |      B     |      A     |
+    list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_ALPHA,           0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
+    list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT,          GL_LUMINANCE,       1,        8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
+    list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT,   GL_LUMINANCE_ALPHA, 1,        8, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_RGB,             1,        5, 1,        6, 1,        5, 0, UINT_MAX));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_RGB,             6,        8, 7,        8, 6,        8, 0, UINT_MAX));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_RGBA,            1,        4, 1,        4, 1,        4, 1,        4));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_RGBA,            5,        5, 5,        5, 5,        5, 1,        1));
+    list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_RGBA,            5,        8, 5,        8, 5,        8, 5,        8));
+
+    return list;
+}
+
+static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat, const InternalFormat &destFormat,
+                                       GLenum *outEffectiveFormat)
+{
+    const EffectiveInternalFormatList *list = NULL;
+    GLenum targetFormat = GL_NONE;
+
+    if (destFormat.pixelBytes > 0)
+    {
+        static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
+        list = &sizedList;
+    }
+    else
+    {
+        static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
+        list = &unsizedList;
+        targetFormat = destFormat.format;
+    }
+
+    for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
+    {
+        const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
+        if ((formatInfo.mDestFormat == targetFormat) &&
+            (formatInfo.mMinRedBits   <= srcFormat.redBits   && formatInfo.mMaxRedBits   >= srcFormat.redBits)   &&
+            (formatInfo.mMinGreenBits <= srcFormat.greenBits && formatInfo.mMaxGreenBits >= srcFormat.greenBits) &&
+            (formatInfo.mMinBlueBits  <= srcFormat.blueBits  && formatInfo.mMaxBlueBits  >= srcFormat.blueBits)  &&
+            (formatInfo.mMinAlphaBits <= srcFormat.alphaBits && formatInfo.mMaxAlphaBits >= srcFormat.alphaBits))
+        {
+            *outEffectiveFormat = formatInfo.mEffectiveFormat;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+struct CopyConversion
+{
+    GLenum mTextureFormat;
+    GLenum mFramebufferFormat;
+
+    CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
+        : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
+
+    bool operator<(const CopyConversion& other) const
+    {
+        return memcmp(this, &other, sizeof(CopyConversion)) < 0;
+    }
+};
+
+typedef std::set<CopyConversion> CopyConversionSet;
+
+static CopyConversionSet BuildValidES3CopyTexImageCombinations()
+{
+    CopyConversionSet set;
+
+    // From ES 3.0.1 spec, table 3.15
+    set.insert(CopyConversion(GL_ALPHA, GL_RGBA));
+    set.insert(CopyConversion(GL_LUMINANCE, GL_RED));
+    set.insert(CopyConversion(GL_LUMINANCE, GL_RG));
+    set.insert(CopyConversion(GL_LUMINANCE, GL_RGB));
+    set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA));
+    set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
+    set.insert(CopyConversion(GL_RED, GL_RED));
+    set.insert(CopyConversion(GL_RED, GL_RG));
+    set.insert(CopyConversion(GL_RED, GL_RGB));
+    set.insert(CopyConversion(GL_RED, GL_RGBA));
+    set.insert(CopyConversion(GL_RG, GL_RG));
+    set.insert(CopyConversion(GL_RG, GL_RGB));
+    set.insert(CopyConversion(GL_RG, GL_RGBA));
+    set.insert(CopyConversion(GL_RGB, GL_RGB));
+    set.insert(CopyConversion(GL_RGB, GL_RGBA));
+    set.insert(CopyConversion(GL_RGBA, GL_RGBA));
+
+    // Necessary for ANGLE back-buffers
+    set.insert(CopyConversion(GL_ALPHA, GL_BGRA_EXT));
+    set.insert(CopyConversion(GL_LUMINANCE, GL_BGRA_EXT));
+    set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
+    set.insert(CopyConversion(GL_RED, GL_BGRA_EXT));
+    set.insert(CopyConversion(GL_RG, GL_BGRA_EXT));
+    set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT));
+    set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT));
+
+    set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER));
+    set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER));
+    set.insert(CopyConversion(GL_RED_INTEGER, GL_RGB_INTEGER));
+    set.insert(CopyConversion(GL_RED_INTEGER, GL_RGBA_INTEGER));
+    set.insert(CopyConversion(GL_RG_INTEGER, GL_RG_INTEGER));
+    set.insert(CopyConversion(GL_RG_INTEGER, GL_RGB_INTEGER));
+    set.insert(CopyConversion(GL_RG_INTEGER, GL_RGBA_INTEGER));
+    set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGB_INTEGER));
+    set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGBA_INTEGER));
+    set.insert(CopyConversion(GL_RGBA_INTEGER, GL_RGBA_INTEGER));
+
+    return set;
+}
+
+static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle)
+{
+    const InternalFormat &textureInternalFormatInfo = GetInternalFormatInfo(textureInternalFormat);
+    const InternalFormat &framebufferInternalFormatInfo = GetInternalFormatInfo(frameBufferInternalFormat);
+
+    static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
+    if (conversionSet.find(CopyConversion(textureInternalFormatInfo.format, framebufferInternalFormatInfo.format)) != conversionSet.end())
+    {
+        // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
+        // must both be signed, unsigned, or fixed point and both source and destinations
+        // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
+        // conversion between fixed and floating point.
+
+        if ((textureInternalFormatInfo.colorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.colorEncoding == GL_SRGB))
+        {
+            return false;
+        }
+
+        if (((textureInternalFormatInfo.componentType == GL_INT)          != (framebufferInternalFormatInfo.componentType == GL_INT         )) ||
+            ((textureInternalFormatInfo.componentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.componentType == GL_UNSIGNED_INT)))
+        {
+            return false;
+        }
+
+        if ((textureInternalFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
+             textureInternalFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
+             textureInternalFormatInfo.componentType == GL_FLOAT) &&
+            !(framebufferInternalFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
+              framebufferInternalFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
+              framebufferInternalFormatInfo.componentType == GL_FLOAT))
+        {
+            return false;
+        }
+
+        // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
+        // The effective internal format of the source buffer is determined with the following rules applied in order:
+        //    * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
+        //      effective internal format is the source buffer's sized internal format.
+        //    * If the source buffer is a texture that was created with an unsized base internal format, then the
+        //      effective internal format is the source image array's effective internal format, as specified by table
+        //      3.12, which is determined from the <format> and <type> that were used when the source image array was
+        //      specified by TexImage*.
+        //    * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
+        //      Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
+        //      with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
+        //      FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
+        //      is SRGB.
+        const InternalFormat *sourceEffectiveFormat = NULL;
+        if (readBufferHandle != 0)
+        {
+            // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
+            if (framebufferInternalFormatInfo.pixelBytes > 0)
+            {
+                sourceEffectiveFormat = &framebufferInternalFormatInfo;
+            }
+            else
+            {
+                // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
+                // texture. We can use the same table we use when creating textures to get its effective sized format.
+                const FormatType &typeInfo = GetFormatTypeInfo(framebufferInternalFormatInfo.format, framebufferInternalFormatInfo.type);
+                sourceEffectiveFormat = &GetInternalFormatInfo(typeInfo.internalFormat);
+            }
+        }
+        else
+        {
+            // The effective internal format must be derived from the source framebuffer's channel sizes.
+            // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
+            if (framebufferInternalFormatInfo.colorEncoding == GL_LINEAR)
+            {
+                GLenum effectiveFormat;
+                if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat))
+                {
+                    sourceEffectiveFormat = &GetInternalFormatInfo(effectiveFormat);
+                }
+                else
+                {
+                    return false;
+                }
+            }
+            else if (framebufferInternalFormatInfo.colorEncoding == GL_SRGB)
+            {
+                // SRGB buffers can only be copied to sized format destinations according to table 3.18
+                if ((textureInternalFormatInfo.pixelBytes > 0) &&
+                    (framebufferInternalFormatInfo.redBits   >= 1 && framebufferInternalFormatInfo.redBits   <= 8) &&
+                    (framebufferInternalFormatInfo.greenBits >= 1 && framebufferInternalFormatInfo.greenBits <= 8) &&
+                    (framebufferInternalFormatInfo.blueBits  >= 1 && framebufferInternalFormatInfo.blueBits  <= 8) &&
+                    (framebufferInternalFormatInfo.alphaBits >= 1 && framebufferInternalFormatInfo.alphaBits <= 8))
+                {
+                    sourceEffectiveFormat = &GetInternalFormatInfo(GL_SRGB8_ALPHA8);
+                }
+                else
+                {
+                    return false;
+                }
+            }
+            else
+            {
+                UNREACHABLE();
+                return false;
+            }
+        }
+
+        if (textureInternalFormatInfo.pixelBytes > 0)
+        {
+            // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
+            // component sizes of the source and destination formats must exactly match
+            if (textureInternalFormatInfo.redBits   != sourceEffectiveFormat->redBits   ||
+                textureInternalFormatInfo.greenBits != sourceEffectiveFormat->greenBits ||
+                textureInternalFormatInfo.blueBits  != sourceEffectiveFormat->blueBits  ||
+                textureInternalFormatInfo.alphaBits != sourceEffectiveFormat->alphaBits)
+            {
+                return false;
+            }
+        }
+
+
+        return true; // A conversion function exists, and no rule in the specification has precluded conversion
+                     // between these formats.
+    }
+
+    return false;
+}
+
+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)
 {
@@ -315,16 +870,18 @@
         return false;
     }
 
-    gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+    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->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
+    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();
@@ -332,20 +889,20 @@
 
     if (isSubImage)
     {
-        if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
-                                                context->getReadFramebufferHandle(),
-                                                context->getClientVersion()))
+        if (!IsValidES3CopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
+                                               context->getState().getReadFramebuffer()->id()))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
     else
     {
-        if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat,
-                                                context->getReadFramebufferHandle(),
-                                                context->getClientVersion()))
+        if (!gl::IsValidES3CopyTexImageCombination(internalformat, colorbufferInternalFormat,
+                                                context->getState().getReadFramebuffer()->id()))
         {
-            return gl::error(GL_INVALID_OPERATION, false);
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
@@ -353,19 +910,23 @@
     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();
+
     gl::Texture *texture = NULL;
     switch (target)
     {
@@ -373,10 +934,11 @@
         {
             texture = context->getTexture2D();
 
-            if (width > (context->getMaximum2DTextureDimension()) ||
-                height > (context->getMaximum2DTextureDimension()))
+            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;
@@ -387,12 +949,14 @@
 
             if (width != height)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
 
-            if (width > (context->getMaximumCubeTextureDimension()))
+            if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize)
             {
-                return gl::error(GL_INVALID_VALUE, false);
+                context->recordError(Error(GL_INVALID_VALUE));
+                return false;
             }
         }
         break;
@@ -401,11 +965,12 @@
         {
             texture = context->getTexture3D();
 
-            if (width > (context->getMaximum3DTextureDimension()) ||
-                height > (context->getMaximum3DTextureDimension()) ||
-                depth > (context->getMaximum3DTextureDimension()))
+            if (static_cast<GLuint>(width) > caps.max3DTextureSize ||
+                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;
@@ -414,215 +979,136 @@
         {
             texture = context->getTexture2DArray();
 
-            if (width > (context->getMaximum2DTextureDimension()) ||
-                height > (context->getMaximum2DTextureDimension()) ||
-                depth > (context->getMaximum2DArrayTextureLayers()))
+            if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
+                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;
     }
 
-    if (!gl::IsValidInternalFormat(internalformat, context))
+    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 (!gl::IsSizedInternalFormat(internalformat, context->getClientVersion()))
+    if (formatInfo.pixelBytes == 0)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_ENUM));
+        return false;
     }
 
     return true;
 }
 
-bool ValidateES3FramebufferTextureParameters(gl::Context *context, GLenum target, GLenum attachment,
-                                             GLenum textarget, GLuint texture, GLint level, GLint layer,
-                                             bool layerCall)
+bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment,
+                                     GLuint texture, GLint level, GLint layer)
 {
-    if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
+    if (context->getClientVersion() < 3)
     {
-        return gl::error(GL_INVALID_ENUM, false);
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
     }
 
-    if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
+    if (layer < 0)
     {
-        const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0);
-        if (colorAttachment >= context->getMaximumRenderTargets())
-        {
-            return gl::error(GL_INVALID_VALUE, false);
-        }
-    }
-    else
-    {
-        switch (attachment)
-        {
-          case GL_DEPTH_ATTACHMENT:
-          case GL_STENCIL_ATTACHMENT:
-          case GL_DEPTH_STENCIL_ATTACHMENT:
-            break;
-          default:
-            return gl::error(GL_INVALID_ENUM, false);
-        }
+        context->recordError(Error(GL_INVALID_VALUE));
+        return false;
     }
 
+    if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
+    {
+        return false;
+    }
+
+    const gl::Caps &caps = context->getCaps();
     if (texture != 0)
     {
         gl::Texture *tex = context->getTexture(texture);
+        ASSERT(tex);
 
-        if (tex == NULL)
+        switch (tex->getTarget())
         {
-            return gl::error(GL_INVALID_OPERATION, false);
-        }
-
-        if (level < 0)
-        {
-            return gl::error(GL_INVALID_VALUE, false);
-        }
-
-        if (layer < 0)
-        {
-            return gl::error(GL_INVALID_VALUE, false);
-        }
-
-        if (!layerCall)
-        {
-            switch (textarget)
+          case GL_TEXTURE_2D_ARRAY:
             {
-              case GL_TEXTURE_2D:
+                if (level > gl::log2(caps.max2DTextureSize))
                 {
-                    if (level > gl::log2(context->getMaximum2DTextureDimension()))
-                    {
-                        return gl::error(GL_INVALID_VALUE, false);
-                    }
-                    if (tex->getTarget() != GL_TEXTURE_2D)
-                    {
-                        return gl::error(GL_INVALID_OPERATION, false);
-                    }
-                    gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
-                    if (tex2d->isCompressed(level))
-                    {
-                        return gl::error(GL_INVALID_OPERATION, false);
-                    }
-                    break;
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
 
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+                if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
                 {
-                    if (level > gl::log2(context->getMaximumCubeTextureDimension()))
-                    {
-                        return gl::error(GL_INVALID_VALUE, false);
-                    }
-                    if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
-                    {
-                        return gl::error(GL_INVALID_OPERATION, false);
-                    }
-                    gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
-                    if (texcube->isCompressed(textarget, level))
-                    {
-                        return gl::error(GL_INVALID_OPERATION, false);
-                    }
-                    break;
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
 
-              default:
-                return gl::error(GL_INVALID_ENUM, false);
+                gl::Texture2DArray *texArray = static_cast<gl::Texture2DArray *>(tex);
+                if (texArray->isCompressed(level))
+                {
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
+                }
             }
-        }
-        else
-        {
-            switch (tex->getTarget())
+            break;
+
+          case GL_TEXTURE_3D:
             {
-              case GL_TEXTURE_2D_ARRAY:
+                if (level > gl::log2(caps.max3DTextureSize))
                 {
-                    if (level > gl::log2(context->getMaximum2DTextureDimension()))
-                    {
-                        return gl::error(GL_INVALID_VALUE, false);
-                    }
-
-                    if (layer >= context->getMaximum2DArrayTextureLayers())
-                    {
-                        return gl::error(GL_INVALID_VALUE, false);
-                    }
-
-                    gl::Texture2DArray *texArray = static_cast<gl::Texture2DArray *>(tex);
-                    if (texArray->isCompressed(level))
-                    {
-                        return gl::error(GL_INVALID_OPERATION, false);
-                    }
-
-                    break;
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
 
-              case GL_TEXTURE_3D:
+                if (static_cast<GLuint>(layer) >= caps.max3DTextureSize)
                 {
-                    if (level > gl::log2(context->getMaximum3DTextureDimension()))
-                    {
-                        return gl::error(GL_INVALID_VALUE, false);
-                    }
-
-                    if (layer >= context->getMaximum3DTextureDimension())
-                    {
-                        return gl::error(GL_INVALID_VALUE, false);
-                    }
-
-                    gl::Texture3D *tex3d = static_cast<gl::Texture3D *>(tex);
-                    if (tex3d->isCompressed(level))
-                    {
-                        return gl::error(GL_INVALID_OPERATION, false);
-                    }
-
-                    break;
+                    context->recordError(Error(GL_INVALID_VALUE));
+                    return false;
                 }
 
-              default:
-                return gl::error(GL_INVALID_OPERATION, false);
+                gl::Texture3D *tex3d = static_cast<gl::Texture3D *>(tex);
+                if (tex3d->isCompressed(level))
+                {
+                    context->recordError(Error(GL_INVALID_OPERATION));
+                    return false;
+                }
             }
+            break;
+
+          default:
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return false;
         }
     }
 
-    gl::Framebuffer *framebuffer = NULL;
-    GLuint framebufferHandle = 0;
-    if (target == GL_READ_FRAMEBUFFER)
-    {
-        framebuffer = context->getReadFramebuffer();
-        framebufferHandle = context->getReadFramebufferHandle();
-    }
-    else
-    {
-        framebuffer = context->getDrawFramebuffer();
-        framebufferHandle = context->getDrawFramebufferHandle();
-    }
-
-    if (framebufferHandle == 0 || !framebuffer)
-    {
-        return gl::error(GL_INVALID_OPERATION, 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);
+
     switch (format)
     {
       case GL_RGBA:
@@ -637,7 +1123,7 @@
             }
             break;
           case GL_FLOAT:
-            if (gl::GetComponentType(internalFormat, 3) != GL_FLOAT)
+            if (internalFormatInfo.componentType != GL_FLOAT)
             {
                 return false;
             }
@@ -650,13 +1136,13 @@
         switch (type)
         {
           case GL_INT:
-            if (gl::GetComponentType(internalFormat, 3) != GL_INT)
+            if (internalFormatInfo.componentType != GL_INT)
             {
                 return false;
             }
             break;
           case GL_UNSIGNED_INT:
-            if (gl::GetComponentType(internalFormat, 3) != GL_UNSIGNED_INT)
+            if (internalFormatInfo.componentType != GL_UNSIGNED_INT)
             {
                 return false;
             }
@@ -678,7 +1164,7 @@
         break;
       case GL_RG_EXT:
       case GL_RED_EXT:
-        if (!context->supportsRGTextures())
+        if (!context->getExtensions().textureRG)
         {
             return false;
         }
@@ -696,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;
@@ -705,13 +1191,14 @@
     {
       case GL_DRAW_FRAMEBUFFER:
       case GL_FRAMEBUFFER:
-        defaultFramebuffer = context->getDrawFramebufferHandle() == 0;
+        defaultFramebuffer = context->getState().getDrawFramebuffer()->id() == 0;
         break;
       case GL_READ_FRAMEBUFFER:
-        defaultFramebuffer = context->getReadFramebufferHandle() == 0;
+        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)
@@ -720,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->getMaximumRenderTargets())
+            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
@@ -737,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:
@@ -745,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;
             }
         }
     }
@@ -757,4 +1249,33 @@
     return true;
 }
 
+bool ValidateClearBuffer(Context *context)
+{
+    if (context->getClientVersion() < 3)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
+    if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
+    {
+        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 93917c2..cafacca 100644
--- a/src/libGLESv2/validationES3.h
+++ b/src/libGLESv2/validationES3.h
@@ -9,31 +9,36 @@
 #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 ValidateES3FramebufferTextureParameters(gl::Context *context, GLenum target, GLenum attachment,
-                                             GLenum textarget, GLuint texture, GLint level, GLint layer,
-                                             bool layerCall);
+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(Context *context);
+
+bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params);
+
 }
 
 #endif // LIBGLESV2_VALIDATION_ES3_H
diff --git a/src/preprocessor.target.darwin-arm.mk b/src/preprocessor.target.darwin-arm.mk
index 5791e30..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 \
@@ -82,8 +81,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -100,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -128,23 +126,24 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -154,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 \
@@ -186,8 +185,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -204,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -232,69 +230,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 d9444d0..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,14 +63,13 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -89,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -117,21 +115,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -163,8 +162,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -181,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -209,60 +207,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 b474672..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 \
@@ -77,8 +74,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -95,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -123,24 +119,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -149,8 +146,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -176,8 +171,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -194,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -222,65 +216,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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-mips64.mk b/src/preprocessor.target.darwin-mips64.mk
new file mode 100644
index 0000000..c9c8134
--- /dev/null
+++ b/src/preprocessor.target.darwin-mips64.mk
@@ -0,0 +1,251 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
+LOCAL_MODULE_SUFFIX := .a
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp \
+	third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp \
+	third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp \
+	third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp \
+	third_party/angle/src/compiler/preprocessor/Input.cpp \
+	third_party/angle/src/compiler/preprocessor/Lexer.cpp \
+	third_party/angle/src/compiler/preprocessor/Macro.cpp \
+	third_party/angle/src/compiler/preprocessor/MacroExpander.cpp \
+	third_party/angle/src/compiler/preprocessor/Preprocessor.cpp \
+	third_party/angle/src/compiler/preprocessor/Token.cpp \
+	third_party/angle/src/compiler/preprocessor/Tokenizer.cpp
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-g \
+	-gdwarf-4 \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir) \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir) \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_preprocessor_gyp
+
+# Alias gyp target name.
+.PHONY: preprocessor
+preprocessor: third_party_angle_src_preprocessor_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/preprocessor.target.darwin-x86.mk b/src/preprocessor.target.darwin-x86.mk
index a0b45a8..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 \
@@ -77,8 +76,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -95,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -123,21 +121,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -175,8 +174,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -193,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -221,64 +219,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 e026795..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 \
@@ -76,8 +75,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -94,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -122,22 +120,23 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -173,8 +172,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -191,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -219,64 +217,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 5791e30..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 \
@@ -82,8 +81,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -100,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -128,23 +126,24 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -154,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 \
@@ -186,8 +185,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -204,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -232,69 +230,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 d9444d0..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,14 +63,13 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -89,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -117,21 +115,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -163,8 +162,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -181,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -209,60 +207,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 b474672..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 \
@@ -77,8 +74,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -95,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -123,24 +119,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -149,8 +146,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -176,8 +171,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -194,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -222,65 +216,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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-mips64.mk b/src/preprocessor.target.linux-mips64.mk
new file mode 100644
index 0000000..c9c8134
--- /dev/null
+++ b/src/preprocessor.target.linux-mips64.mk
@@ -0,0 +1,251 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_angle_src_preprocessor_gyp
+LOCAL_MODULE_SUFFIX := .a
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp \
+	third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp \
+	third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp \
+	third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp \
+	third_party/angle/src/compiler/preprocessor/Input.cpp \
+	third_party/angle/src/compiler/preprocessor/Lexer.cpp \
+	third_party/angle/src/compiler/preprocessor/Macro.cpp \
+	third_party/angle/src/compiler/preprocessor/MacroExpander.cpp \
+	third_party/angle/src/compiler/preprocessor/Preprocessor.cpp \
+	third_party/angle/src/compiler/preprocessor/Token.cpp \
+	third_party/angle/src/compiler/preprocessor/Tokenizer.cpp
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-g \
+	-gdwarf-4 \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir) \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir) \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_preprocessor_gyp
+
+# Alias gyp target name.
+.PHONY: preprocessor
+preprocessor: third_party_angle_src_preprocessor_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/preprocessor.target.linux-x86.mk b/src/preprocessor.target.linux-x86.mk
index a0b45a8..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 \
@@ -77,8 +76,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -95,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -123,21 +121,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -175,8 +174,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -193,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -221,64 +219,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 e026795..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 \
@@ -76,8 +75,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -94,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -122,22 +120,23 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -173,8 +172,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -191,12 +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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -219,64 +217,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 9a95bd2..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))
@@ -23,14 +22,14 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -40,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 \
@@ -65,6 +64,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -72,8 +72,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -90,13 +88,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -121,23 +120,24 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -147,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 \
@@ -179,8 +179,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -197,13 +195,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -228,69 +227,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 4831b79..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))
@@ -23,13 +22,13 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # 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 \
@@ -55,14 +54,13 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -79,13 +77,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -110,21 +109,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -156,8 +156,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -174,13 +172,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -205,60 +204,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 8be98ed..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))
@@ -23,7 +22,8 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -31,7 +31,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -40,8 +39,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -60,6 +57,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -67,8 +65,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -85,13 +81,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -116,24 +113,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -142,8 +140,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -169,8 +165,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -187,13 +181,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -218,65 +213,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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-mips64.mk b/src/translator.target.darwin-mips64.mk
new file mode 100644
index 0000000..2336fd6
--- /dev/null
+++ b/src/translator.target.darwin-mips64.mk
@@ -0,0 +1,248 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_angle_src_translator_gyp
+LOCAL_MODULE_SUFFIX := .a
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-g \
+	-gdwarf-4 \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/angle/src \
+	$(LOCAL_PATH)/third_party/angle/include \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/angle/src \
+	$(LOCAL_PATH)/third_party/angle/include \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_translator_gyp
+
+# Alias gyp target name.
+.PHONY: translator
+translator: third_party_angle_src_translator_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/translator.target.darwin-x86.mk b/src/translator.target.darwin-x86.mk
index b0becf7..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))
@@ -23,13 +22,13 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # 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 \
@@ -60,6 +59,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -67,8 +67,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -85,13 +83,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -116,21 +115,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -168,8 +168,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -186,13 +184,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -217,64 +216,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 f3d83ca..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))
@@ -23,14 +22,14 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -59,6 +58,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -66,8 +66,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -84,13 +82,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -115,22 +114,23 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -166,8 +166,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -184,13 +182,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -215,64 +214,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 9a95bd2..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))
@@ -23,14 +22,14 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -40,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 \
@@ -65,6 +64,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -72,8 +72,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -90,13 +88,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -121,23 +120,24 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -147,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 \
@@ -179,8 +179,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -197,13 +195,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -228,69 +227,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 4831b79..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))
@@ -23,13 +22,13 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # 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 \
@@ -55,14 +54,13 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -79,13 +77,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -110,21 +109,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -156,8 +156,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -174,13 +172,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -205,60 +204,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 8be98ed..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))
@@ -23,7 +22,8 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -31,7 +31,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -40,8 +39,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -60,6 +57,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -67,8 +65,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -85,13 +81,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -116,24 +113,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -142,8 +140,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -169,8 +165,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -187,13 +181,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -218,65 +213,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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-mips64.mk b/src/translator.target.linux-mips64.mk
new file mode 100644
index 0000000..2336fd6
--- /dev/null
+++ b/src/translator.target.linux-mips64.mk
@@ -0,0 +1,248 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_angle_src_translator_gyp
+LOCAL_MODULE_SUFFIX := .a
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-g \
+	-gdwarf-4 \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/angle/src \
+	$(LOCAL_PATH)/third_party/angle/include \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/angle/src \
+	$(LOCAL_PATH)/third_party/angle/include \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_translator_gyp
+
+# Alias gyp target name.
+.PHONY: translator
+translator: third_party_angle_src_translator_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/translator.target.linux-x86.mk b/src/translator.target.linux-x86.mk
index b0becf7..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))
@@ -23,13 +22,13 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # 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 \
@@ -60,6 +59,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -67,8 +67,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -85,13 +83,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -116,21 +115,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -168,8 +168,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -186,13 +184,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -217,64 +216,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 f3d83ca..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))
@@ -23,14 +22,14 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	third_party/angle/src/compiler/translator/ShaderLang.cpp
+	third_party/angle/src/compiler/translator/ShaderLang.cpp \
+	third_party/angle/src/compiler/translator/ShaderVars.cpp
 
 
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Debug := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -59,6 +58,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -66,8 +66,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -84,13 +82,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -115,22 +114,23 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -166,8 +166,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -184,13 +182,14 @@
 	'-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' \
-	'-DNOMINMAX' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -215,64 +214,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 250d907..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -88,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 \
@@ -98,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 \
@@ -123,6 +127,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -130,8 +135,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -148,12 +151,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -178,23 +183,24 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -204,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 \
@@ -236,8 +242,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -254,12 +258,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -284,69 +290,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 26d9daf..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -87,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 \
@@ -113,14 +117,13 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -137,12 +140,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -167,21 +172,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -213,8 +219,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -231,12 +235,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -261,60 +267,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 4f5a8b4..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -89,7 +94,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -98,8 +102,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -118,6 +120,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -125,8 +128,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -143,12 +144,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -173,24 +176,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -199,8 +203,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,8 +228,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -244,12 +244,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -274,65 +276,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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-mips64.mk b/src/translator_lib.target.darwin-mips64.mk
new file mode 100644
index 0000000..a8ba23e
--- /dev/null
+++ b/src/translator_lib.target.darwin-mips64.mk
@@ -0,0 +1,311 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
+LOCAL_MODULE_SUFFIX := .a
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	third_party/angle/src/common/RefCountObject.cpp \
+	third_party/angle/src/common/blocklayout.cpp \
+	third_party/angle/src/common/debug.cpp \
+	third_party/angle/src/common/event_tracer.cpp \
+	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
+	third_party/angle/src/common/utilities.cpp \
+	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
+	third_party/angle/src/compiler/translator/CodeGen.cpp \
+	third_party/angle/src/compiler/translator/Compiler.cpp \
+	third_party/angle/src/compiler/translator/DetectCallDepth.cpp \
+	third_party/angle/src/compiler/translator/DetectDiscontinuity.cpp \
+	third_party/angle/src/compiler/translator/Diagnostics.cpp \
+	third_party/angle/src/compiler/translator/DirectiveHandler.cpp \
+	third_party/angle/src/compiler/translator/FlagStd140Structs.cpp \
+	third_party/angle/src/compiler/translator/ForLoopUnroll.cpp \
+	third_party/angle/src/compiler/translator/InfoSink.cpp \
+	third_party/angle/src/compiler/translator/Initialize.cpp \
+	third_party/angle/src/compiler/translator/InitializeDll.cpp \
+	third_party/angle/src/compiler/translator/InitializeParseContext.cpp \
+	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 \
+	third_party/angle/src/compiler/translator/OutputGLSLBase.cpp \
+	third_party/angle/src/compiler/translator/OutputHLSL.cpp \
+	third_party/angle/src/compiler/translator/ParseContext.cpp \
+	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
+	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
+	third_party/angle/src/compiler/translator/RemoveTree.cpp \
+	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
+	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
+	third_party/angle/src/compiler/translator/SymbolTable.cpp \
+	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
+	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
+	third_party/angle/src/compiler/translator/TranslatorHLSL.cpp \
+	third_party/angle/src/compiler/translator/Types.cpp \
+	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
+	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
+	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
+	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
+	third_party/angle/src/compiler/translator/VariableInfo.cpp \
+	third_party/angle/src/compiler/translator/VariablePacker.cpp \
+	third_party/angle/src/compiler/translator/VersionGLSL.cpp \
+	third_party/angle/src/compiler/translator/compilerdebug.cpp \
+	third_party/angle/src/compiler/translator/depgraph/DependencyGraph.cpp \
+	third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp \
+	third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp \
+	third_party/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp \
+	third_party/angle/src/compiler/translator/glslang_lex.cpp \
+	third_party/angle/src/compiler/translator/glslang_tab.cpp \
+	third_party/angle/src/compiler/translator/intermOut.cpp \
+	third_party/angle/src/compiler/translator/parseConst.cpp \
+	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
+	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
+	third_party/angle/src/compiler/translator/util.cpp \
+	third_party/angle/src/third_party/compiler/ArrayBoundsClamper.cpp
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-g \
+	-gdwarf-4 \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/angle/src \
+	$(LOCAL_PATH)/third_party/angle/include \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/angle/src \
+	$(LOCAL_PATH)/third_party/angle/include \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_translator_lib_gyp
+
+# Alias gyp target name.
+.PHONY: translator_lib
+translator_lib: third_party_angle_src_translator_lib_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/translator_lib.target.darwin-x86.mk b/src/translator_lib.target.darwin-x86.mk
index fbe45c4..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -87,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 +122,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -125,8 +130,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -143,12 +146,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -173,21 +178,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -225,8 +231,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -243,12 +247,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -273,64 +279,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 5898630..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -88,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 \
@@ -117,6 +121,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -124,8 +129,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -142,12 +145,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -172,22 +177,23 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -223,8 +229,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -241,12 +245,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -271,64 +277,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 250d907..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -88,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 \
@@ -98,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 \
@@ -123,6 +127,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -130,8 +135,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -148,12 +151,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -178,23 +183,24 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -204,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 \
@@ -236,8 +242,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -254,12 +258,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -284,69 +290,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-abi \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 26d9daf..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -87,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 \
@@ -113,14 +117,13 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-funwind-tables
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -137,12 +140,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -167,21 +172,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -213,8 +219,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -231,12 +235,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -261,60 +267,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 4f5a8b4..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -89,7 +94,6 @@
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -98,8 +102,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -118,6 +120,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -125,8 +128,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -143,12 +144,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -173,24 +176,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
 	 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -199,8 +203,6 @@
 	-fPIC \
 	-Wno-unused-local-typedefs \
 	-Wno-format \
-	-EL \
-	-mhard-float \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,8 +228,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -244,12 +244,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -274,65 +276,26 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
 	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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-mips64.mk b/src/translator_lib.target.linux-mips64.mk
new file mode 100644
index 0000000..a8ba23e
--- /dev/null
+++ b/src/translator_lib.target.linux-mips64.mk
@@ -0,0 +1,311 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_angle_src_translator_lib_gyp
+LOCAL_MODULE_SUFFIX := .a
+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))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	third_party/angle/src/common/RefCountObject.cpp \
+	third_party/angle/src/common/blocklayout.cpp \
+	third_party/angle/src/common/debug.cpp \
+	third_party/angle/src/common/event_tracer.cpp \
+	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
+	third_party/angle/src/common/utilities.cpp \
+	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
+	third_party/angle/src/compiler/translator/CodeGen.cpp \
+	third_party/angle/src/compiler/translator/Compiler.cpp \
+	third_party/angle/src/compiler/translator/DetectCallDepth.cpp \
+	third_party/angle/src/compiler/translator/DetectDiscontinuity.cpp \
+	third_party/angle/src/compiler/translator/Diagnostics.cpp \
+	third_party/angle/src/compiler/translator/DirectiveHandler.cpp \
+	third_party/angle/src/compiler/translator/FlagStd140Structs.cpp \
+	third_party/angle/src/compiler/translator/ForLoopUnroll.cpp \
+	third_party/angle/src/compiler/translator/InfoSink.cpp \
+	third_party/angle/src/compiler/translator/Initialize.cpp \
+	third_party/angle/src/compiler/translator/InitializeDll.cpp \
+	third_party/angle/src/compiler/translator/InitializeParseContext.cpp \
+	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 \
+	third_party/angle/src/compiler/translator/OutputGLSLBase.cpp \
+	third_party/angle/src/compiler/translator/OutputHLSL.cpp \
+	third_party/angle/src/compiler/translator/ParseContext.cpp \
+	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
+	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
+	third_party/angle/src/compiler/translator/RemoveTree.cpp \
+	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
+	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
+	third_party/angle/src/compiler/translator/SymbolTable.cpp \
+	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
+	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
+	third_party/angle/src/compiler/translator/TranslatorHLSL.cpp \
+	third_party/angle/src/compiler/translator/Types.cpp \
+	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
+	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
+	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
+	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
+	third_party/angle/src/compiler/translator/VariableInfo.cpp \
+	third_party/angle/src/compiler/translator/VariablePacker.cpp \
+	third_party/angle/src/compiler/translator/VersionGLSL.cpp \
+	third_party/angle/src/compiler/translator/compilerdebug.cpp \
+	third_party/angle/src/compiler/translator/depgraph/DependencyGraph.cpp \
+	third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp \
+	third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp \
+	third_party/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp \
+	third_party/angle/src/compiler/translator/glslang_lex.cpp \
+	third_party/angle/src/compiler/translator/glslang_tab.cpp \
+	third_party/angle/src/compiler/translator/intermOut.cpp \
+	third_party/angle/src/compiler/translator/parseConst.cpp \
+	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
+	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
+	third_party/angle/src/compiler/translator/util.cpp \
+	third_party/angle/src/third_party/compiler/ArrayBoundsClamper.cpp
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-g \
+	-gdwarf-4 \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/angle/src \
+	$(LOCAL_PATH)/third_party/angle/include \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-strict-aliasing \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-Wno-format \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Wno-address \
+	-Wno-format-security \
+	-Wno-return-type \
+	-Wno-sequence-point \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_BROWSER_CDMS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DDATA_REDUCTION_FALLBACK_HOST="http://compress.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' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/angle/src \
+	$(LOCAL_PATH)/third_party/angle/include \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wno-deprecated \
+	-Wno-uninitialized \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo \
+	-Wno-non-virtual-dtor
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_angle_src_translator_lib_gyp
+
+# Alias gyp target name.
+.PHONY: translator_lib
+translator_lib: third_party_angle_src_translator_lib_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/translator_lib.target.linux-x86.mk b/src/translator_lib.target.linux-x86.mk
index fbe45c4..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -87,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 +122,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -125,8 +130,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -143,12 +146,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -173,21 +178,22 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # 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 \
@@ -225,8 +231,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -243,12 +247,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -273,64 +279,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 5898630..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))
@@ -28,6 +27,7 @@
 	third_party/angle/src/common/debug.cpp \
 	third_party/angle/src/common/event_tracer.cpp \
 	third_party/angle/src/common/mathutil.cpp \
+	third_party/angle/src/common/tls.cpp \
 	third_party/angle/src/common/utilities.cpp \
 	third_party/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp \
 	third_party/angle/src/compiler/translator/CodeGen.cpp \
@@ -45,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 \
@@ -53,9 +54,12 @@
 	third_party/angle/src/compiler/translator/ParseContext.cpp \
 	third_party/angle/src/compiler/translator/PoolAlloc.cpp \
 	third_party/angle/src/compiler/translator/QualifierAlive.cpp \
+	third_party/angle/src/compiler/translator/RegenerateStructNames.cpp \
 	third_party/angle/src/compiler/translator/RemoveTree.cpp \
 	third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp \
+	third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
 	third_party/angle/src/compiler/translator/SearchSymbol.cpp \
+	third_party/angle/src/compiler/translator/StructureHLSL.cpp \
 	third_party/angle/src/compiler/translator/SymbolTable.cpp \
 	third_party/angle/src/compiler/translator/TranslatorESSL.cpp \
 	third_party/angle/src/compiler/translator/TranslatorGLSL.cpp \
@@ -63,6 +67,8 @@
 	third_party/angle/src/compiler/translator/Types.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuit.cpp \
 	third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp \
+	third_party/angle/src/compiler/translator/UniformHLSL.cpp \
+	third_party/angle/src/compiler/translator/UtilsHLSL.cpp \
 	third_party/angle/src/compiler/translator/ValidateLimitations.cpp \
 	third_party/angle/src/compiler/translator/ValidateOutputs.cpp \
 	third_party/angle/src/compiler/translator/VariableInfo.cpp \
@@ -76,7 +82,6 @@
 	third_party/angle/src/compiler/translator/glslang_lex.cpp \
 	third_party/angle/src/compiler/translator/glslang_tab.cpp \
 	third_party/angle/src/compiler/translator/intermOut.cpp \
-	third_party/angle/src/compiler/translator/ossource_posix.cpp \
 	third_party/angle/src/compiler/translator/parseConst.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
 	third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \
@@ -88,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 \
@@ -117,6 +121,7 @@
 	-Wno-sequence-point \
 	-Os \
 	-g \
+	-gdwarf-4 \
 	-fdata-sections \
 	-ffunction-sections \
 	-fomit-frame-pointer \
@@ -124,8 +129,6 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -142,12 +145,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -172,22 +177,23 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Debug := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Debug := false
-
 # Flags passed to both C and C++ files.
 MY_CFLAGS_Release := \
 	-fstack-protector \
 	--param=ssp-buffer-size=4 \
-	-fno-exceptions \
 	-fno-strict-aliasing \
 	-Wno-unused-parameter \
 	-Wno-missing-field-initializers \
@@ -223,8 +229,6 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
-	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
-	'-DANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ TEXT("d3dcompiler_46.dll"), TEXT("d3dcompiler_43.dll") }' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -241,12 +245,14 @@
 	'-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' \
-	'-DNOMINMAX' \
+	'-DENABLE_LOAD_COMPLETION_HACKS=1' \
+	'-DANGLE_TRANSLATOR_STATIC' \
 	'-DUSE_OPENSSL=1' \
 	'-DUSE_OPENSSL_CERTS=1' \
 	'-DANDROID' \
@@ -271,64 +277,25 @@
 
 # Flags passed to only C++ (and not C) files.
 LOCAL_CPPFLAGS_Release := \
+	-fno-exceptions \
 	-fno-rtti \
 	-fno-threadsafe-statics \
 	-fvisibility-inlines-hidden \
 	-Wno-deprecated \
+	-std=gnu++11 \
+	-Wno-narrowing \
+	-Wno-literal-suffix \
 	-Wno-non-virtual-dtor \
 	-Wno-sign-promo \
 	-Wno-non-virtual-dtor
 
 
-LOCAL_FDO_SUPPORT_Release := false
-
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
-LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
 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 d8cd311..1bed5e7 100644
--- a/tests/angle_tests/ANGLETest.cpp
+++ b/tests/angle_tests/ANGLETest.cpp
@@ -1,26 +1,18 @@
 #include "ANGLETest.h"
+#include "EGLWindow.h"
+#include "OSWindow.h"
+
+OSWindow *ANGLETest::mOSWindow = NULL;
 
 ANGLETest::ANGLETest()
-    : 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.";
@@ -30,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)
@@ -97,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));
@@ -148,177 +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()
 {
-    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
-    };
+    return mEGLWindow->initializeGL(mOSWindow);
+}
 
-    EGLint configCount;
-    if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
+bool ANGLETest::destroyEGLContext()
+{
+    mEGLWindow->destroyGL();
+    return true;
+}
+
+bool ANGLETest::InitTestWindow()
+{
+    mOSWindow = CreateOSWindow();
+    if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
     {
-        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);
+    mOSWindow->setVisible(true);
 
-    EGLint samples;
-    eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLE_BUFFERS, &samples);
-    mMultisample = (samples != 0);
+    return true;
+}
 
-    mSurface = eglCreateWindowSurface(mDisplay, mConfig, mNativeWindow, NULL);
-    if(mSurface == EGL_NO_SURFACE)
+bool ANGLETest::DestroyTestWindow()
+{
+    if (mOSWindow)
     {
-        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)
 {
-    eglDestroySurface(mDisplay, mSurface);
-    eglDestroyContext(mDisplay, mContext);
-
-    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 7193c09..c3de55c 100644
--- a/tests/angle_tests/ANGLETest.h
+++ b/tests/angle_tests/ANGLETest.h
@@ -11,14 +11,12 @@
 
 #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 "angle_gl.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)
 
@@ -36,7 +34,8 @@
     EXPECT_EQ((a), pixel[3]); \
 }
 
-#define SHADER_SOURCE(...) #__VA_ARGS__
+class EGLWindow;
+class OSWindow;
 
 class ANGLETest : public testing::Test
 {
@@ -46,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();
@@ -56,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);
@@ -73,36 +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();
 
-    int mClientVersion;
-    int mWidth;
-    int mHeight;
-    int mRedBits;
-    int mGreenBits;
-    int mBlueBits;
-    int mAlphaBits;
-    int mDepthBits;
-    int mStencilBits;
-    bool mMultisample;
+    EGLWindow *mEGLWindow;
 
-    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 9b14fa8..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.";
@@ -136,19 +136,19 @@
     GLuint mColorRenderbuffer;
 };
 
-TEST_F(BlendMinMaxTest, rgba8)
+TEST_F(BlendMinMaxTest, RGBA8)
 {
     SetUpFramebuffer(GL_RGBA8);
     runTest();
 }
 
-TEST_F(BlendMinMaxTest, rgba32f)
+TEST_F(BlendMinMaxTest, RGBA32f)
 {
     SetUpFramebuffer(GL_RGBA32F);
     runTest();
 }
 
-TEST_F(BlendMinMaxTest, rgba16f)
+TEST_F(BlendMinMaxTest, RGBA16F)
 {
     SetUpFramebuffer(GL_RGBA16F);
     runTest();
diff --git a/tests/angle_tests/BlitFramebufferANGLETest.cpp b/tests/angle_tests/BlitFramebufferANGLETest.cpp
index 65302c9..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.";
@@ -302,7 +302,7 @@
 };
 
 // Draw to user-created framebuffer, blit whole-buffer color to original framebuffer.
-TEST_F(BlitFramebufferANGLETest, blit_color_to_default)
+TEST_F(BlitFramebufferANGLETest, BlitColorToDefault)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -329,7 +329,7 @@
 }
 
 // Draw to system framebuffer, blit whole-buffer color to user-created framebuffer.
-TEST_F(BlitFramebufferANGLETest, reverse_color_blit)
+TEST_F(BlitFramebufferANGLETest, ReverseColorBlit)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
 
@@ -356,7 +356,7 @@
 }
 
 // blit from user-created FBO to system framebuffer, with the scissor test enabled.
-TEST_F(BlitFramebufferANGLETest, scissored_blit)
+TEST_F(BlitFramebufferANGLETest, ScissoredBlit)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -391,7 +391,7 @@
 }
 
 // blit from system FBO to user-created framebuffer, with the scissor test enabled.
-TEST_F(BlitFramebufferANGLETest, reverse_scissored_blit)
+TEST_F(BlitFramebufferANGLETest, ReverseScissoredBlit)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
 
@@ -426,7 +426,7 @@
 }
 
 // blit from user-created FBO to system framebuffer, using region larger than buffer.
-TEST_F(BlitFramebufferANGLETest, oversized_blit)
+TEST_F(BlitFramebufferANGLETest, OversizedBlit)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -456,7 +456,7 @@
 }
 
 // blit from system FBO to user-created framebuffer, using region larger than buffer.
-TEST_F(BlitFramebufferANGLETest, reverse_oversized_blit)
+TEST_F(BlitFramebufferANGLETest, ReverseOversizedBlit)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
 
@@ -485,7 +485,7 @@
 }
 
 // blit from user-created FBO to system framebuffer, with depth buffer.
-TEST_F(BlitFramebufferANGLETest, blit_with_depth)
+TEST_F(BlitFramebufferANGLETest, BlitWithDepth)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -522,7 +522,7 @@
 }
 
 // blit from system FBO to user-created framebuffer, with depth buffer.
-TEST_F(BlitFramebufferANGLETest, reverse_blit_with_depth)
+TEST_F(BlitFramebufferANGLETest, ReverseBlitWithDepth)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
 
@@ -559,7 +559,7 @@
 }
 
 // blit from one region of the system fbo to another-- this should fail.
-TEST_F(BlitFramebufferANGLETest, blit_same_buffer_original)
+TEST_F(BlitFramebufferANGLETest, BlitSameBufferOriginal)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
 
@@ -575,7 +575,7 @@
 }
 
 // blit from one region of the system fbo to another.
-TEST_F(BlitFramebufferANGLETest, blit_same_buffer_user)
+TEST_F(BlitFramebufferANGLETest, BlitSameBufferUser)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -590,7 +590,7 @@
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
-TEST_F(BlitFramebufferANGLETest, blit_partial_color)
+TEST_F(BlitFramebufferANGLETest, BlitPartialColor)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -619,7 +619,7 @@
     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
 }
 
-TEST_F(BlitFramebufferANGLETest, blit_different_sizes)
+TEST_F(BlitFramebufferANGLETest, BlitDifferentSizes)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -647,7 +647,7 @@
     EXPECT_GL_NO_ERROR();
 }
 
-TEST_F(BlitFramebufferANGLETest, blit_with_missing_attachments)
+TEST_F(BlitFramebufferANGLETest, BlitWithMissingAttachments)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
 
@@ -685,7 +685,7 @@
     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0,   0, 255, 255);
 }
 
-TEST_F(BlitFramebufferANGLETest, blit_stencil)
+TEST_F(BlitFramebufferANGLETest, BlitStencil)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -727,7 +727,7 @@
 }
 
 // make sure that attempting to blit a partial depth buffer issues an error
-TEST_F(BlitFramebufferANGLETest, blit_partial_depth_stencil)
+TEST_F(BlitFramebufferANGLETest, BlitPartialDepthStencil)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -746,7 +746,7 @@
 }
 
 // Test blit with MRT framebuffers
-TEST_F(BlitFramebufferANGLETest, blit_mrt)
+TEST_F(BlitFramebufferANGLETest, BlitMRT)
 {
     if (!extensionEnabled("GL_EXT_draw_buffers"))
     {
@@ -794,7 +794,7 @@
 }
 
 // Make sure that attempts to stretch in a blit call issue an error
-TEST_F(BlitFramebufferANGLETest, error_stretching)
+TEST_F(BlitFramebufferANGLETest, ErrorStretching)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -813,7 +813,7 @@
 }
 
 // Make sure that attempts to flip in a blit call issue an error
-TEST_F(BlitFramebufferANGLETest, error_flipping)
+TEST_F(BlitFramebufferANGLETest, ErrorFlipping)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
@@ -831,7 +831,7 @@
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
-TEST_F(BlitFramebufferANGLETest, errors)
+TEST_F(BlitFramebufferANGLETest, Errors)
 {
     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
 
diff --git a/tests/angle_tests/BufferDataTest.cpp b/tests/angle_tests/BufferDataTest.cpp
index 1cfaec3..c566a85 100644
--- a/tests/angle_tests/BufferDataTest.cpp
+++ b/tests/angle_tests/BufferDataTest.cpp
@@ -1,8 +1,10 @@
 #include "ANGLETest.h"
 
+#include <cstdint>
+
 class BufferDataTest : public ANGLETest
 {
-protected:
+  protected:
     BufferDataTest()
         : mBuffer(0),
           mProgram(0),
@@ -46,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");
@@ -74,7 +76,7 @@
     GLint mAttribLocation;
 };
 
-TEST_F(BufferDataTest, null_data)
+TEST_F(BufferDataTest, NULLData)
 {
     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
     EXPECT_GL_NO_ERROR();
@@ -97,29 +99,54 @@
     }
 }
 
-TEST_F(BufferDataTest, huge_setdata_should_not_crash)
+TEST_F(BufferDataTest, ZeroNonNULLData)
 {
     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
     EXPECT_GL_NO_ERROR();
 
-    // use as large a size as possible without causing an exception
-    GLsizei hugeSize = (1 << 30);
+    char *zeroData = new char[0];
+    glBufferData(GL_ARRAY_BUFFER, 0, zeroData, GL_STATIC_DRAW);
+    EXPECT_GL_NO_ERROR();
 
-    // on x64, use as large a GLsizei value as possible
-    if (sizeof(size_t) > 4)
+    glBufferSubData(GL_ARRAY_BUFFER, 0, 0, zeroData);
+    EXPECT_GL_NO_ERROR();
+
+    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);
+    EXPECT_GL_NO_ERROR();
+
+    GLsizei allocSize = std::numeric_limits<GLsizei>::max() >> 2;
+
+    uint8_t *data = NULL;
+    while (data == NULL && allocSize >= 4)
     {
-        hugeSize = std::numeric_limits<GLsizei>::max();
+        data = new (std::nothrow) uint8_t[allocSize];
+
+        if (data == NULL)
+        {
+            allocSize >>= 1;
+        }
     }
 
-    char *data = new (std::nothrow) char[hugeSize];
-    EXPECT_NE((char * const)NULL, data);
-
-    if (data == NULL)
-    {
-        return;
-    }
-
-    memset(data, 0, hugeSize);
+    ASSERT_NE(static_cast<uint8_t*>(NULL), data);
+    memset(data, 0, allocSize);
 
     float * fValue = reinterpret_cast<float*>(data);
     for (unsigned int f = 0; f < 6; f++)
@@ -127,7 +154,7 @@
         fValue[f] = 1.0f;
     }
 
-    glBufferData(GL_ARRAY_BUFFER, hugeSize, data, GL_STATIC_DRAW);
+    glBufferData(GL_ARRAY_BUFFER, allocSize, data, GL_STATIC_DRAW);
 
     GLenum error = glGetError();
     if (error == GL_NO_ERROR)
@@ -169,3 +196,128 @@
     delete[] data;
 }
 
+class IndexedBufferCopyTest : public ANGLETest
+{
+  protected:
+    IndexedBufferCopyTest()
+    {
+        setWindowWidth(16);
+        setWindowHeight(16);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+        setConfigDepthBits(24);
+        setClientVersion(3);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+
+        const char * vsSource = SHADER_SOURCE
+        (
+            attribute vec3 in_attrib;
+            varying vec3 v_attrib;
+            void main()
+            {
+                v_attrib = in_attrib;
+                gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
+                gl_PointSize = 100.0;
+            }
+        );
+
+        const char * fsSource = SHADER_SOURCE
+        (
+            precision mediump float;
+            varying vec3 v_attrib;
+            void main()
+            {
+                gl_FragColor = vec4(v_attrib, 1);
+            }
+        );
+
+        glGenBuffers(2, mBuffers);
+        ASSERT_NE(mBuffers[0], 0U);
+        ASSERT_NE(mBuffers[1], 0U);
+
+        glGenBuffers(1, &mElementBuffer);
+        ASSERT_NE(mElementBuffer, 0U);
+
+        mProgram = CompileProgram(vsSource, fsSource);
+        ASSERT_NE(mProgram, 0U);
+
+        mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
+        ASSERT_NE(mAttribLocation, -1);
+
+        glClearColor(0, 0, 0, 0);
+        glDisable(GL_DEPTH_TEST);
+        glClear(GL_COLOR_BUFFER_BIT);
+
+        ASSERT_GL_NO_ERROR();
+    }
+
+    virtual void TearDown()
+    {
+        glDeleteBuffers(2, mBuffers);
+        glDeleteBuffers(1, &mElementBuffer);
+        glDeleteProgram(mProgram);
+
+        ANGLETest::TearDown();
+    }
+
+    GLuint mBuffers[2];
+    GLuint mElementBuffer;
+    GLuint mProgram;
+    GLint mAttribLocation;
+};
+
+// The following test covers an ANGLE bug where our index ranges
+// weren't updated from CopyBufferSubData calls
+// https://code.google.com/p/angleproject/issues/detail?id=709
+TEST_F(IndexedBufferCopyTest, IndexRangeBug)
+{
+    unsigned char vertexData[] = { 255, 0, 0, 0, 0, 0 };
+    unsigned int indexData[] = { 0, 1 };
+
+    glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(char) * 6, vertexData, GL_STATIC_DRAW);
+
+    glUseProgram(mProgram);
+    glVertexAttribPointer(mAttribLocation, 3, GL_UNSIGNED_BYTE, GL_TRUE, 3, NULL);
+    glEnableVertexAttribArray(mAttribLocation);
+
+    ASSERT_GL_NO_ERROR();
+
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBuffer);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 1, indexData, GL_STATIC_DRAW);
+
+    glUseProgram(mProgram);
+
+    ASSERT_GL_NO_ERROR();
+
+    glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
+
+    glBindBuffer(GL_COPY_READ_BUFFER, mBuffers[1]);
+    glBufferData(GL_COPY_READ_BUFFER, 4, &indexData[1], GL_STATIC_DRAW);
+
+    glBindBuffer(GL_COPY_WRITE_BUFFER, mElementBuffer);
+
+    glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(int));
+
+    ASSERT_GL_NO_ERROR();
+
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
+
+    unsigned char newData[] = { 0, 255, 0 };
+    glBufferSubData(GL_ARRAY_BUFFER, 3, 3, newData);
+
+    glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
+
+    EXPECT_GL_NO_ERROR();
+    EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
+}
diff --git a/tests/angle_tests/ClearTest.cpp b/tests/angle_tests/ClearTest.cpp
index 2f0f153..a8c0476 100644
--- a/tests/angle_tests/ClearTest.cpp
+++ b/tests/angle_tests/ClearTest.cpp
@@ -12,6 +12,7 @@
         setConfigBlueBits(8);
         setConfigAlphaBits(8);
         setConfigDepthBits(24);
+        setClientVersion(3);
     }
 
     virtual void SetUp()
@@ -39,27 +40,31 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSource, fragmentShaderSource);
+        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
         if (mProgram == 0)
         {
             FAIL() << "shader compilation failed.";
         }
+
+        glGenFramebuffers(1, &mFBO);
+
+        ASSERT_GL_NO_ERROR();
     }
 
     virtual void TearDown()
     {
         glDeleteProgram(mProgram);
+        glDeleteFramebuffers(1, &mFBO);
 
         ANGLETest::TearDown();
     }
 
     GLuint mProgram;
+    GLuint mFBO;
 };
 
-TEST_F(ClearTest, clear_issue)
+TEST_F(ClearTest, ClearIssue)
 {
-    EXPECT_GL_NO_ERROR();
-
     glEnable(GL_DEPTH_TEST);
     glDepthFunc(GL_LEQUAL);
 
@@ -69,9 +74,7 @@
 
     EXPECT_GL_NO_ERROR();
 
-    GLuint fbo;
-    glGenFramebuffers(1, &fbo);
-    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
 
     GLuint rbo;
     glGenRenderbuffers(1, &rbo);
@@ -97,3 +100,91 @@
 
     EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
 }
+
+// Requires ES3
+// This tests a bug where in a masked clear when calling "ClearBuffer", we would
+// mistakenly clear every channel (including the masked-out ones)
+TEST_F(ClearTest, MaskedClearBufferBug)
+{
+    unsigned char pixelData[] = { 255, 255, 255, 255 };
+
+    glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+
+    GLuint textures[2];
+    glGenTextures(2, &textures[0]);
+
+    glBindTexture(GL_TEXTURE_2D, textures[0]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
+
+    glBindTexture(GL_TEXTURE_2D, textures[1]);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
+
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
+
+    float clearValue[] = { 0, 0.5f, 0.5f, 1.0f };
+    GLenum drawBuffers[] = { GL_NONE, GL_COLOR_ATTACHMENT1 };
+    glDrawBuffers(2, drawBuffers);
+    glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
+    glClearBufferfv(GL_COLOR, 1, clearValue);
+
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
+
+    // TODO: glReadBuffer support
+    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 c59c2ee..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.";
@@ -66,7 +66,7 @@
     GLint mTextureUniformLocation;
 };
 
-TEST_F(CompressedTextureTest, compressed_tex_image)
+TEST_F(CompressedTextureTest, CompressedTexImage)
 {
     if (getClientVersion() < 3 && !extensionEnabled("GL_EXT_texture_compression_dxt1"))
     {
@@ -106,7 +106,7 @@
     EXPECT_GL_NO_ERROR();
 }
 
-TEST_F(CompressedTextureTest, compressed_tex_storage)
+TEST_F(CompressedTextureTest, CompressedTexStorage)
 {
     if (getClientVersion() < 3 && !extensionEnabled("GL_EXT_texture_compression_dxt1"))
     {
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/FramebufferFormatsTest.cpp b/tests/angle_tests/FramebufferFormatsTest.cpp
new file mode 100644
index 0000000..bffd4d1
--- /dev/null
+++ b/tests/angle_tests/FramebufferFormatsTest.cpp
@@ -0,0 +1,98 @@
+#include "ANGLETest.h"
+
+class FramebufferFormatsTest : public ANGLETest
+{
+protected:
+    FramebufferFormatsTest()
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+
+    void checkBitCount(GLuint fbo, GLenum channel, GLint minBits)
+    {
+        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+        GLint bits = 0;
+        glGetIntegerv(channel, &bits);
+
+        if (minBits == 0)
+        {
+            EXPECT_EQ(minBits, bits);
+        }
+        else
+        {
+            EXPECT_GE(bits, minBits);
+        }
+    }
+
+    void testBitCounts(GLuint fbo, GLint minRedBits, GLint minGreenBits, GLint minBlueBits,
+                       GLint minAlphaBits, GLint minDepthBits, GLint minStencilBits)
+    {
+        checkBitCount(fbo, GL_RED_BITS, minRedBits);
+        checkBitCount(fbo, GL_GREEN_BITS, minGreenBits);
+        checkBitCount(fbo, GL_BLUE_BITS, minBlueBits);
+        checkBitCount(fbo, GL_ALPHA_BITS, minAlphaBits);
+        checkBitCount(fbo, GL_DEPTH_BITS, minDepthBits);
+        checkBitCount(fbo, GL_STENCIL_BITS, minStencilBits);
+    }
+
+    void testTextureFormat(GLenum internalFormat, GLint minRedBits, GLint minGreenBits, GLint minBlueBits,
+                           GLint minAlphaBits)
+    {
+        GLuint tex = 0;
+        glGenTextures(1, &tex);
+        glBindTexture(GL_TEXTURE_2D, tex);
+        glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
+
+        GLuint fbo = 0;
+        glGenFramebuffers(1, &fbo);
+        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+
+        testBitCounts(fbo, minRedBits, minGreenBits, minBlueBits, minAlphaBits, 0, 0);
+
+        glDeleteTextures(1, &tex);
+        glDeleteFramebuffers(1, &fbo);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+    }
+
+    virtual void TearDown()
+    {
+        ANGLETest::TearDown();
+    }
+};
+
+TEST_F(FramebufferFormatsTest, RGBA4)
+{
+    testTextureFormat(GL_RGBA4, 4, 4, 4, 4);
+}
+
+TEST_F(FramebufferFormatsTest, RGB565)
+{
+    testTextureFormat(GL_RGB565, 5, 6, 5, 0);
+}
+
+TEST_F(FramebufferFormatsTest, RGB8)
+{
+    testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0);
+}
+
+TEST_F(FramebufferFormatsTest, BGRA8)
+{
+    testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8);
+}
+
+TEST_F(FramebufferFormatsTest, RGBA8)
+{
+    testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8);
+}
+
diff --git a/tests/angle_tests/GLSLStructTest.cpp b/tests/angle_tests/GLSLStructTest.cpp
deleted file mode 100644
index 531afe1..0000000
--- a/tests/angle_tests/GLSLStructTest.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "ANGLETest.h"
-
-class GLSLStructTest : public ANGLETest
-{
-protected:
-    GLSLStructTest()
-    {
-        setWindowWidth(128);
-        setWindowHeight(128);
-        setConfigRedBits(8);
-        setConfigGreenBits(8);
-        setConfigBlueBits(8);
-        setConfigAlphaBits(8);
-    }
-
-    virtual void SetUp()
-    {
-        ANGLETest::SetUp();
-
-        mVertexShaderSource = SHADER_SOURCE
-        (
-            attribute vec4 inputAttribute;
-            void main()
-            {
-                gl_Position = inputAttribute;
-            }
-        );
-    }
-
-    std::string mVertexShaderSource;
-};
-
-TEST_F(GLSLStructTest, nameless_scoped_structs)
-{
-    const std::string fragmentShaderSource = SHADER_SOURCE
-    (
-        precision mediump float;
-
-        void main()
-        {
-            struct
-            {
-                float q;
-            } b;
-
-            gl_FragColor = vec4(1, 0, 0, 1);
-            gl_FragColor.a += b.q;
-        }
-    );
-
-    GLuint program = compileProgram(mVertexShaderSource, fragmentShaderSource);
-    EXPECT_NE(0u, program);
-}
-TEST_F(GLSLStructTest, scoped_structs_order_bug)
-{
-    const std::string fragmentShaderSource = SHADER_SOURCE
-    (
-        precision mediump float;
-
-        struct T
-        {
-            float f;
-        };
-
-        void main()
-        {
-            T a;
-
-            struct T
-            {
-                float q;
-            };
-
-            T b;
-
-            gl_FragColor = vec4(1, 0, 0, 1);
-            gl_FragColor.a += a.f;
-            gl_FragColor.a += b.q;
-        }
-    );
-
-    GLuint program = compileProgram(mVertexShaderSource, fragmentShaderSource);
-    EXPECT_NE(0u, program);
-}
-
-TEST_F(GLSLStructTest, scoped_structs_bug)
-{
-    const std::string fragmentShaderSource = SHADER_SOURCE
-    (
-        precision mediump float;
-
-        struct T_0
-        {
-            float f;
-        };
-
-        void main()
-        {
-            gl_FragColor = vec4(1, 0, 0, 1);
-
-            struct T
-            {
-                vec2 v;
-            };
-
-            T_0 a;
-            T b;
-
-            gl_FragColor.a += a.f;
-            gl_FragColor.a += b.v.x;
-        }
-    );
-
-    GLuint program = compileProgram(mVertexShaderSource, fragmentShaderSource);
-    EXPECT_NE(0u, program);
-}
diff --git a/tests/angle_tests/GLSLTest.cpp b/tests/angle_tests/GLSLTest.cpp
new file mode 100644
index 0000000..dca8ac2
--- /dev/null
+++ b/tests/angle_tests/GLSLTest.cpp
@@ -0,0 +1,722 @@
+#include "ANGLETest.h"
+
+class GLSLTest : public ANGLETest
+{
+protected:
+    GLSLTest()
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+
+        mSimpleVSSource = SHADER_SOURCE
+        (
+            attribute vec4 inputAttribute;
+            void main()
+            {
+                gl_Position = inputAttribute;
+            }
+        );
+    }
+
+    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;
+};
+
+TEST_F(GLSLTest, NamelessScopedStructs)
+{
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+
+        void main()
+        {
+            struct
+            {
+                float q;
+            } b;
+
+            gl_FragColor = vec4(1, 0, 0, 1);
+            gl_FragColor.a += b.q;
+        }
+    );
+
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+TEST_F(GLSLTest, ScopedStructsOrderBug)
+{
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+
+        struct T
+        {
+            float f;
+        };
+
+        void main()
+        {
+            T a;
+
+            struct T
+            {
+                float q;
+            };
+
+            T b;
+
+            gl_FragColor = vec4(1, 0, 0, 1);
+            gl_FragColor.a += a.f;
+            gl_FragColor.a += b.q;
+        }
+    );
+
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, ScopedStructsBug)
+{
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+
+        struct T_0
+        {
+            float f;
+        };
+
+        void main()
+        {
+            gl_FragColor = vec4(1, 0, 0, 1);
+
+            struct T
+            {
+                vec2 v;
+            };
+
+            T_0 a;
+            T b;
+
+            gl_FragColor.a += a.f;
+            gl_FragColor.a += b.v.x;
+        }
+    );
+
+    GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, DxPositionBug)
+{
+    const std::string &vertexShaderSource = SHADER_SOURCE
+    (
+        attribute vec4 inputAttribute;
+        varying float dx_Position;
+        void main()
+        {
+            gl_Position = vec4(inputAttribute);
+            dx_Position = 0.0;
+        }
+    );
+
+    const std::string &fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+
+        varying float dx_Position;
+
+        void main()
+        {
+            gl_FragColor = vec4(dx_Position, 0, 0, 1);
+        }
+    );
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, ElseIfRewriting)
+{
+    const std::string &vertexShaderSource =
+        "attribute vec4 a_position;\n"
+        "varying float v;\n"
+        "void main() {\n"
+        "  gl_Position = a_position;\n"
+        "  v = 1.0;\n"
+        "  if (a_position.x <= 0.5) {\n"
+        "    v = 0.0;\n"
+        "  } else if (a_position.x >= 0.5) {\n"
+        "    v = 2.0;\n"
+        "  }\n"
+        "}\n";
+
+    const std::string &fragmentShaderSource =
+        "precision highp float;\n"
+        "varying float v;\n"
+        "void main() {\n"
+        "  vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+        "  if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+        "  if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
+        "  gl_FragColor = color;\n"
+        "}\n";
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    ASSERT_NE(0u, program);
+
+    drawQuad(program, "a_position", 0.5f);
+    swapBuffers();
+
+    EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
+    EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
+}
+
+TEST_F(GLSLTest, TwoElseIfRewriting)
+{
+    const std::string &vertexShaderSource =
+        "attribute vec4 a_position;\n"
+        "varying float v;\n"
+        "void main() {\n"
+        "  gl_Position = a_position;\n"
+        "  if (a_position.x == 0.0) {\n"
+        "    v = 1.0;\n"
+        "  } else if (a_position.x > 0.5) {\n"
+        "    v = 0.0;\n"
+        "  } else if (a_position.x > 0.75) {\n"
+        "    v = 0.5;\n"
+        "  }\n"
+        "}\n";
+
+    const std::string &fragmentShaderSource =
+        "precision highp float;\n"
+        "varying float v;\n"
+        "void main() {\n"
+        "  gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
+        "}\n";
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, InvariantVaryingOut)
+{
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+        varying float v_varying;
+        void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
+    );
+
+    const std::string vertexShaderSource = SHADER_SOURCE
+    (
+        attribute vec4 a_position;
+        invariant varying float v_varying;
+        void main() { v_varying = a_position.x; gl_Position = a_position; }
+    );
+
+    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);
+}
+
+TEST_F(GLSLTest, InvariantVaryingIn)
+{
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+        invariant varying float v_varying;
+        void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
+    );
+
+    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; }
+    );
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, InvariantVaryingBoth)
+{
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+        invariant varying float v_varying;
+        void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
+    );
+
+    const std::string vertexShaderSource = SHADER_SOURCE
+    (
+        attribute vec4 a_position;
+        invariant varying float v_varying;
+        void main() { v_varying = a_position.x; gl_Position = a_position; }
+    );
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, InvariantGLPosition)
+{
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+        varying float v_varying;
+        void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
+    );
+
+    const std::string vertexShaderSource = SHADER_SOURCE
+    (
+        attribute vec4 a_position;
+        invariant gl_Position;
+        varying float v_varying;
+        void main() { v_varying = a_position.x; gl_Position = a_position; }
+    );
+
+    GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
+    EXPECT_NE(0u, program);
+}
+
+TEST_F(GLSLTest, InvariantAll)
+{
+    const std::string fragmentShaderSource = SHADER_SOURCE
+    (
+        precision mediump float;
+        varying float v_varying;
+        void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
+    );
+
+    const std::string vertexShaderSource =
+        "#pragma STDGL invariant(all)\n"
+        "attribute vec4 a_position;\n"
+        "varying float v_varying;\n"
+        "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
+
+    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 7499ef9..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.";
@@ -76,7 +76,7 @@
     GLint mTextureUniformLocation;
 };
 
-TEST_F(IncompleteTextureTest, incomplete_texture_2d)
+TEST_F(IncompleteTextureTest, IncompleteTexture2D)
 {
     GLuint tex;
     glGenTextures(1, &tex);
@@ -110,7 +110,7 @@
     glDeleteTextures(1, &tex);
 }
 
-TEST_F(IncompleteTextureTest, update_texture)
+TEST_F(IncompleteTextureTest, UpdateTexture)
 {
     GLuint tex;
     glGenTextures(1, &tex);
diff --git a/tests/angle_tests/IndexedPointsTest.cpp b/tests/angle_tests/IndexedPointsTest.cpp
index 3989482..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.";
@@ -125,51 +125,51 @@
 
 typedef IndexedPointsTest<GLubyte, GL_UNSIGNED_BYTE> IndexedPointsTestUByte;
 
-TEST_F(IndexedPointsTestUByte, unsigned_byte_offset_0)
+TEST_F(IndexedPointsTestUByte, UnsignedByteOffset0)
 {
     runTest(0);
 }
 
-TEST_F(IndexedPointsTestUByte, unsigned_byte_offset_1)
+TEST_F(IndexedPointsTestUByte, UnsignedByteOffset1)
 {
     runTest(1);
 }
 
-TEST_F(IndexedPointsTestUByte, unsigned_byte_offset_2)
+TEST_F(IndexedPointsTestUByte, UnsignedByteOffset2)
 {
     runTest(2);
 }
 
-TEST_F(IndexedPointsTestUByte, unsigned_byte_offset_3)
+TEST_F(IndexedPointsTestUByte, UnsignedByteOffset3)
 {
     runTest(3);
 }
 
 typedef IndexedPointsTest<GLushort, GL_UNSIGNED_SHORT> IndexedPointsTestUShort;
 
-TEST_F(IndexedPointsTestUShort, unsigned_short_offset_0)
+TEST_F(IndexedPointsTestUShort, UnsignedShortOffset0)
 {
     runTest(0);
 }
 
-TEST_F(IndexedPointsTestUShort, unsigned_short_offset_1)
+TEST_F(IndexedPointsTestUShort, UnsignedShortOffset1)
 {
     runTest(1);
 }
 
-TEST_F(IndexedPointsTestUShort, unsigned_short_offset_2)
+TEST_F(IndexedPointsTestUShort, UnsignedShortOffset2)
 {
     runTest(2);
 }
 
-TEST_F(IndexedPointsTestUShort, unsigned_short_offset_3)
+TEST_F(IndexedPointsTestUShort, UnsignedShortOffset3)
 {
     runTest(3);
 }
 
 typedef IndexedPointsTest<GLuint, GL_UNSIGNED_INT> IndexedPointsTestUInt;
 
-TEST_F(IndexedPointsTestUInt, unsigned_int_offset_0)
+TEST_F(IndexedPointsTestUInt, UnsignedIntOffset0)
 {
     if (getClientVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
     {
@@ -179,7 +179,7 @@
     runTest(0);
 }
 
-TEST_F(IndexedPointsTestUInt, unsigned_int_offset_1)
+TEST_F(IndexedPointsTestUInt, UnsignedIntOffset1)
 {
     if (getClientVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
     {
@@ -189,7 +189,7 @@
     runTest(1);
 }
 
-TEST_F(IndexedPointsTestUInt, unsigned_int_offset_2)
+TEST_F(IndexedPointsTestUInt, UnsignedIntOffset2)
 {
     if (getClientVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
     {
@@ -199,7 +199,7 @@
     runTest(2);
 }
 
-TEST_F(IndexedPointsTestUInt, unsigned_int_offset_3)
+TEST_F(IndexedPointsTestUInt, UnsignedIntOffset3)
 {
     if (getClientVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
     {
diff --git a/tests/angle_tests/LineLoopTest.cpp b/tests/angle_tests/LineLoopTest.cpp
index 17fc53e..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.";
@@ -126,19 +126,19 @@
     GLint mColorLocation;
 };
 
-TEST_F(LineLoopTest, line_loop_ubyte_indices)
+TEST_F(LineLoopTest, LineLoopUByteIndices)
 {
     static const GLubyte indices[] = { 0, 7, 6, 9, 8, 0 };
     runTest(GL_UNSIGNED_BYTE, 0, indices + 1);
 }
 
-TEST_F(LineLoopTest, line_loop_ushort_indices)
+TEST_F(LineLoopTest, LineLoopUShortIndices)
 {
     static const GLushort indices[] = { 0, 7, 6, 9, 8, 0 };
     runTest(GL_UNSIGNED_SHORT, 0, indices + 1);
 }
 
-TEST_F(LineLoopTest, line_loop_uint_indices)
+TEST_F(LineLoopTest, LineLoopUIntIndices)
 {
     if (!extensionEnabled("GL_OES_element_index_uint"))
     {
@@ -149,7 +149,7 @@
     runTest(GL_UNSIGNED_INT, 0, indices + 1);
 }
 
-TEST_F(LineLoopTest, line_loop_ubyte_index_buffer)
+TEST_F(LineLoopTest, LineLoopUByteIndexBuffer)
 {
     static const GLubyte indices[] = { 0, 7, 6, 9, 8, 0 };
 
@@ -163,7 +163,7 @@
     glDeleteBuffers(1, &buf);
 }
 
-TEST_F(LineLoopTest, line_loop_ushort_index_buffer)
+TEST_F(LineLoopTest, LineLoopUShortIndexBuffer)
 {
     static const GLushort indices[] = { 0, 7, 6, 9, 8, 0 };
 
@@ -177,7 +177,7 @@
     glDeleteBuffers(1, &buf);
 }
 
-TEST_F(LineLoopTest, line_loop_uint_index_buffer)
+TEST_F(LineLoopTest, LineLoopUIntIndexBuffer)
 {
     if (!extensionEnabled("GL_OES_element_index_uint"))
     {
diff --git a/tests/angle_tests/MaxTextureSizeTest.cpp b/tests/angle_tests/MaxTextureSizeTest.cpp
index 84fc281..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.";
@@ -86,7 +86,7 @@
     GLint mMaxRenderbufferSize;
 };
 
-TEST_F(MaxTextureSizeTest, specification_tex_image)
+TEST_F(MaxTextureSizeTest, SpecificationTexImage)
 {
     GLuint tex;
     glGenTextures(1, &tex);
@@ -141,7 +141,7 @@
     }
 }
 
-TEST_F(MaxTextureSizeTest, specification_tex_storage)
+TEST_F(MaxTextureSizeTest, SpecificationTexStorage)
 {
     if (getClientVersion() < 3 && (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8")))
     {
@@ -211,7 +211,7 @@
     }
 }
 
-TEST_F(MaxTextureSizeTest, render_to_texture)
+TEST_F(MaxTextureSizeTest, RenderToTexture)
 {
     GLuint fbo = 0;
     GLuint textureId = 0;
diff --git a/tests/angle_tests/OcclusionQueriesTest.cpp b/tests/angle_tests/OcclusionQueriesTest.cpp
index 137bcd2..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.";
@@ -55,7 +58,7 @@
     GLuint mProgram;
 };
 
-TEST_F(OcclusionQueriesTest, is_occuluded)
+TEST_F(OcclusionQueriesTest, IsOccluded)
 {
     glDepthMask(GL_TRUE);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -95,7 +98,7 @@
     EXPECT_EQ(result, GL_FALSE);
 }
 
-TEST_F(OcclusionQueriesTest, is_not_occuluded)
+TEST_F(OcclusionQueriesTest, IsNotOccluded)
 {
     glDepthMask(GL_TRUE);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -122,7 +125,7 @@
     EXPECT_EQ(result, GL_TRUE);
 }
 
-TEST_F(OcclusionQueriesTest, errors)
+TEST_F(OcclusionQueriesTest, Errors)
 {
     glDepthMask(GL_TRUE);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
diff --git a/tests/angle_tests/PBOExtensionTest.cpp b/tests/angle_tests/PBOExtensionTest.cpp
index 73eae71..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);
@@ -73,7 +73,7 @@
     GLuint mPositionVBO;
 };
 
-TEST_F(PBOExtensionTest, pbo_with_other_target)
+TEST_F(PBOExtensionTest, PBOWithOtherTarget)
 {
     if (extensionEnabled("NV_pixel_buffer_object"))
     {
@@ -101,7 +101,7 @@
     EXPECT_GL_NO_ERROR();
 }
 
-TEST_F(PBOExtensionTest, pbo_with_existing_data)
+TEST_F(PBOExtensionTest, PBOWithExistingData)
 {
     if (extensionEnabled("NV_pixel_buffer_object"))
     {
diff --git a/tests/angle_tests/ProgramBinaryTest.cpp b/tests/angle_tests/ProgramBinaryTest.cpp
index 28158ca..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.";
@@ -62,7 +62,7 @@
 
 // This tests the assumption that float attribs of different size
 // should not internally cause a vertex shader recompile (for conversion).
-TEST_F(ProgramBinaryTest, float_dynamic_shader_size)
+TEST_F(ProgramBinaryTest, FloatDynamicShaderSize)
 {
     glUseProgram(mProgram);
     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
diff --git a/tests/angle_tests/ReadPixelsTest.cpp b/tests/angle_tests/ReadPixelsTest.cpp
index 70efe99..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);
@@ -84,7 +84,7 @@
     GLuint mPositionVBO;
 };
 
-TEST_F(ReadPixelsTest, out_of_bounds)
+TEST_F(ReadPixelsTest, OutOfBounds)
 {
     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT);
@@ -117,7 +117,7 @@
     }
 }
 
-TEST_F(ReadPixelsTest, pbo_with_other_target)
+TEST_F(ReadPixelsTest, PBOWithOtherTarget)
 {
     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT);
@@ -142,7 +142,7 @@
     EXPECT_GL_NO_ERROR();
 }
 
-TEST_F(ReadPixelsTest, pbo_with_existing_data)
+TEST_F(ReadPixelsTest, PBOWithExistingData)
 {
     // Clear backbuffer to red
     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
@@ -180,7 +180,7 @@
     EXPECT_GL_NO_ERROR();
 }
 
-TEST_F(ReadPixelsTest, pbo_and_sub_data)
+TEST_F(ReadPixelsTest, PBOAndSubData)
 {
     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT);
@@ -208,7 +208,7 @@
     EXPECT_GL_NO_ERROR();
 }
 
-TEST_F(ReadPixelsTest, pbo_and_sub_data_offset)
+TEST_F(ReadPixelsTest, PBOAndSubDataOffset)
 {
     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT);
@@ -241,7 +241,7 @@
     EXPECT_GL_NO_ERROR();
 }
 
-TEST_F(ReadPixelsTest, draw_with_pbo)
+TEST_F(ReadPixelsTest, DrawWithPBO)
 {
     unsigned char data[4] = { 1, 2, 3, 4 };
 
@@ -293,3 +293,33 @@
     EXPECT_EQ(3, data[2]);
     EXPECT_EQ(4, data[3]);
 }
+
+TEST_F(ReadPixelsTest, MultisampledPBO)
+{
+    GLuint fbo;
+    glGenFramebuffers(1, &fbo);
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+    GLuint rbo;
+    glGenRenderbuffers(1, &rbo);
+    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+    glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
+
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
+
+    ASSERT_GL_NO_ERROR();
+
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+
+    EXPECT_GL_NO_ERROR();
+
+    glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, NULL);
+
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glDeleteRenderbuffers(1, &rbo);
+    glDeleteFramebuffers(1, &fbo);
+}
diff --git a/tests/angle_tests/SRGBTextureTest.cpp b/tests/angle_tests/SRGBTextureTest.cpp
new file mode 100644
index 0000000..b00d5ae
--- /dev/null
+++ b/tests/angle_tests/SRGBTextureTest.cpp
@@ -0,0 +1,133 @@
+#include "ANGLETest.h"
+
+class SRGBTextureTest : public ANGLETest
+{
+protected:
+    SRGBTextureTest()
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+    }
+
+    virtual void TearDown()
+    {
+        ANGLETest::TearDown();
+    }
+};
+
+TEST_F(SRGBTextureTest, SRGBValidation)
+{
+    bool supported = extensionEnabled("GL_EXT_sRGB") || getClientVersion() == 3;
+
+    GLuint tex = 0;
+    glGenTextures(1, &tex);
+    glBindTexture(GL_TEXTURE_2D, tex);
+
+    GLubyte pixel[3] = { 0 };
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, 1, 1, 0, GL_SRGB, GL_UNSIGNED_BYTE, pixel);
+    if (supported)
+    {
+        EXPECT_GL_NO_ERROR();
+
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB, GL_UNSIGNED_BYTE, pixel);
+        EXPECT_GL_NO_ERROR();
+
+        glGenerateMipmap(GL_TEXTURE_2D);
+        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+    }
+    else
+    {
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+    }
+
+    glDeleteTextures(1, &tex);
+}
+
+TEST_F(SRGBTextureTest, SRGBAValidation)
+{
+    bool supported = extensionEnabled("GL_EXT_sRGB") || getClientVersion() == 3;
+
+    GLuint tex = 0;
+    glGenTextures(1, &tex);
+    glBindTexture(GL_TEXTURE_2D, tex);
+
+    GLubyte pixel[4] = { 0 };
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel);
+    if (supported)
+    {
+        EXPECT_GL_NO_ERROR();
+
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel);
+        EXPECT_GL_NO_ERROR();
+
+        glGenerateMipmap(GL_TEXTURE_2D);
+        if (getClientVersion() == 2)
+        {
+            EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+        }
+        else
+        {
+            EXPECT_GL_NO_ERROR();
+        }
+    }
+    else
+    {
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+    }
+
+    glDeleteTextures(1, &tex);
+}
+
+TEST_F(SRGBTextureTest, SRGBARenderbuffer)
+{
+    bool supported = extensionEnabled("GL_EXT_sRGB") || getClientVersion() == 3;
+
+    GLuint rbo = 0;
+    glGenRenderbuffers(1, &rbo);
+    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8_EXT, 1, 1);
+    if (supported)
+    {
+        EXPECT_GL_NO_ERROR();
+    }
+    else
+    {
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+        // Make sure the rbo has a size for future tests
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1);
+        EXPECT_GL_NO_ERROR();
+    }
+
+    GLuint fbo = 0;
+    glGenFramebuffers(1, &fbo);
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
+    EXPECT_GL_NO_ERROR();
+
+    GLint colorEncoding = 0;
+    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                          GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT, &colorEncoding);
+    if (supported)
+    {
+        EXPECT_GL_NO_ERROR();
+        EXPECT_EQ(GL_SRGB_EXT, colorEncoding);
+    }
+    else
+    {
+        EXPECT_GL_ERROR(GL_INVALID_ENUM);
+    }
+
+    glDeleteFramebuffers(1, &fbo);
+    glDeleteRenderbuffers(1, &rbo);
+}
diff --git a/tests/angle_tests/SwizzleTest.cpp b/tests/angle_tests/SwizzleTest.cpp
index 8fdd9f2..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.";
@@ -181,77 +181,77 @@
     std::vector<swizzlePermutation> mPermutations;
 };
 
-TEST_F(SwizzleTest, rgba8_2d)
+TEST_F(SwizzleTest, RGBA8_2D)
 {
     GLubyte data[] = { 1, 64, 128, 200 };
     init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, rgb8_2d)
+TEST_F(SwizzleTest, RGB8_2D)
 {
     GLubyte data[] = { 77, 66, 55 };
     init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, rg8_2d)
+TEST_F(SwizzleTest, RG8_2D)
 {
     GLubyte data[] = { 11, 99 };
     init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, r8_2d)
+TEST_F(SwizzleTest, R8_2D)
 {
     GLubyte data[] = { 2 };
     init2DTexture<GLubyte>(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, rgba32f_2d)
+TEST_F(SwizzleTest, RGBA32F_2D)
 {
     GLfloat data[] = { 0.25f, 0.5f, 0.75f, 0.8f };
     init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, rgb32f_2d)
+TEST_F(SwizzleTest, RGB32F_2D)
 {
     GLfloat data[] = { 0.1f, 0.2f, 0.3f };
     init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, rg32f_2d)
+TEST_F(SwizzleTest, RG32F_2D)
 {
     GLfloat data[] = { 0.9f, 0.1f  };
     init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, r32f_2d)
+TEST_F(SwizzleTest, R32F_2D)
 {
     GLfloat data[] = { 0.5f };
     init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, d32f_2d)
+TEST_F(SwizzleTest, D32F_2D)
 {
     GLfloat data[] = { 0.5f };
     init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, d16_2d)
+TEST_F(SwizzleTest, D16_2D)
 {
     GLushort data[] = { 0xFF };
     init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
     runTest2D();
 }
 
-TEST_F(SwizzleTest, d24_2d)
+TEST_F(SwizzleTest, D24_2D)
 {
     GLuint data[] = { 0xFFFF };
     init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
@@ -260,7 +260,7 @@
 
 #include "media/pixel.inl"
 
-TEST_F(SwizzleTest, compressed_dxt_2d)
+TEST_F(SwizzleTest, CompressedDXT_2D)
 {
     init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, pixel_0_size, pixel_0_data);
     runTest2D();
diff --git a/tests/angle_tests/TextureTest.cpp b/tests/angle_tests/TextureTest.cpp
index f5fff41..6323d8d 100644
--- a/tests/angle_tests/TextureTest.cpp
+++ b/tests/angle_tests/TextureTest.cpp
@@ -16,12 +16,17 @@
     virtual void SetUp()
     {
         ANGLETest::SetUp();
-        glGenTextures(1, &mTexture);
+        glGenTextures(1, &mTexture2D);
+        glGenTextures(1, &mTextureCube);
 
-        glBindTexture(GL_TEXTURE_2D, mTexture);
+        glBindTexture(GL_TEXTURE_2D, mTexture2D);
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
         EXPECT_GL_NO_ERROR();
 
+        glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
+        glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
+        EXPECT_GL_NO_ERROR();
+
         ASSERT_GL_NO_ERROR();
 
         const std::string vertexShaderSource = SHADER_SOURCE
@@ -37,7 +42,7 @@
             }
         );
 
-        const std::string fragmentShaderSource = SHADER_SOURCE
+        const std::string fragmentShaderSource2D = SHADER_SOURCE
         (
             precision highp float;
             uniform sampler2D tex;
@@ -49,32 +54,51 @@
             }
         );
 
-        mProgram = compileProgram(vertexShaderSource, fragmentShaderSource);
-        if (mProgram == 0)
+        const std::string fragmentShaderSourceCube = SHADER_SOURCE
+        (
+            precision highp float;
+            uniform sampler2D tex2D;
+            uniform samplerCube texCube;
+            varying vec2 texcoord;
+
+            void main()
+            {
+                gl_FragColor = texture2D(tex2D, texcoord);
+                gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
+            }
+        );
+
+        m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D);
+        mCubeProgram = CompileProgram(vertexShaderSource, fragmentShaderSourceCube);
+        if (m2DProgram == 0 || mCubeProgram == 0)
         {
             FAIL() << "shader compilation failed.";
         }
 
-        mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
+        mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");
     }
 
     virtual void TearDown()
     {
-        glDeleteTextures(1, &mTexture);
-        glDeleteProgram(mProgram);
+        glDeleteTextures(1, &mTexture2D);
+        glDeleteTextures(1, &mTextureCube);
+        glDeleteProgram(m2DProgram);
+        glDeleteProgram(mCubeProgram);
 
         ANGLETest::TearDown();
     }
 
-    GLuint mTexture;
+    GLuint mTexture2D;
+    GLuint mTextureCube;
 
-    GLuint mProgram;
-    GLint mTextureUniformLocation;
+    GLuint m2DProgram;
+    GLuint mCubeProgram;
+    GLint mTexture2DUniformLocation;
 };
 
-TEST_F(TextureTest, negative_api_subimage)
+TEST_F(TextureTest, NegativeAPISubImage)
 {
-    glBindTexture(GL_TEXTURE_2D, mTexture);
+    glBindTexture(GL_TEXTURE_2D, mTexture2D);
     EXPECT_GL_ERROR(GL_NO_ERROR);
 
     const GLubyte *pixels[20] = { 0 };
@@ -82,15 +106,15 @@
     EXPECT_GL_ERROR(GL_INVALID_VALUE);
 }
 
-TEST_F(TextureTest, zero_sized_uploads)
+TEST_F(TextureTest, ZeroSizedUploads)
 {
-    glBindTexture(GL_TEXTURE_2D, mTexture);
+    glBindTexture(GL_TEXTURE_2D, mTexture2D);
     EXPECT_GL_ERROR(GL_NO_ERROR);
 
     // Use the texture first to make sure it's in video memory
-    glUseProgram(mProgram);
-    glUniform1i(mTextureUniformLocation, 0);
-    drawQuad(mProgram, "position", 0.5f);
+    glUseProgram(m2DProgram);
+    glUniform1i(mTexture2DUniformLocation, 0);
+    drawQuad(m2DProgram, "position", 0.5f);
 
     const GLubyte *pixel[4] = { 0 };
 
@@ -103,3 +127,23 @@
     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
     EXPECT_GL_NO_ERROR();
 }
+
+// Test drawing with two texture types, to trigger an ANGLE bug in validation
+TEST_F(TextureTest, CubeMapBug)
+{
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, mTexture2D);
+    glActiveTexture(GL_TEXTURE1);
+    glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
+    EXPECT_GL_ERROR(GL_NO_ERROR);
+
+    glUseProgram(mCubeProgram);
+    GLint tex2DUniformLocation = glGetUniformLocation(mCubeProgram, "tex2D");
+    GLint texCubeUniformLocation = glGetUniformLocation(mCubeProgram, "texCube");
+    EXPECT_NE(-1, tex2DUniformLocation);
+    EXPECT_NE(-1, texCubeUniformLocation);
+    glUniform1i(tex2DUniformLocation, 0);
+    glUniform1i(texCubeUniformLocation, 1);
+    drawQuad(mCubeProgram, "position", 0.5f);
+    EXPECT_GL_NO_ERROR();
+}
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 69c8269..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.";
@@ -133,7 +133,7 @@
     GLuint mProgram;
 };
 
-TEST_F(UnpackAlignmentTest, default_alignment)
+TEST_F(UnpackAlignmentTest, DefaultAlignment)
 {
     GLint defaultAlignment;
     glGetIntegerv(GL_UNPACK_ALIGNMENT, &defaultAlignment);
@@ -141,165 +141,165 @@
 }
 
 
-TEST_F(UnpackAlignmentTest, alignment_1_rgba_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment1RGBAUByte)
 {
     testAlignment(1, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_1_rgb_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment1RGBUByte)
 {
     testAlignment(1, 7 * 3, GL_RGB, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_1_rgba_ushort4444)
+TEST_F(UnpackAlignmentTest, Alignment1RGBAUShort4444)
 {
     testAlignment(1, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_1_rgba_ushort5551)
+TEST_F(UnpackAlignmentTest, Alignment1RGBAUShort5551)
 {
     testAlignment(1, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_1_rgb_ushort565)
+TEST_F(UnpackAlignmentTest, Alignment1RGBAUShort565)
 {
     testAlignment(1, 7 * 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_1_la_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment1LAUByte)
 {
     testAlignment(1, 7 * 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_1_l_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment1LUByte)
 {
     testAlignment(1, 7, GL_LUMINANCE, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_1_a_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment1AUByte)
 {
     testAlignment(1, 7, GL_ALPHA, GL_UNSIGNED_BYTE);
 }
 
 
-TEST_F(UnpackAlignmentTest, alignment_2_rgba_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment2RGBAUByte)
 {
     testAlignment(2, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_2_rgb_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment2RGBUByte)
 {
     testAlignment(2, 7 * 3 + 1, GL_RGB, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_2_rgba_ushort4444)
+TEST_F(UnpackAlignmentTest, Alignment2RGBAUShort4444)
 {
     testAlignment(2, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_2_rgba_ushort5551)
+TEST_F(UnpackAlignmentTest, Alignment2RGBAUShort5551)
 {
     testAlignment(2, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_2_rgb_ushort565)
+TEST_F(UnpackAlignmentTest, Alignment2RGBAUShort565)
 {
     testAlignment(2, 7 * 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_2_la_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment2LAUByte)
 {
     testAlignment(2, 7 * 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_2_l_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment2LAByte)
 {
     testAlignment(2, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_2_a_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment2AUByte)
 {
     testAlignment(2, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE);
 }
 
 
-TEST_F(UnpackAlignmentTest, alignment_4_rgba_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment4RGBAUByte)
 {
     testAlignment(4, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_4_rgb_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment4RGBUByte)
 {
     testAlignment(4, 7 * 3 + 3, GL_RGB, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_4_rgba_ushort4444)
+TEST_F(UnpackAlignmentTest, Alignment4RGBAUShort4444)
 {
     testAlignment(4, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_4_rgba_ushort5551)
+TEST_F(UnpackAlignmentTest, Alignment4RGBAUShort5551)
 {
     testAlignment(4, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_4_rgb_ushort565)
+TEST_F(UnpackAlignmentTest, Alignment4RGBAUShort565)
 {
     testAlignment(4, 7 * 2 + 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_4_la_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment4LAUByte)
 {
     testAlignment(4, 7 * 2 + 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_4_l_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment4LUByte)
 {
     testAlignment(4, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_4_a_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment4AUByte)
 {
     testAlignment(4, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE);
 }
 
 
-TEST_F(UnpackAlignmentTest, alignment_8_rgba_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment8RGBAUByte)
 {
     testAlignment(8, 7 * 4 + 4, GL_RGBA, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_8_rgb_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment8RGBUByte)
 {
     testAlignment(8, 7 * 3 + 3, GL_RGB, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_8_rgba_ushort4444)
+TEST_F(UnpackAlignmentTest, Alignment8RGBAUShort4444)
 {
     testAlignment(8, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_8_rgba_ushort5551)
+TEST_F(UnpackAlignmentTest, Alignment8RGBAUShort5551)
 {
     testAlignment(8, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_8_rgb_ushort565)
+TEST_F(UnpackAlignmentTest, Alignment8RGBAUShort565)
 {
     testAlignment(8, 7 * 2 + 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_8_la_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment8LAUByte)
 {
     testAlignment(8, 7 * 2 + 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_8_l_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment8LUByte)
 {
     testAlignment(8, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
 }
 
-TEST_F(UnpackAlignmentTest, alignment_8_a_ubyte)
+TEST_F(UnpackAlignmentTest, Alignment8AUByte)
 {
     testAlignment(8, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE);
 }
diff --git a/tests/angle_tests/VertexAttributeTest.cpp b/tests/angle_tests/VertexAttributeTest.cpp
index 0adc403..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.";
@@ -118,7 +118,7 @@
     GLint mExpectedAttrib;
 };
 
-TEST_F(VertexAttributeTest, unsigned_byte_unormalized)
+TEST_F(VertexAttributeTest, UnsignedByteUnnormalized)
 {
     GLubyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, 5, 6, 7, 125, 126, 127, 128, 129, 250, 251, 252, 253, 254, 255 };
     GLfloat expectedData[mVertexCount];
@@ -131,7 +131,7 @@
     runTest(data);
 }
 
-TEST_F(VertexAttributeTest, unsigned_byte_normalized)
+TEST_F(VertexAttributeTest, UnsignedByteNormalized)
 {
     GLubyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, 5, 6, 7, 125, 126, 127, 128, 129, 250, 251, 252, 253, 254, 255 };
     GLfloat expectedData[mVertexCount];
@@ -144,7 +144,7 @@
     runTest(data);
 }
 
-TEST_F(VertexAttributeTest, byte_unnormalized)
+TEST_F(VertexAttributeTest, ByteUnnormalized)
 {
     GLbyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, -1, -2, -3, -4, 125, 126, 127, -128, -127, -126 };
     GLfloat expectedData[mVertexCount];
@@ -157,7 +157,7 @@
     runTest(data);
 }
 
-TEST_F(VertexAttributeTest, byte_normalized)
+TEST_F(VertexAttributeTest, ByteNormalized)
 {
     GLbyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, -1, -2, -3, -4, 125, 126, 127, -128, -127, -126 };
     GLfloat expectedData[mVertexCount];
@@ -170,7 +170,7 @@
     runTest(data);
 }
 
-TEST_F(VertexAttributeTest, unsigned_short_unormalized)
+TEST_F(VertexAttributeTest, UnsignedShortUnnormalized)
 {
     GLushort inputData[mVertexCount] = { 0, 1, 2, 3, 254, 255, 256, 32766, 32767, 32768, 65533, 65534, 65535 };
     GLfloat expectedData[mVertexCount];
@@ -183,7 +183,7 @@
     runTest(data);
 }
 
-TEST_F(VertexAttributeTest, unsigned_short_normalized)
+TEST_F(VertexAttributeTest, UnsignedShortNormalized)
 {
     GLushort inputData[mVertexCount] = { 0, 1, 2, 3, 254, 255, 256, 32766, 32767, 32768, 65533, 65534, 65535 };
     GLfloat expectedData[mVertexCount];
@@ -196,7 +196,7 @@
     runTest(data);
 }
 
-TEST_F(VertexAttributeTest, short_unnormalized)
+TEST_F(VertexAttributeTest, ShortUnnormalized)
 {
     GLshort inputData[mVertexCount] = {  0, 1, 2, 3, -1, -2, -3, -4, 32766, 32767, -32768, -32767, -32766 };
     GLfloat expectedData[mVertexCount];
@@ -209,7 +209,7 @@
     runTest(data);
 }
 
-TEST_F(VertexAttributeTest, short_normalized)
+TEST_F(VertexAttributeTest, ShortNormalized)
 {
     GLshort inputData[mVertexCount] = {  0, 1, 2, 3, -1, -2, -3, -4, 32766, 32767, -32768, -32767, -32766 };
     GLfloat expectedData[mVertexCount];
diff --git a/tests/angle_tests/win32/ANGLETest_win32.cpp b/tests/angle_tests/win32/ANGLETest_win32.cpp
deleted file mode 100644
index 6a02c0b..0000000
--- a/tests/angle_tests/win32/ANGLETest_win32.cpp
+++ /dev/null
@@ -1,115 +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;
-    }
-
-    mDisplay = eglGetDisplay(mNativeDisplay);
-    if(mDisplay == EGL_NO_DISPLAY)
-    {
-         mDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
-    }
-
-    EGLint majorVersion, minorVersion;
-    if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
-    {
-        DestroyTestWindow();
-        return false;
-    }
-
-    eglBindAPI(EGL_OPENGL_ES_API);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        DestroyTestWindow();
-        return false;
-    }
-
-    return true;
-}
-
-bool ANGLETest::DestroyTestWindow()
-{
-    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    eglTerminate(mDisplay);
-
-    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
new file mode 100644
index 0000000..0c3160e
--- /dev/null
+++ b/tests/compiler_tests/CollectVariables_test.cpp
@@ -0,0 +1,338 @@
+//
+// 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.
+//
+// CollectVariables_test.cpp:
+//   Some tests for shader inspection
+//
+
+#include "angle_gl.h"
+#include "gtest/gtest.h"
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/TranslatorGLSL.h"
+
+#define EXPECT_GLENUM_EQ(expected, actual) \
+    EXPECT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
+
+class CollectVariablesTest : public testing::Test
+{
+  public:
+    CollectVariablesTest(GLenum shaderType)
+        : mShaderType(shaderType)
+    {}
+
+  protected:
+    virtual void SetUp()
+    {
+        ShBuiltInResources resources;
+        ShInitBuiltInResources(&resources);
+        resources.MaxDrawBuffers = 8;
+
+        mTranslator = new TranslatorGLSL(mShaderType, SH_GLES2_SPEC);
+        ASSERT_TRUE(mTranslator->Init(resources));
+    }
+
+    virtual void TearDown()
+    {
+        delete mTranslator;
+    }
+
+    GLenum mShaderType;
+    TranslatorGLSL *mTranslator;
+};
+
+class CollectVertexVariablesTest : public CollectVariablesTest
+{
+  public:
+    CollectVertexVariablesTest() : CollectVariablesTest(GL_VERTEX_SHADER) {}
+};
+
+class CollectFragmentVariablesTest : public CollectVariablesTest
+{
+  public:
+      CollectFragmentVariablesTest() : CollectVariablesTest(GL_FRAGMENT_SHADER) {}
+};
+
+TEST_F(CollectFragmentVariablesTest, SimpleOutputVar)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "precision mediump float;\n"
+        "out vec4 out_fragColor;\n"
+        "void main() {\n"
+        "   out_fragColor = vec4(1.0);\n"
+        "}\n";
+
+    const char *shaderStrings[] = { shaderString.c_str() };
+    ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
+
+    const std::vector<sh::Attribute> &outputVariables = mTranslator->getOutputVariables();
+    ASSERT_EQ(1u, outputVariables.size());
+
+    const sh::Attribute &outputVariable = outputVariables[0];
+
+    EXPECT_EQ(0u, outputVariable.arraySize);
+    EXPECT_EQ(-1, outputVariable.location);
+    EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable.precision);
+    EXPECT_TRUE(outputVariable.staticUse);
+    EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable.type);
+    EXPECT_EQ("out_fragColor", outputVariable.name);
+}
+
+TEST_F(CollectFragmentVariablesTest, LocationOutputVar)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "precision mediump float;\n"
+        "layout(location=5) out vec4 out_fragColor;\n"
+        "void main() {\n"
+        "   out_fragColor = vec4(1.0);\n"
+        "}\n";
+
+    const char *shaderStrings[] = { shaderString.c_str() };
+    ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
+
+    const std::vector<sh::Attribute> &outputVariables = mTranslator->getOutputVariables();
+    ASSERT_EQ(1u, outputVariables.size());
+
+    const sh::Attribute &outputVariable = outputVariables[0];
+
+    EXPECT_EQ(0u, outputVariable.arraySize);
+    EXPECT_EQ(5, outputVariable.location);
+    EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable.precision);
+    EXPECT_TRUE(outputVariable.staticUse);
+    EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable.type);
+    EXPECT_EQ("out_fragColor", outputVariable.name);
+}
+
+TEST_F(CollectVertexVariablesTest, LocationAttribute)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "layout(location=5) in vec4 in_Position;\n"
+        "void main() {\n"
+        "   gl_Position = in_Position;\n"
+        "}\n";
+
+    const char *shaderStrings[] = { shaderString.c_str() };
+    ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
+
+    const std::vector<sh::Attribute> &attributes = mTranslator->getAttributes();
+    ASSERT_EQ(1u, attributes.size());
+
+    const sh::Attribute &attribute = attributes[0];
+
+    EXPECT_EQ(0u, attribute.arraySize);
+    EXPECT_EQ(5, attribute.location);
+    EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, attribute.precision);
+    EXPECT_TRUE(attribute.staticUse);
+    EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, attribute.type);
+    EXPECT_EQ("in_Position", attribute.name);
+}
+
+TEST_F(CollectVertexVariablesTest, SimpleInterfaceBlock)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "uniform b {\n"
+        "  float f;\n"
+        "};"
+        "void main() {\n"
+        "   gl_Position = vec4(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("f", field.name);
+    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 2ae0de3..0236064 100644
--- a/tests/compiler_tests/ExpressionLimit_test.cpp
+++ b/tests/compiler_tests/ExpressionLimit_test.cpp
@@ -6,8 +6,9 @@
 #include <sstream>
 #include <string>
 #include <vector>
-#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
 #include "gtest/gtest.h"
+#include "GLSLANG/ShaderLang.h"
 
 #define SHADER(Src) #Src
 
@@ -179,7 +180,7 @@
     ShShaderSpec spec = SH_WEBGL_SPEC;
     ShShaderOutput output = SH_ESSL_OUTPUT;
     ShHandle vertexCompiler = ShConstructCompiler(
-        SH_FRAGMENT_SHADER, spec, output, &resources);
+        GL_FRAGMENT_SHADER, spec, output, &resources);
     int compileOptions = SH_LIMIT_EXPRESSION_COMPLEXITY;
 
     // Test expression under the limit passes.
@@ -200,6 +201,7 @@
         GenerateShaderWithLongExpression(
             kMaxExpressionComplexity + 10).c_str(),
         compileOptions & ~SH_LIMIT_EXPRESSION_COMPLEXITY, NULL));
+    ShDestruct(vertexCompiler);
 }
 
 TEST_F(ExpressionLimitTest, UnusedExpressionComplexity)
@@ -207,7 +209,7 @@
     ShShaderSpec spec = SH_WEBGL_SPEC;
     ShShaderOutput output = SH_ESSL_OUTPUT;
     ShHandle vertexCompiler = ShConstructCompiler(
-        SH_FRAGMENT_SHADER, spec, output, &resources);
+        GL_FRAGMENT_SHADER, spec, output, &resources);
     int compileOptions = SH_LIMIT_EXPRESSION_COMPLEXITY;
 
     // Test expression under the limit passes.
@@ -228,6 +230,7 @@
         GenerateShaderWithUnusedLongExpression(
             kMaxExpressionComplexity + 10).c_str(),
         compileOptions & ~SH_LIMIT_EXPRESSION_COMPLEXITY, NULL));
+    ShDestruct(vertexCompiler);
 }
 
 TEST_F(ExpressionLimitTest, CallStackDepth)
@@ -235,7 +238,7 @@
     ShShaderSpec spec = SH_WEBGL_SPEC;
     ShShaderOutput output = SH_ESSL_OUTPUT;
     ShHandle vertexCompiler = ShConstructCompiler(
-        SH_FRAGMENT_SHADER, spec, output, &resources);
+        GL_FRAGMENT_SHADER, spec, output, &resources);
     int compileOptions = SH_LIMIT_CALL_STACK_DEPTH;
 
     // Test call stack under the limit passes.
@@ -256,6 +259,7 @@
         GenerateShaderWithDeepFunctionStack(
             kMaxCallStackDepth + 10).c_str(),
         compileOptions & ~SH_LIMIT_CALL_STACK_DEPTH, NULL));
+    ShDestruct(vertexCompiler);
 }
 
 TEST_F(ExpressionLimitTest, UnusedCallStackDepth)
@@ -263,7 +267,7 @@
     ShShaderSpec spec = SH_WEBGL_SPEC;
     ShShaderOutput output = SH_ESSL_OUTPUT;
     ShHandle vertexCompiler = ShConstructCompiler(
-        SH_FRAGMENT_SHADER, spec, output, &resources);
+        GL_FRAGMENT_SHADER, spec, output, &resources);
     int compileOptions = SH_LIMIT_CALL_STACK_DEPTH;
 
     // Test call stack under the limit passes.
@@ -284,6 +288,7 @@
         GenerateShaderWithUnusedDeepFunctionStack(
             kMaxCallStackDepth + 10).c_str(),
         compileOptions & ~SH_LIMIT_CALL_STACK_DEPTH, NULL));
+    ShDestruct(vertexCompiler);
 }
 
 TEST_F(ExpressionLimitTest, Recursion)
@@ -291,7 +296,7 @@
     ShShaderSpec spec = SH_WEBGL_SPEC;
     ShShaderOutput output = SH_ESSL_OUTPUT;
     ShHandle vertexCompiler = ShConstructCompiler(
-        SH_FRAGMENT_SHADER, spec, output, &resources);
+        GL_FRAGMENT_SHADER, spec, output, &resources);
     int compileOptions = 0;
 
     static const char* shaderWithRecursion0 = SHADER(
@@ -501,5 +506,6 @@
     EXPECT_TRUE(CheckShaderCompilation(
         vertexCompiler, shaderWithNoRecursion,
         compileOptions | SH_LIMIT_CALL_STACK_DEPTH, NULL));
+    ShDestruct(vertexCompiler);
 }
 
diff --git a/tests/compiler_tests/VariablePacker_test.cpp b/tests/compiler_tests/VariablePacker_test.cpp
index 8280853..1089524 100644
--- a/tests/compiler_tests/VariablePacker_test.cpp
+++ b/tests/compiler_tests/VariablePacker_test.cpp
@@ -3,56 +3,91 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-#include "compiler/translator/VariablePacker.h"
 #include "gtest/gtest.h"
+#include "angle_gl.h"
+#include "common/utilities.h"
+#include "common/angleutils.h"
+#include "compiler/translator/VariablePacker.h"
+
+static sh::GLenum types[] = {
+  GL_FLOAT_MAT4,            // 0
+  GL_FLOAT_MAT2,            // 1
+  GL_FLOAT_VEC4,            // 2
+  GL_INT_VEC4,              // 3
+  GL_BOOL_VEC4,             // 4
+  GL_FLOAT_MAT3,            // 5
+  GL_FLOAT_VEC3,            // 6
+  GL_INT_VEC3,              // 7
+  GL_BOOL_VEC3,             // 8
+  GL_FLOAT_VEC2,            // 9
+  GL_INT_VEC2,              // 10
+  GL_BOOL_VEC2,             // 11
+  GL_FLOAT,                 // 12
+  GL_INT,                   // 13
+  GL_BOOL,                  // 14
+  GL_SAMPLER_2D,            // 15
+  GL_SAMPLER_CUBE,          // 16
+  GL_SAMPLER_EXTERNAL_OES,  // 17
+  GL_SAMPLER_2D_RECT_ARB,   // 18
+  GL_UNSIGNED_INT,          // 19
+  GL_UNSIGNED_INT_VEC2,     // 20
+  GL_UNSIGNED_INT_VEC3,     // 21
+  GL_UNSIGNED_INT_VEC4,     // 22
+  GL_FLOAT_MAT2x3,          // 23
+  GL_FLOAT_MAT2x4,          // 24
+  GL_FLOAT_MAT3x2,          // 25
+  GL_FLOAT_MAT3x4,          // 26
+  GL_FLOAT_MAT4x2,          // 27
+  GL_FLOAT_MAT4x3,          // 28
+  GL_SAMPLER_3D,            // 29
+  GL_SAMPLER_2D_ARRAY,      // 30
+  GL_SAMPLER_2D_SHADOW,     // 31
+  GL_SAMPLER_CUBE_SHADOW,   // 32
+  GL_SAMPLER_2D_ARRAY_SHADOW, // 33
+  GL_INT_SAMPLER_2D,        // 34
+  GL_INT_SAMPLER_CUBE,      // 35
+  GL_INT_SAMPLER_3D,        // 36
+  GL_INT_SAMPLER_2D_ARRAY,  // 37
+  GL_UNSIGNED_INT_SAMPLER_2D, // 38
+  GL_UNSIGNED_INT_SAMPLER_CUBE, // 39
+  GL_UNSIGNED_INT_SAMPLER_3D, // 40
+  GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, // 41
+};
+
+static sh::GLenum nonSqMatTypes[] = {
+  GL_FLOAT_MAT2x3,
+  GL_FLOAT_MAT2x4,
+  GL_FLOAT_MAT3x2,
+  GL_FLOAT_MAT3x4,
+  GL_FLOAT_MAT4x2,
+  GL_FLOAT_MAT4x3
+};
 
 TEST(VariablePacking, Pack) {
   VariablePacker packer;
-  TVariableInfoList vars;
+  std::vector<sh::ShaderVariable> vars;
   const int kMaxRows = 16;
   // test no vars.
   EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
 
-  ShDataType types[] = {
-    SH_FLOAT_MAT4,            // 0
-    SH_FLOAT_MAT2,            // 1
-    SH_FLOAT_VEC4,            // 2
-    SH_INT_VEC4,              // 3
-    SH_BOOL_VEC4,             // 4
-    SH_FLOAT_MAT3,            // 5
-    SH_FLOAT_VEC3,            // 6
-    SH_INT_VEC3,              // 7
-    SH_BOOL_VEC3,             // 8
-    SH_FLOAT_VEC2,            // 9
-    SH_INT_VEC2,              // 10
-    SH_BOOL_VEC2,             // 11
-    SH_FLOAT,                 // 12
-    SH_INT,                   // 13
-    SH_BOOL,                  // 14
-    SH_SAMPLER_2D,            // 15
-    SH_SAMPLER_CUBE,          // 16
-    SH_SAMPLER_EXTERNAL_OES,  // 17
-    SH_SAMPLER_2D_RECT_ARB,   // 18
-  };
-
-  for (size_t tt = 0; tt < sizeof(types) / sizeof(types[0]); ++tt) {
-    ShDataType type = types[tt];
+  for (size_t tt = 0; tt < ArraySize(types); ++tt) {
+    sh::GLenum type = types[tt];
     int num_rows = VariablePacker::GetNumRows(type);
     int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type);
     // Check 1 of the type.
     vars.clear();
-    vars.push_back(TVariableInfo(type, 1));
+    vars.push_back(sh::ShaderVariable(type, 0));
     EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
 
     // Check exactly the right amount of 1 type as an array.
     int num_vars = kMaxRows / num_rows;
     vars.clear();
-    vars.push_back(TVariableInfo(type, num_vars));
+    vars.push_back(sh::ShaderVariable(type, num_vars == 1 ? 0 : num_vars));
     EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
 
     // test too many
     vars.clear();
-    vars.push_back(TVariableInfo(type, num_vars + 1));
+    vars.push_back(sh::ShaderVariable(type, num_vars == 0 ? 0 : (num_vars + 1)));
     EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
 
     // Check exactly the right amount of 1 type as individual vars.
@@ -60,26 +95,78 @@
         ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
     vars.clear();
     for (int ii = 0; ii < num_vars; ++ii) {
-      vars.push_back(TVariableInfo(type, 1));
+      vars.push_back(sh::ShaderVariable(type, 0));
     }
     EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
 
     // Check 1 too many.
-    vars.push_back(TVariableInfo( type, 1));
+    vars.push_back(sh::ShaderVariable(type, 0));
     EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
   }
 
   // Test example from GLSL ES 3.0 spec chapter 11.
   vars.clear();
-  vars.push_back(TVariableInfo(SH_FLOAT_VEC4, 1));
-  vars.push_back(TVariableInfo(SH_FLOAT_MAT3, 1));
-  vars.push_back(TVariableInfo(SH_FLOAT_MAT3, 1));
-  vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 6));
-  vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 4));
-  vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 1));
-  vars.push_back(TVariableInfo(SH_FLOAT, 3));
-  vars.push_back(TVariableInfo(SH_FLOAT, 2));
-  vars.push_back(TVariableInfo(SH_FLOAT, 1));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4, 0));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 0));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT, 3));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT, 2));
+  vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
   EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
 }
 
+TEST(VariablePacking, PackSizes) {
+  for (size_t tt = 0; tt < ArraySize(types); ++tt) {
+    GLenum type = types[tt];
+
+    int expectedComponents = gl::VariableComponentCount(type);
+    int expectedRows = gl::VariableRowCount(type);
+
+    if (type == GL_FLOAT_MAT2) {
+      expectedComponents = 4;
+    } else if (gl::IsMatrixType(type)) {
+      int squareSize = std::max(gl::VariableRowCount(type),
+          gl::VariableColumnCount(type));
+      expectedComponents = squareSize;
+      expectedRows = squareSize;
+    }
+
+    EXPECT_EQ(expectedComponents,
+      VariablePacker::GetNumComponentsPerRow(type));
+    EXPECT_EQ(expectedRows, VariablePacker::GetNumRows(type));
+  }
+}
+
+// Check special assumptions about packing non-square mats
+TEST(VariablePacking, NonSquareMats) {
+
+  for (size_t mt = 0; mt < ArraySize(nonSqMatTypes); ++mt) {
+    
+    GLenum type = nonSqMatTypes[mt];
+
+    int rows = gl::VariableRowCount(type);
+    int cols = gl::VariableColumnCount(type);
+    int squareSize = std::max(rows, cols);
+
+    std::vector<sh::ShaderVariable> vars;
+    vars.push_back(sh::ShaderVariable(type, 0));
+
+    // Fill columns
+    for (int row = 0; row < squareSize; row++) {
+      for (int col = squareSize; col < 4; ++col) {
+        vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
+      }
+    }
+
+    VariablePacker packer;
+
+    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(squareSize, vars));
+
+    // and one scalar and packing should fail
+    vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
+    EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(squareSize, vars));
+  }
+}
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/preprocessor_tests/input_test.cpp b/tests/preprocessor_tests/input_test.cpp
index 3c23729..7f2a848 100644
--- a/tests/preprocessor_tests/input_test.cpp
+++ b/tests/preprocessor_tests/input_test.cpp
@@ -12,11 +12,6 @@
 {
 };
 
-TEST_F(InitTest, NegativeCount)
-{
-    EXPECT_FALSE(mPreprocessor.init(-1, NULL, NULL));
-}
-
 TEST_F(InitTest, ZeroCount)
 {
     EXPECT_TRUE(mPreprocessor.init(0, NULL, NULL));
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 75%
rename from samples/angle/sample_util/Window.h
rename to util/OSWindow.h
index adf95e8..7d25a1e 100644
--- a/samples/angle/sample_util/Window.h
+++ b/util/OSWindow.h
@@ -13,38 +13,37 @@
 #include <EGL/eglext.h>
 #include <list>
 
-enum RendererType
-{
-    RENDERER_D3D9,
-    RENDERER_D3D11
-};
-
-class Window
+class OSWindow
 {
   public:
-    Window();
+    OSWindow();
+    virtual ~OSWindow();
 
-    virtual bool initialize(const std::string &name, size_t width, size_t height, RendererType requestedRenderer) = 0;
+    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 EGLDisplay getDisplay() const = 0;
     virtual EGLNativeWindowType getNativeWindow() const = 0;
     virtual EGLNativeDisplayType getNativeDisplay() const = 0;
 
     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 81%
rename from samples/angle/sample_util/win32/Win32Window.cpp
rename to util/win32/Win32Window.cpp
index 49eaa37..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,9 +362,8 @@
 }
 
 Win32Window::Win32Window()
-    : mClassName(),
-      mDisplay(0),
-      mNativeWindow(0),
+    : mNativeWindow(0),
+      mParentWindow(0),
       mNativeDisplay(0)
 {
 }
@@ -374,42 +373,59 @@
     destroy();
 }
 
-bool Win32Window::initialize(const std::string &name, size_t width, size_t height, RendererType requestedRenderer)
+bool Win32Window::initialize(const std::string &name, size_t width, size_t height)
 {
     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)
@@ -418,44 +434,11 @@
         return false;
     }
 
-    EGLNativeDisplayType requestedDisplay = mNativeDisplay;
-    if (requestedRenderer == RENDERER_D3D11)
-    {
-        requestedDisplay = EGL_D3D11_ONLY_DISPLAY_ANGLE;
-    }
-
-    mDisplay = eglGetDisplay(requestedDisplay);
-    if (mDisplay == EGL_NO_DISPLAY)
-    {
-        mDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
-    }
-
-    EGLint majorVersion, minorVersion;
-    if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
-    {
-        destroy();
-        return false;
-    }
-
-    eglBindAPI(EGL_OPENGL_ES_API);
-    if (eglGetError() != EGL_SUCCESS)
-    {
-        destroy();
-        return false;
-    }
-
     return true;
 }
 
 void Win32Window::destroy()
 {
-    if (mDisplay != EGL_NO_DISPLAY)
-    {
-        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-        eglTerminate(mDisplay);
-        mDisplay = EGL_NO_DISPLAY;
-    }
-
     if (mNativeDisplay)
     {
         ReleaseDC(mNativeWindow, mNativeDisplay);
@@ -468,12 +451,14 @@
         mNativeWindow = 0;
     }
 
-    UnregisterClassA(mClassName.c_str(), NULL);
-}
+    if (mParentWindow)
+    {
+        DestroyWindow(mParentWindow);
+        mParentWindow = 0;
+    }
 
-EGLDisplay Win32Window::getDisplay() const
-{
-    return mDisplay;
+    UnregisterClassA(mParentClassName.c_str(), NULL);
+    UnregisterClassA(mChildClassName.c_str(), NULL);
 }
 
 EGLNativeWindowType Win32Window::getNativeWindow() const
@@ -508,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 71%
rename from samples/angle/sample_util/win32/Win32Window.h
rename to util/win32/Win32Window.h
index 44839b9..7510f60 100644
--- a/samples/angle/sample_util/win32/Win32Window.h
+++ b/util/win32/Win32Window.h
@@ -7,35 +7,36 @@
 #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();
     ~Win32Window();
 
-    bool initialize(const std::string &name, size_t width, size_t height, RendererType requestedRenderer);
+    bool initialize(const std::string &name, size_t width, size_t height);
     void destroy();
 
-    EGLDisplay getDisplay() const;
     EGLNativeWindowType getNativeWindow() const;
     EGLNativeDisplayType getNativeDisplay() const;
 
     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;
 
-    EGLDisplay mDisplay;
     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