Sign in to follow this  
BrentMorris

Stream Out and DrawAuto() Question

Recommended Posts

I have a few questions related to streaming geometry data out to a buffer, and then using DrawAuto() to render it.

 

1. Does DrawAuto() skip vertex/geometry shaders with the information from the stream-out buffer? Can you get away with binding only a pixel shader on the re-render? 

 

2. Can a DrawAuto() pass data back through a vertex or geometry shader somehow? I'm wondering if you can render the vertex/geometry shader output to a stream-out buffer without a view/projection matrix transform, and then re-use the data with different view/projection matrices. I'm hoping to render my world geometry to a stream-out buffer, before re-using it multiple times with different view/projection matrices for shadow mapping.

 

3. Is anyone using stream-out buffers for depth pre-pass rendering? You can totally avoid running vertex/geometry shaders twice, which is awesome.

Share this post


Link to post
Share on other sites

When you stream out, the data goes to a vertex buffer. So when you DrawAuto, all of the vertices go through the vertex shader and geometry shader again. You can not bind a geometry shader when using DrawAuto, but you will still need to have a vertex shader bound. However your vertex shader can be a simple pass-through shader that doesn't perform any transformations.

In general stream out really isn't popular as an optimization. There's several reasons for this:

 

1. Stream out and geometry shaders tend to be pretty expensive, because they involve dumping lots of data to GPU memory instead of just keeping it all on-chip

2. You can't stream out indexed vertex data and rasterize at the same time. The GS stage gets fully expanded primitives, and if you stream that out you'll get end up with a vertex buffer where repeated vertices are duplicated. You can work around this by rendering with point topology, but then you can't rasterize so you have to do a draw pass that *only* streams out.

3. Vertex shader work tends to be only a small fraction of overall GPU processing. Typically the only time it even registers is if you have a really heavy vertex shader (for instancing skinning with lots of joints, or blend shapes). So for a lot of cases the savings won't be enough to justify the expense. At work we used to do it only for skinned meshes, and eventually I turned it off because too often it ended up being slower.

A far better option is available in DX11.1 feature level, which is to directly write out vertex data to UAV's from a vertex shader. On 11.0 you can also just use a compute shader, although that can present some logistical problems in terms of juggling shaders.

Share this post


Link to post
Share on other sites

The only time I have ever heard that the stream output was a win is when you are using the tessellation stages and want to do multi-pass rendering.  Then you can cache the tessellated geometry and reuse it in subsequent passes.

 

@DementedCarrot: For point #2, that is precisely how normal rendering works :)  you have object space vertices that get transformed to multiple projections depending on what you are doing!

 

@MJP: For point #2, it is actually possible to rasterize and output to a stream (up to three streams IIRC) at the same time.  But you are right about the limitations - there is no indexed geometry possible, so the extra memory size of the buffers can be a big negative if you want to try to do the caching method.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this