2
\$\begingroup\$

I'm using DX11. I understand how render targets are created, set, and why they are used, but I am really unsure how this all plays together with presenting it to the screen.

Does the GPU automatically flatten all render targets onto the back buffer, and how does this work with multiple back buffers?

If I were to have multiple render-targets for deferred rendering, or some customized post processing shader (using a ping-pong model) how do multiple render targets get presented accordingly? I assume I have to set the final render-target used to be presented to the screen. But I am not sure.

\$\endgroup\$
1
\$\begingroup\$

The render targets become sampling textures for a final compositing pass shader rendering to the back buffer.

The GPU doesn't do any automatic flattening. It all has to be done in a shader.

Ping-pong is less often necessary now that GPUs can handle large number of texture sampling operations in a single pass.

Support for older GPUs may still require ping-pong for those effects such as ambient occlusion, ambient lighting, depth blur, bloom, etc.

Or for simplicity's sake it's easier to have each post effect be a separate process/module and this requires ping-pong between temporary buffers.

With recent GPUs combining the compositing passes inside a single shader can improve performance by reducing memory bandwidth as long as it doesn't hit the GPU's internal shader code size cache limit. This limit varies between GPU models.

The memory bandwidth penalty of ping-pong becomes more significant as the resolution increases (4K, 8K, ...) and GPUs become faster relative to their memory. This tends to even more significant for mobile and integrated GPUs as their memory bandwidth is very limited relative to GPU core speed.

Ping-ponging also introduces stalls in the pipeline: The GPU's tile dispatcher has to wait for the previous render to finish before using the render target as a texture in the next step. Doing this multiple times can quickly cause post-effects to become the largest consumer (>50%) of your GPU render time. This is when it's time to consider combining post-processing passes if possible.

This is not DX11 specific. All of this applies to just about any GPU rendering APIs.

\$\endgroup\$
  • \$\begingroup\$ Are multiple render targets for special effects used anymore? Seems like you could just render a screen quad around objects, or full screen to do what you want, on the main render target. Also, I am assuming, there is 1 render target associated with the back buffer, so you need to do a final pass onto this buffer, correct? \$\endgroup\$ – Mike5050 Mar 19 '18 at 12:38
  • \$\begingroup\$ Not so simple. You actually could render to multiple targets and the final render pass to a target could be sampling from the others and compositing. Therefore not using a full screen quad at all. \$\endgroup\$ – ErnieDingo Jun 11 '18 at 23:37
0
\$\begingroup\$

To answer your question about how multiple render targets are presented, it's not that simple but you can imagine at the end of your frame for rendering you have one output presented on screen (although you have rendered to multiple targets in that time).

Whether forward rendering or deferred rendering, you will end up sending a frame to the swap chain. In earlier versions of the swap chain, you grabbed a pointer to the backbuffer frame and rendered everything into it. Later, the addition of SWAP_DISCARD and SWAP_SEQUENTIAL were developed. These are the only compatible modes for UWP based applications. These require you to use the resolve resource call for MSAA render targets into the backbuffer, which ever one you choose you must resolve. This is usually your final frame composition as the backbuffer will not be multisampled.

Basically, you can create multiple render targets in memory, and render to each individually OR, you can set multiple render targets and tell your pixel shader to render to each one at the same time (with different data obviously). These render targets are usually have a shader resource view attached also, so they then can be used on the next render pass as source textures.

For example - very simple cascaded set

Pass 1 - Multiple targets

Render Diffuse Render Normals

Pass 2 - SSAO

Read Z Buffer Read Normals from Texture Render Ambient Lighting Frame

pass 3 - combine - Some use screen space quad

Combine Diffuse and Ambient Render to FinalBuffer

resolve resource to backbuffer

That was a simple example, but you can leverage that pattern to be able to use for on forward and deferred.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.