I am newbie to OpenGL ES (so far, I used mainly DX11). Now for my scene, I have about 100 draw calls. I can use instancing, but only about half of objects can be instanced, so draw calls count would be about 50 - 60 / frame. Every object is max. 700 triangles (I use low-poly models)

What is some kind of limit of drawcalls per scene (targeting iPhone 4 like performance devices) ? So far I am running my code via ATI GLES on Windows, but there is a lot of power from my CPU and GPU.

Or is there a way, how to find bottleneck of my application ? I know gDebugger is for OpenGL, but with ES version it behave sometimes weird (a lot of warnings in calls I dont have in my code, so I suspect them to be from ATI layer code).


2 Answers 2


Draw calls by themselves are not always the bottleneck, it is what happens between them that is. Generally when you issue a draw call, the command buffer (state changes, data uploads, etc.) is evaluated and the expense of changing many states is actually deferred until this point. For instance, if you issue the same draw call back-to-back the second draw call will be significantly less expensive since there are no state changes. Because of this it is difficult to definitively say "keep your draw call count below X."

The story has traditionally been different in Direct3D, where pre-Windows Vista draw calls invoked a user-mode to kernel-mode context switch. Before D3D had a user-mode front-end (Windows Vista+) every draw call would cause an expensive context switch in addition to the expense of deferred state setup. When people optimize to minimize draw calls, this is probably why.

It is more effective to minimize state changes, which usually has a side-effect of reducing draw calls too. You'll want to develop a batch processor that sorts your geometry to minimize state changes - generally textures are the most important state change to minimize.

If you are seeing a lot of errors in gDEBugger, you may want to run your Windows software in an OpenGL debug context and enable debug output. This is an OpenGL 4.x-era feature, but if your driver supports the OpenGL ES extension it almost certainly has ARB_debug_output as well. Debug output will warn you when you do things like use misaligned data structures, which is handy for performance testing. See this answer for more details.

  • 1
    \$\begingroup\$ Actually according to the DX10 Technical Brief, the problem was not mode transitions (Dx9 did batch calls in it's own command buffer too and only needed to make a transition when flushing the buffer), it was validation; see static.compusa.com/pdf/… \$\endgroup\$ Aug 24, 2013 at 23:51
  • \$\begingroup\$ That is true too, but prior to Windows Vista's driver model, D3D calls were kernel-mode. When they added the user-mode front-end in Windows Vista (which applies to D3D9 as well) it reduced overhead significantly. \$\endgroup\$ Aug 25, 2013 at 1:28
  • \$\begingroup\$ Much validation was moved to creation time instead of runtime; that's why you see advice that creating resources in D3D10+ at runtime is not recommended. \$\endgroup\$ Aug 25, 2013 at 10:37

I wouldn't consider "700 triangles" as "low poly" for ES. Try to see if you can get your poly count even lower. Then make the poly count lower than that. I mean really decimate it.

Anyway, you need to run some experiments. I've been meaning to test this too, but haven't yet. At a certain point the pixel shader will likely be what limits your frame rate. Mobile devices don't have a very high fill rate, if you're alpha blending or trying to use bloom effects, that will be your limitation. I could not use bloom even on iPad 4 simply because it dropped the framerate by far too much (for even only relatively little geometry).

So anyway, run profiler on an actual device. Instance your model and be sure you compile in release mode and watch the frame rate in Xcode. You'll find the limits by testing.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .