DirectX 12 Render Pass Beginning and Ending Actions

DirectX 12 render passes optimize GPU workloads by explicitly declaring how render targets and depth-stencil buffers are accessed across a series of rendering commands. By defining explicit beginning and ending actions within the render pass description, the graphics driver can optimize resource allocation and memory bandwidth, which provides significant performance advantages on Tile-Based Deferred Rendering (TBDR) architectures and unified memory systems.

In DirectX 12, render passes are initiated via the BeginRenderPass method. The configuration is declared using D3D12_RENDER_PASS_RENDER_TARGET_DESC and D3D12_RENDER_PASS_DEPTH_STENCIL_DESC structures. Each structure requires developers to define a beginning access type and an ending access type.

Beginning Actions (D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE)

The beginning action tells the GPU what state the resource is in and what needs to happen to the surface before rendering begins.

  • DISCARD: Indicates that the existing contents of the surface do not need to be preserved and can be overwritten. On TBDR architectures, this prevents the GPU from loading stale data from main memory into high-speed on-chip cache.
  • PRESERVE: Indicates that the existing contents of the surface must be maintained. The GPU will ensure existing data from previous operations is loaded into local memory or made available for rendering.
  • CLEAR: Clears the resource to a specified optimized clear value immediately upon starting the pass, combining clear operations directly into the render pass setup.
  • NO_ACCESS: Indicates that the GPU will neither read from nor write to the surface at the start of the pass. This is commonly used in depth-only or stencil-only passes to indicate that the unused subresource is ignored.

Ending Actions (D3D12_RENDER_PASS_ENDING_ACCESS_TYPE)

The ending action defines what should happen to the rendered surface once all draw calls within the render pass are complete.

  • DISCARD: Specifies that the final contents of the resource are not needed after the pass completes. The GPU does not need to write the contents back out to main memory, conserving valuable memory bandwidth. This is ideal for transient surfaces such as intermediate depth buffers.
  • PRESERVE: Writes the final rendered results back to the underlying resource memory so that subsequent passes or shaders can sample or display the contents.
  • RESOLVE: Automatically downsamples and resolves a multi-sampled render target (MSAA) into a separate single-sampled target at the end of the pass. This combines what previously required a distinct ResolveSubresource call directly into the render pipeline.
  • NO_ACCESS: Specifies that the GPU will not write to or read from the surface at the end of the pass, keeping it inactive.

By utilizing accurate beginning and ending actions, engines eliminate redundant memory traffic between system VRAM and local GPU caches, minimizing stalls and maximizing execution efficiency.