1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // TimerQueriesTest.cpp
7 // Various tests for EXT_disjoint_timer_query functionality and validation
8 //
9
10 #include "system_utils.h"
11 #include "test_utils/ANGLETest.h"
12 #include "random_utils.h"
13
14 using namespace angle;
15
16 class TimerQueriesTest : public ANGLETest
17 {
18 protected:
TimerQueriesTest()19 TimerQueriesTest() : mProgram(0), mProgramCostly(0)
20 {
21 setWindowWidth(128);
22 setWindowHeight(128);
23 setConfigRedBits(8);
24 setConfigGreenBits(8);
25 setConfigBlueBits(8);
26 setConfigAlphaBits(8);
27 setConfigDepthBits(24);
28 }
29
SetUp()30 virtual void SetUp()
31 {
32 ANGLETest::SetUp();
33
34 const std::string passthroughVS =
35 "attribute highp vec4 position; void main(void)\n"
36 "{\n"
37 " gl_Position = position;\n"
38 "}\n";
39
40 const std::string passthroughPS =
41 "precision highp float; void main(void)\n"
42 "{\n"
43 " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
44 "}\n";
45
46 const std::string costlyVS =
47 "attribute highp vec4 position; varying highp vec4 testPos; void main(void)\n"
48 "{\n"
49 " testPos = position;\n"
50 " gl_Position = position;\n"
51 "}\n";
52
53 const std::string costlyPS =
54 "precision highp float; varying highp vec4 testPos; void main(void)\n"
55 "{\n"
56 " vec4 test = testPos;\n"
57 " for (int i = 0; i < 500; i++)\n"
58 " {\n"
59 " test = sqrt(test);\n"
60 " }\n"
61 " gl_FragColor = test;\n"
62 "}\n";
63
64 mProgram = CompileProgram(passthroughVS, passthroughPS);
65 ASSERT_NE(0u, mProgram) << "shader compilation failed.";
66
67 mProgramCostly = CompileProgram(costlyVS, costlyPS);
68 ASSERT_NE(0u, mProgramCostly) << "shader compilation failed.";
69 }
70
TearDown()71 virtual void TearDown()
72 {
73 glDeleteProgram(mProgram);
74 glDeleteProgram(mProgramCostly);
75 ANGLETest::TearDown();
76 }
77
78 GLuint mProgram;
79 GLuint mProgramCostly;
80 };
81
82 // Test that all proc addresses are loadable
TEST_P(TimerQueriesTest,ProcAddresses)83 TEST_P(TimerQueriesTest, ProcAddresses)
84 {
85 if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
86 {
87 std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
88 << std::endl;
89 return;
90 }
91
92 ASSERT_NE(nullptr, eglGetProcAddress("glGenQueriesEXT"));
93 ASSERT_NE(nullptr, eglGetProcAddress("glDeleteQueriesEXT"));
94 ASSERT_NE(nullptr, eglGetProcAddress("glIsQueryEXT"));
95 ASSERT_NE(nullptr, eglGetProcAddress("glBeginQueryEXT"));
96 ASSERT_NE(nullptr, eglGetProcAddress("glEndQueryEXT"));
97 ASSERT_NE(nullptr, eglGetProcAddress("glQueryCounterEXT"));
98 ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryivEXT"));
99 ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectivEXT"));
100 ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectuivEXT"));
101 ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjecti64vEXT"));
102 ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectui64vEXT"));
103 }
104
105 // Tests the time elapsed query
TEST_P(TimerQueriesTest,TimeElapsed)106 TEST_P(TimerQueriesTest, TimeElapsed)
107 {
108 if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
109 {
110 std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
111 << std::endl;
112 return;
113 }
114
115 GLint queryTimeElapsedBits = 0;
116 glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits);
117 ASSERT_GL_NO_ERROR();
118
119 std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl;
120
121 // Skip test if the number of bits is 0
122 if (queryTimeElapsedBits == 0)
123 {
124 std::cout << "Test skipped because of 0 counter bits" << std::endl;
125 return;
126 }
127
128 glDepthMask(GL_TRUE);
129 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
130
131 GLuint query1 = 0;
132 GLuint query2 = 0;
133 glGenQueriesEXT(1, &query1);
134 glGenQueriesEXT(1, &query2);
135
136 // Test time elapsed for a single quad
137 glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query1);
138 drawQuad(mProgram, "position", 0.8f);
139 glEndQueryEXT(GL_TIME_ELAPSED_EXT);
140 ASSERT_GL_NO_ERROR();
141
142 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
143
144 // Test time elapsed for costly quad
145 glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query2);
146 drawQuad(mProgramCostly, "position", 0.8f);
147 glEndQueryEXT(GL_TIME_ELAPSED_EXT);
148 ASSERT_GL_NO_ERROR();
149
150 swapBuffers();
151
152 int timeout = 200000;
153 GLuint ready = GL_FALSE;
154 while (ready == GL_FALSE && timeout > 0)
155 {
156 angle::Sleep(0);
157 glGetQueryObjectuivEXT(query1, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
158 timeout--;
159 }
160 ready = GL_FALSE;
161 while (ready == GL_FALSE && timeout > 0)
162 {
163 angle::Sleep(0);
164 glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
165 timeout--;
166 }
167 ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl;
168
169 GLuint64 result1 = 0;
170 GLuint64 result2 = 0;
171 glGetQueryObjectui64vEXT(query1, GL_QUERY_RESULT_EXT, &result1);
172 glGetQueryObjectui64vEXT(query2, GL_QUERY_RESULT_EXT, &result2);
173 ASSERT_GL_NO_ERROR();
174
175 glDeleteQueriesEXT(1, &query1);
176 glDeleteQueriesEXT(1, &query2);
177 ASSERT_GL_NO_ERROR();
178
179 std::cout << "Elapsed time: " << result1 << " cheap quad" << std::endl;
180 std::cout << "Elapsed time: " << result2 << " costly quad" << std::endl;
181
182 // The time elapsed should be nonzero
183 EXPECT_LT(0ul, result1);
184 EXPECT_LT(0ul, result2);
185
186 // The costly quad should take longer than the cheap quad
187 EXPECT_LT(result1, result2);
188 }
189
190 // Tests time elapsed for a non draw call (texture upload)
TEST_P(TimerQueriesTest,TimeElapsedTextureTest)191 TEST_P(TimerQueriesTest, TimeElapsedTextureTest)
192 {
193 // OSX drivers don't seem to properly time non-draw calls so we skip the test on Mac
194 if (IsOSX())
195 {
196 std::cout << "Test skipped on OSX" << std::endl;
197 return;
198 }
199
200 if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
201 {
202 std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
203 << std::endl;
204 return;
205 }
206
207 GLint queryTimeElapsedBits = 0;
208 glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits);
209 ASSERT_GL_NO_ERROR();
210
211 std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl;
212
213 // Skip test if the number of bits is 0
214 if (queryTimeElapsedBits == 0)
215 {
216 std::cout << "Test skipped because of 0 counter bits" << std::endl;
217 return;
218 }
219
220 GLubyte pixels[] = {0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0};
221
222 // Query and texture initialization
223 GLuint texture;
224 GLuint query = 0;
225 glGenQueriesEXT(1, &query);
226 glGenTextures(1, &texture);
227
228 // Upload a texture inside the query
229 glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query);
230 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
231 glBindTexture(GL_TEXTURE_2D, texture);
232 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
233 glGenerateMipmap(GL_TEXTURE_2D);
234 glFinish();
235 glEndQueryEXT(GL_TIME_ELAPSED_EXT);
236 ASSERT_GL_NO_ERROR();
237
238 int timeout = 200000;
239 GLuint ready = GL_FALSE;
240 while (ready == GL_FALSE && timeout > 0)
241 {
242 angle::Sleep(0);
243 glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
244 timeout--;
245 }
246 ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl;
247
248 GLuint64 result = 0;
249 glGetQueryObjectui64vEXT(query, GL_QUERY_RESULT_EXT, &result);
250 ASSERT_GL_NO_ERROR();
251
252 glDeleteTextures(1, &texture);
253 glDeleteQueriesEXT(1, &query);
254
255 std::cout << "Elapsed time: " << result << std::endl;
256 EXPECT_LT(0ul, result);
257 }
258
259 // Tests validation of query functions with respect to elapsed time query
TEST_P(TimerQueriesTest,TimeElapsedValidationTest)260 TEST_P(TimerQueriesTest, TimeElapsedValidationTest)
261 {
262 if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
263 {
264 std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
265 << std::endl;
266 return;
267 }
268
269 GLint queryTimeElapsedBits = 0;
270 glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits);
271 ASSERT_GL_NO_ERROR();
272
273 std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl;
274
275 // Skip test if the number of bits is 0
276 if (queryTimeElapsedBits == 0)
277 {
278 std::cout << "Test skipped because of 0 counter bits" << std::endl;
279 return;
280 }
281
282 GLuint query = 0;
283 glGenQueriesEXT(-1, &query);
284 EXPECT_GL_ERROR(GL_INVALID_VALUE);
285
286 glGenQueriesEXT(1, &query);
287 EXPECT_GL_NO_ERROR();
288
289 glBeginQueryEXT(GL_TIMESTAMP_EXT, query);
290 EXPECT_GL_ERROR(GL_INVALID_ENUM);
291
292 glBeginQueryEXT(GL_TIME_ELAPSED_EXT, 0);
293 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
294
295 glEndQueryEXT(GL_TIME_ELAPSED_EXT);
296 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
297
298 glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query);
299 EXPECT_GL_NO_ERROR();
300
301 glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query);
302 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
303
304 glEndQueryEXT(GL_TIME_ELAPSED_EXT);
305 EXPECT_GL_NO_ERROR();
306
307 glEndQueryEXT(GL_TIME_ELAPSED_EXT);
308 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
309 }
310
311 // Tests timer queries operating under multiple EGL contexts with mid-query switching
TEST_P(TimerQueriesTest,TimeElapsedMulticontextTest)312 TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest)
313 {
314 if (IsAMD() && IsOpenGL() && IsWindows() && IsDebug())
315 {
316 // TODO(jmadill): Figure out why this test is flaky on Win/AMD/OpenGL/Debug.
317 std::cout << "Test skipped on Windows AMD OpenGL Debug." << std::endl;
318 return;
319 }
320
321 if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
322 {
323 std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
324 << std::endl;
325 return;
326 }
327
328 GLint queryTimeElapsedBits = 0;
329 glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits);
330 ASSERT_GL_NO_ERROR();
331
332 std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl;
333
334 // Skip test if the number of bits is 0
335 if (queryTimeElapsedBits == 0)
336 {
337 std::cout << "Test skipped because of 0 counter bits" << std::endl;
338 return;
339 }
340
341 // Without a glClear, the first draw call on GL takes a huge amount of time when run after the
342 // D3D test on certain NVIDIA drivers
343 glDepthMask(GL_TRUE);
344 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
345
346 EGLint contextAttributes[] = {
347 EGL_CONTEXT_MAJOR_VERSION_KHR,
348 GetParam().majorVersion,
349 EGL_CONTEXT_MINOR_VERSION_KHR,
350 GetParam().minorVersion,
351 EGL_NONE,
352 };
353
354 EGLWindow *window = getEGLWindow();
355
356 EGLDisplay display = window->getDisplay();
357 EGLConfig config = window->getConfig();
358 EGLSurface surface = window->getSurface();
359
360 struct ContextInfo
361 {
362 EGLContext context;
363 GLuint program;
364 GLuint query;
365 EGLDisplay display;
366
367 ContextInfo() : context(EGL_NO_CONTEXT), program(0), query(0), display(EGL_NO_DISPLAY) {}
368
369 ~ContextInfo()
370 {
371 if (context != EGL_NO_CONTEXT && display != EGL_NO_DISPLAY)
372 {
373 eglDestroyContext(display, context);
374 }
375 }
376 };
377 ContextInfo contexts[2];
378
379 // Shaders
380 const std::string cheapVS =
381 "attribute highp vec4 position; void main(void)\n"
382 "{\n"
383 " gl_Position = position;\n"
384 "}\n";
385
386 const std::string cheapPS =
387 "precision highp float; void main(void)\n"
388 "{\n"
389 " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
390 "}\n";
391
392 const std::string costlyVS =
393 "attribute highp vec4 position; varying highp vec4 testPos; void main(void)\n"
394 "{\n"
395 " testPos = position;\n"
396 " gl_Position = position;\n"
397 "}\n";
398
399 const std::string costlyPS =
400 "precision highp float; varying highp vec4 testPos; void main(void)\n"
401 "{\n"
402 " vec4 test = testPos;\n"
403 " for (int i = 0; i < 500; i++)\n"
404 " {\n"
405 " test = sqrt(test);\n"
406 " }\n"
407 " gl_FragColor = test;\n"
408 "}\n";
409
410 // Setup the first context with a cheap shader
411 contexts[0].context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
412 contexts[0].display = display;
413 ASSERT_NE(contexts[0].context, EGL_NO_CONTEXT);
414 eglMakeCurrent(display, surface, surface, contexts[0].context);
415 contexts[0].program = CompileProgram(cheapVS, cheapPS);
416 glGenQueriesEXT(1, &contexts[0].query);
417 ASSERT_GL_NO_ERROR();
418
419 // Setup the second context with an expensive shader
420 contexts[1].context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
421 contexts[1].display = display;
422 ASSERT_NE(contexts[1].context, EGL_NO_CONTEXT);
423 eglMakeCurrent(display, surface, surface, contexts[1].context);
424 contexts[1].program = CompileProgram(costlyVS, costlyPS);
425 glGenQueriesEXT(1, &contexts[1].query);
426 ASSERT_GL_NO_ERROR();
427
428 // Start the query and draw a quad on the first context without ending the query
429 eglMakeCurrent(display, surface, surface, contexts[0].context);
430 glBeginQueryEXT(GL_TIME_ELAPSED_EXT, contexts[0].query);
431 drawQuad(contexts[0].program, "position", 0.8f);
432 ASSERT_GL_NO_ERROR();
433
434 // Switch contexts, draw the expensive quad and end its query
435 eglMakeCurrent(display, surface, surface, contexts[1].context);
436 glBeginQueryEXT(GL_TIME_ELAPSED_EXT, contexts[1].query);
437 drawQuad(contexts[1].program, "position", 0.8f);
438 glEndQueryEXT(GL_TIME_ELAPSED_EXT);
439 ASSERT_GL_NO_ERROR();
440
441 // Go back to the first context, end its query, and get the result
442 eglMakeCurrent(display, surface, surface, contexts[0].context);
443 glEndQueryEXT(GL_TIME_ELAPSED_EXT);
444
445 GLuint64 result1 = 0;
446 GLuint64 result2 = 0;
447 glGetQueryObjectui64vEXT(contexts[0].query, GL_QUERY_RESULT_EXT, &result1);
448 glDeleteQueriesEXT(1, &contexts[0].query);
449 glDeleteProgram(contexts[0].program);
450 ASSERT_GL_NO_ERROR();
451
452 // Get the 2nd context's results
453 eglMakeCurrent(display, surface, surface, contexts[1].context);
454 glGetQueryObjectui64vEXT(contexts[1].query, GL_QUERY_RESULT_EXT, &result2);
455 glDeleteQueriesEXT(1, &contexts[1].query);
456 glDeleteProgram(contexts[1].program);
457 ASSERT_GL_NO_ERROR();
458
459 // Switch back to main context
460 eglMakeCurrent(display, surface, surface, window->getContext());
461
462 // Compare the results. The cheap quad should be smaller than the expensive one if
463 // virtualization is working correctly
464 std::cout << "Elapsed time: " << result1 << " cheap quad" << std::endl;
465 std::cout << "Elapsed time: " << result2 << " costly quad" << std::endl;
466 EXPECT_LT(0ul, result1);
467 EXPECT_LT(0ul, result2);
468 EXPECT_LT(result1, result2);
469 }
470
471 // Tests GPU timestamp functionality
TEST_P(TimerQueriesTest,Timestamp)472 TEST_P(TimerQueriesTest, Timestamp)
473 {
474 if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
475 {
476 std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
477 << std::endl;
478 return;
479 }
480
481 GLint queryTimestampBits = 0;
482 glGetQueryivEXT(GL_TIMESTAMP_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimestampBits);
483 ASSERT_GL_NO_ERROR();
484
485 std::cout << "Timestamp counter bits: " << queryTimestampBits << std::endl;
486
487 // Macs for some reason return 0 bits so skip the test for now if either are 0
488 if (queryTimestampBits == 0)
489 {
490 std::cout << "Test skipped because of 0 counter bits" << std::endl;
491 return;
492 }
493
494 glDepthMask(GL_TRUE);
495 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
496
497 GLuint query1 = 0;
498 GLuint query2 = 0;
499 glGenQueriesEXT(1, &query1);
500 glGenQueriesEXT(1, &query2);
501 glQueryCounterEXT(query1, GL_TIMESTAMP_EXT);
502 drawQuad(mProgram, "position", 0.8f);
503 glQueryCounterEXT(query2, GL_TIMESTAMP_EXT);
504
505 ASSERT_GL_NO_ERROR();
506
507 swapBuffers();
508
509 int timeout = 200000;
510 GLuint ready = GL_FALSE;
511 while (ready == GL_FALSE && timeout > 0)
512 {
513 angle::Sleep(0);
514 glGetQueryObjectuivEXT(query1, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
515 timeout--;
516 }
517 ready = GL_FALSE;
518 while (ready == GL_FALSE && timeout > 0)
519 {
520 angle::Sleep(0);
521 glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
522 timeout--;
523 }
524 ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl;
525
526 GLuint64 result1 = 0;
527 GLuint64 result2 = 0;
528 glGetQueryObjectui64vEXT(query1, GL_QUERY_RESULT_EXT, &result1);
529 glGetQueryObjectui64vEXT(query2, GL_QUERY_RESULT_EXT, &result2);
530
531 ASSERT_GL_NO_ERROR();
532
533 glDeleteQueriesEXT(1, &query1);
534 glDeleteQueriesEXT(1, &query2);
535
536 std::cout << "Timestamps: " << result1 << " " << result2 << std::endl;
537 EXPECT_LT(0ul, result1);
538 EXPECT_LT(0ul, result2);
539 EXPECT_LT(result1, result2);
540 }
541
542 class TimerQueriesTestES3 : public TimerQueriesTest
543 {
544 };
545
546 // Tests getting timestamps via glGetInteger64v
TEST_P(TimerQueriesTestES3,TimestampGetInteger64)547 TEST_P(TimerQueriesTestES3, TimestampGetInteger64)
548 {
549 if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
550 {
551 std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
552 << std::endl;
553 return;
554 }
555
556 GLint queryTimestampBits = 0;
557 glGetQueryivEXT(GL_TIMESTAMP_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimestampBits);
558 ASSERT_GL_NO_ERROR();
559
560 std::cout << "Timestamp counter bits: " << queryTimestampBits << std::endl;
561
562 if (queryTimestampBits == 0)
563 {
564 std::cout << "Test skipped because of 0 counter bits" << std::endl;
565 return;
566 }
567
568 glDepthMask(GL_TRUE);
569 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
570
571 GLint64 result1 = 0;
572 GLint64 result2 = 0;
573 glGetInteger64v(GL_TIMESTAMP_EXT, &result1);
574 drawQuad(mProgram, "position", 0.8f);
575 glGetInteger64v(GL_TIMESTAMP_EXT, &result2);
576 ASSERT_GL_NO_ERROR();
577 std::cout << "Timestamps (getInteger64v): " << result1 << " " << result2 << std::endl;
578 EXPECT_LT(0l, result1);
579 EXPECT_LT(0l, result2);
580 EXPECT_LT(result1, result2);
581 }
582
583 ANGLE_INSTANTIATE_TEST(TimerQueriesTest,
584 ES2_D3D9(),
585 ES2_D3D11(),
586 ES3_D3D11(),
587 ES2_OPENGL(),
588 ES3_OPENGL());
589
590 ANGLE_INSTANTIATE_TEST(TimerQueriesTestES3, ES3_D3D11(), ES3_OPENGL());