Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / extensions / ext-disjoint-timer-query-webgl2.html
blobf1e9a82d8af26a6fc6ea7f9595b3805bc9a05464
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>WebGL 2 EXT_disjoint_timer_query_webgl2 Conformance 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>
15 </head>
16 <body>
17 <div id="description"></div>
18 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
19 <div id="console"></div>
21 <script>
22 "use strict";
23 description("This test verifies the functionality of the EXT_disjoint_timer_query_webgl2 extension, if it is available.");
25 var wtu = WebGLTestUtils;
26 var canvas = document.getElementById("canvas");
27 var gl = wtu.create3DContext(canvas, null, 2);
28 var gl2 = null;
29 var ext = null;
30 var ext2 = null;
31 var query = null;
32 var query2 = null;
33 var elapsed_query = null;
34 var timestamp_query1 = null;
35 var timestamp_query2 = null;
36 var availability_retry = 500;
37 var timestamp_counter_bits = 0;
39 if (!gl) {
40 testFailed("WebGL context does not exist");
41 finishTest();
42 } else {
43 testPassed("WebGL context exists");
45 // Query the extension and store globally so shouldBe can access it
46 ext = wtu.getExtensionWithKnownPrefixes(gl, "EXT_disjoint_timer_query_webgl2");
47 if (!ext) {
48 testPassed("No EXT_disjoint_timer_query_webgl2 support -- this is legal");
49 finishTest();
50 } else {
51 runSanityTests();
52 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
54 // Clear disjoint value.
55 gl.getParameter(ext.GPU_DISJOINT_EXT);
56 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
58 runElapsedTimeTest();
59 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
61 timestamp_counter_bits = gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT);
62 if (timestamp_counter_bits > 0) {
63 runTimeStampTest();
64 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
66 verifyQueryResultsNotAvailable();
67 verifyDeleteQueryBehavior();
68 verifyDeleteQueryErrorBehavior();
69 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
71 window.requestAnimationFrame(checkQueryResults);
75 function runSanityTests() {
76 debug("");
77 debug("Testing other query types");
78 query = gl.createQuery();
79 gl.beginQuery(gl.ANY_SAMPLES_PASSED, query);
80 shouldBeTrue("gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY) !== null");
81 gl.endQuery(gl.ANY_SAMPLES_PASSED);
82 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "enabling EXT_disjoint_timer_query_webgl2 should not break other queries");
84 debug("");
85 debug("Testing timer query expectations");
87 shouldBe("ext.QUERY_COUNTER_BITS_EXT", "0x8864");
88 shouldBe("ext.TIME_ELAPSED_EXT", "0x88BF");
89 shouldBe("ext.TIMESTAMP_EXT", "0x8E28");
90 shouldBe("ext.GPU_DISJOINT_EXT", "0x8FBB");
92 shouldBe("gl.isQuery(null)", "false");
94 shouldBeTrue("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY) === null");
95 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
96 shouldBeTrue("gl.getQuery(ext.TIME_ELAPSED_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30");
97 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
99 shouldBeTrue("gl.getQuery(ext.TIMESTAMP_EXT, gl.CURRENT_QUERY) === null");
100 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
102 // Certain drivers set timestamp counter bits to 0 as they don't support timestamps
103 shouldBeTrue("gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30 || " +
104 "gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) === 0");
105 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
107 debug("");
108 debug("Testing time elapsed query lifecycle");
109 query = gl.createQuery();
110 shouldBe("gl.isQuery(query)", "false");
111 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query creation must succeed.");
112 gl.beginQuery(ext.TIMESTAMP_EXT, query);
113 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Beginning a timestamp query should fail.");
114 gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
115 shouldBe("gl.isQuery(query)", "true");
116 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Beginning an inactive time elapsed query should succeed.");
117 gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
118 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Attempting to begin an active query should fail.");
119 gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
120 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result availability of an active query should fail.");
121 gl.getQueryParameter(query, gl.QUERY_RESULT);
122 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result of an active query should fail.");
123 shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query");
124 gl.endQuery(ext.TIME_ELAPSED_EXT);
125 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Ending an active time elapsed query should succeed.");
126 gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
127 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Fetching query result availability after query end should succeed.");
128 gl.endQuery(ext.TIME_ELAPSED_EXT);
129 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Attempting to end an inactive query should fail.");
130 ext.queryCounterEXT(query, ext.TIMESTAMP_EXT);
131 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should not be able to use time elapsed query to store a timestamp.");
132 gl.deleteQuery(query);
133 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query deletion must succeed.");
134 gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
135 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Beginning a deleted query must fail.");
136 gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
137 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result availability after query deletion should fail.");
138 shouldBe("gl.isQuery(query)", "false");
140 debug("");
141 debug("Testing timestamp counter");
142 query = gl.createQuery();
143 shouldThrow("ext.queryCounterEXT(null, ext.TIMESTAMP_EXT)");
144 ext.queryCounterEXT(query, ext.TIMESTAMP_EXT);
145 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Timestamp counter queries should work.");
146 gl.deleteQuery(query);
147 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
149 debug("");
150 debug("Performing parameter sanity checks");
151 gl.getParameter(ext.TIMESTAMP_EXT);
152 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter timestamp calls should work.");
153 gl.getParameter(ext.GPU_DISJOINT_EXT);
154 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter disjoint calls should work.");
156 debug("");
157 debug("Testing current query conditions");
158 query = gl.createQuery();
159 query2 = gl.createQuery();
160 shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null");
161 gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
162 shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query");
163 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
165 debug("");
166 debug("Testing failed begin query should not change the current query.");
167 gl.beginQuery(ext.TIME_ELAPSED_EXT, query2);
168 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Beginning an elapsed query without ending should fail.");
169 shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query");
170 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
172 debug("");
173 debug("Testing beginning a timestamp query is invalid and should not change the elapsed query.");
174 gl.beginQuery(ext.TIMESTAMP_EXT, query2)
175 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM);
176 shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query");
177 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
179 debug("");
180 debug("Testing timestamp queries end immediately so are never current.");
181 ext.queryCounterEXT(query2, ext.TIMESTAMP_EXT);
182 shouldBe("gl.getQuery(ext.TIMESTAMP_EXT, gl.CURRENT_QUERY)", "null");
183 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
185 debug("");
186 debug("Testing ending the query should clear the current query.");
187 gl.endQuery(ext.TIME_ELAPSED_EXT);
188 shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null");
189 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
191 debug("");
192 debug("Testing beginning a elapsed query using a timestamp query should fail and not affect current query.")
193 gl.beginQuery(ext.TIME_ELAPSED_EXT, query2);
194 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Switching query targets should fail.");
195 shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null");
196 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
198 gl.deleteQuery(query);
199 gl.deleteQuery(query2);
201 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at end of sanity tests");
204 function runElapsedTimeTest() {
205 debug("");
206 debug("Testing elapsed time query");
208 elapsed_query = gl.createQuery();
209 gl.beginQuery(ext.TIME_ELAPSED_EXT, elapsed_query);
210 gl.clearColor(0, 0, 1, 1);
211 gl.clear(gl.COLOR_BUFFER_BIT);
212 gl.endQuery(ext.TIME_ELAPSED_EXT);
213 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Time elapsed query should have no errors");
216 function runTimeStampTest() {
217 debug("");
218 debug("Testing timestamp query");
220 timestamp_query1 = gl.createQuery();
221 timestamp_query2 = gl.createQuery();
222 ext.queryCounterEXT(timestamp_query1, ext.TIMESTAMP_EXT);
223 gl.clearColor(1, 0, 0, 1);
224 gl.clear(gl.COLOR_BUFFER_BIT);
225 ext.queryCounterEXT(timestamp_query2, ext.TIMESTAMP_EXT);
226 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Timestamp queries should have no errors");
229 function verifyQueryResultsNotAvailable() {
230 debug("");
231 debug("Verifying queries' results don't become available too early");
233 // Verify as best as possible that the implementation doesn't
234 // allow a query's result to become available the same frame, by
235 // spin-looping for some time and ensuring that none of the
236 // queries' results become available.
237 var startTime = Date.now();
238 while (Date.now() - startTime < 2000) {
239 gl.finish();
240 if (gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE)) {
241 testFailed("One of the queries' results became available too early");
242 return;
244 if (timestamp_counter_bits > 0) {
245 if (gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT_AVAILABLE) ||
246 gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE)) {
247 testFailed("One of the queries' results became available too early");
248 return;
253 testPassed("Queries' results didn't become available in a spin loop");
256 function verifyDeleteQueryBehavior() {
257 debug("");
258 debug("Testing deleting an active query should end it.");
260 // Use a new context for this test
261 gl2 = wtu.create3DContext(null, null, 2);
262 if (!gl2) return;
263 ext2 = gl2.getExtension("EXT_disjoint_timer_query_webgl2");
264 if (!ext2) return;
266 query = gl2.createQuery();
267 gl2.beginQuery(ext.TIME_ELAPSED_EXT, query);
268 wtu.glErrorShouldBe(gl2, gl2.NONE, "The query began successfully");
269 gl2.deleteQuery(query);
270 wtu.glErrorShouldBe(gl2, gl2.NONE, "Deletion of the active query succeeds");
271 shouldBeNull("gl2.getQuery(ext2.TIME_ELAPSED_EXT, gl2.CURRENT_QUERY)");
272 shouldBeFalse("gl2.isQuery(query)");
273 query = gl2.createQuery();
274 gl2.beginQuery(ext2.TIME_ELAPSED_EXT, query);
275 wtu.glErrorShouldBe(gl, gl2.NONE, "Beginning a new query succeeds");
276 gl2.endQuery(gl2.TIME_ELAPSED_EXT);
277 gl2.deleteQuery(query);
278 wtu.glErrorShouldBe(gl, gl.NONE);
279 query = null;
280 ext2 = null;
281 gl2 = null;
284 function verifyDeleteQueryErrorBehavior() {
285 debug("");
286 debug("Testing deleting a query created by another context.");
288 // Use new contexts for this test
289 gl2 = wtu.create3DContext(null, null, 2);
290 var gl3 = wtu.create3DContext(null, null, 2);
291 if (!gl2 || !gl3) return;
292 ext2 = gl2.getExtension("EXT_disjoint_timer_query_webgl2");
293 if (!ext2) return;
295 query = gl2.createQuery();
296 gl2.beginQuery(ext2.TIME_ELAPSED_EXT, query);
297 gl3.deleteQuery(query);
298 wtu.glErrorShouldBe(gl3, gl3.INVALID_OPERATION);
299 shouldBeTrue("gl2.isQuery(query)");
300 shouldBe("gl2.getQuery(ext2.TIME_ELAPSED_EXT, gl2.CURRENT_QUERY)", "query");
301 gl2.endQuery(ext2.TIME_ELAPSED_EXT);
302 gl2.deleteQuery(query);
303 wtu.glErrorShouldBe(gl2, gl2.NONE);
304 query = null;
305 ext2 = null;
306 gl2 = null;
307 gl3 = null;
310 function checkQueryResults() {
311 if (availability_retry > 0) {
312 // Make a reasonable attempt to wait for the queries' results to become available.
313 if (!gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE) ||
314 (timestamp_counter_bits > 0 && !gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE))) {
315 var error = gl.getError();
316 if (error != gl.NO_ERROR) {
317 testFailed("getQueryParameter should have no errors: " + wtu.glEnumToString(gl, error));
318 debug("");
319 finishTest();
320 return;
322 availability_retry--;
323 window.requestAnimationFrame(checkQueryResults);
324 return;
328 debug("");
329 debug("Testing query results");
331 // Make sure queries are available.
332 shouldBe("gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE)", "true");
333 if (timestamp_counter_bits > 0) {
334 shouldBe("gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT_AVAILABLE)", "true");
335 shouldBe("gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE)", "true");
338 var disjoint_value = gl.getParameter(ext.GPU_DISJOINT_EXT);
339 if (disjoint_value) {
340 // Cannot validate results make sense, but this is okay.
341 testPassed("Disjoint triggered.");
342 } else {
343 var elapsed_result = gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT);
344 if (timestamp_counter_bits > 0) {
345 var timestamp_result1 = gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT);
346 var timestamp_result2 = gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT);
348 // Do some basic validity checking of the elapsed time query. There's no way it should
349 // take more than about half a second for a no-op query.
350 var halfSecondInNanos = 0.5 * 1000 * 1000 * 1000;
351 if (elapsed_result < 0 || elapsed_result > halfSecondInNanos) {
352 testFailed("Time elapsed query returned invalid data: " + elapsed_result);
353 } else {
354 testPassed("Time elapsed query results were valid.");
357 if (timestamp_counter_bits > 0) {
358 if (timestamp_result1 <= 0 ||
359 timestamp_result2 <= 0 ||
360 timestamp_result2 <= timestamp_result1) {
361 testFailed("Timestamp queries returned invalid data: timestamp_result1 = " +
362 timestamp_result1 + ", timestamp_result2 = " + timestamp_result2);
363 } else {
364 testPassed("Timestamp query results were valid.");
369 debug("");
370 finishTest();
372 </script>
373 </body>
374 </html>