7
\$\begingroup\$

I don't seem to be able to understand this. Microsoft says that one of the possible optimizations of for a Direct3D 11 if to batch primitives draw calls. For example in order to draw say 300 triangles calling the Draw method each time, you would instead pack and Draw them all at once.

The thing I don't get is how you would actually draw them in different locations and everything, because for example, I need one different world transformation matrix for each one. The only thing that comes to my mind is to calculate everything on the CPU and set the values for each vertex manually, however this approach doesn't seem like it would be a very good code optimization to me.

I feel like I'm missing something but I can't find the answer anywhere. The question is: how would you be able to pack things in a draw call without needing a render state change, and still get objects in different locations?

Note that I am not asking for pieces of code here, I'm primarily looking for a theorical answer to this.

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

There is many ways to do Batching. But for DX11, Instancing is the best choise, and it´s realy efficent and easy to use!

there is plenty of resources on DX11 instancing :

Rastertek instancing
MSDN Instancing reference

How it works is that you create an extra Buffer containing all the worldtransform matrixes. that you pass to the shader.

from there, you will get a "perlayout" matrix, that corresponds to each instance.

The old way of doing this is via calculating the world position for all the triangles befor drawing them, and then using the view_projection matrix.

\$\endgroup\$
1
  • \$\begingroup\$ I actually read about instancing before, but I wasn't sure what it was about. Thank you! I'll read more on this matter now. \$\endgroup\$
    – Kaboose
    Apr 25, 2013 at 15:01
4
\$\begingroup\$

The only thing that comes to my mind is to calculate everything on the CPU and set the values for each vertex manually, however this approach doesn't seem like it would be a very good code optimization to me.

You might be surprised, then.

Obviously, this will depend on the complexity of the geometry you're drawing and the transformations you're applying to it, but you have to remember that the CPU time consumed by Draw calls is not insignificant. It will very quickly add up if you have lots of little batches. So if the geometry and transformations are simple, it can very often make a lot of sense to trade the (relatively expensive) Draw calls for (relatively cheap) CPU-based transformations.

This is how XNA's SpriteBatch works--it accumulates potentially thousands of sprites into a CPU-based buffer by manually transforming vertices, then it sends them all to the GPU at once. Doing a separate Draw call for hundreds or thousands of sprites would bring your framerate to its knees, but calculating the positions of their vertices is easy and fast. It's a huge win.

As Tordin explains in his answer, hardware instancing can let you have your cake and eat it too, and is often a good idea. However, the idea of batching primitives the manual way is a general principle that applies even when hardware instancing isn't available.

\$\endgroup\$
6
  • \$\begingroup\$ Oh, then... wouldn't you be better off just using software rendering? Like GDI+ or something like that? For a 2D sprite based game for example. \$\endgroup\$
    – Kaboose
    Apr 25, 2013 at 14:59
  • 1
    \$\begingroup\$ What makes you think that hardware transformation is the only benefit of rendering on the GPU? The GPU is still going to be faster at drawing the sprites, as well as having more functionality. For that matter, what makes you think that you only need to render sprites in a sprite-based game? Even a 3D game needs a 2D interface. \$\endgroup\$ Apr 25, 2013 at 15:10
  • \$\begingroup\$ Lesson to be learned: when people quote "premature optimization is the root of all evil" it is exactly this that they are talking about. You summarily dismissed the "best" option that Microsoft offers because you thought it wouldn't be very fast. \$\endgroup\$ Apr 25, 2013 at 15:45
  • \$\begingroup\$ I'm not sure how what I wrote could be construed to mean that. I explained the benefit of manually transforming batched primitives because it is a concept which is important for game developers to understand. I absolutely did not "dismiss" anything; hardware instancing is very probably the correct solution to this problem. But pointing someone to a solution without explaining the core issues involved, or in this case why the Microsoft documentation said what it did, is not something I consider helpful to anybody. \$\endgroup\$ Apr 25, 2013 at 15:56
  • \$\begingroup\$ That's to the Kaboose quote "doesn't seem like it would be a very good code optimization" and definitely not to your answer, which is pretty good. \$\endgroup\$ Apr 25, 2013 at 20:58

You must log in to answer this question.

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