summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html250
1 files changed, 250 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html
new file mode 100644
index 0000000000..06ce2ecb5a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html
@@ -0,0 +1,250 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 getBufferSubData validity 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>
+<div id="console"></div>
+
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in uint in_data;
+flat out uint out_data;
+void main() {
+ out_data = in_data;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+void main() {}
+</script>
+
+<script>
+"use strict";
+description("Test that getBufferSubData returns valid data in edge cases");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+const srcData = new Uint8Array([ 1, 2, 3, 4, 5, 6, 7, 8 ]);
+const noData = new Uint8Array(8);
+
+const srcBuffer = gl.createBuffer();
+gl.bindBuffer(gl.COPY_READ_BUFFER, srcBuffer);
+gl.bufferData(gl.COPY_READ_BUFFER, srcData, gl.STATIC_DRAW);
+
+const badBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, badBuffer);
+gl.bufferData(gl.ARRAY_BUFFER, 8, gl.STATIC_DRAW);
+
+let readbackBuffer;
+function deleteReadbackBuffer() {
+ gl.deleteBuffer(readbackBuffer);
+}
+function recreateReadbackBuffer() {
+ readbackBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
+ gl.bufferData(gl.COPY_WRITE_BUFFER, 8, gl.STREAM_READ);
+}
+recreateReadbackBuffer();
+
+const dest = new Uint8Array(8);
+
+// Makes a new "resolvable" Promise
+function resolvable() {
+ let resolve;
+ const promise = new Promise(res => { resolve = res; });
+ promise.resolve = resolve;
+ return promise;
+}
+
+function wait() {
+ return new Promise(res => {
+ setTimeout(res, 0);
+ });
+}
+
+async function fence() {
+ const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ gl.flush();
+
+ let status;
+ do {
+ await wait();
+ status = gl.clientWaitSync(sync, 0, 0);
+ } while (status != gl.ALREADY_SIGNALED && status != gl.CONDITION_SATISFIED);
+ gl.deleteSync(sync);
+}
+
+function checkGetBufferSubData(err, data) {
+ dest.fill(0);
+ wtu.shouldGenerateGLError(gl, err, "gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)");
+ if (!err) {
+ shouldBeTrue(`areArraysEqual(dest, ${data})`);
+ }
+}
+
+const tfProgram = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_data"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+shouldBeNonNull("tfProgram");
+const tf = gl.createTransformFeedback();
+
+function copyBufferUsingTransformFeedback(src, dst) {
+ gl.enableVertexAttribArray(0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, src);
+ gl.vertexAttribIPointer(0, 1, gl.UNSIGNED_INT, 0, 0);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, dst);
+
+ gl.drawBuffers([gl.NONE]);
+
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.beginTransformFeedback(gl.POINTS);
+ // treats the input and output data as two uint32s
+ gl.drawArrays(gl.POINTS, 0, 2);
+ gl.endTransformFeedback();
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, badBuffer);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+}
+
+(async () => {
+ debug("");
+ debug("write-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("fence-wait-write-read");
+ await fence();
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-read-fence-wait");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+ await fence();
+
+ debug("");
+ debug("write-fence-fence-wait-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ fence(); // no await
+ await fence();
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-wait-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ await fence();
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-wait-write-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ await fence();
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-write-wait-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ {
+ const p = fence();
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ await p;
+ }
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-transformfeedback-wait-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ {
+ const p = fence();
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
+ copyBufferUsingTransformFeedback(srcBuffer, readbackBuffer);
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
+ await p;
+ }
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-unbind-fence-wait-bind-read");
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
+ gl.bindBuffer(gl.ARRAY_BUFFER, readbackBuffer);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.ARRAY_BUFFER, 0, 0, 8);
+ gl.bindBuffer(gl.ARRAY_BUFFER, badBuffer);
+ await fence();
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-wait-delete-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ await fence();
+ deleteReadbackBuffer();
+ checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
+ recreateReadbackBuffer();
+
+ debug("");
+ debug("write-fence-delete-wait-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ {
+ const p = fence();
+ deleteReadbackBuffer();
+ await p;
+ }
+ checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
+ recreateReadbackBuffer();
+
+ debug("");
+ debug("write-fence-delete-wait-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ deleteReadbackBuffer();
+ await fence();
+ checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
+ recreateReadbackBuffer();
+
+ // crbug.com/941930
+ {
+ debug("");
+ debug("write-delete-recreate-fence-wait-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ deleteReadbackBuffer();
+ recreateReadbackBuffer();
+ await fence();
+ checkGetBufferSubData(gl.NO_ERROR, "noData");
+
+ debug("");
+ debug("write-delete-fence-wait-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ {
+ const p = fence();
+ deleteReadbackBuffer();
+ await p;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+
+ finishTest();
+})();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>