summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/buffers
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/buffers')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt9
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html140
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html197
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html123
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html204
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html72
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html141
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html176
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/getBufferSubData.html105
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html152
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html428
11 files changed, 1747 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt
new file mode 100644
index 000000000..96921fbea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt
@@ -0,0 +1,9 @@
+bound-buffer-size-change-test.html
+buffer-copying-contents.html
+buffer-copying-restrictions.html
+buffer-data-and-buffer-sub-data-sub-source.html
+buffer-type-restrictions.html
+buffer-overflow-test.html
+get-buffer-sub-data.html
+one-large-uniform-buffer.html
+uniform-buffers.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html
new file mode 100644
index 000000000..a9d13496a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html
@@ -0,0 +1,140 @@
+<!--
+
+/*
+** Copyright (c) 2016 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 buffer size change test for bindBufferBase/bindBufferRange</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("WebGL buffer size change for bindings through bindBufferBase/bindBufferRange");
+
+// This test verifies the ES3 behavior, that the bound buffer range (offset, size) is not
+// limited by the actual buffer size, and the driver is responsible that no out-of-range
+// access may happen.
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+debug("");
+debug("bindBufferBase with TRANSFORM_FEEDBACK_BUFFER target");
+var buffer1 = gl.createBuffer();
+gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferBase on a buffer where no storage is allocated should succeed.");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)", "buffer1");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer1");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "0");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "0");
+
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer1");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "0");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "0");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("bindBufferBase with UNIFORM_BUFFER target");
+var buffer2 = gl.createBuffer();
+gl.bindBufferBase(gl.UNIFORM_BUFFER, 1, buffer2);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferBase on a buffer where no storage is allocated should succeed.");
+shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "buffer2");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer2");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "0");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "0");
+
+gl.bufferData(gl.UNIFORM_BUFFER, 8, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer2");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "0");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "0");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("bindBufferRange with TRANSFORM_FEEDBACK_BUFFER target");
+var buffer3 = gl.createBuffer();
+gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer3, 4, 8);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferRange on a buffer where no storage is allocated should succeed.");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)", "buffer3");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer3");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4");
+
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer3");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4");
+
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 12, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer3");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("bindBufferRange with UNIFORM_BUFFER target");
+var buffer4 = gl.createBuffer();
+var offset = gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+gl.bindBufferRange(gl.UNIFORM_BUFFER, 1, buffer4, offset, 12);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferRange on a buffer where no storage is allocated should succeed.");
+shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "buffer4");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer4");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "12");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "offset");
+
+gl.bufferData(gl.UNIFORM_BUFFER, offset + 8, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer4");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "12");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "offset");
+
+gl.bufferData(gl.UNIFORM_BUFFER, offset + 12, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer4");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "12");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "offset");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html
new file mode 100644
index 000000000..8006f2181
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html
@@ -0,0 +1,197 @@
+<!--
+
+/*
+** Copyright (c) 2015 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 buffer copying contents test.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test copying a buffer's contents to another buffer governed by the WebGL 2 spec.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var vertices = [
+ 1.1, 1.0, 1.3,
+ -1.0, -1.0, -5.0,
+ 5.3, -1.0, 1.0
+];
+
+debug("");
+debug("Test copying between buffers returns correct data");
+
+function testCopyBuffers(srcTarget, dstTarget, copyRead, copyWrite) {
+ var msg = "Copying from " + targetToString(gl, srcTarget) +
+ " to " + targetToString(gl, dstTarget)
+ if (copyRead && copyWrite)
+ msg += " via COPY_READ_BUFFER and COPY_WRITE_BUFFER"
+ else if (copyRead)
+ msg += " via COPY_READ_BUFFER"
+ else if (copyWrite)
+ msg += " via COPY_WRITE_BUFFER"
+ else
+ msg += " directly"
+ debug("")
+ debug(msg)
+
+ var srcBuffer = gl.createBuffer(), dstBuffer = gl.createBuffer();
+ var originalData = new Float32Array(vertices);
+ var length = vertices.length * 4;
+
+ gl.bindBuffer(srcTarget, srcBuffer);
+ gl.bufferData(srcTarget, originalData, gl.STATIC_DRAW);
+ if (copyRead)
+ gl.bindBuffer(gl.COPY_READ_BUFFER, srcBuffer);
+
+ gl.bindBuffer(dstTarget, dstBuffer);
+ gl.bufferData(dstTarget, new Float32Array(length), gl.STATIC_DRAW);
+ if (copyWrite)
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, dstBuffer);
+
+ var expectedGLError = gl.NO_ERROR;
+
+ if (srcTarget == dstTarget) {
+ if (!copyRead && copyWrite) {
+ // srcBuffer isn't bound to any targets because of setting up dstBuffer.
+ gl.bindBuffer(srcTarget, srcBuffer);
+ }
+ if (!copyRead && !copyWrite) {
+ // Same buffer object, overlapping range.
+ expectedGLError = gl.INVALID_VALUE;
+ }
+ }
+ if ((srcTarget == gl.ELEMENT_ARRAY_BUFFER &&
+ dstTarget != gl.ELEMENT_ARRAY_BUFFER) ||
+ (srcTarget != gl.ELEMENT_ARRAY_BUFFER &&
+ dstTarget == gl.ELEMENT_ARRAY_BUFFER)) {
+ expectedGLError = gl.INVALID_OPERATION;
+ }
+
+ gl.copyBufferSubData(copyRead ? gl.COPY_READ_BUFFER : srcTarget,
+ copyWrite ? gl.COPY_WRITE_BUFFER : dstTarget,
+ 0, 0, length);
+ if (expectedGLError == gl.NO_ERROR) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Copying should work");
+
+ var retBuffer = new Uint8Array(length);
+ gl.getBufferSubData(dstTarget, 0, retBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.getBufferSubData(" + targetToString(gl, dstTarget) +
+ ", 0, retBuffer) should work");
+
+ var failed = false;
+ var retArray = new Float32Array(retBuffer.buffer);
+ for (var i = 0; i < vertices.length; i++) {
+ if (originalData[i] != retArray[i]) {
+ failed = true;
+ break;
+ }
+ }
+ if (failed)
+ testFailed("The returned array buffer fails to match original data");
+ else
+ testPassed("The returned array buffer matches original data");
+ } else {
+ wtu.glErrorShouldBe(gl, expectedGLError, "Copying should fail");
+ }
+
+ gl.deleteBuffer(srcBuffer);
+ gl.deleteBuffer(dstBuffer);
+ shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.COPY_READ_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.COPY_WRITE_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.PIXEL_PACK_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.PIXEL_UNPACK_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+}
+
+function targetToString(gl, target) {
+ switch (target) {
+ case gl.ARRAY_BUFFER:
+ return "ARRAY_BUFFER";
+ case gl.COPY_READ_BUFFER:
+ return "COPY_READ_BUFFER";
+ case gl.COPY_WRITE_BUFFER:
+ return "COPY_WRITE_BUFFER";
+ case gl.ELEMENT_ARRAY_BUFFER:
+ return "ELEMENT_ARRAY_BUFFER";
+ case gl.PIXEL_PACK_BUFFER:
+ return "PIXEL_PACK_BUFFER";
+ case gl.PIXEL_UNPACK_BUFFER:
+ return "PIXEL_UNPACK_BUFFER";
+ case gl.TRANSFORM_FEEDBACK_BUFFER:
+ return "TRANSFORM_FEEDBACK_BUFFER";
+ case gl.UNIFORM_BUFFER:
+ return "UNIFORM_BUFFER";
+ default:
+ return "UNKNOWN BUFFER";
+ }
+}
+
+var targets = [
+ gl.ARRAY_BUFFER,
+ gl.ELEMENT_ARRAY_BUFFER,
+ gl.PIXEL_PACK_BUFFER,
+ gl.PIXEL_UNPACK_BUFFER,
+ gl.TRANSFORM_FEEDBACK_BUFFER,
+ gl.UNIFORM_BUFFER,
+]
+
+for (var srcIndex in targets) {
+ for (var dstIndex in targets) {
+ if (targets[srcIndex] != gl.TRANSFORM_FEEDBACK_BUFFER &&
+ targets[dstIndex] != gl.TRANSFORM_FEEDBACK_BUFFER) {
+ testCopyBuffers(targets[srcIndex], targets[dstIndex], true, true);
+ }
+ if (targets[srcIndex] != gl.TRANSFORM_FEEDBACK_BUFFER) {
+ testCopyBuffers(targets[srcIndex], targets[dstIndex], true, false);
+ }
+ if (targets[dstIndex] != gl.TRANSFORM_FEEDBACK_BUFFER) {
+ testCopyBuffers(targets[srcIndex], targets[dstIndex], false, true);
+ }
+ testCopyBuffers(targets[srcIndex], targets[dstIndex], false, false);
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html
new file mode 100644
index 000000000..1833c53fc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html
@@ -0,0 +1,123 @@
+<!--
+
+/*
+** Copyright (c) 2015 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 buffer copying restrictions test.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test buffer copying restrictions governed by the WebGL 2 spec. The test makes sure that copyBufferSubData acts as expected.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+var validTargets = [gl.ARRAY_BUFFER, gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER,
+ gl.ELEMENT_ARRAY_BUFFER, gl.PIXEL_PACK_BUFFER,
+ gl.PIXEL_UNPACK_BUFFER, gl.TRANSFORM_FEEDBACK_BUFFER,
+ gl.UNIFORM_BUFFER];
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var testCopyBuffer = function(srcTarget, dstTarget) {
+ var srcTargetStr = wtu.glEnumToString(gl, srcTarget),
+ dstTargetStr = wtu.glEnumToString(gl, dstTarget);
+ var srcBuffer = gl.createBuffer(),
+ dstBuffer = gl.createBuffer();
+ var testCopyStr = "copying from a gl." + wtu.glEnumToString(gl, srcTarget) + " buffer to a gl."
+ + wtu.glEnumToString(gl, dstTarget) + " buffer"
+
+ gl.bindBuffer(srcTarget, srcBuffer);
+ gl.bufferData(srcTarget, new Float32Array(32), gl.STATIC_DRAW);
+ gl.bindBuffer(dstTarget, dstBuffer);
+ gl.bufferData(dstTarget, new Float32Array(32), gl.STATIC_DRAW);
+ gl.copyBufferSubData(srcTarget, dstTarget, 8, 0, 4);
+ if (srcTarget == dstTarget)
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, testCopyStr + " should work.");
+ else if (srcTarget == gl.ELEMENT_ARRAY_BUFFER || dstTarget == gl.ELEMENT_ARRAY_BUFFER )
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, testCopyStr + " should fail.");
+ else
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, testCopyStr + " should work.");
+
+ // Special case: COPY_READ_BUFFER and COPY_WRITE_BUFFER are compatible with ELEMENT_ARRAY_BUFFER
+ // only if the buffer had been initially bound to an ELEMENT_ARRAY_BUFFER
+ if (srcTarget == gl.ELEMENT_ARRAY_BUFFER &&
+ (dstTarget == gl.COPY_READ_BUFFER || dstTarget == gl.COPY_WRITE_BUFFER)) {
+ dstBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, dstBuffer);
+ } else if (dstTarget == gl.ELEMENT_ARRAY_BUFFER &&
+ (srcTarget == gl.COPY_READ_BUFFER || srcTarget == gl.COPY_WRITE_BUFFER)) {
+ srcBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, srcBuffer);
+ } else {
+ return;
+ }
+
+ gl.bindBuffer(srcTarget, srcBuffer);
+ gl.bufferData(srcTarget, new Float32Array(32), gl.STATIC_DRAW);
+ gl.bindBuffer(dstTarget, dstBuffer);
+ gl.bufferData(dstTarget, new Float32Array(32), gl.STATIC_DRAW);
+ gl.copyBufferSubData(srcTarget, dstTarget, 8, 0, 4);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, testCopyStr + " should work if all buffers were initially bound to ELEMENT_ARRAY_BUFFER.");
+};
+
+for (var i = 0; i < validTargets.length; i++) {
+ debug("");
+ debug("Copying data from a " + wtu.glEnumToString(gl, validTargets[i])
+ + " buffer to another target");
+ for (var j = 0; j < validTargets.length; j++)
+ testCopyBuffer(validTargets[i], validTargets[j]);
+}
+
+debug("");
+debug("Test copying a buffer of other data (gl.ARRAY_BUFFER) bound to gl.COPY_READ_BUFFER to a "
+ + "buffer bound to gl.ELEMENT_ARRAY_BUFFER");
+var srcBuffer = gl.createBuffer(), dstBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, srcBuffer);
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, dstBuffer);
+gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Float32Array(32), gl.STATIC_DRAW);
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(32), gl.STATIC_DRAW);
+gl.bindBuffer(gl.COPY_READ_BUFFER, srcBuffer);
+gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.ELEMENT_ARRAY_BUFFER, 0, 0, 4);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Copying gl.ARRAY_BUFFER bound to "
+ + "gl.COPY_READ_BUFFER to a buffer bound to gl.ELEMENT_ARRAY_BUFFER should fail.");
+
+finishTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html
new file mode 100644
index 000000000..dbf7d45e8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html
@@ -0,0 +1,204 @@
+<!--
+
+/*
+** Copyright (c) 2016 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="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Test bufferData/bufferSubData with ArrayBufferView sub source input");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+function verifyBufferData(testCase, sourceByteOffset, size, data) {
+ var readbackBuffer = new ArrayBuffer(testCase.size * size);
+ var readbackView = new window[testCase.type](readbackBuffer);
+ gl.getBufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, readbackView);
+ var pass = true;
+ var offset = sourceByteOffset / testCase.size;
+ for (var ii = 0; ii < size; ++ii) {
+ if (readbackView[ii] != data[ii]) {
+ testFailed("expected data at " + ii + ": " + data[iit] + ", got " + readbackView[ii]);
+ pass = false;
+ }
+ }
+ if (pass) {
+ testPassed("buffer data uploaded correctly");
+ }
+}
+
+function bufferDataTest(testCases) {
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ var test = testCases[idx];
+ debug("");
+ debug("Test bufferData with " + test.type);
+
+ var buf = gl.createBuffer();
+ shouldBeNonNull(buf);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var count = 4;
+ var arrayBuffer = new ArrayBuffer(test.size * count);
+ var view = new window[test.type](arrayBuffer);
+ for (var ii = 0; ii < count; ++ii) {
+ view[ii] = ii;
+ }
+
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, 0, count + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferData when srcOffset + length is larger than source size");
+
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, count + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferData when srcOffset + length is larger than source size");
+
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, count - 1, 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferData when srcOffset + length is larger than source size");
+
+ var offset = 2;
+ var size = count - offset;
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, offset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferData with valid sub source should succeed");
+ verifyBufferData(test, 0, size, view.slice(offset, offset + size));
+
+ offset = 1;
+ size = 1;
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, offset, size);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferData with valid sub source should succeed");
+ verifyBufferData(test, 0, size, view.slice(offset, offset + size));
+
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, count);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferData with valid sub source of size 0 should succeed");
+
+ gl.deleteBuffer(buf);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no GL error");
+ }
+}
+
+function bufferSubDataTest(testCases) {
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ var test = testCases[idx];
+ debug("");
+ debug("Test bufferSubData with " + test.type);
+
+ var count = 4;
+ var totalBufferBytes = test.size * count * 2;
+ var buf = gl.createBuffer();
+ shouldBeNonNull(buf);
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bufferData(gl.ARRAY_BUFFER, totalBufferBytes, gl.STATIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var arrayBuffer = new ArrayBuffer(test.size * count);
+ var view = new window[test.type](arrayBuffer);
+ for (var ii = 0; ii < count; ++ii) {
+ view[ii] = ii;
+ }
+
+ var sourceByteOffset = test.size * 2;
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, 0, count + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferSubData when srcOffset + length is larger than source size");
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, count + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferSubData when srcOffset + length is larger than source size");
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, count - 1, 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferSubData when srcOffset + length is larger than source size");
+
+ var offset = 2;
+ var size = count - offset;
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, offset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferSubData with valid sub source should succeed");
+ verifyBufferData(test, sourceByteOffset, size, view.slice(offset, offset + size));
+
+ offset = 1;
+ size = 1;
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, offset, size);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferSubData with valid sub source should succeed");
+ verifyBufferData(test, sourceByteOffset, size, view.slice(offset, offset + size));
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, count);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferSubData with valid sub source of size 0 should succeed");
+
+ gl.deleteBuffer(buf);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no GL error");
+ }
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ var testCases = [
+ {type: "Uint8Array", size: 1},
+ {type: "Int8Array", size: 1},
+ {type: "Int16Array", size: 2},
+ {type: "Uint16Array", size: 2},
+ {type: "Uint32Array", size: 4},
+ {type: "Int32Array", size: 4},
+ {type: "Float32Array", size: 4},
+ {type: "Float64Array", size: 8}
+ ];
+
+ bufferDataTest(testCases);
+ bufferSubDataTest(testCases);
+}
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html
new file mode 100644
index 000000000..929692df8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html
@@ -0,0 +1,72 @@
+<!--
+
+/*
+** Copyright (c) 2015 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 buffer overflow test for bindBufferRange</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("WebGL buffer overflow test: buffer overflow will not lead to failure in bindBufferRange");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+debug("");
+var buffer1 = gl.createBuffer();
+gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer1, 0, 4);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferRange on a buffer where no storage is allocated should succeed.");
+shouldBe("buffer1", "gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)");
+shouldBe("4", "gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)");
+shouldBe("0", "gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)");
+
+var buffer2 = gl.createBuffer();
+gl.bindBuffer(gl.UNIFORM_BUFFER, buffer2);
+gl.bufferData(gl.UNIFORM_BUFFER, 4, gl.STATIC_DRAW);
+gl.bindBufferRange(gl.UNIFORM_BUFFER, 1, buffer2, 0, 8);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferRange on a buffer where the storage is not big enough should succeed.");
+shouldBe("buffer2", "gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)");
+shouldBe("8", "gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)");
+shouldBe("0", "gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)");
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html
new file mode 100644
index 000000000..57a8a8fbf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html
@@ -0,0 +1,141 @@
+<!--
+
+/*
+** Copyright (c) 2015 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 buffer binding restrictions test.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test binding restrictions governed by the WebGL 2 spec. The test makes sure that bindBuffer,"
+ + "bindBufferRange, and bindBufferBase acts as expected with every target combination.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+var validTargets = [gl.ARRAY_BUFFER, gl.ELEMENT_ARRAY_BUFFER, gl.COPY_READ_BUFFER,
+ gl.COPY_WRITE_BUFFER, gl.PIXEL_PACK_BUFFER, gl.PIXEL_UNPACK_BUFFER,
+ gl.TRANSFORM_FEEDBACK_BUFFER, gl.UNIFORM_BUFFER];
+
+var bindFunctions = ["bindBuffer", "bindBufferRange", "bindBufferBase"];
+
+var isCopyTarget = function(target) {
+ return target == gl.COPY_READ_BUFFER || target == gl.COPY_WRITE_BUFFER;
+}
+
+var noElementArrayVsOtherDataConflicts = function(first, second) {
+ return isCopyTarget(second) || ((first == gl.ELEMENT_ARRAY_BUFFER) == (second == gl.ELEMENT_ARRAY_BUFFER));
+};
+
+
+var bind = function(bindFn, target, buffer) {
+ if (bindFn == "bindBuffer")
+ gl.bindBuffer(target, buffer);
+ else if (bindFn == "bindBufferRange")
+ gl.bindBufferRange(target, 0, buffer, 0, 4);
+ else if (bindFn == "bindBufferBase")
+ gl.bindBufferBase(target, 0, buffer);
+ else
+ throw new Error("Cannot bind unknown function: " + bindFn);
+}
+
+var testBindingFn = function(firstBindFn, secondBindFn, firstTarget, secondTarget) {
+ var firstTargetStr = wtu.glEnumToString(gl, firstTarget),
+ secondTargetStr = wtu.glEnumToString(gl, secondTarget);
+ var buffer = gl.createBuffer();
+
+ bind(firstBindFn, firstTarget, buffer);
+ bind(firstBindFn, firstTarget, null);
+ bind(secondBindFn, secondTarget, buffer);
+ bind(secondBindFn, secondTarget, null);
+
+ var messagePrefix = "Binding buffer first with " + firstBindFn + " to gl." + firstTargetStr
+ + " and then binding buffer with " + secondBindFn + " to gl." + secondTargetStr + " should ";
+ if (firstTarget == secondTarget || noElementArrayVsOtherDataConflicts(firstTarget, secondTarget))
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, messagePrefix + "WORK");
+ else
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, messagePrefix + "FAIL");
+
+ if ((firstTarget == gl.TRANSFORM_FEEDBACK_BUFFER && secondTarget != gl.TRANSFORM_FEEDBACK_BUFFER) ||
+ (firstTarget != gl.TRANSFORM_FEEDBACK_BUFFER && secondTarget == gl.TRANSFORM_FEEDBACK_BUFFER)) {
+ bind(firstBindFn, firstTarget, buffer);
+ bind(secondBindFn, secondTarget, buffer);
+
+ var message = "Binding buffer first with " + firstBindFn + " to gl." + firstTargetStr
+ + " and simultaneously binding buffer with " + secondBindFn + " to gl." + secondTargetStr + " should FAIL";
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, message);
+ }
+}
+
+var testBinding = function(firstTarget, secondTarget) {
+ for (var i = 0; i < bindFunctions.length; i++)
+ if (i == 0 || firstTarget == gl.UNIFORM_BUFFER || firstTarget == gl.TRANSFORM_FEEDBACK_BUFFER)
+ for (var j = 0; j < bindFunctions.length; j++)
+ if (j == 0 || secondTarget == gl.UNIFORM_BUFFER || secondTarget == gl.TRANSFORM_FEEDBACK_BUFFER)
+ testBindingFn(bindFunctions[i], bindFunctions[j], firstTarget, secondTarget);
+};
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+debug("");
+debug("Testing each binding function");
+
+var buffer1 = gl.createBuffer();
+bind("bindBuffer", gl.ARRAY_BUFFER, buffer1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bindBuffer(gl.ARRAY_BUFFER, buffer1) should WORK");
+
+var buffer2 = gl.createBuffer();
+bind("bindBufferRange", gl.UNIFORM_BUFFER, buffer2);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bindBufferRange(gl.UNIFORM_BUFFER, 0, buffer2, 0, 4) should WORK");
+
+var buffer3 = gl.createBuffer();
+bind("bindBufferBase", gl.UNIFORM_BUFFER, buffer3);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bindBufferBase(gl.UNIFORM_BUFFER, 0, buffer3) should WORK");
+
+for (var i = 0; i < validTargets.length; i++) {
+ debug("");
+ debug("Testing binding a buffer first to " + wtu.glEnumToString(gl, validTargets[i])
+ + " and then to another target");
+ for (var j = 0; j < validTargets.length; j++)
+ testBinding(validTargets[i], validTargets[j]);
+}
+
+finishTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html
new file mode 100644
index 000000000..6026cc5cc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html
@@ -0,0 +1,176 @@
+<!--
+
+/*
+** Copyright (c) 2015 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 getBufferSubData test.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test makes sure that getBufferSubData acts as expected governed by WebGL 2.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+var vertices = [
+ 1.1, 1.0, 1.3,
+ -1.0, -1.0, -5.0,
+ 5.3, -1.0, 1.0
+];
+var floatArray = new Float32Array(vertices);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var buffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.STATIC_DRAW);
+
+var uninitializedBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, uninitializedBuffer);
+gl.bufferData(gl.ARRAY_BUFFER, 36, gl.STATIC_DRAW);
+gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from buffer setup.");
+
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+debug("");
+debug("Test that getBufferSubData successfully works reading buffer data from gl.ARRAY_BUFFER");
+var retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+
+debug("Argument must be ArrayBufferView, not ArrayBuffer")
+shouldThrow("gl.getBufferSubData(gl.ARRAY_BUFFER, 0, new ArrayBuffer(4))");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should not generate GL error");
+debug("Argument must be ArrayBufferView, not null")
+shouldThrow("gl.getBufferSubData(gl.ARRAY_BUFFER, 0, null)");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should not generate GL error");
+
+debug("Check array data to match original data set by the buffer");
+var failed = false;
+for (var i = 0; i < vertices.length; i++) {
+ if (floatArray[i] != retArray[i]) {
+ failed = true;
+ break;
+ }
+}
+if (failed)
+ testFailed("The returned array buffer fails to match original data");
+else
+ testPassed("The returned array buffer matches original data");
+
+debug("Test that getBufferSubData successfully works with dstOffset");
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, 2)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 2), [0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(2), floatArray.slice(0, floatArray.length - 2))");
+
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length)");
+shouldBeTrue("areArraysEqual(retArray, [0, 0, 0, 0, 0, 0, 0, 0, 0])");
+
+debug("Test that getBufferSubData fails when given a dstOffset beyond the end of retArray");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length + 1)");
+
+debug("Test that getBufferSubData successfully works with dstOffset and length");
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, 2, 2)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 2), [0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(2, 4), floatArray.slice(0, 2))");
+shouldBeTrue("areArraysEqual(retArray.slice(4), [0, 0, 0, 0, 0])");
+
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length - 1, 1)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 8), [0, 0, 0, 0, 0, 0, 0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(8), floatArray.slice(0, 1))");
+
+debug("Test that getBufferSubData fails when given a dstOffset+length beyond the end of retArray");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length - 1, 2)");
+
+debug("Test that getBufferSubData fails when given a buffer with its size larger than the original data");
+var extraLargeBuffer = new Float32Array(vertices.length + 1);
+gl.getBufferSubData(gl.ARRAY_BUFFER, 0, extraLargeBuffer);
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, extraLargeBuffer)",
+ "Extra length should generate INVALID_VALUE.");
+
+debug("Test that getBufferSubData fails when offset summed with buffer length is larger than the size of the original data size");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, retArray.byteLength + 1, retArray)");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 1, retArray)");
+
+debug("Test that getBufferSubData fails when 0 is bound to the target");
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION,
+ "gl.getBufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, retArray)");
+
+debug("Test that getBufferSubData fails when offset is less than 0");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, -1, retArray)");
+
+debug("");
+debug("Test that getBufferSubData successfully works with uninitialized buffers");
+retArray = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
+gl.bindBuffer(gl.ARRAY_BUFFER, uninitializedBuffer);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+shouldBeTrue("areArraysEqual(retArray, [0, 0, 0, 0, 0, 0, 0, 0, 0])");
+
+debug("");
+debug("Test that getBufferSubData works when a buffer is immediately resized to be too small");
+
+retArray = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+gl.bufferData(gl.ARRAY_BUFFER, 4, gl.STATIC_DRAW);
+shouldBeTrue("areArraysEqual(retArray, floatArray)");
+
+debug("");
+debug("Test that getBufferSubData works when a buffer is immediately deleted");
+retArray = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.STATIC_DRAW);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+gl.deleteBuffer(buffer);
+shouldBeTrue("areArraysEqual(retArray, floatArray)");
+
+finishTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/getBufferSubData.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/getBufferSubData.html
new file mode 100644
index 000000000..d751e8070
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/getBufferSubData.html
@@ -0,0 +1,105 @@
+<!--
+
+/*
+** Copyright (c) 2015 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 getBufferSubData test.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test makes sure that getBufferSubData acts as expected governed by WebGL 2.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+var vertices = [
+ 1.1, 1.0, 1.3,
+ -1.0, -1.0, -5.0,
+ 5.3, -1.0, 1.0
+];
+var floatArray = new Float32Array(vertices);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var buffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.STATIC_DRAW);
+
+debug("");
+debug("Test that getBufferSubData successfully works reading buffer data from gl.ARRAY_BUFFER");
+var retArray = new Float32Array(vertices.length);
+gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, arrBuffer) should WORK");
+
+debug("Check array data to match original data set by the buffer");
+var failed = false;
+for (var i = 0; i < vertices.length; i++) {
+ if (floatArray[i] != retArray[i]) {
+ failed = true;
+ break;
+ }
+}
+if (failed)
+ testFailed("The returned array buffer fails to match original data");
+else
+ testPassed("The returned array buffer matches original data");
+
+debug("Test that getBufferSubData fails when given a buffer with its size larger than the original data");
+var extraLargeBuffer = new Uint8Array(vertices.length * Float32Array.BYTES_PER_ELEMENT + 1);
+gl.getBufferSubData(gl.ARRAY_BUFFER, 0, extraLargeBuffer);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, extraLargeBuffer) with extra length should generate INVALID_VALUE");
+
+debug("Test that getBufferSubData fails when offset summed with buffer length is larger than the size of the original data size");
+gl.getBufferSubData(gl.ARRAY_BUFFER, vertices.length * Float32Array.BYTES_PER_ELEMENT + 1, retArray);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, vertices.length * Float32Array.BYTES_PER_ELEMENT + 1, arrBuffer) with offset larger than original data size should generate INVALID_VALUE");
+gl.getBufferSubData(gl.ARRAY_BUFFER, 1, retArray);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 1, arrBuffer) with offset and length larger than buffer size should generate INVALID_VALUE");
+
+debug("Test that getBufferSubData fails when 0 is bound to the target");
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+gl.getBufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, retArray);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "gl.getBufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, arrBuffer) should generate INVALID_OPERATION");
+
+debug("Test that getBufferSubData fails when offset is less than 0");
+gl.getBufferSubData(gl.ARRAY_BUFFER, -1, retArray);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, -1, arrBuffer) should generate INVALID_VALUE");
+
+finishTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html
new file mode 100644
index 000000000..5265e1dbf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html
@@ -0,0 +1,152 @@
+<!--
+
+/*
+** Copyright (c) 2016 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 Uniform Buffers Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/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 id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 position;
+void main()
+{
+ gl_Position = position;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform uni {
+ vec4 color;
+};
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = color;
+}
+</script>
+<script>
+"use strict";
+description("This test covers an ANGLE bug when using a large uniform block data store. ANGLE would confuse an internal clipped uniform buffer size and produce an assert or error.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var quadVB;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ debug("");
+ debug("Testing uniform block with large data store");
+ runTest();
+}
+
+function getQuadVerts(depth) {
+ var quadVerts = new Float32Array(3 * 6);
+ quadVerts[0] = -1.0; quadVerts[1] = 1.0; quadVerts[2] = depth;
+ quadVerts[3] = -1.0; quadVerts[4] = -1.0; quadVerts[5] = depth;
+ quadVerts[6] = 1.0; quadVerts[7] = -1.0; quadVerts[8] = depth;
+ quadVerts[9] = -1.0; quadVerts[10] = 1.0; quadVerts[11] = depth;
+ quadVerts[12] = 1.0; quadVerts[13] = -1.0; quadVerts[14] = depth;
+ quadVerts[15] = 1.0; quadVerts[16] = 1.0; quadVerts[17] = depth;
+ return quadVerts;
+}
+
+function drawQuad(depth) {
+ if (!quadVB) {
+ quadVB = gl.createBuffer()
+ }
+
+ var quadVerts = getQuadVerts(depth);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, quadVB);
+ gl.bufferData(gl.ARRAY_BUFFER, quadVerts, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, 0);
+ gl.enableVertexAttribArray(0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+}
+
+function runTest() {
+
+ // Create the program
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["position"]);
+ if (!program) {
+ testFailed("Failed to set up the program");
+ return;
+ }
+
+ // Init uniform buffer. To trigger the bug, it's necessary to use the
+ // DYNAMIC_DRAW usage. This makes ANGLE attempt to map the buffer internally
+ // with an incorrect copy size.
+ var ubo = gl.createBuffer();
+ var big_size = 4096 * 64;
+ var data = new Float32Array([0.5, 0.75, 0.25, 1.0]);
+ gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
+ gl.bufferData(gl.UNIFORM_BUFFER, big_size, gl.DYNAMIC_DRAW);
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
+
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, ubo);
+ var buffer_index = gl.getUniformBlockIndex(program, "uni");
+ if (buffer_index == -1) {
+ testFailed("Failed to get uniform block index");
+ return;
+ }
+ gl.uniformBlockBinding(program, buffer_index, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up uniform block should succeed");
+
+ // Draw the quad
+ gl.useProgram(program);
+ drawQuad(0.5);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw with uniform block should succeed");
+
+ // Verify the output color
+ var color = [127, 191, 64, 255];
+ wtu.checkCanvas(gl, color, "canvas should be same as input uniform", 1);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html
new file mode 100644
index 000000000..8fc8db756
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html
@@ -0,0 +1,428 @@
+<!--
+
+/*
+** Copyright (c) 2015 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 Uniform Buffers Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id='vshader' type='x-shader/x-vertex'>#version 300 es
+layout(location=0) in vec3 p;
+void main()
+{
+ gl_Position = vec4(p.xyz, 1.0);
+}
+</script>
+<script id='fbadshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float UBORed;
+ float UBOGreen;
+ float UBOBlue;
+};
+
+uniform Color {
+ float Red;
+ float UBOGreen;
+ float Blue;
+};
+
+void main()
+{
+ oColor = vec4(UBORed * Red, UBOGreen * UBOGreen, UBOBlue * Blue, 1.0);
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float UBORed;
+ float UBOGreen;
+ float UBOBlue;
+};
+
+uniform UBOD {
+ float UBOR;
+ float UBOG;
+ float UBOB;
+};
+
+void main()
+{
+ oColor = vec4(UBORed * UBOR, UBOGreen * UBOG, UBOBlue * UBOB, 1.0);
+}
+</script>
+<script id='fshadernamed' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float Red;
+ float Green;
+ float Blue;
+} UBOA;
+
+void main()
+{
+ oColor = vec4(UBOA.Red, UBOA.Green, UBOA.Blue, 1.0);
+}
+</script>
+<script id='fshadernamedarray' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float Red;
+ float Green;
+ float Blue;
+} UBOA[2];
+
+void main()
+{
+ oColor = vec4((UBOA[0].Red + UBOA[1].Red) / 2.0,
+ (UBOA[0].Green + UBOA[1].Green) / 2.0,
+ (UBOA[0].Blue + UBOA[1].Blue) / 2.0, 1.0);
+}
+</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 Uniform Buffer objects");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var b1 = null;
+var b2 = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runBindingTest();
+ runDrawTest();
+ runNamedDrawTest();
+ runNamedArrayDrawTest();
+}
+
+function runBindingTest() {
+ debug("");
+ debug("Testing uniform buffer binding behavior");
+ shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "UNIFORM_BUFFER_BINDING query should succeed");
+
+ debug("Testing basic uniform buffer binding and unbinding");
+ b1 = gl.createBuffer();
+ b2 = gl.createBuffer();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "createBuffer should not set an error");
+ shouldBeNonNull("b1");
+ shouldBeNonNull("b2");
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to bind uniform buffer");
+ shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "b1");
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to update uniform buffer binding");
+ shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "b2");
+ gl.bindBuffer(gl.UNIFORM_BUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to unbind uniform buffer");
+
+ debug("Testing deleting uniform buffers");
+ gl.deleteBuffer(b1);
+ gl.deleteBuffer(b2);
+ shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+
+ // Shouldn't be able to bind a deleted buffer.
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "binding a deleted buffer should generate INVALID_OPERATION");
+ shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+}
+
+function runDrawTest() {
+ debug("");
+ debug("Testing drawing with uniform buffers");
+
+ wtu.setupUnitQuad(gl);
+
+ var testProgram = wtu.setupProgram(gl, ['vshader', 'fbadshader']);
+ if (testProgram) {
+ testFailed("To define the same uniform in two uniform blocks should fail");
+ } else {
+ testPassed("To define the same uniform in two uniform blocks should fail");
+ }
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ if (!program) {
+ testFailed("Could not compile shader with uniform blocks without error");
+ return;
+ }
+
+ var blockIndex_1 = gl.getUniformBlockIndex(program, "UBOData");
+ var blockSize_1 = gl.getActiveUniformBlockParameter(program, blockIndex_1, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices_1 = gl.getUniformIndices(program, ["UBORed", "UBOGreen", "UBOBlue"]);
+ var uniformOffsets_1 = gl.getActiveUniforms(program, uniformIndices_1, gl.UNIFORM_OFFSET);
+ var blockIndex_2 = gl.getUniformBlockIndex(program, "UBOD");
+ var blockSize_2 = gl.getActiveUniformBlockParameter(program, blockIndex_2, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices_2 = gl.getUniformIndices(program, ["UBOR", "UBOG", "UBOB"]);
+ var uniformOffsets_2 = gl.getActiveUniforms(program, uniformIndices_2, gl.UNIFORM_OFFSET);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block information without error");
+
+ if (uniformOffsets_1.length < 3 || uniformOffsets_2.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ // Verify that the uniform offsets are aligned on 4-byte boundries
+ // While unaligned values are allowed by the ES3 spec it would be *really* weird for anyone to actually do that.
+ if (uniformOffsets_1[0] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets_1[0] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets_1[1] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets_1[1] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets_1[2] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets_1[2] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets_2[0] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets_2[0] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets_2[1] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets_2[1] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets_2[2] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets_2[2] / Float32Array.BYTES_PER_ELEMENT)) {
+ testFailed("Uniform offsets are not well aligned");
+ return;
+ }
+
+ var uboArray_1 = new ArrayBuffer(blockSize_1);
+ var uboFloatView_1 = new Float32Array(uboArray_1);
+ uboFloatView_1[uniformOffsets_1[0] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // UBORed
+ uboFloatView_1[uniformOffsets_1[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // UBOGreen
+ uboFloatView_1[uniformOffsets_1[2] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // UBOBlue
+ var uboArray_2 = new ArrayBuffer(blockSize_2);
+ var uboFloatView_2 = new Float32Array(uboArray_2);
+ uboFloatView_2[uniformOffsets_2[0] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // UBOR
+ uboFloatView_2[uniformOffsets_2[1] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // UBOG
+ uboFloatView_2[uniformOffsets_2[2] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // UBOB
+
+ var b_1 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b_1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboFloatView_1, gl.DYNAMIC_DRAW);
+ var b_2 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b_2);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboFloatView_2, gl.DYNAMIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to set UBO data with no errors");
+
+ var bindings = [1, 2];
+ gl.uniformBlockBinding(program, blockIndex_1, bindings[0]);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, bindings[0], b_1);
+ gl.uniformBlockBinding(program, blockIndex_2, bindings[1]);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, bindings[1], b_2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferBase without errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+
+ debug("Changing the data in the uniform buffer should automatically update the uniforms exposed to the draw call");
+ uboFloatView_1[uniformOffsets_1[0] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // UBORed
+ uboFloatView_1[uniformOffsets_1[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // UBOGreen
+ uboFloatView_1[uniformOffsets_1[2] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // UBOBlue
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b_1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboFloatView_1, gl.DYNAMIC_DRAW);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 0, 255, 255], "draw call should set canvas to blue", 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runNamedDrawTest() {
+ debug("");
+ debug("Testing drawing with named uniform buffers");
+
+ wtu.setupUnitQuad(gl);
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshadernamed']);
+ if (!program) {
+ testFailed("Could not compile shader with named uniform blocks without error");
+ }
+
+ var blockIndex = gl.getUniformBlockIndex(program, "UBOData");
+ var blockSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices = gl.getUniformIndices(program, ["UBOData.Red", "UBOData.Green", "UBOData.Blue"]);
+ var uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block information without error");
+
+ if (uniformOffsets.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ // Verify that the uniform offsets are aligned on 4-byte boundries
+ // While unaligned values are allowed by the ES3 spec it would be *really* weird for anyone to actually do that.
+ if (uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT)) {
+ testFailed("Uniform offsets are not well aligned");
+ return;
+ }
+
+ var uboArray = new ArrayBuffer(blockSize);
+ var uboFloatView = new Float32Array(uboArray);
+ uboFloatView[uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // Red
+ uboFloatView[uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Green
+ uboFloatView[uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Blue
+
+ b1 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to set UBO data with no errors");
+
+ var binding = 3;
+ gl.uniformBlockBinding(program, blockIndex, binding);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, binding, b1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferBase without errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+
+ debug("Changing the data in the uniform buffer should automatically update the uniforms exposed to the draw call");
+ uboFloatView[uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Red
+ uboFloatView[uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Green
+ uboFloatView[uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // Blue
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 0, 255, 255], "draw call should set canvas to blue", 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runNamedArrayDrawTest() {
+ debug("");
+ debug("Testing drawing with named uniform buffer arrays");
+
+ wtu.setupUnitQuad(gl);
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshadernamedarray']);
+ if (!program) {
+ testFailed("could not compile shader with named uniform block arrays without error");
+ return;
+ }
+
+ var blockIndex = [gl.getUniformBlockIndex(program, "UBOData[0]"),
+ gl.getUniformBlockIndex(program, "UBOData[1]")];
+ if (blockIndex[0] == gl.INVALID_INDEX ||
+ blockIndex[1] == gl.INVALID_INDEX) {
+ testFailed("Could not query uniform block index");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block indices without error");
+ var blockSize = [gl.getActiveUniformBlockParameter(program, blockIndex[0], gl.UNIFORM_BLOCK_DATA_SIZE),
+ gl.getActiveUniformBlockParameter(program, blockIndex[1], gl.UNIFORM_BLOCK_DATA_SIZE)];
+ if (blockSize[0] != blockSize[1]) {
+ testFailed("uniform block instance array with different block sizes");
+ }
+ var uniformIndices = gl.getUniformIndices(program, ["UBOData.Red", "UBOData.Green", "UBOData.Blue"]);
+ if (uniformIndices < 3 ||
+ uniformIndices[0] == gl.INVALID_INDEX ||
+ uniformIndices[1] == gl.INVALID_INDEX ||
+ uniformIndices[2] == gl.INVALID_INDEX) {
+ testFailed("Could not query uniform indices");
+ return;
+ }
+ var uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block information without error");
+ if (uniformOffsets.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ var offsetAlignment = gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+ var offset = Math.ceil(blockSize[0] / offsetAlignment) * offsetAlignment;
+ // Verify that the uniform offsets are aligned on 4-byte boundries
+ // While unaligned values are allowed by the ES3 spec it would be *really* weird for anyone to actually do that.
+ if (offset / Float32Array.BYTES_PER_ELEMENT != Math.floor(offset / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT) ||
+ uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT != Math.floor(uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT)) {
+ testFailed("Uniform offsets are not well aligned");
+ return;
+ }
+ var bufferSize = offset + blockSize[1];
+ var uboArray = new ArrayBuffer(bufferSize);
+ var uboFloatView = new Float32Array(uboArray);
+ uboFloatView[uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // Red
+ uboFloatView[uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Green
+ uboFloatView[uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Blue
+ uboFloatView[offset / Float32Array.BYTES_PER_ELEMENT +
+ uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Red
+ uboFloatView[offset / Float32Array.BYTES_PER_ELEMENT +
+ uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Green
+ uboFloatView[offset / Float32Array.BYTES_PER_ELEMENT +
+ uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // Blue
+
+ b1 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to set UBO data with no errors");
+
+ var bindings = [4, 5];
+ gl.uniformBlockBinding(program, blockIndex[0], bindings[0]);
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, bindings[0], b1, 0, blockSize[0]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferRange without errors");
+ gl.uniformBlockBinding(program, blockIndex[1], bindings[1]);
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, bindings[1], b1, offset, blockSize[1]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferRange without errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [127, 0, 127, 255], "draw call should set canvas to (0.5, 0, 0.5)", 2);
+
+ debug("Changing the data in the uniform buffer should automatically update the uniforms exposed to the draw call");
+ uboFloatView[uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Red
+ uboFloatView[uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // Green
+ uboFloatView[uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // Blue
+ uboFloatView[offset / Float32Array.BYTES_PER_ELEMENT +
+ uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Red
+ uboFloatView[offset / Float32Array.BYTES_PER_ELEMENT +
+ uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // Green
+ uboFloatView[offset / Float32Array.BYTES_PER_ELEMENT +
+ uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // Blue
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 127, 255, 255], "draw call should set canvas to (0, 0.5, 1)", 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>