PDA

View Full Version : glDrawElements taking too long



gaubtas123
11-06-2015, 04:57 PM
Hi. I've been having this problem where 300k model takes 1ms to draw on the previously written modelling program and takes 250ms on the new one. Here's what I've tried and which didn't have effect:

Switching shaders (eg 1st program to 2nd one and the other way around).
Disabling MSAA.
Disabling/Enabling Culling.

Switching libs/includes to previous project.
Switching resolution resolutions of the project.
Switching entire Display class.
Removing FPS caps.
Checking if both models have the same amount of vertices, they do.
Switching Opengl versions used by program.
Switching Dynamic draw and Static draw modes.
Checking if I'm not adding 300k vertex entities to my renderer each frame;
Switching between drawArrays, drawElements, drawElementsBaseVertex;
Double checking if both projects use 32bit;

I am only timing how long it takes for glDrawElements to complete. I am using <time.h> to do it.
P.S I have a sneaking suspicion that for some reason the new program doesn't use graphics card for some reason. Both programs aren't CPU intensive (atm basically just rendering 300k poly just diffrent structure) but the new one uses 17% of CPU while the old one uses 3% CPU.

GClements
11-06-2015, 10:52 PM
I am only timing how long it takes for glDrawElements to complete. I am using <time.h> to do it.

Are you calling glFinish() before and after the glDrawElements() call?

To time a single OpenGL function call, use e.g.


struct timeval start, finish;
glFinish();
gettimeofday(&start, NULL);
glDrawElements(...); // or whatever
glFinish();
gettimeofday(&finish, NULL);
// calculate time difference

The first glFinish() ensures that you aren't including the time taken to process any queued commands, the second ensures that you are measuring the time taken to actually execute the draw call rather than to simply enqueue it.

Alternatively, you can measure the time on the GPU with glBeginQuery(GL_TIME_ELAPSED). This should eliminate any CPU-side factors, and avoids stalling the pipeline (which can avoid potential issues with overal timing affecting what's actually being rendered due to e.g. scaling to frame rate).

gaubtas123
11-07-2015, 06:48 AM
When using glFinish() I still got 250ms, but when using glBeginQuery() I got 4ms which is what I expected. Then I tried using glBeginQuery() method for 1 call and then the entire draw procedure and it still got 4ms.

gaubtas123
11-07-2015, 07:33 PM
Found the problem:

calling
glDrawElements(GL_TRIANGLES, entities_[i]->get_num_indices(), GL_UNSIGNED_INT, 0);
and
inline unsigned int get_num_indices() { return model_.indices.size(); }
in the entity class takes no time what so ever.

But calling:
glDrawElements(GL_TRIANGLES, entities_[i]->get_model().indices.size(), GL_UNSIGNED_INT, 0);
takes 200ms.

I have no idea why. If anyone does please theorize.

GClements
11-07-2015, 11:32 PM
Found the problem:

calling
glDrawElements(GL_TRIANGLES, entities_[i]->get_num_indices(), GL_UNSIGNED_INT, 0);
and
inline unsigned int get_num_indices() { return model_.indices.size(); }
in the entity class takes no time what so ever.

But calling:
glDrawElements(GL_TRIANGLES, entities_[i]->get_model().indices.size(), GL_UNSIGNED_INT, 0);
takes 200ms.

I have no idea why. If anyone does please theorize.

Presumably calling the get_model() method takes 200ms while accessing the model_ field directly takes negligible time.