Render Targets and Render Target Manager

A unified mechanism for hardware (GPU) render target creation and management is exposed in the API. All render targets are managed by the resource manager and are cached for reuse. Any kind of resource management for resizing targets is also handled by the resource manager. As with other GPU resources, the interface can encapsu­late the resource in a draw API agnostic manner.

A render target can be described as a target block of pixels (buffer) into which rendering will occur.

A render target should not be thought of as an onscreen output buffer such as DirectX SwapChain, nor an Open frame buffer or an OpenGL context. This goes back to the notion that the renderer is not necessarily a viewport, which assumes that rendering into a viewport is the same as rendering into an OpenGL context.

In the API a render target is represented by an MRenderTarget.

It is possible to have a target which:

  1. Holds color values. This is called a color target.
  2. Holds depth values. This is called a depth target.
  3. Holds depth and stencil values. This is called a depth+stencil target.

The most accurate description of a colour and depth target is that it’s a texture that can be rendered into. One or more color targets and/or a depth target can be set to indicate where rendering is actively being sent to.

In legacy interfaces, only one format was supported for color and one for depth. This was fixed RGBA 24-bit color and fixed 24-bit depth. The stencil format support remains single channel 8-bit fixed point. The current possible variations are described using an MRenderTargetDescription. This descriptor includes options for:

The process to acquire a render target is as follows:

  1. Create and fill in a descriptor (MRenderTargetDescription) for a render target.
  2. Attempt to acquire a target from the target manager (MRenderTargetManager)
  3. It is possible that this acquire can fail and is dependent on the video card, the card driver and the currently available resources. For instance render targets can use up a fair amount of GPU memory and it is possible to fail trying to create a target with large dimensions, high bit depth and a multisampling parameter value.

To avoid the complications of target management, a convenient method has been provided on the target to allow a new descriptor to be set. Whenever this method is invoked, a format change or a resize is attempted. As with an initial acquire, it is possible that the resize may fail.

Figure 32: On the left are 2 possible render targets. The target with the name “MyColorTarget” is a color target with an R16G16_Float. The second target named “MyDepthTarget” is a 32 bit floating point depth target. The names are used to reference the actual render targets on the GPU. On the right is the layout for acquisition and update. The “Update Description” action attempts to update the GPU resource via another acquire

It is possible to access the resource handle for color and depth render targets but not necessarily a depth+stencil target. For DirectX11, color and depth targets are returned as a reference to a view (ID3D11RenderTargetView) of a target. Depth+stencil targets are returned as depth stencil (ID3D11DepthStencilView) views. For OpenGL, color and depth targets are returned as references to textures (integer texture identifier). Depth+stencil targets are not accessible. It is possible to modify the contents of the target directly but is generally not recommended. Plug-ins should never delete the underlying resource.

To avoid confusion, the legacy interface, which is also called MRenderTarget differs from the construct discussed here which is in the MHWRender namespace (MHWRender::MRenderTarget). The previous definition is simply a wrapper around a viewport OpenGL context and has no relation to this framework.