2 Copyright (c) 2019 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
10 <meta charset=
"utf-8">
11 <title>WebGL2 getBufferSubData validity tests
</title>
12 <link rel=
"stylesheet" href=
"../../resources/js-test-style.css"/>
13 <script src=
"../../js/js-test-pre.js"></script>
14 <script src=
"../../js/webgl-test-utils.js"> </script>
17 <div id=
"description"></div>
18 <div id=
"console"></div>
20 <script id=
"vshader" type=
"x-shader/x-vertex">#version
300 es
22 flat out uint out_data;
27 <script id=
"fshader" type=
"x-shader/x-fragment">#version
300 es
33 description("Test that getBufferSubData returns valid data in edge cases");
35 var wtu
= WebGLTestUtils
;
37 var gl
= wtu
.create3DContext(undefined, undefined, 2);
39 const srcData
= new Uint8Array([ 1, 2, 3, 4, 5, 6, 7, 8 ]);
40 const noData
= new Uint8Array(8);
42 const srcBuffer
= gl
.createBuffer();
43 gl
.bindBuffer(gl
.COPY_READ_BUFFER
, srcBuffer
);
44 gl
.bufferData(gl
.COPY_READ_BUFFER
, srcData
, gl
.STATIC_DRAW
);
46 const badBuffer
= gl
.createBuffer();
47 gl
.bindBuffer(gl
.ARRAY_BUFFER
, badBuffer
);
48 gl
.bufferData(gl
.ARRAY_BUFFER
, 8, gl
.STATIC_DRAW
);
51 function deleteReadbackBuffer() {
52 gl
.deleteBuffer(readbackBuffer
);
54 function recreateReadbackBuffer() {
55 readbackBuffer
= gl
.createBuffer();
56 gl
.bindBuffer(gl
.COPY_WRITE_BUFFER
, readbackBuffer
);
57 gl
.bufferData(gl
.COPY_WRITE_BUFFER
, 8, gl
.STREAM_READ
);
59 recreateReadbackBuffer();
61 const dest
= new Uint8Array(8);
63 // Makes a new "resolvable" Promise
64 function resolvable() {
66 const promise
= new Promise(res
=> { resolve
= res
; });
67 promise
.resolve
= resolve
;
72 return new Promise(res
=> {
77 async
function fence() {
78 const sync
= gl
.fenceSync(gl
.SYNC_GPU_COMMANDS_COMPLETE
, 0);
84 status
= gl
.clientWaitSync(sync
, 0, 0);
85 } while (status
!= gl
.ALREADY_SIGNALED
&& status
!= gl
.CONDITION_SATISFIED
);
89 function checkGetBufferSubData(err
, data
) {
91 wtu
.shouldGenerateGLError(gl
, err
, "gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)");
93 shouldBeTrue(`areArraysEqual(dest, ${data})`);
97 const tfProgram
= wtu
.setupTransformFeedbackProgram(gl
, ["vshader", "fshader"],
98 ["out_data"], gl
.SEPARATE_ATTRIBS
,
100 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "linking transform feedback shader should not set an error");
101 shouldBeNonNull("tfProgram");
102 const tf
= gl
.createTransformFeedback();
104 function copyBufferUsingTransformFeedback(src
, dst
) {
105 gl
.enableVertexAttribArray(0);
106 gl
.bindBuffer(gl
.ARRAY_BUFFER
, src
);
107 gl
.vertexAttribIPointer(0, 1, gl
.UNSIGNED_INT
, 0, 0);
109 gl
.bindTransformFeedback(gl
.TRANSFORM_FEEDBACK
, tf
);
110 gl
.bindBufferBase(gl
.TRANSFORM_FEEDBACK_BUFFER
, 0, dst
);
112 gl
.drawBuffers([gl
.NONE
]);
114 gl
.enable(gl
.RASTERIZER_DISCARD
);
115 gl
.beginTransformFeedback(gl
.POINTS
);
116 // treats the input and output data as two uint32s
117 gl
.drawArrays(gl
.POINTS
, 0, 2);
118 gl
.endTransformFeedback();
119 gl
.disable(gl
.RASTERIZER_DISCARD
);
121 gl
.bindBuffer(gl
.ARRAY_BUFFER
, badBuffer
);
122 gl
.bindBufferBase(gl
.TRANSFORM_FEEDBACK_BUFFER
, 0, null);
123 gl
.bindTransformFeedback(gl
.TRANSFORM_FEEDBACK
, null);
129 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
130 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
133 debug("fence-wait-write-read");
135 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
136 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
139 debug("write-read-fence-wait");
140 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
141 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
145 debug("write-fence-fence-wait-read");
146 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
149 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
152 debug("write-fence-wait-read");
153 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
155 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
158 debug("write-fence-wait-write-read");
159 gl
.copyBufferSubData(gl
.ARRAY_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
161 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
162 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
165 debug("write-fence-write-wait-read");
166 gl
.copyBufferSubData(gl
.ARRAY_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
169 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
172 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
175 debug("write-fence-transformfeedback-wait-read");
176 gl
.copyBufferSubData(gl
.ARRAY_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
179 gl
.bindBuffer(gl
.COPY_WRITE_BUFFER
, null);
180 copyBufferUsingTransformFeedback(srcBuffer
, readbackBuffer
);
181 gl
.bindBuffer(gl
.COPY_WRITE_BUFFER
, readbackBuffer
);
184 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
187 debug("write-unbind-fence-wait-bind-read");
188 gl
.bindBuffer(gl
.COPY_WRITE_BUFFER
, null);
189 gl
.bindBuffer(gl
.ARRAY_BUFFER
, readbackBuffer
);
190 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.ARRAY_BUFFER
, 0, 0, 8);
191 gl
.bindBuffer(gl
.ARRAY_BUFFER
, badBuffer
);
193 gl
.bindBuffer(gl
.COPY_WRITE_BUFFER
, readbackBuffer
);
194 checkGetBufferSubData(gl
.NO_ERROR
, "srcData");
197 debug("write-fence-wait-delete-read");
198 gl
.copyBufferSubData(gl
.ARRAY_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
200 deleteReadbackBuffer();
201 checkGetBufferSubData(gl
.INVALID_OPERATION
, "noData");
202 recreateReadbackBuffer();
205 debug("write-fence-delete-wait-read");
206 gl
.copyBufferSubData(gl
.ARRAY_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
209 deleteReadbackBuffer();
212 checkGetBufferSubData(gl
.INVALID_OPERATION
, "noData");
213 recreateReadbackBuffer();
216 debug("write-fence-delete-wait-read");
217 gl
.copyBufferSubData(gl
.ARRAY_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
218 deleteReadbackBuffer();
220 checkGetBufferSubData(gl
.INVALID_OPERATION
, "noData");
221 recreateReadbackBuffer();
226 debug("write-delete-recreate-fence-wait-read");
227 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
228 deleteReadbackBuffer();
229 recreateReadbackBuffer();
231 checkGetBufferSubData(gl
.NO_ERROR
, "noData");
234 debug("write-delete-fence-wait-read");
235 gl
.copyBufferSubData(gl
.COPY_READ_BUFFER
, gl
.COPY_WRITE_BUFFER
, 0, 0, 8);
238 deleteReadbackBuffer();
241 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
247 var successfullyParsed
= true;