Hello,
I want to use the EXT_disjoint_timer_query extension for performance measures, but the functions always return values of 0. I'm using a Samsung Galaxy Note 4 with an Adreno 420 GPU, Android 5.0.1, OpenGL ES 3.1 (Extension support checked). My code is pretty much the same as in the examples (https://www.khronos.org/registry/gles/extensions/EXT/EXT_disjoint_timer_...), except `glGetQueryObjectivEXT`instead of `glGetQueryObjectiv` as it's not part of the core api.
Init code:
// load extensions
glGenQueriesEXT = (PFNGLGENQUERIESEXTPROC) eglGetProcAddress("glGenQueriesEXT");
glDeleteQueriesEXT = (PFNGLDELETEQUERIESEXTPROC) eglGetProcAddress("glDeleteQueriesEXT");
glIsQueryEXT = (PFNGLISQUERYEXTPROC) eglGetProcAddress("glIsQueryEXT");
glBeginQueryEXT = (PFNGLBEGINQUERYEXTPROC) eglGetProcAddress("glBeginQueryEXT");
glEndQueryEXT = (PFNGLENDQUERYEXTPROC) eglGetProcAddress("glEndQueryEXT");
glQueryCounterEXT = (PFNGLQUERYCOUNTEREXTPROC) eglGetProcAddress("glQueryCounterEXT");
glGetQueryivEXT = (PFNGLGETQUERYIVEXTPROC) eglGetProcAddress("glGetQueryivEXT");
glGetQueryObjectivEXT = (PFNGLGETQUERYOBJECTIVEXTPROC) eglGetProcAddress("glGetQueryObjectivEXT");
glGetQueryObjectuivEXT = (PFNGLGETQUERYOBJECTUIVEXTPROC) eglGetProcAddress("glGetQueryObjectuivEXT");
glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC) eglGetProcAddress("glGetQueryObjecti64vEXT");
glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC) eglGetProcAddress("glGetQueryObjectui64vEXT");
GL_CHECK(glGenQueries(1, &m_QueryScope));
GL_CHECK(glGenQueries(1, &m_QueryStart));
GL_CHECK(glGenQueries(1, &m_QueryStop));
Rendering code (with glBeginQuery/glEndQuery):
GLuint64 TimeStart;
int ResultAvailable = 0;
int disjointOccurred = 0;
GL_CHECK(glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjointOccurred));
GL_CHECK(glBeginQuery(GL_TIME_ELAPSED_EXT, m_QueryScope));
//
// Some draw calls ..
//
GL_CHECK(glEndQuery(GL_TIME_ELAPSED_EXT));
while(!ResultAvailable) {
GL_CHECK(glGetQueryObjectivEXT(m_QueryScope, GL_QUERY_RESULT_AVAILABLE, &ResultAvailable));
}
GL_CHECK(glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjointOccurred));
if(!disjointOccurred) {
GL_CHECK(glGetQueryObjectui64vEXT(m_QueryScope, GL_QUERY_RESULT, &TimeElapsed));
}
else
LOGI("disjoint occured");
LOGI("Time elapsed: %llu", TimeElapsed); // TimeElapsed return 0
Rendering code (with glQueryCounter):
GLuint64 TimeStart, TimeStop;
int ResultAvailable = 0;
int disjointOccurred = 0;
GL_CHECK(glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjointOccurred));
GL_CHECK(glQueryCounterEXT(m_QueryStart, GL_TIMESTAMP_EXT));
//
// Some draw calls ..
//
GL_CHECK(glQueryCounterEXT(m_QueryStop, GL_TIMESTAMP_EXT));
while(!ResultAvailable) {
GL_CHECK(glGetQueryObjectivEXT(m_QueryStop, GL_QUERY_RESULT_AVAILABLE, &ResultAvailable));
}
GL_CHECK(glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjointOccurred));
if(!disjointOccurred) {
GL_CHECK(glGetQueryObjectui64vEXT(m_QueryStart, GL_QUERY_RESULT, &TimeStart));
GL_CHECK(glGetQueryObjectui64vEXT(m_QueryStop, GL_QUERY_RESULT, &TimeStop));
}
else
LOGI("disjoint occured");
LOGI("Time elapsed: %llu, Start: %llu, Stop: %llu", TimeStop-TimeStart, TimeStart, TimeStop); // TimeStart and TimeStop return 0
Note: GL_CHECK() just executes the functions and checks for errors (none occured).
Help would be appreciated.
Kind regards
I started a thread on this a few weeks ago as well: https://developer.qualcomm.com/forum/qdn-forums/software/adreno-gpu-sdk/...
I was wondering if anyone had gotten this functionality to work since none of my googling found anyone who had. For me using these functions lead to unexplainable behaviour (crashes, opengl errors). My current working assumption (which I really hope is wrong) is that this functionality doesnt work in adreno. It's a shame because they are very much needed in order to balance GPGPU work with FPS.
so, on a tiler you really want to use time-elapsed query, instead of timestamp query (since start and stop time kind of have no sensible meaning with a tiler)
That said, at least w/ version of blob driver I have, I'm not really sure that even time-elapsed query works properly. From the cmdstream, it looks like it is overwriting the saved timestamps from the previous tile on the next tile (vs, say, occlusion query where it adds a per-tile offset to the memory location where the counters are saved to).
Not really sure how they test this internally? Maybe with a render target small enough to fit in a single tile?