Add the WebGL Conformance Tests extensions folder.
https://bugs.webkit.org/show_bug.cgi?id=109117

Reviewed by Kenneth Russell.

* webgl/conformance/extensions/ext-texture-filter-anisotropic-expected.txt: Added.
* webgl/conformance/extensions/ext-texture-filter-anisotropic.html: Added.
* webgl/conformance/extensions/get-extension-expected.txt: Added.
* webgl/conformance/extensions/get-extension.html: Added.
* webgl/conformance/extensions/oes-element-index-uint-expected.txt: Added.
* webgl/conformance/extensions/oes-element-index-uint.html: Added.
* webgl/conformance/extensions/oes-standard-derivatives-expected.txt: Added.
* webgl/conformance/extensions/oes-standard-derivatives.html: Added.
* webgl/conformance/extensions/oes-texture-float-expected.txt: Added.
* webgl/conformance/extensions/oes-texture-float-with-canvas-expected.txt: Added.
* webgl/conformance/extensions/oes-texture-float-with-canvas.html: Added.
* webgl/conformance/extensions/oes-texture-float-with-image-data-expected.txt: Added.
* webgl/conformance/extensions/oes-texture-float-with-image-data.html: Added.
* webgl/conformance/extensions/oes-texture-float-with-image-expected.txt: Added.
* webgl/conformance/extensions/oes-texture-float-with-image.html: Added.
* webgl/conformance/extensions/oes-texture-float-with-video-expected.txt: Added.
* webgl/conformance/extensions/oes-texture-float-with-video.html: Added.
* webgl/conformance/extensions/oes-texture-float.html: Added.
* webgl/conformance/extensions/oes-vertex-array-object-expected.txt: Added.
* webgl/conformance/extensions/oes-vertex-array-object.html: Added.
* webgl/conformance/extensions/webgl-compressed-texture-s3tc-expected.txt: Added.
* webgl/conformance/extensions/webgl-compressed-texture-s3tc.html: Added.
* webgl/conformance/extensions/webgl-debug-renderer-info-expected.txt: Added.
* webgl/conformance/extensions/webgl-debug-renderer-info.html: Added.
* webgl/conformance/extensions/webgl-debug-shaders-expected.txt: Added.
* webgl/conformance/extensions/webgl-debug-shaders.html: Added.
* webgl/conformance/extensions/webgl-depth-texture-expected.txt: Added.
* webgl/conformance/extensions/webgl-depth-texture.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/00_test_list.txt: Added.
* webgl/resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/get-extension.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html: Added.
* webgl/resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@142853 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index cc73b76..a8aaf92 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,54 @@
+2013-02-06  Gregg Tavares  <gman@chromium.org>
+
+        Add the WebGL Conformance Tests extensions folder.
+        https://bugs.webkit.org/show_bug.cgi?id=109117
+
+        Reviewed by Kenneth Russell.
+
+        * webgl/conformance/extensions/ext-texture-filter-anisotropic-expected.txt: Added.
+        * webgl/conformance/extensions/ext-texture-filter-anisotropic.html: Added.
+        * webgl/conformance/extensions/get-extension-expected.txt: Added.
+        * webgl/conformance/extensions/get-extension.html: Added.
+        * webgl/conformance/extensions/oes-element-index-uint-expected.txt: Added.
+        * webgl/conformance/extensions/oes-element-index-uint.html: Added.
+        * webgl/conformance/extensions/oes-standard-derivatives-expected.txt: Added.
+        * webgl/conformance/extensions/oes-standard-derivatives.html: Added.
+        * webgl/conformance/extensions/oes-texture-float-expected.txt: Added.
+        * webgl/conformance/extensions/oes-texture-float-with-canvas-expected.txt: Added.
+        * webgl/conformance/extensions/oes-texture-float-with-canvas.html: Added.
+        * webgl/conformance/extensions/oes-texture-float-with-image-data-expected.txt: Added.
+        * webgl/conformance/extensions/oes-texture-float-with-image-data.html: Added.
+        * webgl/conformance/extensions/oes-texture-float-with-image-expected.txt: Added.
+        * webgl/conformance/extensions/oes-texture-float-with-image.html: Added.
+        * webgl/conformance/extensions/oes-texture-float-with-video-expected.txt: Added.
+        * webgl/conformance/extensions/oes-texture-float-with-video.html: Added.
+        * webgl/conformance/extensions/oes-texture-float.html: Added.
+        * webgl/conformance/extensions/oes-vertex-array-object-expected.txt: Added.
+        * webgl/conformance/extensions/oes-vertex-array-object.html: Added.
+        * webgl/conformance/extensions/webgl-compressed-texture-s3tc-expected.txt: Added.
+        * webgl/conformance/extensions/webgl-compressed-texture-s3tc.html: Added.
+        * webgl/conformance/extensions/webgl-debug-renderer-info-expected.txt: Added.
+        * webgl/conformance/extensions/webgl-debug-renderer-info.html: Added.
+        * webgl/conformance/extensions/webgl-debug-shaders-expected.txt: Added.
+        * webgl/conformance/extensions/webgl-debug-shaders.html: Added.
+        * webgl/conformance/extensions/webgl-depth-texture-expected.txt: Added.
+        * webgl/conformance/extensions/webgl-depth-texture.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/00_test_list.txt: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/get-extension.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html: Added.
+        * webgl/resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html: Added.
+
 2013-02-13  Christophe Dumez  <ch.dumez@sisa.samsung.com>
 
         Unreviewed EFL gardening.
