Draw indirect for DX11

Started by
13 comments, last by MJP 7 years, 2 months ago

Is there any documentation or complete tutorial or references for draw indirect on D3D11? Is the D3D11 version of draw indirect as robust as the D3D12 version? I found one barebones tutorial on it through google but thats about it. Any help would be greatly appreciated.

-potential energy is easily made kinetic-

Advertisement

ExecuteIndirect has a lot of functionality that's not supported by DrawIndirect and DispatchIndirect. DrawIndexedInstancedIndirect is exactly the same as DrawIndexedInstanced, except the arguments come from buffer resource instead of being passed in. So you'll need to have the GPU write to a buffer where the first 4 bytes represent IndexCountPerInstance, the next 4 bytes represent InstanceCount, the next 4 represent StartIndexLocation, and so on. DispatchIndirect is exactly the same, except your buffer contains ThreadGroupCountX, ThreadGroupCountY, and ThreadGroupCountZ. The buffer resource needs to be created with D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS to be used as indirect arguments.

I'm not sure if there were ever any official samples that used DrawIndirect. I used it in a depth of field sample I wrote a long time ago, where I basically spawned bokeh-shaped particles for certain pixels. For something more advanced, you could look at my shadow rendering sample, where I used DrawIndirect to render meshes after performing culling on the GPU.

Can you change any state like texture bindings? Or is it barebones DIP parameters only?

-potential energy is easily made kinetic-

You can only change the draw args.

The best approximation would be to DrawIndirect once for each set of textures you might want to apply to the draw and then zero out the index count for any draw you want to cull completely. So long as there aren't too many zero-count draws you shouldn't hit the unfortunate bottleneck of being Command Processor bound.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

But if you can't change state how would you use for example a different MVP matrix within the same texture batch?

-potential energy is easily made kinetic-

You can change state between draws, just not between different instances within the same DrawInstancedIndirect call.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

You might have heard the term multi-draw indirect (MDI). I believe there was an OpenGL extension for it. That's the idea of submitting multiple draws with state changes in a single indirect call, which is similar to ExecuteIndirect, but D3D11 does not have any form of MDI. Like Adam said, no state changes between instances.

AMD has a MDI extension for D3D11 accessible via their AGS library.

But if you can't change state how would you use for example a different MVP matrix within the same texture batch?

Bind more than one matrix in a buffer (cb or srv).

AMD has a MDI extension for D3D11 accessible via their AGS library.


Nvidia also has an NVAPI extension: https://docs.google.com/spreadsheets/d/1J_HIRVlYK8iI4u6AJrCeb66L5W36UDkd9ExSCku9s_o

Anyway to get back to state changes, it's the same as if you made a normal DrawIndexedInstanced call. Your vertex shader will have SV_VertexID available as well ad SV_InstanceID, so you're free to use those to index into buffers however you'd like. But you can't actually change bindings per-instance, just like a normal instanced draw call.

This topic is closed to new replies.

Advertisement