Reputation: 21
It seems that this feature is very poorly documented.In the Geometry Shader tutorials in the DirectX SDK there is no example of using CreateGeometryShaderWithStreamOutput and there are no threads anywhere that explain the basics of it.In msdn they say what functions to use to create it,but not how and what it's used for.Is there anyone who has successfully used it,can you share a small example or a link to a tutorial for it?What's it used for and is it good performance wise?As far as I understood,it's used for GPU-based frustum culling?
Upvotes: 2
Views: 5431
Reputation: 8963
You can find 2 examples in the DirectX SDK (In the directX 10 section)
You can also check the NVidia samples: http://developer.download.nvidia.com/SDK/10/direct3d/samples.html
Rain and Metaballs are using stream out
All those samples are on dx10, but they fairly easy to port to dx11 (just few bits to replace).
There's quite several usages for it (non exhaustive list):
In case you want to use raw pipeline instead of stream output, you need to perform the following (this is a summary from Microsoft Stream Output documentation)
FX Framework does the same under the hood.
Your Geometry shader must be created with CreateGeometryShaderWithStreamOutput
instead of CreateGeometryShader
You need to set D3D11_SO_DECLARATION_ENTRY to match your geometry shader output layout (This works the same as Input Assembler)
Next make sure your buffer is created with stream output access:
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.BindFlags = otherBindFlags | D3D11_BIND_STREAM_OUTPUT;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.CPUAccessFlags = 0;
Please note that otherBindFlags cannot be D3D11_BIND_UNORDERED_ACCESS at the same time (Shader View and Raw Views are allowed tho).
Finally, before to perform your draw, assign your stream output buffer with SOSetTargets:
UINT offset[1] = 0;
ID3D11Buffer* m_pBuffer (your buffer created before)
deviceContext->SOSetTargets( 1, &m_pBuffer, offset );
Once you are done with your draw call, don't forget to clean using:
UINT offset[1] = 0;
ID3D11Buffer* pNullBuffer = 0;
deviceContext->SOSetTargets( 1, &pNullBuffer, offset );
Upvotes: 3