diff --git a/LayoutTests/webgl/conformance/extensions/ext-texture-filter-anisotropic-expected.txt b/LayoutTests/webgl/conformance/extensions/ext-texture-filter-anisotropic-expected.txt
new file mode 100644
index 0000000..9fc64ce
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/ext-texture-filter-anisotropic-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/ext-texture-filter-anisotropic.html b/LayoutTests/webgl/conformance/extensions/ext-texture-filter-anisotropic.html
new file mode 100644
index 0000000..3e8f75f
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/ext-texture-filter-anisotropic.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for ext-texture-filter-anisotropic.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html">../../resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/get-extension-expected.txt b/LayoutTests/webgl/conformance/extensions/get-extension-expected.txt
new file mode 100644
index 0000000..311fbfa
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/get-extension-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/get-extension.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/get-extension.html b/LayoutTests/webgl/conformance/extensions/get-extension.html
new file mode 100644
index 0000000..b94486d
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/get-extension.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for get-extension.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/get-extension.html">../../resources/webgl_test_files/conformance/extensions/get-extension.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/get-extension.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/oes-element-index-uint-expected.txt b/LayoutTests/webgl/conformance/extensions/oes-element-index-uint-expected.txt
new file mode 100644
index 0000000..620fbe8
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-element-index-uint-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/oes-element-index-uint.html b/LayoutTests/webgl/conformance/extensions/oes-element-index-uint.html
new file mode 100644
index 0000000..5924a92
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-element-index-uint.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for oes-element-index-uint.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html">../../resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/oes-standard-derivatives-expected.txt b/LayoutTests/webgl/conformance/extensions/oes-standard-derivatives-expected.txt
new file mode 100644
index 0000000..eb7d0ca
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-standard-derivatives-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/oes-standard-derivatives.html b/LayoutTests/webgl/conformance/extensions/oes-standard-derivatives.html
new file mode 100644
index 0000000..1546177
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-standard-derivatives.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for oes-standard-derivatives.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html">../../resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-expected.txt b/LayoutTests/webgl/conformance/extensions/oes-texture-float-expected.txt
new file mode 100644
index 0000000..b7dc0bd
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/oes-texture-float.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-canvas-expected.txt b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-canvas-expected.txt
new file mode 100644
index 0000000..2bef16f
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-canvas-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-canvas.html b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-canvas.html
new file mode 100644
index 0000000..29e3ba1
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-canvas.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for oes-texture-float-with-canvas.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html">../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-data-expected.txt b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-data-expected.txt
new file mode 100644
index 0000000..1e97334
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-data-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-data.html b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-data.html
new file mode 100644
index 0000000..90e6536
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-data.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for oes-texture-float-with-image-data.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html">../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-expected.txt b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-expected.txt
new file mode 100644
index 0000000..4a07917
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image.html b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image.html
new file mode 100644
index 0000000..1591c03
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-image.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for oes-texture-float-with-image.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html">../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-video-expected.txt b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-video-expected.txt
new file mode 100644
index 0000000..a9f1fe8
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-video-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-video.html b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-video.html
new file mode 100644
index 0000000..ae7bcc4
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float-with-video.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for oes-texture-float-with-video.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html">../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/oes-texture-float.html b/LayoutTests/webgl/conformance/extensions/oes-texture-float.html
new file mode 100644
index 0000000..dc0f9ef
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-texture-float.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for oes-texture-float.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/oes-texture-float.html">../../resources/webgl_test_files/conformance/extensions/oes-texture-float.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/oes-texture-float.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/oes-vertex-array-object-expected.txt b/LayoutTests/webgl/conformance/extensions/oes-vertex-array-object-expected.txt
new file mode 100644
index 0000000..c50e0b8
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-vertex-array-object-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/oes-vertex-array-object.html b/LayoutTests/webgl/conformance/extensions/oes-vertex-array-object.html
new file mode 100644
index 0000000..1187f36
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/oes-vertex-array-object.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for oes-vertex-array-object.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html">../../resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/webgl-compressed-texture-s3tc-expected.txt b/LayoutTests/webgl/conformance/extensions/webgl-compressed-texture-s3tc-expected.txt
new file mode 100644
index 0000000..f6924a3
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/webgl-compressed-texture-s3tc-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/webgl-compressed-texture-s3tc.html b/LayoutTests/webgl/conformance/extensions/webgl-compressed-texture-s3tc.html
new file mode 100644
index 0000000..5cf4365
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/webgl-compressed-texture-s3tc.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for webgl-compressed-texture-s3tc.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html">../../resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/webgl-debug-renderer-info-expected.txt b/LayoutTests/webgl/conformance/extensions/webgl-debug-renderer-info-expected.txt
new file mode 100644
index 0000000..6e0227b
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/webgl-debug-renderer-info-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/webgl-debug-renderer-info.html b/LayoutTests/webgl/conformance/extensions/webgl-debug-renderer-info.html
new file mode 100644
index 0000000..2696112
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/webgl-debug-renderer-info.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for webgl-debug-renderer-info.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html">../../resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/webgl-debug-shaders-expected.txt b/LayoutTests/webgl/conformance/extensions/webgl-debug-shaders-expected.txt
new file mode 100644
index 0000000..3578352
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/webgl-debug-shaders-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/webgl-debug-shaders.html b/LayoutTests/webgl/conformance/extensions/webgl-debug-shaders.html
new file mode 100644
index 0000000..b9bc4b8
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/webgl-debug-shaders.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for webgl-debug-shaders.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html">../../resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/conformance/extensions/webgl-depth-texture-expected.txt b/LayoutTests/webgl/conformance/extensions/webgl-depth-texture-expected.txt
new file mode 100644
index 0000000..6e8dec0
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/webgl-depth-texture-expected.txt
@@ -0,0 +1,5 @@
+This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
+
+Test: ../../resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html
+PASS
+
diff --git a/LayoutTests/webgl/conformance/extensions/webgl-depth-texture.html b/LayoutTests/webgl/conformance/extensions/webgl-depth-texture.html
new file mode 100644
index 0000000..b7739c0
--- /dev/null
+++ b/LayoutTests/webgl/conformance/extensions/webgl-depth-texture.html
@@ -0,0 +1,18 @@
+<!-- This file is auto-generated by generate-webgl-tests.py. DO NOT EDIT -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Test Wrapper for webgl-depth-texture.html</title>
+<script type="text/javascript" src="../../../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="../../resources/webkit-webgl-test-harness.js"></script>
+</head>
+<body>
+<p>This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.</p>
+Test: <a href="../../resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html">../../resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html</a>
+<div id="result"></div>
+<div id="iframe">
+<iframe src="../../resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html" width="800" height="600"></iframe>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/00_test_list.txt b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/00_test_list.txt
new file mode 100644
index 0000000..c003de5
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/00_test_list.txt
@@ -0,0 +1,14 @@
+--min-version 1.0.2 get-extension.html
+oes-standard-derivatives.html
+oes-texture-float-with-canvas.html
+oes-texture-float-with-image-data.html
+oes-texture-float-with-image.html
+oes-texture-float-with-video.html
+oes-texture-float.html
+oes-vertex-array-object.html
+--min-version 1.0.2 oes-element-index-uint.html
+webgl-debug-renderer-info.html
+webgl-debug-shaders.html
+--min-version 1.0.2 webgl-compressed-texture-s3tc.html
+--min-version 1.0.2 webgl-depth-texture.html
+--min-version 1.0.2 ext-texture-filter-anisotropic.html
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html
new file mode 100644
index 0000000..a8c9fcb
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/ext-texture-filter-anisotropic.html
@@ -0,0 +1,180 @@
+<!--
+
+/*
+** Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_texture_filter_anisotropic Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("This test verifies the functionality of the EXT_texture_filter_anisotropic extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas);
+var ext = null;
+
+if (!gl) {
+    testFailed("WebGL context does not exist");
+} else {
+    testPassed("WebGL context exists");
+
+    // Run tests with extension disabled
+    runHintTestDisabled();
+
+    // Query the extension and store globally so shouldBe can access it
+    ext = wtu.getExtensionWithKnownPrefixes(gl, "EXT_texture_filter_anisotropic");
+
+    if (!ext) {
+        testPassed("No EXT_texture_filter_anisotropic support -- this is legal");
+
+        runSupportedTest(false);
+    } else {
+        testPassed("Successfully enabled EXT_texture_filter_anisotropic extension");
+
+        runSupportedTest(true);
+        runHintTestEnabled();
+    }
+}
+
+function runSupportedTest(extensionEnabled) {
+    if (wtu.getSupportedExtensionWithKnownPrefixes(gl, "EXT_texture_filter_anisotropic") !== undefined) {
+        if (extensionEnabled) {
+            testPassed("EXT_texture_filter_anisotropic listed as supported and getExtension succeeded");
+        } else {
+            testFailed("EXT_texture_filter_anisotropic listed as supported but getExtension failed");
+        }
+    } else {
+        if (extensionEnabled) {
+            testFailed("EXT_texture_filter_anisotropic not listed as supported but getExtension succeeded");
+        } else {
+            testPassed("EXT_texture_filter_anisotropic not listed as supported and getExtension failed -- this is legal");
+        }
+    }
+}
+
+function runHintTestDisabled() {
+    debug("Testing MAX_TEXTURE_MAX_ANISOTROPY_EXT with extension disabled");
+    
+    var MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
+    gl.getParameter(MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "MAX_TEXTURE_MAX_ANISOTROPY_EXT should not be queryable if extension is disabled");
+    
+    debug("Testing TEXTURE_MAX_ANISOTROPY_EXT with extension disabled");
+    var TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE;
+    var texture = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+   
+    gl.getTexParameter(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY_EXT);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY_EXT should not be queryable if extension is disabled");
+
+    gl.texParameterf(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY_EXT, 1);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY_EXT should not be settable if extension is disabled");
+    
+    gl.texParameteri(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY_EXT, 1);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY_EXT should not be settable if extension is disabled");
+
+    gl.deleteTexture(texture);
+}
+
+function runHintTestEnabled() {
+    debug("Testing MAX_TEXTURE_MAX_ANISOTROPY_EXT with extension enabled");
+
+    shouldBe("ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT", "0x84FF");
+
+    var max_anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+    glErrorShouldBe(gl, gl.NO_ERROR, "MAX_TEXTURE_MAX_ANISOTROPY_EXT query should succeed if extension is enabled");
+
+    if(max_anisotropy >= 2){
+        testPassed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY_EXT is 2.0");
+    }
+    else{
+        testFailed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY_EXT is 2.0, returned values was: " + max_anisotropy);
+    }
+    
+    // TODO make a texture and verify initial value == 1 and setting to less than 1 is invalid value
+
+    debug("Testing TEXTURE_MAX_ANISOTROPY_EXT with extension disabled");
+    shouldBe("ext.TEXTURE_MAX_ANISOTROPY_EXT", "0x84FE");
+
+    var texture = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+   
+    var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT);
+    glErrorShouldBe(gl, gl.NO_ERROR, "TEXTURE_MAX_ANISOTROPY_EXT query should succeed if extension is enabled");
+
+    if(queried_value == 1){
+        testPassed("Initial value of TEXTURE_MAX_ANISOTROPY_EXT is 1.0");
+    }
+    else{
+        testFailed("Initial value of TEXTURE_MAX_ANISOTROPY_EXT should be 1.0, returned value was: " + queried_value);
+    }
+
+    gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, 0);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameterf TEXTURE_MAX_ANISOTROPY_EXT set to < 1 should be an invalid value");
+    
+    gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, 0);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameteri TEXTURE_MAX_ANISOTROPY_EXT set to < 1 should be an invalid value");
+    
+    gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
+    glErrorShouldBe(gl, gl.NO_ERROR, "texParameterf TEXTURE_MAX_ANISOTROPY_EXT set to >= 2 should should succeed");
+    
+    gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
+    glErrorShouldBe(gl, gl.NO_ERROR, "texParameteri TEXTURE_MAX_ANISOTROPY_EXT set to >= 2 should should succeed");
+
+    var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT);
+    if(queried_value == max_anisotropy){
+        testPassed("Set value of TEXTURE_MAX_ANISOTROPY_EXT matches expecation");
+    }
+    else{
+        testFailed("Set value of TEXTURE_MAX_ANISOTROPY_EXT should be: " + max_anisotropy + " , returned value was: " + queried_value);
+    }
+
+    gl.deleteTexture(texture);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/get-extension.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/get-extension.html
new file mode 100644
index 0000000..3fd39e9
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/get-extension.html
@@ -0,0 +1,99 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Extension Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+var randomizeCase = function(str) {
+    var newChars = [];
+    for (var ii = 0; ii < str.length; ++ii) {
+        var c = str.substr(ii, 1);
+        var m = (Math.random() > 0.5) ? c.toLowerCase() : c.toUpperCase();
+        newChars.push(m);
+    }
+    return newChars.join("");
+}
+
+description();
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas);
+
+debug("check every extension advertised can be enabled");
+var extensions = [];
+var extensionNames = gl.getSupportedExtensions();
+for (var ii = 0; ii < extensionNames.length; ++ii) {
+    var originalName = extensionNames[ii];
+    var mixedName = randomizeCase(originalName);
+    var extension = gl.getExtension(mixedName);
+    assertMsg(extension, "able to get " + originalName + " as " + mixedName);
+    if (extension) {
+        var kTestString = "this is a test";
+        var kTestNumber = 123;
+        var kTestFunction = function() { };
+        var kTestObject = { };
+        extension.testStringProperty = kTestString;
+        extension.testNumberProperty = kTestNumber;
+        extension.testFunctionProperty = kTestFunction;
+        extension.testObjectProperty = kTestObject;
+        gc();
+        var extension2 = gl.getExtension(originalName);
+        assertMsg(
+            extension === extension2,
+            "calling getExtension twice for the same extension returns the same object");
+        assertMsg(
+            extension2.testStringProperty === kTestString &&
+            extension2.testFunctionProperty === kTestFunction &&
+            extension2.testObjectProperty === kTestObject &&
+            extension2.testNumberProperty === kTestNumber,
+            "object returned by 2nd call to getExtension has same properties");
+    }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html
new file mode 100644
index 0000000..8164e52
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-element-index-uint.html
@@ -0,0 +1,446 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OES_element_index_uint Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+
+<script id="vs" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec4 vColor;
+varying vec4 color;
+void main() {
+    gl_Position = vPosition;
+    color = vColor;
+}
+</script>
+<script id="fs" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 color;
+void main() {
+  gl_FragColor = color;
+}
+</script>
+
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the OES_element_index_uint extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas);
+var ext = null;
+var vao = null;
+
+if (!gl) {
+    testFailed("WebGL context does not exist");
+} else {
+    testPassed("WebGL context exists");
+
+    // Query the extension and store globally so shouldBe can access it
+    ext = gl.getExtension("OES_element_index_uint");
+    if (!ext) {
+        testPassed("No OES_element_index_uint support -- this is legal");
+
+        runSupportedTest(false);
+    } else {
+        testPassed("Successfully enabled OES_element_index_uint extension");
+
+        runSupportedTest(true);
+        runDrawTests();
+
+        // These tests are tweaked duplicates of the buffers/index-validation* tests
+        // using unsigned int indices to ensure that behavior remains consistent
+        runIndexValidationTests();
+        runCopiesIndicesTests();
+        runResizedBufferTests();
+        runVerifiesTooManyIndicesTests();
+        runCrashWithBufferSubDataTests();
+
+        glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+    }
+}
+
+function runSupportedTest(extensionEnabled) {
+    var supported = gl.getSupportedExtensions();
+    if (supported.indexOf("OES_element_index_uint") >= 0) {
+        if (extensionEnabled) {
+            testPassed("OES_element_index_uint listed as supported and getExtension succeeded");
+        } else {
+            testFailed("OES_element_index_uint listed as supported but getExtension failed");
+        }
+    } else {
+        if (extensionEnabled) {
+            testFailed("OES_element_index_uint not listed as supported but getExtension succeeded");
+        } else {
+            testPassed("OES_element_index_uint not listed as supported and getExtension failed -- this is legal");
+        }
+    }
+}
+
+function runDrawTests() {
+    debug("Test that draws with unsigned integer indices produce the expected results");
+    
+    canvas.width = 50; canvas.height = 50;
+    gl.viewport(0, 0, canvas.width, canvas.height);
+    
+    var program = wtu.setupNoTexCoordTextureProgram(gl);
+
+    function setupDraw(s) {
+        // Create a vertex buffer that cannot be fully indexed via shorts
+        var quadArrayLen = 65537 * 3;
+        var quadArray = new Float32Array(quadArrayLen);
+        
+        // Leave all but the last 4 values zero-ed out
+        var idx = quadArrayLen - 12;
+
+        // Initialized the last 4 values to a quad
+        quadArray[idx++] = 1.0 * s;
+        quadArray[idx++] = 1.0 * s;
+        quadArray[idx++] = 0.0;
+
+        quadArray[idx++] = -1.0 * s;
+        quadArray[idx++] = 1.0 * s;
+        quadArray[idx++] = 0.0;
+
+        quadArray[idx++] = -1.0 * s;
+        quadArray[idx++] = -1.0 * s;
+        quadArray[idx++] = 0.0;
+
+        quadArray[idx++] = 1.0 * s;
+        quadArray[idx++] = -1.0 * s;
+        quadArray[idx++] = 0.0;
+
+        var vertexObject = gl.createBuffer();
+        gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+        gl.bufferData(gl.ARRAY_BUFFER, quadArray, gl.STATIC_DRAW);
+
+        // Create an unsigned int index buffer that indexes the last 4 vertices
+        var baseIndex = (quadArrayLen / 3) - 4;
+
+        var indexObject = gl.createBuffer();
+        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([
+            baseIndex + 0,
+            baseIndex + 1,
+            baseIndex + 2,
+            baseIndex + 2,
+            baseIndex + 3,
+            baseIndex + 0]), gl.STATIC_DRAW);
+
+        var opt_positionLocation = 0;
+        gl.enableVertexAttribArray(opt_positionLocation);
+        gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
+    };
+    function readLocation(x, y) {
+        var pixels = new Uint8Array(1 * 1 * 4);
+        gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+        return pixels;
+    };
+    function testPixel(blackList, whiteList) {
+        function testList(list, expected) {
+            for (var n = 0; n < list.length; n++) {
+                var l = list[n];
+                var x = -Math.floor(l * canvas.width / 2) + canvas.width / 2;
+                var y = -Math.floor(l * canvas.height / 2) + canvas.height / 2;
+                var source = readLocation(x, y);
+                if (Math.abs(source[0] - expected) > 2) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return testList(blackList, 0) && testList(whiteList, 255);
+    };
+    function verifyDraw(drawNumber, s) {
+        gl.clearColor(1.0, 1.0, 1.0, 1.0);
+        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, 0);
+
+        var blackList = [];
+        var whiteList = [];
+        var points = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0];
+        for (var n = 0; n < points.length; n++) {
+            if (points[n] <= s) {
+                blackList.push(points[n]);
+            } else {
+                whiteList.push(points[n]);
+            }
+        }
+        if (testPixel(blackList, whiteList)) {
+            testPassed("Draw " + drawNumber + " passed pixel test");
+        } else {
+            testFailed("Draw " + drawNumber + " failed pixel test");
+        }
+    };
+
+    setupDraw(0.5);
+    verifyDraw(0, 0.5);
+}
+
+function runIndexValidationTests() {
+    description("Tests that index validation verifies the correct number of indices");
+
+    function sizeInBytes(type) {
+      switch (type) {
+      case gl.BYTE:
+      case gl.UNSIGNED_BYTE:
+        return 1;
+      case gl.SHORT:
+      case gl.UNSIGNED_SHORT:
+        return 2;
+      case gl.INT:
+      case gl.UNSIGNED_INT:
+      case gl.FLOAT:
+        return 4;
+      default:
+        throw "unknown type";
+      }
+    }
+
+    var program = wtu.loadStandardProgram(gl);
+
+    // 3 vertices => 1 triangle, interleaved data
+    var dataComplete = new Float32Array([0, 0, 0, 1,
+                                         0, 0, 1,
+                                         1, 0, 0, 1,
+                                         0, 0, 1,
+                                         1, 1, 1, 1,
+                                         0, 0, 1]);
+    var dataIncomplete = new Float32Array([0, 0, 0, 1,
+                                           0, 0, 1,
+                                           1, 0, 0, 1,
+                                           0, 0, 1,
+                                           1, 1, 1, 1]);
+    var indices = new Uint32Array([0, 1, 2]);
+
+    debug("Testing with valid indices");
+
+    var bufferComplete = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, bufferComplete);
+    gl.bufferData(gl.ARRAY_BUFFER, dataComplete, gl.STATIC_DRAW);
+    var elements = gl.createBuffer();
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elements);
+    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+    gl.useProgram(program);
+    var vertexLoc = gl.getAttribLocation(program, "a_vertex");
+    var normalLoc = gl.getAttribLocation(program, "a_normal");
+    gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
+    gl.enableVertexAttribArray(vertexLoc);
+    gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
+    gl.enableVertexAttribArray(normalLoc);
+    shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+    glErrorShouldBe(gl, gl.NO_ERROR);
+
+    debug("Testing with out-of-range indices");
+
+    var bufferIncomplete = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, bufferIncomplete);
+    gl.bufferData(gl.ARRAY_BUFFER, dataIncomplete, gl.STATIC_DRAW);
+    gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
+    gl.enableVertexAttribArray(vertexLoc);
+    gl.disableVertexAttribArray(normalLoc);
+    debug("Enable vertices, valid");
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    debug("Enable normals, out-of-range");
+    gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
+    gl.enableVertexAttribArray(normalLoc);
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+    glErrorShouldBe(gl, gl.INVALID_OPERATION);
+
+    debug("Test with enabled attribute that does not belong to current program");
+
+    gl.disableVertexAttribArray(normalLoc);
+    var extraLoc = Math.max(vertexLoc, normalLoc) + 1;
+    gl.enableVertexAttribArray(extraLoc);
+    debug("Enable an extra attribute with null");
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+    glErrorShouldBe(gl, gl.INVALID_OPERATION);
+    debug("Enable an extra attribute with insufficient data buffer");
+    gl.vertexAttribPointer(extraLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
+    glErrorShouldBe(gl, gl.NO_ERROR);
+    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+    debug("Pass large negative index to vertexAttribPointer");
+    gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), -2000000000 * sizeInBytes(gl.FLOAT));
+    glErrorShouldBe(gl, gl.INVALID_VALUE);
+    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+}
+
+function runCopiesIndicesTests() {
+    debug("Test that client data is always copied during bufferData and bufferSubData calls");
+
+    var program = wtu.loadStandardProgram(gl);
+
+    gl.useProgram(program);
+    var vertexObject = gl.createBuffer();
+    gl.enableVertexAttribArray(0);
+    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+    // 4 vertices -> 2 triangles
+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 1,1,0 ]), gl.STATIC_DRAW);
+    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+    var indexObject = gl.createBuffer();
+
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+    var indices = new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]);
+    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+    shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
+    shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
+    shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
+    indices[0] = 2;
+    indices[5] = 1;
+    shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
+    shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
+    shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
+}
+
+function runResizedBufferTests() {
+    debug("Test that updating the size of a vertex buffer is properly noticed by the WebGL implementation.");
+
+    var program = wtu.setupProgram(gl, ["vs", "fs"], ["vPosition", "vColor"]);
+    glErrorShouldBe(gl, gl.NO_ERROR, "after initialization");
+
+    var vertexObject = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
+        [-1,1,0, 1,1,0, -1,-1,0,
+         -1,-1,0, 1,1,0, 1,-1,0]), gl.STATIC_DRAW);
+    gl.enableVertexAttribArray(0);
+    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+    glErrorShouldBe(gl, gl.NO_ERROR, "after vertex setup");
+
+    var texCoordObject = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
+        [0,0, 1,0, 0,1,
+         0,1, 1,0, 1,1]), gl.STATIC_DRAW);
+    gl.enableVertexAttribArray(1);
+    gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+    glErrorShouldBe(gl, gl.NO_ERROR, "after texture coord setup");
+
+    // Now resize these buffers because we want to change what we're drawing.
+    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+        -1,1,0, 1,1,0, -1,-1,0, 1,-1,0,
+        -1,1,0, 1,1,0, -1,-1,0, 1,-1,0]), gl.STATIC_DRAW);
+    glErrorShouldBe(gl, gl.NO_ERROR, "after vertex redefinition");
+    gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
+    gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([
+        255, 0, 0, 255,
+        255, 0, 0, 255,
+        255, 0, 0, 255,
+        255, 0, 0, 255,
+        0, 255, 0, 255,
+        0, 255, 0, 255,
+        0, 255, 0, 255,
+        0, 255, 0, 255]), gl.STATIC_DRAW);
+    gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0);
+    glErrorShouldBe(gl, gl.NO_ERROR, "after texture coordinate / color redefinition");
+
+    var numQuads = 2;
+    var indices = new Uint32Array(numQuads * 6);
+    for (var ii = 0; ii < numQuads; ++ii) {
+        var offset = ii * 6;
+        var quad = (ii == (numQuads - 1)) ? 4 : 0;
+        indices[offset + 0] = quad + 0;
+        indices[offset + 1] = quad + 1;
+        indices[offset + 2] = quad + 2;
+        indices[offset + 3] = quad + 2;
+        indices[offset + 4] = quad + 1;
+        indices[offset + 5] = quad + 3;
+    }
+    var indexObject = gl.createBuffer();
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+    glErrorShouldBe(gl, gl.NO_ERROR, "after setting up indices");
+    gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_INT, 0);
+    glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
+}
+
+function runVerifiesTooManyIndicesTests() {
+    description("Tests that index validation for drawElements does not examine too many indices");
+
+    var program = wtu.loadStandardProgram(gl);
+
+    gl.useProgram(program);
+    var vertexObject = gl.createBuffer();
+    gl.enableVertexAttribArray(0);
+    gl.disableVertexAttribArray(1);
+    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+    // 4 vertices -> 2 triangles
+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 1,1,0 ]), gl.STATIC_DRAW);
+    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+    var indexObject = gl.createBuffer();
+
+    debug("Test out of range indices")
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]), gl.STATIC_DRAW);
+    shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
+    shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
+    shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
+}
+
+function runCrashWithBufferSubDataTests() {
+    debug('Verifies that the index validation code which is within bufferSubData does not crash.')
+
+    var elementBuffer = gl.createBuffer();
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 256, gl.STATIC_DRAW);
+    var data = new Uint32Array(127);
+    gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 64, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "after attempting to update a buffer outside of the allocated bounds");
+    testPassed("bufferSubData, when buffer object was initialized with null, did not crash");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html
new file mode 100644
index 0000000..bd9f215
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-standard-derivatives.html
@@ -0,0 +1,381 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OES_standard_derivatives Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing standard derivatives -->
+
+<!-- Shader omitting the required #extension pragma -->
+<script id="missingPragmaFragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+varying vec2 texCoord;
+void main() {
+    float dx = dFdx(texCoord.x);
+    float dy = dFdy(texCoord.y);
+    float w = fwidth(texCoord.x);
+    gl_FragColor = vec4(dx, dy, w, 1.0);
+}
+</script>
+
+<!-- Shader to test macro definition -->
+<script id="macroFragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+#ifdef GL_OES_standard_derivatives
+    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+#else
+    // Error expected
+    #error no GL_OES_standard_derivatives;
+#endif
+}
+</script>
+
+<!-- Shader with required #extension pragma -->
+<script id="testFragmentShader" type="x-shader/x-fragment">
+#extension GL_OES_standard_derivatives : enable
+precision mediump float;
+varying vec2 texCoord;
+void main() {
+    float dx = dFdx(texCoord.x);
+    float dy = dFdy(texCoord.y);
+    float w = fwidth(texCoord.x);
+    gl_FragColor = vec4(dx, dy, w, 1.0);
+}
+</script>
+<!-- Shaders to link with test fragment shaders -->
+<script id="goodVertexShader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+varying vec2 texCoord;
+void main() {
+    texCoord = vPosition.xy;
+    gl_Position = vPosition;
+}
+</script>
+<!-- Shaders to test output -->
+<script id="outputVertexShader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+varying vec4 position;
+void main() {
+    position = vPosition;
+    gl_Position = vPosition;
+}
+</script>
+<script id="outputFragmentShader" type="x-shader/x-fragment">
+#extension GL_OES_standard_derivatives : enable
+precision mediump float;
+varying vec4 position;
+void main() {
+    float dzdx = dFdx(position.z);
+    float dzdy = dFdy(position.z);
+    float fw = fwidth(position.z);
+    gl_FragColor = vec4(abs(dzdx) * 40.0, abs(dzdy) * 40.0, fw * 40.0, 1.0);
+}
+</script>
+
+<script>
+"use strict";
+description("This test verifies the functionality of the OES_standard_derivatives extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas);
+var ext = null;
+
+if (!gl) {
+    testFailed("WebGL context does not exist");
+} else {
+    testPassed("WebGL context exists");
+
+    // Run tests with extension disabled
+    runHintTestDisabled();
+    runShaderTests(false);
+
+    // Query the extension and store globally so shouldBe can access it
+    ext = gl.getExtension("OES_standard_derivatives");
+    if (!ext) {
+        testPassed("No OES_standard_derivatives support -- this is legal");
+
+        runSupportedTest(false);
+    } else {
+        testPassed("Successfully enabled OES_standard_derivatives extension");
+
+        runSupportedTest(true);
+
+        runHintTestEnabled();
+        runShaderTests(true);
+        runOutputTests();
+        runUniqueObjectTest();
+    }
+}
+
+function runSupportedTest(extensionEnabled) {
+    var supported = gl.getSupportedExtensions();
+    if (supported.indexOf("OES_standard_derivatives") >= 0) {
+        if (extensionEnabled) {
+            testPassed("OES_standard_derivatives listed as supported and getExtension succeeded");
+        } else {
+            testFailed("OES_standard_derivatives listed as supported but getExtension failed");
+        }
+    } else {
+        if (extensionEnabled) {
+            testFailed("OES_standard_derivatives not listed as supported but getExtension succeeded");
+        } else {
+            testPassed("OES_standard_derivatives not listed as supported and getExtension failed -- this is legal");
+        }
+    }
+}
+
+function runHintTestDisabled() {
+    debug("Testing FRAGMENT_SHADER_DERIVATIVE_HINT_OES with extension disabled");
+
+    // Use the constant directly as we don't have the extension
+    var FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
+
+    gl.getParameter(FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "FRAGMENT_SHADER_DERIVATIVE_HINT_OES should not be queryable if extension is disabled");
+
+    gl.hint(FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.DONT_CARE);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "hint should not accept FRAGMENT_SHADER_DERIVATIVE_HINT_OES if extension is disabled");
+}
+
+function runHintTestEnabled() {
+    debug("Testing FRAGMENT_SHADER_DERIVATIVE_HINT_OES with extension enabled");
+
+    shouldBe("ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES", "0x8B8B");
+
+    gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
+    glErrorShouldBe(gl, gl.NO_ERROR, "FRAGMENT_SHADER_DERIVATIVE_HINT_OES query should succeed if extension is enabled");
+
+    // Default value is DONT_CARE
+    if (gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) == gl.DONT_CARE) {
+        testPassed("Default value of FRAGMENT_SHADER_DERIVATIVE_HINT_OES is DONT_CARE");
+    } else {
+        testFailed("Default value of FRAGMENT_SHADER_DERIVATIVE_HINT_OES is not DONT_CARE");
+    }
+
+    // Ensure that we can set the target
+    gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.DONT_CARE);
+    glErrorShouldBe(gl, gl.NO_ERROR, "hint should accept FRAGMENT_SHADER_DERIVATIVE_HINT_OES");
+
+    // Test all the hint modes
+    var validModes = ["FASTEST", "NICEST", "DONT_CARE"];
+    var anyFailed = false;
+    for (var n = 0; n < validModes.length; n++) {
+        var mode = validModes[n];
+        gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl[mode]);
+        if (gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) != gl[mode]) {
+            testFailed("Round-trip of hint()/getParameter() failed on mode " + mode);
+            anyFailed = true;
+        }
+    }
+    if (!anyFailed) {
+        testPassed("Round-trip of hint()/getParameter() with all supported modes");
+    }
+}
+
+function runShaderTests(extensionEnabled) {
+    debug("");
+    debug("Testing various shader compiles with extension " + (extensionEnabled ? "enabled" : "disabled"));
+
+    // Expect the macro shader to succeed ONLY if enabled
+    var macroFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "macroFragmentShader");
+    if (extensionEnabled) {
+        if (macroFragmentProgram) {
+            // Expected result
+            testPassed("GL_OES_standard_derivatives defined in shaders when extension is enabled");
+        } else {
+            testFailed("GL_OES_standard_derivatives not defined in shaders when extension is enabled");
+        }
+    } else {
+        if (macroFragmentProgram) {
+            testFailed("GL_OES_standard_derivatives defined in shaders when extension is disabled");
+        } else {
+            testPassed("GL_OES_standard_derivatives not defined in shaders when extension disabled");
+        }
+    }
+
+    // Always expect the shader missing the #pragma to fail (whether enabled or not)
+    var missingPragmaFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "missingPragmaFragmentShader");
+    if (missingPragmaFragmentProgram) {
+        testFailed("Shader built-ins allowed without #extension pragma");
+    } else {
+        testPassed("Shader built-ins disallowed without #extension pragma");
+    }
+
+    // Try to compile a shader using the built-ins that should only succeed if enabled
+    var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "testFragmentShader");
+    if (extensionEnabled) {
+        if (testFragmentProgram) {
+            testPassed("Shader built-ins compiled successfully when extension enabled");
+        } else {
+            testFailed("Shader built-ins failed to compile when extension enabled");
+        }
+    } else {
+        if (testFragmentProgram) {
+            testFailed("Shader built-ins compiled successfully when extension disabled");
+        } else {
+            testPassed("Shader built-ins failed to compile when extension disabled");
+        }
+    }
+}
+
+function runOutputTests() {
+    // This tests does several draws with various values of z.
+    // The output of the fragment shader is:
+    // [dFdx(z), dFdy(z), fwidth(z), 1.0]
+    // The expected math: (note the conversion to uint8)
+    //    canvas.width = canvas.height = 50
+    //    dFdx = totalChange.x / canvas.width  = 0.5 / 50.0 = 0.01
+    //    dFdy = totalChange.y / canvas.height = 0.5 / 50.0 = 0.01
+    //    fw = abs(dFdx + dFdy) = 0.01 + 0.01 = 0.02
+    //    r = floor(dFdx * 40.0 * 255) = 102
+    //    g = floor(dFdy * 40.0 * 255) = 102
+    //    b = floor(fw * 40.0 * 255) = 204
+
+    var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
+
+    debug("Testing various draws for valid built-in function behavior");
+
+    canvas.width = 50; canvas.height = 50;
+    gl.viewport(0, 0, canvas.width, canvas.height);
+    gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.NICEST);
+
+    var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['vPosition', 'texCoord0'], [0, 1]);
+    var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
+
+    function readLocation(x, y) {
+        var pixels = new Uint8Array(1 * 1 * 4);
+        var px = Math.floor(x * canvas.width);
+        var py = Math.floor(y * canvas.height);
+        gl.readPixels(px, py, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+        return pixels;
+    };
+    function toString(arr) {
+        var s = "[";
+        for (var n = 0; n < arr.length; n++) {
+            s += arr[n];
+            if (n < arr.length - 1) {
+                s += ", ";
+            }
+        }
+        return s + "]";
+    };
+    function expectResult(target, successMessage, failureMessage) {
+        var locations = [
+            readLocation(0.1, 0.1),
+            readLocation(0.9, 0.1),
+            readLocation(0.1, 0.9),
+            readLocation(0.9, 0.9),
+            readLocation(0.5, 0.5)
+        ];
+        var anyDiffer = false;
+        for (var n = 0; n < locations.length; n++) {
+            var source = locations[n];
+            for (var m = 0; m < 4; m++) {
+                if (Math.abs(source[m] - target[m]) > e) {
+                    anyDiffer = true;
+                    testFailed(failureMessage + "; should be " + toString(target) + ", was " + toString(source));
+                    break;
+                }
+            }
+        }
+        if (!anyDiffer) {
+            testPassed(successMessage);
+        }
+    };
+
+    function setupBuffers(tl, tr, bl, br) {
+        gl.bindBuffer(gl.ARRAY_BUFFER, quadParameters[0]);
+        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+           1.0,  1.0, tr,
+          -1.0,  1.0, tl,
+          -1.0, -1.0, bl,
+           1.0,  1.0, tr,
+          -1.0, -1.0, bl,
+           1.0, -1.0, br]), gl.STATIC_DRAW);
+    };
+
+    // Draw 1: (no variation)
+    setupBuffers(0.0, 0.0, 0.0, 0.0);
+    wtu.drawQuad(gl);
+    expectResult([0, 0, 0, 255],
+                 "Draw 1 (no variation) returned the correct data",
+                 "Draw 1 (no variation) returned incorrect data");
+
+    // Draw 2: (variation in x)
+    setupBuffers(1.0, 0.0, 1.0, 0.0);
+    wtu.drawQuad(gl);
+    expectResult([204, 0, 204, 255],
+                 "Draw 2 (variation in x) returned the correct data",
+                 "Draw 2 (variation in x) returned incorrect data");
+
+    // Draw 3: (variation in y)
+    setupBuffers(1.0, 1.0, 0.0, 0.0);
+    wtu.drawQuad(gl);
+    expectResult([0, 204, 204, 255],
+                 "Draw 3 (variation in y) returned the correct data",
+                 "Draw 3 (variation in y) returned incorrect data");
+
+    // Draw 4: (variation in x & y)
+    setupBuffers(1.0, 0.5, 0.5, 0.0);
+    wtu.drawQuad(gl);
+    expectResult([102, 102, 204, 255],
+                 "Draw 4 (variation in x & y) returned the correct data",
+                 "Draw 4 (variation in x & y) returned incorrect data");
+
+}
+
+function runUniqueObjectTest()
+{
+    debug("Testing that getExtension() returns the same object each time");
+    gl.getExtension("OES_standard_derivatives").myProperty = 2;
+    gc();
+    shouldBe('gl.getExtension("OES_standard_derivatives").myProperty', '2');
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html
new file mode 100644
index 0000000..d343e86
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-canvas.html
@@ -0,0 +1,55 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+<script src="../resources/tex-image-and-sub-image-2d-with-canvas.js"></script>
+<script>
+"use strict";
+function testPrologue(gl) {
+    if (!gl.getExtension("OES_texture_float")) {
+        testPassed("No OES_texture_float support -- this is legal");
+        return false;
+    }
+
+    testPassed("Successfully enabled OES_texture_float extension");
+    return true;
+}
+</script>
+</head>
+<body onload='generateTest("RGBA", "FLOAT", testPrologue)()'>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html
new file mode 100644
index 0000000..e81cfb3
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image-data.html
@@ -0,0 +1,56 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+<script src="../resources/tex-image-and-sub-image-2d-with-image-data.js"></script>
+<script>
+"use strict";
+function testPrologue(gl) {
+    if (!gl.getExtension("OES_texture_float")) {
+        testPassed("No OES_texture_float support -- this is legal");
+        return false;
+    }
+
+    testPassed("Successfully enabled OES_texture_float extension");
+    return true;
+}
+</script>
+</head>
+<body onload='generateTest("RGBA", "FLOAT", testPrologue)()'>
+<canvas id="texcanvas" width="1" height="2"></canvas>
+<canvas id="example" width="1" height="2"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html
new file mode 100644
index 0000000..bd4bdc9
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-image.html
@@ -0,0 +1,55 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+<script src="../resources/tex-image-and-sub-image-2d-with-image.js"></script>
+<script>
+"use strict";
+function testPrologue(gl) {
+    if (!gl.getExtension("OES_texture_float")) {
+        testPassed("No OES_texture_float support -- this is legal");
+        return false;
+    }
+
+    testPassed("Successfully enabled OES_texture_float extension");
+    return true;
+}
+</script>
+</head>
+<body onload='generateTest("RGBA", "FLOAT", "..", testPrologue)()'>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html
new file mode 100644
index 0000000..0deb7ae
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float-with-video.html
@@ -0,0 +1,60 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+<script src="../resources/tex-image-and-sub-image-2d-with-video.js"></script>
+<script>
+"use strict";
+function testPrologue(gl) {
+    if (!gl.getExtension("OES_texture_float")) {
+        testPassed("No OES_texture_float support -- this is legal");
+        return false;
+    }
+
+    testPassed("Successfully enabled OES_texture_float extension");
+    return true;
+}
+</script>
+</head>
+<body onload='generateTest("RGBA", "FLOAT", testPrologue)()'>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<video width="640" height="228" id="vid" controls>
+  <source src="../resources/red-green.mp4"  type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
+  <source src="../resources/red-green.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' />
+  <source src="../resources/red-green.theora.ogv"  type='video/ogg; codecs="theora, vorbis"' />
+</video>
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float.html
new file mode 100644
index 0000000..7ad0a8a
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-texture-float.html
@@ -0,0 +1,230 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OES_texture_float Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing floating-point textures -->
+<script id="testFragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D tex;
+uniform vec4 subtractor;
+varying vec2 texCoord;
+void main()
+{
+    vec4 color = texture2D(tex, texCoord);
+    if (abs(color.r - subtractor.r) +
+        abs(color.g - subtractor.g) +
+        abs(color.b - subtractor.b) +
+        abs(color.a - subtractor.a) < 8.0) {
+        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+    } else {
+        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+    }
+}
+</script>
+<!-- Shaders for testing floating-point render targets -->
+<script id="positionVertexShader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+void main()
+{
+    gl_Position = vPosition;
+}
+</script>
+<script id="floatingPointFragmentShader" type="x-shader/x-fragment">
+void main()
+{
+    gl_FragColor = vec4(10000.0, 10000.0, 10000.0, 10000.0);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies the functionality of the OES_texture_float extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas);
+
+if (!gl) {
+  testFailed("WebGL context does not exist");
+} else {
+  testPassed("WebGL context exists");
+
+  var texturedShaders = [
+      wtu.setupSimpleTextureVertexShader(gl),
+      "testFragmentShader"
+  ];
+  var testProgram =
+      wtu.setupProgram(gl,
+                       texturedShaders,
+                       ['vPosition', 'texCoord0'],
+                       [0, 1]);
+  var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
+
+  // First verify that allocation of floating-point textures fails if
+  // the extension has not been enabled yet.
+  runTextureCreationTest(testProgram, false);
+
+  if (!gl.getExtension("OES_texture_float")) {
+      testPassed("No OES_texture_float support -- this is legal");
+  } else {
+      testPassed("Successfully enabled OES_texture_float extension");
+      runTextureCreationTest(testProgram, true, gl.RGBA, 4, [10000, 10000, 10000, 10000]);
+      runTextureCreationTest(testProgram, true, gl.RGB, 3, [10000, 10000, 10000, 0]);
+      runTextureCreationTest(testProgram, true, gl.LUMINANCE, 1, [10000, 10000, 10000, 0]);
+      runTextureCreationTest(testProgram, true, gl.ALPHA, 1, [0, 0, 0, 10000]);
+      runTextureCreationTest(testProgram, true, gl.LUMINANCE_ALPHA, 2, [10000, 10000, 10000, 10000]);
+      runRenderTargetTest(testProgram);
+      runUniqueObjectTest();
+  }
+}
+
+// Needs to be global for shouldBe to see it.
+var pixels;
+
+function allocateTexture()
+{
+    var texture = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+    glErrorShouldBe(gl, gl.NO_ERROR, "texture parameter setup should succeed");
+    return texture;
+}
+
+function checkRenderingResults()
+{
+    wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+function runTextureCreationTest(testProgram, extensionEnabled, opt_format, opt_numChannels, opt_subtractor)
+{
+    var format = opt_format || gl.RGBA;
+    var numberOfChannels = opt_numChannels || 4;
+    var expectFailure = !extensionEnabled;
+    var subtractor = opt_subtractor || [10000, 10000, 10000, 10000];
+
+    debug("");
+    debug("testing format: " + wtu.glEnumToString(gl, format) +
+          " expect:" + (extensionEnabled ? "success" : "failure"));
+
+    var texture = allocateTexture();
+    // Generate data.
+    var width = 2;
+    var height = 2;
+    var data = new Float32Array(width * height * numberOfChannels);
+    for (var ii = 0; ii < data.length; ++ii) {
+        data[ii] = 10000;
+    }
+    gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, gl.FLOAT, data);
+    if (expectFailure) {
+        glErrorShouldBe(gl, gl.INVALID_ENUM, "floating-point texture allocation must be disallowed if OES_texture_float isn't enabled");
+        return;
+    } else {
+        glErrorShouldBe(gl, gl.NO_ERROR, "floating-point texture allocation should succeed if OES_texture_float is enabled");
+    }
+    // Verify that the texture actually works for sampling and contains the expected data.
+    gl.uniform1i(gl.getUniformLocation(testProgram, "tex"), 0);
+    gl.uniform4fv(gl.getUniformLocation(testProgram, "subtractor"), subtractor);
+    wtu.drawQuad(gl);
+    checkRenderingResults();
+}
+
+function runRenderTargetTest(testProgram)
+{
+    debug("");
+    debug("testing floating-point render targets");
+
+    var texture = allocateTexture();
+    var width = 2;
+    var height = 2;
+    var numberOfChannels = 4;
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, null);
+    glErrorShouldBe(gl, gl.NO_ERROR, "floating-point texture allocation should succeed if OES_texture_float is enabled");
+
+    // Try to use this texture as a render target.
+    var fbo = gl.createFramebuffer();
+    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+    gl.bindTexture(gl.TEXTURE_2D, null);
+    // It is legal for a WebGL implementation exposing the OES_texture_float extension to
+    // support floating-point textures but not as attachments to framebuffer objects.
+    if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+        debug("floating-point render targets not supported -- this is legal");
+        return;
+    }
+
+    var renderProgram =
+        wtu.setupProgram(gl,
+                         ["positionVertexShader", "floatingPointFragmentShader"],
+                         ['vPosition'],
+                         [0]);
+    wtu.drawQuad(gl);
+    glErrorShouldBe(gl, gl.NO_ERROR, "rendering to floating-point texture should succeed");
+
+    // Now sample from the floating-point texture and verify we got the correct values.
+    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+    gl.useProgram(testProgram);
+    gl.uniform1i(gl.getUniformLocation(testProgram, "tex"), 0);
+    wtu.drawQuad(gl);
+    glErrorShouldBe(gl, gl.NO_ERROR, "rendering from floating-point texture should succeed");
+    checkRenderingResults();
+}
+
+function runUniqueObjectTest()
+{
+    debug("Testing that getExtension() returns the same object each time");
+    gl.getExtension("OES_texture_float").myProperty = 2;
+    gc();
+    shouldBe('gl.getExtension("OES_texture_float").myProperty', '2');
+}
+
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html
new file mode 100644
index 0000000..066b324
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/oes-vertex-array-object.html
@@ -0,0 +1,655 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OES_vertex_array_object Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+<!-- comment in the script tag below to test through JS emualation of the extension. -->
+<!--
+<script src="../../../demos/google/resources/OESVertexArrayObject.js"></script>
+-->
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader", type="x-shader/x-vertex">
+attribute vec4 a_position;
+attribute vec4 a_color;
+varying vec4 v_color;
+void main(void) {
+    gl_Position = a_position;
+    v_color = a_color;
+}
+</script>
+<script id="fshader", type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 v_color;
+void main(void) {
+    gl_FragColor = v_color;
+}
+</script>
+<script>
+"use strict";
+description("This test verifies the functionality of the OES_vertex_array_object extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas);
+var ext = null;
+var vao = null;
+
+if (!gl) {
+    testFailed("WebGL context does not exist");
+} else {
+    testPassed("WebGL context exists");
+
+    // Setup emulated OESVertexArrayObject if it has been included.
+    if (window.setupVertexArrayObject) {
+        debug("using emuated OES_vertex_array_object");
+        setupVertexArrayObject(gl);
+    }
+
+    // Run tests with extension disabled
+    runBindingTestDisabled();
+
+    // Query the extension and store globally so shouldBe can access it
+    ext = gl.getExtension("OES_vertex_array_object");
+    if (!ext) {
+        testPassed("No OES_vertex_array_object support -- this is legal");
+
+        runSupportedTest(false);
+    } else {
+        testPassed("Successfully enabled OES_vertex_array_object extension");
+
+        runSupportedTest(true);
+        runBindingTestEnabled();
+        runObjectTest();
+        runAttributeTests();
+        runAttributeValueTests();
+        runDrawTests();
+        runDeleteTests();
+        runArrayBufferBindTests();
+        glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+    }
+}
+
+function runSupportedTest(extensionEnabled) {
+    var supported = gl.getSupportedExtensions();
+    if (supported.indexOf("OES_vertex_array_object") >= 0) {
+        if (extensionEnabled) {
+            testPassed("OES_vertex_array_object listed as supported and getExtension succeeded");
+        } else {
+            testFailed("OES_vertex_array_object listed as supported but getExtension failed");
+        }
+    } else {
+        if (extensionEnabled) {
+            testFailed("OES_vertex_array_object not listed as supported but getExtension succeeded");
+        } else {
+            testPassed("OES_vertex_array_object not listed as supported and getExtension failed -- this is legal");
+        }
+    }
+}
+
+function runBindingTestDisabled() {
+    debug("Testing binding enum with extension disabled");
+    
+    // Use the constant directly as we don't have the extension
+    var VERTEX_ARRAY_BINDING_OES = 0x85B5;
+    
+    gl.getParameter(VERTEX_ARRAY_BINDING_OES);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "VERTEX_ARRAY_BINDING_OES should not be queryable if extension is disabled");
+}
+
+function runBindingTestEnabled() {
+    debug("Testing binding enum with extension enabled");
+    
+    shouldBe("ext.VERTEX_ARRAY_BINDING_OES", "0x85B5");
+    
+    gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES);
+    glErrorShouldBe(gl, gl.NO_ERROR, "VERTEX_ARRAY_BINDING_OES query should succeed if extension is enable");
+    
+    // Default value is null
+    if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) === null) {
+        testPassed("Default value of VERTEX_ARRAY_BINDING_OES is null");
+    } else {
+        testFailed("Default value of VERTEX_ARRAY_BINDING_OES is not null");
+    }
+    
+    debug("Testing binding a VAO");
+    var vao0 = ext.createVertexArrayOES();
+    var vao1 = ext.createVertexArrayOES();
+    shouldBeNull("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)");
+    ext.bindVertexArrayOES(vao0);
+    if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) == vao0) {
+        testPassed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is expected VAO");
+    } else {
+        testFailed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is not expected VAO")
+    }
+    ext.bindVertexArrayOES(vao1);
+    if (gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) == vao1) {
+        testPassed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is expected VAO");
+    } else {
+        testFailed("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES) is not expected VAO")
+    }
+    ext.deleteVertexArrayOES(vao1);
+    shouldBeNull("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)");
+    ext.bindVertexArrayOES(vao1);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "binding a deleted vertex array object");
+    ext.bindVertexArrayOES(null);
+    shouldBeNull("gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)");
+    ext.deleteVertexArrayOES(vao1);
+}
+
+function runObjectTest() {
+    debug("Testing object creation");
+    
+    vao = ext.createVertexArrayOES();
+    glErrorShouldBe(gl, gl.NO_ERROR, "createVertexArrayOES should not set an error");
+    shouldBeNonNull("vao");
+    
+    // Expect false if never bound
+    shouldBeFalse("ext.isVertexArrayOES(vao)");
+    ext.bindVertexArrayOES(vao);
+    shouldBeTrue("ext.isVertexArrayOES(vao)");
+    ext.bindVertexArrayOES(null);
+    shouldBeTrue("ext.isVertexArrayOES(vao)");
+    
+    shouldBeFalse("ext.isVertexArrayOES()");
+    shouldBeFalse("ext.isVertexArrayOES(null)");
+    
+    ext.deleteVertexArrayOES(vao);
+    vao = null;
+}
+
+function runAttributeTests() {
+    debug("Testing attributes work across bindings");
+    
+    var states = [];
+    
+    var attrCount = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+    for (var n = 0; n < attrCount; n++) {
+        gl.bindBuffer(gl.ARRAY_BUFFER, null);
+        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+        
+        var state = {};
+        states.push(state);
+        
+        var vao = state.vao = ext.createVertexArrayOES();
+        ext.bindVertexArrayOES(vao);
+        
+        var enableArray = (n % 2 == 0);
+        if (enableArray) {
+            gl.enableVertexAttribArray(n);
+        } else {
+            gl.disableVertexAttribArray(n);
+        }
+        
+        if (enableArray) {
+            var buffer = state.buffer = gl.createBuffer();
+            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+            gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW);
+            
+            gl.vertexAttribPointer(n, 1 + n % 4, gl.FLOAT, true, n * 4, n * 4);
+        }
+        
+        if (enableArray) {
+            var elbuffer = state.elbuffer = gl.createBuffer();
+            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elbuffer);
+            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 1024, gl.STATIC_DRAW);
+        }
+        
+        ext.bindVertexArrayOES(null);
+    }
+    
+    var anyMismatch = false;
+    for (var n = 0; n < attrCount; n++) {
+        var state = states[n];
+        
+        ext.bindVertexArrayOES(state.vao);
+        
+        var shouldBeEnabled = (n % 2 == 0);
+        var isEnabled = gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+        if (shouldBeEnabled != isEnabled) {
+            testFailed("VERTEX_ATTRIB_ARRAY_ENABLED not preserved");
+            anyMismatch = true;
+        }
+        
+        var buffer = gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
+        if (shouldBeEnabled) {
+            if (buffer == state.buffer) {
+                // Matched
+                if ((gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_SIZE) == 1 + n % 4) &&
+                    (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_TYPE) == gl.FLOAT) &&
+                    (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED) == true) &&
+                    (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_STRIDE) == n * 4) &&
+                    (gl.getVertexAttribOffset(n, gl.VERTEX_ATTRIB_ARRAY_POINTER) == n * 4)) {
+                    // Matched
+                } else {
+                    testFailed("VERTEX_ATTRIB_ARRAY_* not preserved");
+                    anyMismatch = true;
+                }
+            } else {
+                testFailed("VERTEX_ATTRIB_ARRAY_BUFFER_BINDING not preserved");
+                anyMismatch = true;
+            }
+        } else {
+            // GL_CURRENT_VERTEX_ATTRIB is not preserved
+            if (buffer) {
+                testFailed("VERTEX_ATTRIB_ARRAY_BUFFER_BINDING not preserved");
+                anyMismatch = true;
+            }
+        }
+        
+        var elbuffer = gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING);
+        if (shouldBeEnabled) {
+            if (elbuffer == state.elbuffer) {
+                // Matched
+            } else {
+                testFailed("ELEMENT_ARRAY_BUFFER_BINDING not preserved");
+                anyMismatch = true;
+            }
+        } else {
+            if (elbuffer == null) {
+                // Matched
+            } else {
+                testFailed("ELEMENT_ARRAY_BUFFER_BINDING not preserved");
+                anyMismatch = true;
+            }
+        }
+    }
+    ext.bindVertexArrayOES(null);
+    if (!anyMismatch) {
+        testPassed("All attributes preserved across bindings");
+    }
+    
+    for (var n = 0; n < attrCount; n++) {
+        var state = states[n];
+        ext.deleteVertexArrayOES(state.vao);
+    }
+}
+
+function runAttributeValueTests() {
+    debug("Testing that attribute values are not attached to bindings");
+    
+    var v;
+    var vao0 = ext.createVertexArrayOES();
+    var anyFailed = false;
+    
+    ext.bindVertexArrayOES(null);
+    gl.vertexAttrib4f(0, 0, 1, 2, 3);
+    
+    v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
+    if (!(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)) {
+        testFailed("Vertex attrib value not round-tripped?");
+        anyFailed = true;
+    }
+    
+    ext.bindVertexArrayOES(vao0);
+    
+    v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
+    if (!(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)) {
+        testFailed("Vertex attrib value reset across bindings");
+        anyFailed = true;
+    }
+    
+    gl.vertexAttrib4f(0, 4, 5, 6, 7);
+    ext.bindVertexArrayOES(null);
+    
+    v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
+    if (!(v[0] == 4 && v[1] == 5 && v[2] == 6 && v[3] == 7)) {
+        testFailed("Vertex attrib value bound to buffer");
+        anyFailed = true;
+    }
+    
+    if (!anyFailed) {
+        testPassed("Vertex attribute values are not attached to bindings")
+    }
+    
+    ext.bindVertexArrayOES(null);
+    ext.deleteVertexArrayOES(vao0);
+}
+
+function runDrawTests() {
+    debug("Testing draws with various VAO bindings");
+    
+    canvas.width = 50; canvas.height = 50;
+    gl.viewport(0, 0, canvas.width, canvas.height);
+    
+    var vao0 = ext.createVertexArrayOES();
+    var vao1 = ext.createVertexArrayOES();
+
+    var opt_positionLocation = 0;
+    var opt_texcoordLocation = 1;
+    
+    var program = wtu.setupSimpleTextureProgram(gl, opt_positionLocation, opt_texcoordLocation);
+    
+    function setupQuad(s) {
+        var vertexObject = gl.createBuffer();
+        gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+             1.0 * s,  1.0 * s, 0.0,
+            -1.0 * s,  1.0 * s, 0.0,
+            -1.0 * s, -1.0 * s, 0.0,
+             1.0 * s,  1.0 * s, 0.0,
+            -1.0 * s, -1.0 * s, 0.0,
+             1.0 * s, -1.0 * s, 0.0]), gl.STATIC_DRAW);
+        gl.enableVertexAttribArray(opt_positionLocation);
+        gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
+
+        var vertexObject = gl.createBuffer();
+        gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+            1.0 * s, 1.0 * s,
+            0.0 * s, 1.0 * s,
+            0.0 * s, 0.0 * s,
+            1.0 * s, 1.0 * s,
+            0.0 * s, 0.0 * s,
+            1.0 * s, 0.0 * s]), gl.STATIC_DRAW);
+        gl.enableVertexAttribArray(opt_texcoordLocation);
+        gl.vertexAttribPointer(opt_texcoordLocation, 2, gl.FLOAT, false, 0, 0);
+    };
+    
+    function readLocation(x, y) {
+        var pixels = new Uint8Array(1 * 1 * 4);
+        gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+        return pixels;
+    };
+    function testPixel(blackList, whiteList) {
+        function testList(list, expected) {
+            for (var n = 0; n < list.length; n++) {
+                var l = list[n];
+                var x = -Math.floor(l * canvas.width / 2) + canvas.width / 2;
+                var y = -Math.floor(l * canvas.height / 2) + canvas.height / 2;
+                var source = readLocation(x, y);
+                if (Math.abs(source[0] - expected) > 2) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return testList(blackList, 0) && testList(whiteList, 255);
+    };
+    function verifyDraw(drawNumber, s) {
+        wtu.drawQuad(gl);
+        var blackList = [];
+        var whiteList = [];
+        var points = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0];
+        for (var n = 0; n < points.length; n++) {
+            if (points[n] <= s) {
+                blackList.push(points[n]);
+            } else {
+                whiteList.push(points[n]);
+            }
+        }
+        if (testPixel(blackList, whiteList)) {
+            testPassed("Draw " + drawNumber + " passed pixel test");
+        } else {
+            testFailed("Draw " + drawNumber + " failed pixel test");
+        }
+    };
+    
+    // Setup all bindings
+    setupQuad(1);
+    ext.bindVertexArrayOES(vao0);
+    setupQuad(0.5);
+    ext.bindVertexArrayOES(vao1);
+    setupQuad(0.25);
+    
+    // Verify drawing
+    ext.bindVertexArrayOES(null);
+    verifyDraw(0, 1);
+    ext.bindVertexArrayOES(vao0);
+    verifyDraw(1, 0.5);
+    ext.bindVertexArrayOES(vao1);
+    verifyDraw(2, 0.25);
+    
+    ext.bindVertexArrayOES(null);
+    ext.deleteVertexArrayOES(vao0);
+    ext.deleteVertexArrayOES(vao1);
+
+    // Disable global vertex attrib array
+    gl.disableVertexAttribArray(opt_positionLocation);
+    gl.disableVertexAttribArray(opt_texcoordLocation);
+
+    // Draw with values.
+    var positionLoc = 0;
+    var colorLoc = 1;
+    var gridRes = 1;
+    wtu.setupQuad(gl, gridRes, positionLoc);
+    // Set the vertex color to red.
+    gl.vertexAttrib4f(colorLoc, 1, 0, 0, 1);
+
+    var vao0 = ext.createVertexArrayOES();
+    ext.bindVertexArrayOES(vao0);
+    var program = wtu.setupSimpleVertexColorProgram(gl, positionLoc, colorLoc);
+    wtu.setupQuad(gl, gridRes, positionLoc);
+    // Set the vertex color to green.
+    gl.vertexAttrib4f(colorLoc, 0, 1, 0, 1);
+    wtu.drawIndexedQuad(gl, gridRes);
+    wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green")
+    ext.deleteVertexArrayOES(vao0);
+    wtu.drawIndexedQuad(gl, gridRes);
+    wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green")
+}
+
+function runDeleteTests() {
+    debug("Testing using deleted buffers referenced by VAOs");
+
+    var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_position", "a_color"]);
+    gl.useProgram(program);
+
+    var positionBuffer = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+    gl.bufferData(
+        gl.ARRAY_BUFFER,
+        new Float32Array([
+           1.0,  1.0,
+          -1.0,  1.0,
+          -1.0, -1.0,
+           1.0, -1.0]),
+        gl.STATIC_DRAW);
+
+    var colors = [
+      [255,   0,   0, 255],
+      [  0, 255,   0, 255],
+      [  0,   0, 255, 255],
+      [  0, 255, 255, 255]
+    ];
+    var colorBuffers = [];
+    var elementBuffers = [];
+    var vaos = [];
+    for (var ii = 0; ii < colors.length; ++ii) {
+      var vao = ext.createVertexArrayOES();
+      vaos.push(vao);
+      ext.bindVertexArrayOES(vao);
+      // Set the position buffer
+      gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+      gl.enableVertexAttribArray(0);
+      gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+
+      var elementBuffer = gl.createBuffer();
+      elementBuffers.push(elementBuffer);
+      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+      gl.bufferData(
+          gl.ELEMENT_ARRAY_BUFFER,
+          new Uint8Array([0, 1, 2, 0, 2, 3]),
+          gl.STATIC_DRAW);
+
+      // Setup the color attrib
+      var color = colors[ii];
+      if (ii < 3) {
+        var colorBuffer = gl.createBuffer();
+        colorBuffers.push(colorBuffer);
+        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+        gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(
+          [ color[0], color[1], color[2], color[3],
+            color[0], color[1], color[2], color[3],
+            color[0], color[1], color[2], color[3],
+            color[0], color[1], color[2], color[3]
+          ]), gl.STATIC_DRAW);
+        gl.enableVertexAttribArray(1);
+        gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+      } else {
+        gl.vertexAttrib4f(1, color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
+      }
+    }
+
+    // delete the color buffers AND the position buffer.
+    ext.bindVertexArrayOES(null);
+    for (var ii = 0; ii < colorBuffers.length; ++ii) {
+      gl.deleteBuffer(colorBuffers[ii]);
+      gl.deleteBuffer(elementBuffers[ii]);
+      // The buffers should still be valid at this point, since it was attached to the VAO
+      if(!gl.isBuffer(colorBuffers[ii])) {
+        testFailed("buffer removed too early");
+      }
+    }
+    gl.deleteBuffer(positionBuffer);
+
+    // Render with the deleted buffers. As they are referenced by VAOs they
+    // must still be around.
+    for (var ii = 0; ii < colors.length; ++ii) {
+      var color = colors[ii];
+      ext.bindVertexArrayOES(vaos[ii]);
+      gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+      wtu.checkCanvas(gl, color, "should be " + color);
+    }
+
+    // Clean up.
+    for (var ii = 0; ii < colorBuffers.length; ++ii) {
+      ext.deleteVertexArrayOES(vaos[ii]);
+    }
+
+    for (var ii = 0; ii < colorBuffers.length; ++ii) {
+      // The buffers should no longer be valid now that the VAOs are deleted
+      if(gl.isBuffer(colorBuffers[ii])) {
+        testFailed("buffer not properly cleaned up after VAO deletion");
+      }
+    }
+}
+
+function runArrayBufferBindTests() {
+    debug("Testing that VAOs don't effect ARRAY_BUFFER binding.");
+
+    ext.bindVertexArrayOES(null);
+
+    var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_color", "a_position"]);
+    gl.useProgram(program);
+
+    // create shared element buuffer
+    var elementBuffer = gl.createBuffer();
+    // bind to default
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+    gl.bufferData(
+        gl.ELEMENT_ARRAY_BUFFER,
+        new Uint8Array([0, 1, 2, 0, 2, 3]),
+        gl.STATIC_DRAW);
+
+    // first create the buffers for no vao draw.
+    var nonVAOColorBuffer = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, nonVAOColorBuffer);
+    gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(
+      [ 0, 255, 0, 255,
+        0, 255, 0, 255,
+        0, 255, 0, 255,
+        0, 255, 0, 255,
+      ]), gl.STATIC_DRAW);
+
+    // shared position buffer.
+    var positionBuffer = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+    gl.bufferData(
+        gl.ARRAY_BUFFER,
+        new Float32Array([
+           1.0,  1.0,
+          -1.0,  1.0,
+          -1.0, -1.0,
+           1.0, -1.0]),
+        gl.STATIC_DRAW);
+
+    // attach position buffer to default
+    gl.enableVertexAttribArray(1);
+    gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+
+    // now create vao
+    var vao = ext.createVertexArrayOES();
+    ext.bindVertexArrayOES(vao);
+
+    // attach the position buffer vao
+    gl.enableVertexAttribArray(1);
+    gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+
+    var vaoColorBuffer = gl.createBuffer();
+    gl.enableVertexAttribArray(0);
+    gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+    gl.bindBuffer(gl.ARRAY_BUFFER, vaoColorBuffer);
+    gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(
+      [ 255, 0, 0, 255,
+        255, 0, 0, 255,
+        255, 0, 0, 255,
+        255, 0, 0, 255,
+      ]), gl.STATIC_DRAW);
+    gl.enableVertexAttribArray(0);
+    gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+
+    // now set the buffer back to the nonVAOColorBuffer
+    gl.bindBuffer(gl.ARRAY_BUFFER, nonVAOColorBuffer);
+
+    // bind to vao
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+    wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
+
+    // unbind vao
+    ext.bindVertexArrayOES(null);
+
+    // At this point the nonVAOColorBuffer should be still be bound.
+    // If the WebGL impl is emulating VAOs it must make sure
+    // it correctly restores this binding.
+    gl.enableVertexAttribArray(0);
+    gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+    wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html
new file mode 100644
index 0000000..eaab737
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-compressed-texture-s3tc.html
@@ -0,0 +1,636 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+<title>WebGL WEBGL_compressed_texture_s3tc Conformance Tests</title>
+<style>
+img {
+ border: 1px solid black;
+ margin-right: 1em;
+}
+.testimages {
+}
+
+.testimages br {
+  clear: both;
+}
+
+.testimages > div {
+  float: left;
+  margin: 1em;
+}
+</style>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the WEBGL_compressed_texture_s3tc extension, if it is available.");
+
+debug("");
+
+var img_4x4_rgba_raw = new Uint8Array([
+    0xff,0x00,0x00,0x69,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,
+]);
+var img_4x4_rgb_dxt1 = new Uint8Array([
+    0xe0,0x07,0x00,0xf8,0x11,0x10,0x15,0x00,
+]);
+var img_4x4_rgba_dxt1 = new Uint8Array([
+    0xe0,0x07,0x00,0xf8,0x13,0x10,0x15,0x00,
+]);
+var img_4x4_rgba_dxt3 = new Uint8Array([
+    0xf6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xe0,0x07,0x44,0x45,0x40,0x55,
+]);
+var img_4x4_rgba_dxt5 = new Uint8Array([
+    0xf6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xe0,0x07,0x44,0x45,0x40,0x55,
+]);
+var img_8x8_rgba_raw = new Uint8Array([
+    0xff,0x00,0x00,0x69,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0x69,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0x69,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0x69,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,
+]);
+var img_8x8_rgb_dxt1 = new Uint8Array([
+    0xe0,0x07,0x00,0xf8,0x11,0x10,0x15,0x00,0x1f,0x00,0xe0,0xff,0x11,0x10,0x15,0x00,0xe0,0x07,0x1f,0xf8,0x44,0x45,0x40,0x55,0x1f,0x00,0xff,0x07,0x44,0x45,0x40,0x55,
+]);
+var img_8x8_rgba_dxt1 = new Uint8Array([
+    0xe0,0x07,0x00,0xf8,0x13,0x13,0x15,0x00,0x1f,0x00,0xe0,0xff,0x11,0x10,0x15,0x00,0xe0,0x07,0x1f,0xf8,0x44,0x45,0x43,0x57,0x1f,0x00,0xff,0x07,0x44,0x45,0x40,0x55,
+]);
+var img_8x8_rgba_dxt3 = new Uint8Array([
+    0xf6,0xff,0xf6,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xe0,0x07,0x44,0x45,0x40,0x55,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0xff,0x1f,0x00,0x44,0x45,0x40,0x55,0xff,0xff,0xff,0xff,0xf6,0xff,0xf6,0xff,0x1f,0xf8,0xe0,0x07,0x11,0x10,0x15,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x1f,0x00,0x11,0x10,0x15,0x00,
+]);
+var img_8x8_rgba_dxt5 = new Uint8Array([
+    0xff,0x69,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0xf8,0xe0,0x07,0x44,0x45,0x40,0x55,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0x1f,0x00,0x44,0x45,0x40,0x55,0xff,0x69,0x00,0x00,0x00,0x01,0x10,0x00,0x1f,0xf8,0xe0,0x07,0x11,0x10,0x15,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x07,0x1f,0x00,0x11,0x10,0x15,0x00,
+]);
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false});
+var program = wtu.setupTexturedQuad(gl);
+var ext = null;
+var vao = null;
+var validFormats = {
+    COMPRESSED_RGB_S3TC_DXT1_EXT        : 0x83F0,
+    COMPRESSED_RGBA_S3TC_DXT1_EXT       : 0x83F1,
+    COMPRESSED_RGBA_S3TC_DXT3_EXT       : 0x83F2,
+    COMPRESSED_RGBA_S3TC_DXT5_EXT       : 0x83F3,
+};
+var name;
+var supportedFormats;
+
+if (!gl) {
+    testFailed("WebGL context does not exist");
+} else {
+    testPassed("WebGL context exists");
+
+    // Run tests with extension disabled
+    runTestDisabled();
+
+    // Query the extension and store globally so shouldBe can access it
+    ext = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_compressed_texture_s3tc");
+    if (!ext) {
+        testPassed("No WEBGL_compressed_texture_s3tc support -- this is legal");
+        runSupportedTest(false);
+    } else {
+        testPassed("Successfully enabled WEBGL_compressed_texture_s3tc extension");
+
+        runSupportedTest(true);
+        runTestExtension();
+    }
+}
+
+function runSupportedTest(extensionEnabled) {
+    var name = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_compressed_texture_s3tc");
+    if (name !== undefined) {
+        if (extensionEnabled) {
+            testPassed("WEBGL_compressed_texture_s3tc listed as supported and getExtension succeeded");
+        } else {
+            testFailed("WEBGL_compressed_texture_s3tc listed as supported but getExtension failed");
+        }
+    } else {
+        if (extensionEnabled) {
+            testFailed("WEBGL_compressed_texture_s3tc not listed as supported but getExtension succeeded");
+        } else {
+            testPassed("WEBGL_compressed_texture_s3tc not listed as supported and getExtension failed -- this is legal");
+        }
+    }
+}
+
+
+function runTestDisabled() {
+    debug("Testing binding enum with extension disabled");
+
+    shouldBe('gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS)', '[]');
+}
+
+function formatExists(format, supportedFormats) {
+    for (var ii = 0; ii < supportedFormats.length; ++ii) {
+        if (format == supportedFormats[ii]) {
+            testPassed("supported format " + formatToString(format) + " is exists");
+            return;
+        }
+    }
+    testFailed("supported format " + formatToString(format) + " does not exist");
+}
+
+function formatToString(format) {
+    for (var p in ext) {
+        if (ext[p] == format) {
+            return p;
+        }
+    }
+    return "0x" + format.toString(16);
+}
+
+function runTestExtension() {
+    debug("Testing WEBGL_compressed_texture_s3tc");
+
+    // check that all format enums exist.
+    for (name in validFormats) {
+        var expected = "0x" + validFormats[name].toString(16);
+        var actual = "ext['" + name + "']";
+        shouldBe(actual, expected);
+    }
+
+    supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
+    // There should be exactly 4 formats
+    shouldBe("supportedFormats.length", "4");
+
+    // check that all 4 formats exist
+    for (var name in validFormats.length) {
+        formatExists(validFormats[name], supportedFormats);
+    }
+
+    // Test each format
+    testDXT1_RGB();
+    testDXT1_RGBA();
+    testDXT3_RGBA();
+    testDXT5_RGBA();
+}
+
+function testDXT1_RGB() {
+    var tests = [
+        {   width: 4,
+            height: 4,
+            channels: 3,
+            data: img_4x4_rgb_dxt1,
+            format: ext.COMPRESSED_RGB_S3TC_DXT1_EXT
+        },
+        {   width: 8,
+            height: 8,
+            channels: 3,
+            data: img_8x8_rgb_dxt1,
+            format: ext.COMPRESSED_RGB_S3TC_DXT1_EXT
+        }
+    ];
+    testDXTTextures(tests);
+}
+
+function testDXT1_RGBA() {
+    var tests = [
+        {   width: 4,
+            height: 4,
+            channels: 4,
+            data: img_4x4_rgba_dxt1,
+            format: ext.COMPRESSED_RGBA_S3TC_DXT1_EXT
+        },
+        {   width: 8,
+            height: 8,
+            channels: 4,
+            data: img_8x8_rgba_dxt1,
+            format: ext.COMPRESSED_RGBA_S3TC_DXT1_EXT
+        }
+    ];
+    testDXTTextures(tests);
+}
+
+function testDXT3_RGBA() {
+    var tests = [
+        {   width: 4,
+            height: 4,
+            channels: 4,
+            data: img_4x4_rgba_dxt3,
+            format: ext.COMPRESSED_RGBA_S3TC_DXT3_EXT
+        },
+        {   width: 8,
+            height: 8,
+            channels: 4,
+            data: img_8x8_rgba_dxt3,
+            format: ext.COMPRESSED_RGBA_S3TC_DXT3_EXT
+        }
+    ];
+    testDXTTextures(tests);
+}
+
+function testDXT5_RGBA() {
+    var tests = [
+        {   width: 4,
+            height: 4,
+            channels: 4,
+            data: img_4x4_rgba_dxt5,
+            format: ext.COMPRESSED_RGBA_S3TC_DXT5_EXT
+        },
+        {   width: 8,
+            height: 8,
+            channels: 4,
+            data: img_8x8_rgba_dxt5,
+            format: ext.COMPRESSED_RGBA_S3TC_DXT5_EXT
+        }
+    ];
+    testDXTTextures(tests);
+}
+
+function testDXTTextures(tests) {
+    debug("<hr/>");
+    for (var ii = 0; ii < tests.length; ++ii) {
+        testDXTTexture(tests[ii]);
+    }
+}
+
+function uncompressDXTBlock(
+    destBuffer, destX, destY, destWidth, src, srcOffset, format) {
+    function make565(src, offset) {
+        return src[offset + 0] + src[offset + 1] * 256;
+    }
+    function make8888From565(c) {
+        return [
+                Math.floor(((c >> 11) & 0x1F) * 255 / 31),
+                Math.floor(((c >>    5) & 0x3F) * 255 / 63),
+                Math.floor(((c >>    0) & 0x1F) * 255 / 31),
+                255
+            ];
+    }
+    function mix(mult, c0, c1, div) {
+        var r = [];
+        for (var ii = 0; ii < c0.length; ++ii) {
+            r[ii] = Math.floor((c0[ii] * mult + c1[ii]) / div);
+        }
+        return r;
+    }
+    var isDXT1 = format == ext.COMPRESSED_RGB_S3TC_DXT1_EXT ||
+                 format == ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
+    var colorOffset = srcOffset + (isDXT1 ? 0 : 8);
+    var color0 = make565(src, colorOffset + 0);
+    var color1 = make565(src, colorOffset + 2);
+    var c0gtc1 = color0 > color1 || !isDXT1;
+    var rgba0 = make8888From565(color0);
+    var rgba1 = make8888From565(color1);
+    var colors = [
+            rgba0,
+            rgba1,
+            c0gtc1 ? mix(2, rgba0, rgba1, 3) : mix(1, rgba0, rgba1, 2),
+            c0gtc1 ? mix(2, rgba1, rgba0, 3) : [0, 0, 0, 255]
+        ];
+
+    // yea I know there is a lot of math in this inner loop.
+    // so sue me.
+    for (var yy = 0; yy < 4; ++yy) {
+        var pixels = src[colorOffset + 4 + yy];
+        for (var xx = 0; xx < 4; ++xx) {
+            var dstOff = ((destY + yy) * destWidth + destX + xx) * 4;
+            var code = (pixels >> (xx * 2)) & 0x3;
+            var srcColor = colors[code];
+            var alpha;
+            switch (format) {
+            case ext.COMPRESSED_RGB_S3TC_DXT1_EXT:
+                alpha = 255;
+                break;
+            case ext.COMPRESSED_RGBA_S3TC_DXT1_EXT:
+                alpha = (code == 3 && !c0gtc1) ? 0 : 255;
+                break;
+            case ext.COMPRESSED_RGBA_S3TC_DXT3_EXT:
+                {
+                    var alpha0 = src[srcOffset + yy * 2 + Math.floor(xx / 2)];
+                    var alpha1 = (alpha0 >> ((xx % 2) * 4)) & 0xF;
+                    alpha = alpha1 | (alpha1 << 4);
+                }
+                break;
+            case ext.COMPRESSED_RGBA_S3TC_DXT5_EXT:
+                {
+                    var alpha0 = src[srcOffset + 0];
+                    var alpha1 = src[srcOffset + 1];
+                    var alphaOff = Math.floor(yy / 2) * 3 + 2;
+                    var alphaBits =
+                         src[srcOffset + alphaOff + 0] +
+                         src[srcOffset + alphaOff + 1] * 256 +
+                         src[srcOffset + alphaOff + 2] * 65536;
+                    var alphaShift = (yy % 2) * 12 + xx * 3;
+                    var alphaCode = (alphaBits >> alphaShift) & 0x7;
+                    if (alpha0 > alpha1) {
+                        switch (alphaCode) {
+                        case 0:
+                            alpha = alpha0;
+                            break;
+                        case 1:
+                            alpha = alpha1;
+                            break;
+                        default:
+                            alpha = ((8 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 7;
+                            break;
+                        }
+                    } else {
+                        switch (alphaCode) {
+                        case 0:
+                            alpha = alpha0;
+                            break;
+                        case 1:
+                            alpha = alpha1;
+                            break;
+                        case 6:
+                            alpha = 0;
+                            break;
+                        case 7:
+                            alpha = 255;
+                            break;
+                        default:
+                            alpha = ((6 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 5;
+                            break;
+                        }
+                    }
+                }
+                break;
+            default:
+                throw "bad format";
+            }
+            destBuffer[dstOff + 0] = srcColor[0];
+            destBuffer[dstOff + 1] = srcColor[1];
+            destBuffer[dstOff + 2] = srcColor[2];
+            destBuffer[dstOff + 3] = alpha;
+        }
+    }
+}
+
+function getBlockSize(format) {
+  var isDXT1 = format == ext.COMPRESSED_RGB_S3TC_DXT1_EXT ||
+               format == ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
+  return isDXT1 ? 8 : 16;
+}
+
+function uncompressDXT(width, height, data, format) {
+    if (width % 4 || height % 4) throw "bad width or height";
+
+    var dest = new Uint8Array(width * height * 4);
+    var blocksAcross = width / 4;
+    var blocksDown = height / 4;
+    var blockSize = getBlockSize(format);
+    for (var yy = 0; yy < blocksDown; ++yy) {
+        for (var xx = 0; xx < blocksAcross; ++xx) {
+            uncompressDXTBlock(
+                dest, xx * 4, yy * 4, width, data,
+                (yy * blocksAcross + xx) * blockSize, format);
+        }
+    }
+    return dest;
+}
+
+function copyRect(data, srcX, srcY, dstX, dstY, width, height, stride) {
+  var bytesPerLine = width * 4;
+  var srcOffset = srcX * 4 + srcY * stride;
+  var dstOffset = dstX * 4 + dstY * stride;
+  for (; height > 0; --height) {
+    for (var ii = 0; ii < bytesPerLine; ++ii) {
+      data[dstOffset + ii] = data[srcOffset + ii];
+    }
+    srcOffset += stride;
+    dstOffset += stride;
+  }
+}
+
+function testDXTTexture(test) {
+    var data = new Uint8Array(test.data);
+    var width = test.width;
+    var height = test.height;
+    var format = test.format;
+
+    var uncompressedData = uncompressDXT(width, height, data, format);
+
+    canvas.width = width;
+    canvas.height = height;
+    gl.viewport(0, 0, width, height);
+    debug("testing " + formatToString(format) + " " + width + "x" + height);
+
+    var tex = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, tex);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
+    glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
+    gl.generateMipmap(gl.TEXTURE_2D);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture");
+    wtu.drawQuad(gl);
+    compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
+
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border");
+
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width + 4, height, 0, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height + 4, 0, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 4, height, 0, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 4, 0, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
+
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 1, height, 0, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 2, height, 0, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 1, 0, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
+    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 2, 0, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
+
+    if (width == 4) {
+      gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
+      glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
+      gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
+      glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
+    }
+    if (height == 4) {
+      gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
+      glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
+      gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
+      glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
+    }
+
+    // pick a wrong format that uses the same amount of data.
+    var wrongFormat;
+    switch (format) {
+    case ext.COMPRESSED_RGB_S3TC_DXT1_EXT:
+      wrongFormat = ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
+      break;
+    case ext.COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      wrongFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT;
+      break;
+    case ext.COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      wrongFormat = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
+      break;
+    case ext.COMPRESSED_RGBA_S3TC_DXT5_EXT:
+      wrongFormat = ext.COMPRESSED_RGBA_S3TC_DXT3_EXT;
+      break;
+    }
+
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, wrongFormat, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "format does not match");
+
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width + 4, height, format, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height + 4, format, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 4, height, format, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 4, format, data);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
+
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 1, height, format, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 2, height, format, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 1, format, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
+    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 2, format, data);
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
+
+    var subData = new Uint8Array(data.buffer, 0, getBlockSize(format));
+
+    if (width == 8 && height == 8) {
+        gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 1, 0, 4, 4, format, subData);
+        glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
+        gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 4, 4, format, subData);
+        glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
+    }
+
+    var stride = width * 4;
+    for (var yoff = 0; yoff < height; yoff += 4) {
+        for (var xoff = 0; xoff < width; xoff += 4) {
+            copyRect(uncompressedData, 0, 0, xoff, yoff, 4, 4, stride);
+            gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, xoff, yoff, 4, 4, format, subData);
+            glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
+            wtu.drawQuad(gl);
+            compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
+        }
+    }
+}
+
+function insertImg(element, caption, img) {
+    var div = document.createElement("div");
+    div.appendChild(img);
+    var label = document.createElement("div");
+    label.appendChild(document.createTextNode(caption));
+    div.appendChild(label);
+    element.appendChild(div);
+}
+
+function makeImage(imageWidth, imageHeight, dataWidth, data, alpha) {
+    var scale = 8;
+    var c = document.createElement("canvas");
+    c.width = imageWidth * scale;
+    c.height = imageHeight * scale;
+    var ctx = c.getContext("2d");
+    for (var yy = 0; yy < imageHeight; ++yy) {
+        for (var xx = 0; xx < imageWidth; ++xx) {
+            var offset = (yy * dataWidth + xx) * 4;
+            ctx.fillStyle = "rgba(" +
+                    data[offset + 0] + "," +
+                    data[offset + 1] + "," +
+                    data[offset + 2] + "," +
+                    (alpha ? data[offset + 3] / 255 : 1) + ")";
+            ctx.fillRect(xx * scale, yy * scale, scale, scale);
+        }
+    }
+    var img = document.createElement("img");
+    img.src = c.toDataURL();
+    return img;
+}
+function compareRect(
+        actualWidth, actualHeight, actualChannels,
+        dataWidth, dataHeight, expectedData,
+        testData, testFormat) {
+    var actual = new Uint8Array(actualWidth * actualHeight * 4);
+    gl.readPixels(
+            0, 0, actualWidth, actualHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual);
+
+    var div = document.createElement("div");
+    div.className = "testimages";
+    insertImg(div, "expected", makeImage(
+            actualWidth, actualHeight, dataWidth, expectedData,
+            actualChannels == 4));
+    insertImg(div, "actual", makeImage(
+            actualWidth, actualHeight, actualWidth, actual,
+            actualChannels == 4));
+    div.appendChild(document.createElement('br'));
+    document.getElementById("console").appendChild(div);
+
+    var failed = false;
+    for (var yy = 0; yy < actualHeight; ++yy) {
+        for (var xx = 0; xx < actualWidth; ++xx) {
+            var actualOffset = (yy * actualWidth + xx) * 4;
+            var expectedOffset = (yy * dataWidth + xx) * 4;
+            var expected = [
+                    expectedData[expectedOffset + 0],
+                    expectedData[expectedOffset + 1],
+                    expectedData[expectedOffset + 2],
+                    (actualChannels == 3 ? 255 : expectedData[expectedOffset + 3])
+            ];
+            for (var jj = 0; jj < 4; ++jj) {
+                if (actual[actualOffset + jj] != expected[jj]) {
+                    failed = true;
+                    var was = actual[actualOffset + 0].toString();
+                    for (j = 1; j < 4; ++j) {
+                        was += "," + actual[actualOffset + j];
+                    }
+                    testFailed('at (' + xx + ', ' + yy +
+                                         ') expected: ' + expected + ' was ' + was);
+                }
+            }
+        }
+    }
+    if (!failed) {
+        testPassed("texture rendered correctly");
+    }
+}
+
+function testPVRTCTextures() {
+    testFailed("PVRTC test not yet implemented");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html
new file mode 100644
index 0000000..d65e6f2
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-renderer-info.html
@@ -0,0 +1,127 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL WebGL_debug_renderer_info Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 1px; height: 1px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing standard derivatives -->
+
+<script>
+"use strict";
+description("This test verifies the functionality of the WEBGL_debug_renderer_info extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+var ext = null;
+var vao = null;
+
+if (!gl) {
+    testFailed("WebGL context does not exist");
+} else {
+    testPassed("WebGL context exists");
+
+    // Run tests with extension disabled
+    runTestDisabled();
+
+    // Query the extension and store globally so shouldBe can access it
+    ext = gl.getExtension("WEBGL_debug_renderer_info");
+    if (!ext) {
+        testPassed("No WEBGL_debug_renderer_info support -- this is legal");
+
+        runSupportedTest(false);
+    } else {
+        testPassed("Successfully enabled WEBGL_debug_renderer_info extension");
+
+        runSupportedTest(true);
+        runTestEnabled();
+    }
+}
+
+function runSupportedTest(extensionEnabled) {
+    var supported = gl.getSupportedExtensions();
+    if (supported.indexOf("WEBGL_debug_renderer_info") >= 0) {
+        if (extensionEnabled) {
+            testPassed("WEBGL_debug_renderer_info listed as supported and getExtension succeeded");
+        } else {
+            testFailed("WEBGL_debug_renderer_info listed as supported but getExtension failed");
+        }
+    } else {
+        if (extensionEnabled) {
+            testFailed("WEBGL_debug_renderer_info not listed as supported but getExtension succeeded");
+        } else {
+            testPassed("WEBGL_debug_renderer_info not listed as supported and getExtension failed -- this is legal");
+        }
+    }
+}
+
+function runTestDisabled() {
+    debug("Testing enums with extension disabled");
+
+    // Use the constants directly as we don't have the extension
+
+    var UNMASKED_VENDOR_WEBGL = 0x9245;
+    gl.getParameter(UNMASKED_VENDOR_WEBGL);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "UNMASKED_VENDOR_WEBGL should not be queryable if extension is disabled");
+
+    var UNMASKED_RENDERER_WEBGL = 0x9246;
+    gl.getParameter(UNMASKED_RENDERER_WEBGL);
+    glErrorShouldBe(gl, gl.INVALID_ENUM, "UNMASKED_RENDERER_WEBGL should not be queryable if extension is disabled");
+}
+
+function runTestEnabled() {
+    debug("Testing enums with extension enabled");
+
+    shouldBe("ext.UNMASKED_VENDOR_WEBGL", "0x9245");
+    gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
+    glErrorShouldBe(gl, gl.NO_ERROR, "UNMASKED_VENDOR_WEBGL query should succeed if extension is enable");
+
+    shouldBe("ext.UNMASKED_RENDERER_WEBGL", "0x9246");
+    gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
+    glErrorShouldBe(gl, gl.NO_ERROR, "UNMASKED_RENDERER_WEBGL query should succeed if extension is enable");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html
new file mode 100644
index 0000000..fd592f7
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-debug-shaders.html
@@ -0,0 +1,165 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL WebGL_debug_shaders Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 1px; height: 1px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing standard derivatives -->
+
+<script>
+"use strict";
+description("This test verifies the functionality of the WEBGL_debug_shaders extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+var ext = null;
+var shader = null;
+var program = null;
+var info = null;
+var translatedSource;
+
+if (!gl) {
+    testFailed("WebGL context does not exist");
+} else {
+    testPassed("WebGL context exists");
+
+    // Query the extension and store globally so shouldBe can access it
+    ext = gl.getExtension("WEBGL_debug_shaders");
+    if (!ext) {
+        testPassed("No WEBGL_debug_shaders support -- this is legal");
+
+        runSupportedTest(false);
+    } else {
+        testPassed("Successfully enabled WEBGL_debug_shaders extension");
+
+        runSupportedTest(true);
+        runTestEnabled();
+    }
+}
+
+function runSupportedTest(extensionEnabled) {
+    var supported = gl.getSupportedExtensions();
+    if (supported.indexOf("WEBGL_debug_shaders") >= 0) {
+        if (extensionEnabled) {
+            testPassed("WEBGL_debug_shaders listed as supported and getExtension succeeded");
+        } else {
+            testFailed("WEBGL_debug_shaders listed as supported but getExtension failed");
+        }
+    } else {
+        if (extensionEnabled) {
+            testFailed("WEBGL_debug_shaders not listed as supported but getExtension succeeded");
+        } else {
+            testPassed("WEBGL_debug_shaders not listed as supported and getExtension failed -- this is legal");
+        }
+    }
+}
+
+function runTestEnabled() {
+    debug("Testing function with extension enabled");
+
+    var shaderInfos = [
+      {
+        source: "void main() { gl_Position = vec4(1.0, 0.0, 0.0, 1.0); }",
+        type: gl.VERTEX_SHADER
+      },
+      {
+        source: "void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }",
+        type: gl.FRAGMENT_SHADER
+      }
+    ];
+
+    // Do this twice to test for caching issues.
+    for (var jj = 0; jj < 2; ++jj) {
+        debug("pass:" + (jj + 1));
+        program = gl.createProgram();
+        for (var ii = 0; ii < shaderInfos.length; ++ii) {
+            info = shaderInfos[ii];
+
+            shader = gl.createShader(info.type);
+
+            // if no source has been defined or compileShader() has not been called,
+            // getTranslatedShaderSource() should return an empty string.
+            shouldBeNull("ext.getTranslatedShaderSource(shader)");
+            gl.shaderSource(shader, info.source);
+            shouldBeNull("ext.getTranslatedShaderSource(shader)");
+            gl.compileShader(shader);
+            shouldBeTrue("gl.getShaderParameter(shader, gl.COMPILE_STATUS)");
+            translatedSource = ext.getTranslatedShaderSource(shader);
+            glErrorShouldBe(gl, gl.NO_ERROR, "No gl error should occur");
+            if (translatedSource && translatedSource.length > 0) {
+                testPassed("Successfully called getTranslatedShaderSource()");
+            } else {
+                testFailed("Calling getTranslatedShaderSource() failed");
+            }
+            gl.attachShader(program, shader);
+        }
+        gl.linkProgram(program);
+        shouldBeTrue("gl.getProgramParameter(program, gl.LINK_STATUS)");
+    }
+
+    // Test changing the source. Make sure we get the correct source each time.
+    debug("test changing source");
+    shader = gl.createShader(gl.FRAGMENT_SHADER);
+    gl.shaderSource(shader, "void main() { gl_FragColor = vec4(gl_FragCoord.x, 0.0, 0.0, 1.0); }");
+    gl.compileShader(shader);
+    shouldBeTrue("gl.getShaderParameter(shader, gl.COMPILE_STATUS)");
+    translatedSource = ext.getTranslatedShaderSource(shader);
+    shouldBeTrue('translatedSource && translatedSource.indexOf("gl_FragCoord") >= 0');
+    // change the source but don't compile.
+    gl.shaderSource(shader, "void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }");
+    // the source should NOT change. It should be the same as the old source.
+    newTranslatedSource = ext.getTranslatedShaderSource(shader);
+    shouldBe('newTranslatedSource', 'translatedSource');
+    // now compile.
+    gl.compileShader(shader);
+    shouldBeTrue("gl.getShaderParameter(shader, gl.COMPILE_STATUS)");
+    // the source should have change.
+    newTranslatedSource = ext.getTranslatedShaderSource(shader);
+    shouldNotBe('newTranslatedSource', 'translatedSource');
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html
new file mode 100644
index 0000000..c792f08
--- /dev/null
+++ b/LayoutTests/webgl/resources/webgl_test_files/conformance/extensions/webgl-depth-texture.html
@@ -0,0 +1,342 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+<title>WebGL WEBGL_depth_texture Conformance Tests</title>
+</head>
+<body>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 a_position;
+void main()
+{
+    gl_Position = a_position;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D u_texture;
+uniform vec2 u_resolution;
+void main()
+{
+    vec2 texcoord = gl_FragCoord.xy / u_resolution;
+    gl_FragColor = texture2D(u_texture, texcoord);
+}
+</script>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
+<script>
+"use strict";
+description("This test verifies the functionality of the WEBGL_depth_texture extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false});
+var program = wtu.setupTexturedQuad(gl);
+var ext = null;
+var vao = null;
+var tex;
+var name;
+var supportedFormats;
+var canvas2;
+
+if (!gl) {
+    testFailed("WebGL context does not exist");
+} else {
+    testPassed("WebGL context exists");
+
+    // Run tests with extension disabled
+    runTestDisabled();
+
+    // Query the extension and store globally so shouldBe can access it
+    ext = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_depth_texture");
+    if (!ext) {
+        testPassed("No WEBGL_depth_texture support -- this is legal");
+        runSupportedTest(false);
+    } else {
+        testPassed("Successfully enabled WEBGL_depth_texture extension");
+
+        runSupportedTest(true);
+        runTestExtension();
+    }
+}
+
+function runSupportedTest(extensionEnabled) {
+    var name = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_depth_texture");
+    if (name !== undefined) {
+        if (extensionEnabled) {
+            testPassed("WEBGL_depth_texture listed as supported and getExtension succeeded");
+        } else {
+            testFailed("WEBGL_depth_texture listed as supported but getExtension failed");
+        }
+    } else {
+        if (extensionEnabled) {
+            testFailed("WEBGL_depth_texture not listed as supported but getExtension succeeded");
+        } else {
+            testPassed("WEBGL_depth_texture not listed as supported and getExtension failed -- this is legal");
+        }
+    }
+}
+
+
+function runTestDisabled() {
+    debug("Testing binding enum with extension disabled");
+
+    var tex = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, tex);
+    shouldGenerateGLError(gl, gl.INVALID_ENUM, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null)');
+    shouldGenerateGLError(gl, gl.INVALID_ENUM, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null)');
+}
+
+
+function dumpIt(gl, res, msg) {
+  return;  // comment out to debug
+  debug(msg);
+  var actualPixels = new Uint8Array(res * res * 4);
+  gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels);
+
+  for (var yy = 0; yy < res; ++yy) {
+    var strs = [];
+    for (var xx = 0; xx < res; ++xx) {
+      var actual = (yy * res + xx) * 4;
+      strs.push("(" + actualPixels[actual] + "," + actualPixels[actual+1] + "," + actualPixels[actual + 2] + "," + actualPixels[actual + 3] + ")");
+    }
+    debug(strs.join(" "));
+  }
+}
+function runTestExtension() {
+    debug("Testing WEBGL_depth_texture");
+
+    var res = 8;
+
+    // make canvas for testing.
+    canvas2 = document.createElement("canvas");
+    canvas2.width = res;
+    canvas2.height = res;
+    var ctx = canvas2.getContext("2d");
+    ctx.fillStyle = "blue";
+    ctx.fillRect(0, 0, canvas2.width, canvas2.height);
+
+    var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_position']);
+    gl.useProgram(program);
+    gl.uniform2f(gl.getUniformLocation(program, "u_resolution"), res, res);
+
+    var buffer = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+    gl.bufferData(
+        gl.ARRAY_BUFFER,
+        new Float32Array(
+            [   1,  1,  1,
+               -1,  1,  0,
+               -1, -1, -1,
+                1,  1,  1,
+               -1, -1, -1,
+                1, -1,  0,
+            ]),
+        gl.STATIC_DRAW);
+    gl.enableVertexAttribArray(0);
+    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+    var types = [
+        {obj: 'gl',  attachment: 'DEPTH_ATTACHMENT',         format: 'DEPTH_COMPONENT', type: 'UNSIGNED_SHORT',          data: 'new Uint16Array(1)' },
+        {obj: 'gl',  attachment: 'DEPTH_ATTACHMENT',         format: 'DEPTH_COMPONENT', type: 'UNSIGNED_INT',            data: 'new Uint32Array(1)' },
+        {obj: 'ext', attachment: 'DEPTH_STENCIL_ATTACHMENT', format: 'DEPTH_STENCIL',   type: 'UNSIGNED_INT_24_8_WEBGL', data: 'new Uint32Array(1)' }
+    ];
+
+    for (var ii = 0; ii < types.length; ++ii) {
+        var typeInfo = types[ii];
+        var type = typeInfo.type;
+        var typeStr = typeInfo.obj + '.' + type;
+
+        debug("");
+        debug("testing: " + type);
+
+        // check that cubemaps are not allowed.
+        var cubeTex = gl.createTexture();
+        gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTex);
+        var targets = [
+          'TEXTURE_CUBE_MAP_POSITIVE_X',
+          'TEXTURE_CUBE_MAP_NEGATIVE_X',
+          'TEXTURE_CUBE_MAP_POSITIVE_Y',
+          'TEXTURE_CUBE_MAP_NEGATIVE_Y',
+          'TEXTURE_CUBE_MAP_POSITIVE_Z',
+          'TEXTURE_CUBE_MAP_NEGATIVE_Z'
+        ];
+        for (var tt = 0; tt < targets.length; ++tt) {
+            shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.' + targets[ii] + ', 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + typeStr + ', null)');
+        }
+
+        // check 2d textures.
+        tex = gl.createTexture();
+        gl.bindTexture(gl.TEXTURE_2D, tex);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+
+        // test level > 0
+        shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.TEXTURE_2D, 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + typeStr + ', null)');
+
+        // test with data
+        shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + typeStr + ', ' + typeInfo.data + ')');
+
+        // test with canvas
+        shouldGenerateGLError(gl, [gl.INVALID_VALUE, gl.INVALID_ENUM, gl.INVALID_OPERATION], 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', gl.' + typeInfo.format + ', ' + typeStr  + ', canvas2)');
+
+        // test copyTexImage2D
+        shouldGenerateGLError(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], 'gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', 0, 0, 1, 1, 0)');
+
+        // test real thing
+        shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.texImage2D(gl.TEXTURE_2D, 0, gl.' + typeInfo.format + ', ' + res + ', ' + res + ', 0, gl.' + typeInfo.format + ', ' + typeStr + ', null)');
+
+        // test texSubImage2D
+        shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.' + typeInfo.format + ', ' + typeStr  + ', ' + typeInfo.data + ')');
+
+        // test copyTexSubImage2D
+        shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1)');
+
+        // test generateMipmap
+        shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.generateMipmap(gl.TEXTURE_2D)');
+
+        var fbo = gl.createFramebuffer();
+        gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXTURE_2D, tex, 0);
+        // TODO: remove this check if the spec is updated to require these combinations to work.
+        if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)
+        {
+            // try adding a color buffer.
+            var colorTex = gl.createTexture();
+            gl.bindTexture(gl.TEXTURE_2D, colorTex);
+            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, res, res, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
+        }
+
+        shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+        // use the default texture to render with while we return to the depth texture.
+        gl.bindTexture(gl.TEXTURE_2D, null);
+
+        // render the z-quad
+        gl.enable(gl.DEPTH_TEST);
+        gl.clearColor(1, 0, 0, 1);
+        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+        gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+        dumpIt(gl, res, "--first--");
+
+        // render the depth texture.
+        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+        gl.bindTexture(gl.TEXTURE_2D, tex);
+        gl.clearColor(0, 0, 1, 1);
+        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+        gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+        var actualPixels = new Uint8Array(res * res * 4);
+        gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels);
+
+        dumpIt(gl, res, "--depth--");
+
+        // Check that each pixel's RGB are the same and that it's value is less
+        // than the previous pixel in either direction. Basically verify we have a
+        // gradient.
+        var success = true;
+        for (var yy = 0; yy < res; ++yy) {
+          for (var xx = 0; xx < res; ++xx) {
+            var actual = (yy * res + xx) * 4;
+            var left = actual - 4;
+            var down = actual - res * 4;
+
+            if (actualPixels[actual + 0] != actualPixels[actual + 1]) {
+                testFailed('R != G');
+                success = false;
+            }
+            if (actualPixels[actual + 0] != actualPixels[actual + 2]) {
+                testFailed('R != B');
+                success = false;
+            }
+            // ALPHA is implementation dependent
+            if (actualPixels[actual + 3] != 0xFF && actualPixels[actual + 3] != actualPixels[actual + 0]) {
+                testFailed('A != 255 && A != R');
+                success = false;
+            }
+
+            if (xx > 0) {
+              if (actualPixels[actual] <= actualPixels[left]) {
+                  testFailed("actual(" + actualPixels[actual] + ") < left(" + actualPixels[left] + ")");
+                  success = false;
+              }
+            }
+            if (yy > 0) {
+                if (actualPixels[actual] <= actualPixels[down]) {
+                    testFailed("actual(" + actualPixels[actual] + ") < down(" + actualPixels[down] + ")");
+                    success = false;
+                }
+            }
+          }
+        }
+
+        // Check that bottom left corner is vastly different thatn top right.
+        if (actualPixels[(res * res - 1) * 4] - actualPixels[0] < 0xC0) {
+            testFailed("corners are not different enough");
+            success = false;
+        }
+
+        if (success) {
+            testPassed("depth texture rendered correctly.");
+        }
+
+        // check limitations
+        gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXTURE_2D, null, 0);
+        var badAttachment = typeInfo.attachment == 'DEPTH_ATTACHMENT' ? 'DEPTH_STENCIL_ATTACHMENT' : 'DEPTH_ATTACHMENT';
+        shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.' + badAttachment + ', gl.TEXTURE_2D, tex, 0)');
+        shouldNotBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+        shouldGenerateGLError(gl, gl.INVALID_FRAMEBUFFER_OPERATION, 'gl.clear(gl.DEPTH_BUFFER_BIT)');
+        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+        shouldBe('gl.getError()', 'gl.NO_ERROR');
+    }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>