7
\$\begingroup\$

Is there any chance draw calls like XNA's Graphics.DrawIndexedPrimitives has an extremely low overhead and performance issues are more than likely due to the complexity of the meshes?

If I had a million quads to render, how significant in XNA is it to pack the vertex buffer as full a possible before calling the draw (as an example)? I know many other methods of culling, vertex welding, etc to lower the count would probably have an even bigger impact if/when they are possible, but just for curiosity's sake lets not hit on those topics for this question.

My hope is that XNA indeed has a low overhead on most draw calls and pretty much buffers the 'transactions' necessary to the GPU in some kind of load balancing type way.

Thanks for any and all help.

\$\endgroup\$

1 Answer 1

7
\$\begingroup\$

Draw calls have a fair amount of CPU overhead, as the driver has to do a bunch of work internally on each call, so reducing the number of draw calls is often important for CPU performance. For the GPU, the number of vertices, triangles, textures etc. matters more than the number of draw calls. Conversely, the size of the draw calls doesn't matter very much for the CPU, only how many of them there are.

The rule of thumb that I've seen quoted often for DX9 (which XNA runs on) is no more than about 2,000-3,000 draws per frame to avoid becoming CPU-limited. YMMV, of course, but the limit is going to be on the order of several thousand, definitely not a million.

With very careful renderer design it's possible for games to push more draws. Firaxis gave a GDC talk describing how they achieved 15K draws in DX11. Another question here noted that Saints Row 3 apparently gets 7K draws in DX9.

In DX10-11 the CPU overhead of draw calls is supposed to be less than in DX9, but I haven't seen a measurement of how much less. The sense I have from talking to people about it is that this doesn't make a big difference, i.e. the draw call limit is still only a few thousand. DX11 also allows multithreaded draw call submission (deferred contexts), which is supposed to let you distribute the CPU overhead over multiple cores. However, internally the graphics driver may still be processing things with a single thread, so DX11 deferred contexts may not be very effective either.

On consoles, due to their lower-level APIs (which avoid a lot of layers of validation and conversion in D3D), you can use multithreading much more effectively and reach 10,000-20,000 draws per frame without being CPU-limited. (All of that doesn't help you for XNA; I mention it only for completeness.)

\$\endgroup\$
5
  • \$\begingroup\$ These are reasonable and practical numbers to work with. I'll just add the usual "always measure performance for the final answer within your own engine," once known parameters like these have been considered in your original implementation. \$\endgroup\$ Jun 15, 2013 at 17:15
  • \$\begingroup\$ Some interesting links on this topic: Charles and George and A elf in a box. I think the are very helpful in understanding how CPU and GPU work. \$\endgroup\$
    – 0xBADF00D
    Jun 18, 2013 at 6:17
  • \$\begingroup\$ It is all well and nice, but can anyone explain how Sait's Row The Third could get away with using over 7000 (!) draw calls with a DX9 engine:gamedev.stackexchange.com/questions/66932/… \$\endgroup\$
    – cubrman
    Dec 6, 2013 at 18:31
  • \$\begingroup\$ @cubrman That's a good question. I don't know how they did it, but I did see a talk about Civilization 5, which claimed that they got 15K draws (in DX11). I added a link to their GDC presentation. \$\endgroup\$ Dec 6, 2013 at 21:03
  • \$\begingroup\$ Would love to find out what they mean by "queuing the frame" and "packetized rendering" :). Thanks for the link. \$\endgroup\$
    – cubrman
    Dec 6, 2013 at 21:37

You must log in to answer this question.

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