summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp')
-rwxr-xr-xgfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp590
1 files changed, 590 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp b/gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp
new file mode 100755
index 000000000..8f3725ec0
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp
@@ -0,0 +1,590 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// TimerQueriesTest.cpp
+// Various tests for EXT_disjoint_timer_query functionality and validation
+//
+
+#include "system_utils.h"
+#include "test_utils/ANGLETest.h"
+#include "random_utils.h"
+
+using namespace angle;
+
+class TimerQueriesTest : public ANGLETest
+{
+ protected:
+ TimerQueriesTest() : mProgram(0), mProgramCostly(0)
+ {
+ setWindowWidth(128);
+ setWindowHeight(128);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ setConfigDepthBits(24);
+ }
+
+ virtual void SetUp()
+ {
+ ANGLETest::SetUp();
+
+ const std::string passthroughVS =
+ "attribute highp vec4 position; void main(void)\n"
+ "{\n"
+ " gl_Position = position;\n"
+ "}\n";
+
+ const std::string passthroughPS =
+ "precision highp float; void main(void)\n"
+ "{\n"
+ " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
+ "}\n";
+
+ const std::string costlyVS =
+ "attribute highp vec4 position; varying highp vec4 testPos; void main(void)\n"
+ "{\n"
+ " testPos = position;\n"
+ " gl_Position = position;\n"
+ "}\n";
+
+ const std::string costlyPS =
+ "precision highp float; varying highp vec4 testPos; void main(void)\n"
+ "{\n"
+ " vec4 test = testPos;\n"
+ " for (int i = 0; i < 500; i++)\n"
+ " {\n"
+ " test = sqrt(test);\n"
+ " }\n"
+ " gl_FragColor = test;\n"
+ "}\n";
+
+ mProgram = CompileProgram(passthroughVS, passthroughPS);
+ ASSERT_NE(0u, mProgram) << "shader compilation failed.";
+
+ mProgramCostly = CompileProgram(costlyVS, costlyPS);
+ ASSERT_NE(0u, mProgramCostly) << "shader compilation failed.";
+ }
+
+ virtual void TearDown()
+ {
+ glDeleteProgram(mProgram);
+ glDeleteProgram(mProgramCostly);
+ ANGLETest::TearDown();
+ }
+
+ GLuint mProgram;
+ GLuint mProgramCostly;
+};
+
+// Test that all proc addresses are loadable
+TEST_P(TimerQueriesTest, ProcAddresses)
+{
+ if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
+ {
+ std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
+ << std::endl;
+ return;
+ }
+
+ ASSERT_NE(nullptr, eglGetProcAddress("glGenQueriesEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glDeleteQueriesEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glIsQueryEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glBeginQueryEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glEndQueryEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glQueryCounterEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryivEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectivEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectuivEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjecti64vEXT"));
+ ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectui64vEXT"));
+}
+
+// Tests the time elapsed query
+TEST_P(TimerQueriesTest, TimeElapsed)
+{
+ if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
+ {
+ std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
+ << std::endl;
+ return;
+ }
+
+ GLint queryTimeElapsedBits = 0;
+ glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits);
+ ASSERT_GL_NO_ERROR();
+
+ std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl;
+
+ // Skip test if the number of bits is 0
+ if (queryTimeElapsedBits == 0)
+ {
+ std::cout << "Test skipped because of 0 counter bits" << std::endl;
+ return;
+ }
+
+ glDepthMask(GL_TRUE);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ GLuint query1 = 0;
+ GLuint query2 = 0;
+ glGenQueriesEXT(1, &query1);
+ glGenQueriesEXT(1, &query2);
+
+ // Test time elapsed for a single quad
+ glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query1);
+ drawQuad(mProgram, "position", 0.8f);
+ glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+ ASSERT_GL_NO_ERROR();
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ // Test time elapsed for costly quad
+ glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query2);
+ drawQuad(mProgramCostly, "position", 0.8f);
+ glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+ ASSERT_GL_NO_ERROR();
+
+ swapBuffers();
+
+ int timeout = 200000;
+ GLuint ready = GL_FALSE;
+ while (ready == GL_FALSE && timeout > 0)
+ {
+ angle::Sleep(0);
+ glGetQueryObjectuivEXT(query1, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
+ timeout--;
+ }
+ ready = GL_FALSE;
+ while (ready == GL_FALSE && timeout > 0)
+ {
+ angle::Sleep(0);
+ glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
+ timeout--;
+ }
+ ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl;
+
+ GLuint64 result1 = 0;
+ GLuint64 result2 = 0;
+ glGetQueryObjectui64vEXT(query1, GL_QUERY_RESULT_EXT, &result1);
+ glGetQueryObjectui64vEXT(query2, GL_QUERY_RESULT_EXT, &result2);
+ ASSERT_GL_NO_ERROR();
+
+ glDeleteQueriesEXT(1, &query1);
+ glDeleteQueriesEXT(1, &query2);
+ ASSERT_GL_NO_ERROR();
+
+ std::cout << "Elapsed time: " << result1 << " cheap quad" << std::endl;
+ std::cout << "Elapsed time: " << result2 << " costly quad" << std::endl;
+
+ // The time elapsed should be nonzero
+ EXPECT_LT(0ul, result1);
+ EXPECT_LT(0ul, result2);
+
+ // The costly quad should take longer than the cheap quad
+ EXPECT_LT(result1, result2);
+}
+
+// Tests time elapsed for a non draw call (texture upload)
+TEST_P(TimerQueriesTest, TimeElapsedTextureTest)
+{
+ // OSX drivers don't seem to properly time non-draw calls so we skip the test on Mac
+ if (IsOSX())
+ {
+ std::cout << "Test skipped on OSX" << std::endl;
+ return;
+ }
+
+ if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
+ {
+ std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
+ << std::endl;
+ return;
+ }
+
+ GLint queryTimeElapsedBits = 0;
+ glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits);
+ ASSERT_GL_NO_ERROR();
+
+ std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl;
+
+ // Skip test if the number of bits is 0
+ if (queryTimeElapsedBits == 0)
+ {
+ std::cout << "Test skipped because of 0 counter bits" << std::endl;
+ return;
+ }
+
+ GLubyte pixels[] = {0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0};
+
+ // Query and texture initialization
+ GLuint texture;
+ GLuint query = 0;
+ glGenQueriesEXT(1, &query);
+ glGenTextures(1, &texture);
+
+ // Upload a texture inside the query
+ glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ glFinish();
+ glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+ ASSERT_GL_NO_ERROR();
+
+ int timeout = 200000;
+ GLuint ready = GL_FALSE;
+ while (ready == GL_FALSE && timeout > 0)
+ {
+ angle::Sleep(0);
+ glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
+ timeout--;
+ }
+ ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl;
+
+ GLuint64 result = 0;
+ glGetQueryObjectui64vEXT(query, GL_QUERY_RESULT_EXT, &result);
+ ASSERT_GL_NO_ERROR();
+
+ glDeleteTextures(1, &texture);
+ glDeleteQueriesEXT(1, &query);
+
+ std::cout << "Elapsed time: " << result << std::endl;
+ EXPECT_LT(0ul, result);
+}
+
+// Tests validation of query functions with respect to elapsed time query
+TEST_P(TimerQueriesTest, TimeElapsedValidationTest)
+{
+ if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
+ {
+ std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
+ << std::endl;
+ return;
+ }
+
+ GLint queryTimeElapsedBits = 0;
+ glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits);
+ ASSERT_GL_NO_ERROR();
+
+ std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl;
+
+ // Skip test if the number of bits is 0
+ if (queryTimeElapsedBits == 0)
+ {
+ std::cout << "Test skipped because of 0 counter bits" << std::endl;
+ return;
+ }
+
+ GLuint query = 0;
+ glGenQueriesEXT(-1, &query);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glGenQueriesEXT(1, &query);
+ EXPECT_GL_NO_ERROR();
+
+ glBeginQueryEXT(GL_TIMESTAMP_EXT, query);
+ EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+ glBeginQueryEXT(GL_TIME_ELAPSED_EXT, 0);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+ glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+ glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query);
+ EXPECT_GL_NO_ERROR();
+
+ glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+ glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+ EXPECT_GL_NO_ERROR();
+
+ glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
+// Tests timer queries operating under multiple EGL contexts with mid-query switching
+TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest)
+{
+ if (IsAMD() && IsOpenGL() && IsWindows() && IsDebug())
+ {
+ // TODO(jmadill): Figure out why this test is flaky on Win/AMD/OpenGL/Debug.
+ std::cout << "Test skipped on Windows AMD OpenGL Debug." << std::endl;
+ return;
+ }
+
+ if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
+ {
+ std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
+ << std::endl;
+ return;
+ }
+
+ GLint queryTimeElapsedBits = 0;
+ glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits);
+ ASSERT_GL_NO_ERROR();
+
+ std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl;
+
+ // Skip test if the number of bits is 0
+ if (queryTimeElapsedBits == 0)
+ {
+ std::cout << "Test skipped because of 0 counter bits" << std::endl;
+ return;
+ }
+
+ // Without a glClear, the first draw call on GL takes a huge amount of time when run after the
+ // D3D test on certain NVIDIA drivers
+ glDepthMask(GL_TRUE);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ EGLint contextAttributes[] = {
+ EGL_CONTEXT_MAJOR_VERSION_KHR,
+ GetParam().majorVersion,
+ EGL_CONTEXT_MINOR_VERSION_KHR,
+ GetParam().minorVersion,
+ EGL_NONE,
+ };
+
+ EGLWindow *window = getEGLWindow();
+
+ EGLDisplay display = window->getDisplay();
+ EGLConfig config = window->getConfig();
+ EGLSurface surface = window->getSurface();
+
+ struct ContextInfo
+ {
+ EGLContext context;
+ GLuint program;
+ GLuint query;
+ EGLDisplay display;
+
+ ContextInfo() : context(EGL_NO_CONTEXT), program(0), query(0), display(EGL_NO_DISPLAY) {}
+
+ ~ContextInfo()
+ {
+ if (context != EGL_NO_CONTEXT && display != EGL_NO_DISPLAY)
+ {
+ eglDestroyContext(display, context);
+ }
+ }
+ };
+ ContextInfo contexts[2];
+
+ // Shaders
+ const std::string cheapVS =
+ "attribute highp vec4 position; void main(void)\n"
+ "{\n"
+ " gl_Position = position;\n"
+ "}\n";
+
+ const std::string cheapPS =
+ "precision highp float; void main(void)\n"
+ "{\n"
+ " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
+ "}\n";
+
+ const std::string costlyVS =
+ "attribute highp vec4 position; varying highp vec4 testPos; void main(void)\n"
+ "{\n"
+ " testPos = position;\n"
+ " gl_Position = position;\n"
+ "}\n";
+
+ const std::string costlyPS =
+ "precision highp float; varying highp vec4 testPos; void main(void)\n"
+ "{\n"
+ " vec4 test = testPos;\n"
+ " for (int i = 0; i < 500; i++)\n"
+ " {\n"
+ " test = sqrt(test);\n"
+ " }\n"
+ " gl_FragColor = test;\n"
+ "}\n";
+
+ // Setup the first context with a cheap shader
+ contexts[0].context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
+ contexts[0].display = display;
+ ASSERT_NE(contexts[0].context, EGL_NO_CONTEXT);
+ eglMakeCurrent(display, surface, surface, contexts[0].context);
+ contexts[0].program = CompileProgram(cheapVS, cheapPS);
+ glGenQueriesEXT(1, &contexts[0].query);
+ ASSERT_GL_NO_ERROR();
+
+ // Setup the second context with an expensive shader
+ contexts[1].context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
+ contexts[1].display = display;
+ ASSERT_NE(contexts[1].context, EGL_NO_CONTEXT);
+ eglMakeCurrent(display, surface, surface, contexts[1].context);
+ contexts[1].program = CompileProgram(costlyVS, costlyPS);
+ glGenQueriesEXT(1, &contexts[1].query);
+ ASSERT_GL_NO_ERROR();
+
+ // Start the query and draw a quad on the first context without ending the query
+ eglMakeCurrent(display, surface, surface, contexts[0].context);
+ glBeginQueryEXT(GL_TIME_ELAPSED_EXT, contexts[0].query);
+ drawQuad(contexts[0].program, "position", 0.8f);
+ ASSERT_GL_NO_ERROR();
+
+ // Switch contexts, draw the expensive quad and end its query
+ eglMakeCurrent(display, surface, surface, contexts[1].context);
+ glBeginQueryEXT(GL_TIME_ELAPSED_EXT, contexts[1].query);
+ drawQuad(contexts[1].program, "position", 0.8f);
+ glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+ ASSERT_GL_NO_ERROR();
+
+ // Go back to the first context, end its query, and get the result
+ eglMakeCurrent(display, surface, surface, contexts[0].context);
+ glEndQueryEXT(GL_TIME_ELAPSED_EXT);
+
+ GLuint64 result1 = 0;
+ GLuint64 result2 = 0;
+ glGetQueryObjectui64vEXT(contexts[0].query, GL_QUERY_RESULT_EXT, &result1);
+ glDeleteQueriesEXT(1, &contexts[0].query);
+ glDeleteProgram(contexts[0].program);
+ ASSERT_GL_NO_ERROR();
+
+ // Get the 2nd context's results
+ eglMakeCurrent(display, surface, surface, contexts[1].context);
+ glGetQueryObjectui64vEXT(contexts[1].query, GL_QUERY_RESULT_EXT, &result2);
+ glDeleteQueriesEXT(1, &contexts[1].query);
+ glDeleteProgram(contexts[1].program);
+ ASSERT_GL_NO_ERROR();
+
+ // Switch back to main context
+ eglMakeCurrent(display, surface, surface, window->getContext());
+
+ // Compare the results. The cheap quad should be smaller than the expensive one if
+ // virtualization is working correctly
+ std::cout << "Elapsed time: " << result1 << " cheap quad" << std::endl;
+ std::cout << "Elapsed time: " << result2 << " costly quad" << std::endl;
+ EXPECT_LT(0ul, result1);
+ EXPECT_LT(0ul, result2);
+ EXPECT_LT(result1, result2);
+}
+
+// Tests GPU timestamp functionality
+TEST_P(TimerQueriesTest, Timestamp)
+{
+ if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
+ {
+ std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
+ << std::endl;
+ return;
+ }
+
+ GLint queryTimestampBits = 0;
+ glGetQueryivEXT(GL_TIMESTAMP_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimestampBits);
+ ASSERT_GL_NO_ERROR();
+
+ std::cout << "Timestamp counter bits: " << queryTimestampBits << std::endl;
+
+ // Macs for some reason return 0 bits so skip the test for now if either are 0
+ if (queryTimestampBits == 0)
+ {
+ std::cout << "Test skipped because of 0 counter bits" << std::endl;
+ return;
+ }
+
+ glDepthMask(GL_TRUE);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ GLuint query1 = 0;
+ GLuint query2 = 0;
+ glGenQueriesEXT(1, &query1);
+ glGenQueriesEXT(1, &query2);
+ glQueryCounterEXT(query1, GL_TIMESTAMP_EXT);
+ drawQuad(mProgram, "position", 0.8f);
+ glQueryCounterEXT(query2, GL_TIMESTAMP_EXT);
+
+ ASSERT_GL_NO_ERROR();
+
+ swapBuffers();
+
+ int timeout = 200000;
+ GLuint ready = GL_FALSE;
+ while (ready == GL_FALSE && timeout > 0)
+ {
+ angle::Sleep(0);
+ glGetQueryObjectuivEXT(query1, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
+ timeout--;
+ }
+ ready = GL_FALSE;
+ while (ready == GL_FALSE && timeout > 0)
+ {
+ angle::Sleep(0);
+ glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
+ timeout--;
+ }
+ ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl;
+
+ GLuint64 result1 = 0;
+ GLuint64 result2 = 0;
+ glGetQueryObjectui64vEXT(query1, GL_QUERY_RESULT_EXT, &result1);
+ glGetQueryObjectui64vEXT(query2, GL_QUERY_RESULT_EXT, &result2);
+
+ ASSERT_GL_NO_ERROR();
+
+ glDeleteQueriesEXT(1, &query1);
+ glDeleteQueriesEXT(1, &query2);
+
+ std::cout << "Timestamps: " << result1 << " " << result2 << std::endl;
+ EXPECT_LT(0ul, result1);
+ EXPECT_LT(0ul, result2);
+ EXPECT_LT(result1, result2);
+}
+
+class TimerQueriesTestES3 : public TimerQueriesTest
+{
+};
+
+// Tests getting timestamps via glGetInteger64v
+TEST_P(TimerQueriesTestES3, TimestampGetInteger64)
+{
+ if (!extensionEnabled("GL_EXT_disjoint_timer_query"))
+ {
+ std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available."
+ << std::endl;
+ return;
+ }
+
+ GLint queryTimestampBits = 0;
+ glGetQueryivEXT(GL_TIMESTAMP_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimestampBits);
+ ASSERT_GL_NO_ERROR();
+
+ std::cout << "Timestamp counter bits: " << queryTimestampBits << std::endl;
+
+ if (queryTimestampBits == 0)
+ {
+ std::cout << "Test skipped because of 0 counter bits" << std::endl;
+ return;
+ }
+
+ glDepthMask(GL_TRUE);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ GLint64 result1 = 0;
+ GLint64 result2 = 0;
+ glGetInteger64v(GL_TIMESTAMP_EXT, &result1);
+ drawQuad(mProgram, "position", 0.8f);
+ glGetInteger64v(GL_TIMESTAMP_EXT, &result2);
+ ASSERT_GL_NO_ERROR();
+ std::cout << "Timestamps (getInteger64v): " << result1 << " " << result2 << std::endl;
+ EXPECT_LT(0l, result1);
+ EXPECT_LT(0l, result2);
+ EXPECT_LT(result1, result2);
+}
+
+ANGLE_INSTANTIATE_TEST(TimerQueriesTest,
+ ES2_D3D9(),
+ ES2_D3D11(),
+ ES3_D3D11(),
+ ES2_OPENGL(),
+ ES3_OPENGL());
+
+ANGLE_INSTANTIATE_TEST(TimerQueriesTestES3, ES3_D3D11(), ES3_OPENGL()); \ No newline at end of file