I'm working on a game that uses CEGUI and Ogre. Recently, we've discovered that some of our customers with GeForce4 MX 4000's, performance is terrible.
After a night spent debugging, I've tracked the issue down to a glDrawArrays call inside the Ogre GL Renderer. Most executions of this call are pretty quick (<10ms, which still sucks but is ok for this terrible card). But one execution of the GLRenderSystem::_render function takes 3500ms every single frame.
It's only drawing a 54-element TRIANGLE_LIST. All the other calls to it are drawing similar-sized TRIANGLE_LISTs, so it's not the size of the array or its type that is the problem.
I've:
- disabled fragment shaders (the GF4 MX doesn't support them)
- disabled vertex shaders (it supports them, but CEGUI can only do all types of shaders or none of them)
- attempted to disable a nearby call for multitexturing
- massively simplified the UI that I'm drawing so that it is only a single CEGUI::Window
But I'm really just shooting in the dark. I'm in a windows environment. What's a good tool to figure out the OpenGL state at the time of a function call? I'm guessing that there's a particularly piggish texture or a fragment shader somehow slipping through and getting rendered.
If there aren't any tools to do what I need, can anyone suggest ways that glDrawArrays could be made really slow on an old card?
Update:
- I grabbed GLTrace and compared the calls that precede both a fast glDrawArrays and a slow one. They're absolutely identical, they're even binding the same texture IDs.
- One consistent difference however, is that the call that executes slowly is the first one in each OGRE/cegui render frame. Perhaps there is some copying-over of texture data to the video card each frame (which would be ridiculous and clearly doesn't happen on other cards...). Update: this isn't the case - no matter where in the queue I draw the offending object, it still takes forever. See below.
- There are 3 main objects being drawn: a full-window background (plain white, gets textured with a 128x128 texture), a smaller rectangular label, and text in that label. The ratios between their draw speeds are approximately the same the ratios between their areas
- If I force the slow object to be drawn several times instead of drawing the entire render queue, it is slow every time, which means it's not a one-time-loading issue.
Update for current theory: this is somehow a fill-rate issue. Is there a way to configure a window so that the card has issues filling it? Since I'm drawing in windowed mode, will that mess up a card sometimes? My window doesn't have power-of-two dimensions (or dimensions similar to any standard resolution), could that be a chokepoint?
glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_DYNAMIC_DRAW)
(replacingGL_ARRAY_BUFFER
as appropriate). \$\endgroup\$