Hi,
I'm having an issue getting plausible values at certain times with a disjoint timer query. I've read the discussion in here but my issue seems slightly different.
I'm not trying to time individual draw calls but rather the time it takes for complete the backbuffer.
I'm getting "roughly" consistent numbers for a large part of the frames, but frequently get 18446744073709551615 (2^64-1). This happens even when glGetQueryObjectuiv() returns true for an available query. Here's a snippet of the code (which is a slightly modified version this Unity plugin to use a 64-bit query):
GLuint available = 0; glGetQueryObjectuiv(queryObject, GL_QUERY_RESULT_AVAILABLE, &available); if (available == GL_TRUE) { GLuint64 elapsed_time_ns; glGetQueryObjectui64vEXT(queryObject, GL_QUERY_RESULT, &elapsed_time_ns); if (glGetError() == GL_NO_ERROR) { ... } ... }
I've tried forcing a synchronous call by ignoring the availability of the result. In such cases, the MAX_UINT above doesn't seem to occur and the values are "roughly" consistent (sometimes a few ms apart, but that's perhaps due HW pipelining).
I've gone through the extension spec but I can't find anything that might explain this. Could I've missed something?
I'm running this on a Samsung A20 with a Mali-G71. I've tried the same test on a device with an old Adreno 330 and I don't seem to get the same issue though.
Our driver will also have a wait in glGetQueryObjectui64vEXT(GL_QUERY_RESULT_EXT) if GL_QUERY_RESULT_AVAILABLE_EXT is not called, and the result is initialized to 0.
Can you please try this?
GLuint query; GLuint64 time; GLuint dis_result = 0; glGenQueriesEXT(1, &query); glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query); glClear(GL_COLOR_BUFFER_BIT); glEndQueryEXT(GL_TIME_ELAPSED_EXT); while (!dis_result) { glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &dis_result); } glGetQueryObjectui64vEXT(query, GL_QUERY_RESULT_EXT, &time); __android_log_print(ANDROID_LOG_ERROR, "Timer", "elapsed time is: %lld\n", (long long)time); glDeleteQueriesEXT(1, &query);
I can always get something like
elapsed time is: 4273
So if you are still getting -1, I think I have to contact Samsung if they changed the driver a little bit.
Hi Sunny,
Thanks for the quick reply. I've inserted that code snippet at the beginning of the frame (after checking the disjoint query) in the same codebase I was using, like so (for clarity):
void BeforeRenderingStarts() { // on disjoint exception, clear query buffer GLint disjointOccurred = false; glGetIntegerv(GL_GPU_DISJOINT, &disjointOccurred); if (disjointOccurred) { query_buffer_n = 0; __android_log_print(ANDROID_LOG_ERROR, "Timer", "Disjoint Exception occurred"); } { GLuint query; GLuint64 time; GLuint dis_result = 0; glGenQueries(1, &query); glBeginQuery(GL_TIME_ELAPSED, query); glClear(GL_COLOR_BUFFER_BIT); glEndQuery(GL_TIME_ELAPSED); while (!dis_result) { glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &dis_result); } glGetQueryObjectui64vEXT(query, GL_QUERY_RESULT, &time); __android_log_print(ANDROID_LOG_ERROR, "Timer", "elapsed time is: %lld\n", (long long)time); glDeleteQueries(1, &query); } ...
I don't seem to get any issues with that though. I get different values I'd consider plausible (e.g., 461268, 741576, etc...).
Regarding the pseudo GL stack I mention above, I forgot to mention that I don't seem to be able to trigger that anomaly (the -1 value) if I remove the shadow pass. Essentially this:
// App init - presumbaly Backbuffer is bound upon the initialization of eGL glBindFramebuffer(auxFBO, DRAW) glInvalidateFramebuffer(...) // makes no sense to me but... // expected glGetQueryObjectui64vEXT() here glBeginQuery() ... ... NO SHADOW PASS IN HERE.. ... glEndQuery() ... quite a few more GL calls (state, FBO binds, etc..) including draw calls eglSwapBuffers()
I can provide an MGD dump if that helps (and you have time to look into this of course). It's nothing but a simple (but rather shadowmap-heavy) scene rendering a bunch of spheres. Thanks for your help so far!
461268 and 741576 looks reasonable (just because your platform has different frequency setting)
yes, please provide an MGD or sample code for the shadow pass
Cheers Sunny! Will send it over soon.
Please find below the MDG trace from the app. Please let me know if that's sufficient or of any other issue you might have. Thanks once more for your help.
render-timing-original.zip
Hi Sunny, did you manage to have a look at the MGD trace? Cheers, Joao
I will have a look
I have created an internal ticket to handle this. I had a brief check with the MGD file, it seems to me that it queries the elapsed time stamp for every renderpass. That should be OK to me.
so I am setting up the Arm DS environment to run the trace, I hope it can give me some ideas
Cheers!
Sorry, the replay functionality has been removed from Arm DS 2020 version.
So can you please use patrace to capture?
https://github.com/ARM-software/patrace
That's the shame (I was actually aware of that functionality).
I had a look at patrace's docs and it seems to require a rooted phone to trace the calls. Do you happen to know if there's a way to use it with commercial devices?
*That's the shame (I WASN'T actually aware of that functionality).
I'll have a look at apitrace (if you think that would help). I'm not sure it has the same limitation.
Peter HarrisJosé Emilio Muñoz-López
Do you know if we can capture patrace on non-root device?
I haven't used apitrace, but looks similar