Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / transform_feedback / too-small-buffers.html
blob64acfbad7bd5a287d006eb30f0aa8358009d1fb0
1 <!--
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.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <title>TF too small buffers</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>
15 </head>
16 <body>
17 <div id="description"></div>
18 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
19 <div id="console"></div>
20 <script id="vshader" type="x-shader/x-vertex">#version 300 es
21 in float in_value1;
22 in float in_value2;
23 out float out_value1;
24 out float out_value2;
25 void main() {
26 out_value1 = in_value1 * 2.;
27 out_value2 = in_value2 * 2.;
29 </script>
30 <script id="fshader" type="x-shader/x-fragment">#version 300 es
31 precision mediump float;
32 out vec4 dummy;
33 void main() {
34 dummy = vec4(0.);
36 </script>
37 <script>
38 "use strict";
39 description("Transform feedback into buffers that are too small should produce errors.");
41 var wtu = WebGLTestUtils;
42 var canvas = document.getElementById("canvas");
43 var gl = wtu.create3DContext(canvas, null, 2);
45 if (!gl) {
46 testFailed("WebGL context does not exist");
47 } else {
48 testPassed("WebGL context exists");
51 const progInterleaved = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
52 ["out_value1", "out_value2"], gl.INTERLEAVED_ATTRIBS,
53 ["in_value1", "in_value2"]);
54 const progSeparate = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
55 ["out_value1", "out_value2"], gl.SEPARATE_ATTRIBS,
56 ["in_value1", "in_value2"]);
57 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "program compilation");
59 // Attrib 1 contains 4 vertices. Attrib 2 contains 4 instance indices.
60 const vertexBuffer0 = gl.createBuffer();
61 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
62 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), gl.STATIC_DRAW);
63 const vertexBuffer1 = gl.createBuffer();
64 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
65 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), gl.STATIC_DRAW);
66 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
67 gl.enableVertexAttribArray(0);
68 gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
69 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
70 gl.enableVertexAttribArray(1);
71 gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
72 gl.vertexAttribDivisor(1, 1);
74 let tfBuffer0 = gl.createBuffer();
75 let tfBuffer1 = gl.createBuffer();
77 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup");
79 const sizeOfFloat = 4;
81 let cases = [
82 { name: "drawArrays",
83 drawFunction: ()=>gl.drawArrays(gl.POINTS, 0, 4),
84 result: [[2, 4, 6, 8], [2, 2, 2, 2]]},
85 { name: "drawArraysInstanced one instance",
86 drawFunction: ()=>gl.drawArraysInstanced(gl.POINTS, 0, 4, 1),
87 result: [[2, 4, 6, 8], [2, 2, 2, 2]]},
88 { name: "drawArraysInstanced four instances",
89 drawFunction: ()=>gl.drawArraysInstanced(gl.POINTS, 0, 1, 4),
90 result: [[2, 2, 2, 2], [2, 4, 6, 8]]},
93 for (let {name, drawFunction, result} of cases) {
94 debug("<h1>" + name + "</h1>")
96 let interleavedResult = [];
97 for (let i = 0; i < result[0].length; i++) {
98 interleavedResult.push(result[0][i], result[1][i]);
101 let doTransformFeedback = (drawFunction, error) => {
102 gl.beginTransformFeedback(gl.POINTS);
103 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "before draw");
104 drawFunction();
105 wtu.glErrorShouldBe(gl, error, "draw");
106 gl.endTransformFeedback();
109 gl.useProgram(progInterleaved);
111 debug("<h3>interleaved - Baseline success case</h3>")
112 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
113 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat, gl.STREAM_READ);
114 doTransformFeedback(drawFunction, gl.NO_ERROR);
115 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult);
117 debug("<h3>interleaved - Buffer too small</h3>")
118 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat-1, gl.STREAM_READ);
119 doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
120 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
121 [0, 0, 0, 0, 0, 0, 0]);
123 debug("<h3>interleaved - Multiple draws success case</h3>")
124 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
125 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat*2, gl.STREAM_READ);
126 doTransformFeedback(()=>{drawFunction(); drawFunction()}, gl.NO_ERROR);
127 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult.concat(interleavedResult))
129 debug("<h3>interleaved - Too small for multiple draws</h3>")
130 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
131 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat*2-1, gl.STREAM_READ);
132 doTransformFeedback(()=>{drawFunction(); drawFunction()}, gl.INVALID_OPERATION);
133 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult.concat([0, 0, 0, 0, 0, 0, 0]))
135 debug("<h3>interleaved - bindBufferRange too small</h3>")
136 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat, gl.STREAM_READ);
137 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0, 0, 7*sizeOfFloat);
138 doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
139 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
140 [0, 0, 0, 0, 0, 0, 0, 0]);
142 debug("<h3>interleaved - bindBufferRange larger than buffer</h3>")
143 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat-1, gl.STREAM_READ);
144 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0, 0, 8*sizeOfFloat);
145 doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
146 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
147 [0, 0, 0, 0, 0, 0, 0]);
149 gl.useProgram(progSeparate);
151 debug("<h3>separate - Baseline success case</h3>")
152 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
153 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
154 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
155 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
156 doTransformFeedback(drawFunction, gl.NO_ERROR);
157 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
158 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0]);
159 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
160 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1]);
162 debug("<h3>separate - Buffer too small</h3>")
163 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
164 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
165 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
166 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat-1, gl.STREAM_READ);
167 doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
168 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
169 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
170 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
171 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
173 debug("<h3>separate - multiple draws success case</h3>")
174 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
175 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
176 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
177 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
178 doTransformFeedback(()=>{drawFunction(); drawFunction();}, gl.NO_ERROR);
179 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
180 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0].concat(result[0]));
181 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
182 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1].concat(result[1]));
184 debug("<h3>separate - Too small for multiple draws</h3>")
185 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
186 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
187 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
188 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2-1, gl.STREAM_READ);
189 doTransformFeedback(()=>{drawFunction(); drawFunction();}, gl.INVALID_OPERATION);
190 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
191 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0].concat([0, 0, 0, 0]));
192 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
193 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1].concat([0, 0, 0]));
195 debug("<h3>separate - bindBufferRange too small</h3>")
196 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
197 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
198 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1, 0, 3*sizeOfFloat);
199 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
200 doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
201 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
202 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
203 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
204 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
206 debug("<h3>separate - bindBufferRange larger than buffer</h3>")
207 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
208 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
209 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1, 0, 4*sizeOfFloat);
210 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat-1, gl.STREAM_READ);
211 doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
212 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
213 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
214 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
215 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
218 debug("<h1>integer overflow</h1>")
220 gl.useProgram(progInterleaved);
221 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
222 gl.bufferData(gl.ARRAY_BUFFER, (1<<16)*sizeOfFloat, gl.STREAM_READ);
223 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
224 gl.bufferData(gl.ARRAY_BUFFER, (1<<16)*sizeOfFloat, gl.STREAM_READ);
225 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
226 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, (1<<16)*sizeOfFloat*2, gl.STREAM_READ);
228 gl.beginTransformFeedback(gl.POINTS);
229 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "before draw");
230 // If count and primcount are stored in 32-bit signed integers and then
231 // multiplied to calculate the number of transform feedback vertices, the
232 // calculation will overflow to 0.
233 gl.drawArraysInstanced(gl.POINTS, 0, 1<<16, 1<<16);
234 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "integer overflow and/or buffer too small");
235 gl.endTransformFeedback();
237 finishTest();
239 </script>
241 </body>
242 </html>