Resource Barriers

Modern graphics APIs like DirectX12 and Vulkan require the use of resource state transitions (or resource barriers). This means that before using any GPU resource in a certain way, you have to tell the driver that the resource will be used in that way. For Dx12 this is done through the ID3D12GraphicsCommandList::ResourceBarrier API and for Vulkan through vkCmdPipelineBarrier.

In Renoir, previously the state transitioning logic was completely handled in the backends. The backend was responsible for inserting the barriers and deciding at which point to do this. This imposes certain complexity to be in the backends while it can be handled by Renoir Core itself.

Currently, Renoir can generate an explicit state transitions in certain cases. This is done through a dedicated backend commands that instruct the backends to insert a resource barrier that transitions a given resource to some state. Given that not all graphics APIs support resource barriers, Renoir will generate state transition commands only when the SupportsResourcesStateTransitions field of renoir::RendererCaps is set to true in RendererBackend::FillCaps.

The two new rendering commands are BC_TransitionTextureState and BC_TransitionDSTextureState handle the state transitions of textures and depth-stencil textures in the backends. Their corresponding command structures look similar and are of the form:

struct TransitionTextureStateCmd
{
	Texture2DObject Tex;     // the texture object for which we want the resource barrier
	TextureState NewState;   // the requested new state for the object.
};

For texture the new state can be one of TS_RenderTarget, TS_ShaderResource, TS_TransferTarget (will be copying some CPU data to the GPU texture), or TS_ResolveTarget. For depth-stencil textures, the new state can be DSTS_DepthStencilReadWrite or DSTS_DepthStencilRead (the depth-stencil won’t be updated).

An example implementation of how the Renoir generated resource barriers are handled can be found in the DirectX12 and Vulkan backends.

Explicit and implicit resource state transitions

Because of architectural reasons, Renoir cannot handle the state transitions of every GPU resource. This means that certain backends must still handle some of their resource barriers implicitly.

Different graphics APIs may require different implicit barriers. For DirectX12 the implicit barriers in the provided backend are when:

  • Vertex buffer is mapped and unmapped
  • Index buffer is mapped and unmapped
  • Constant buffer is created and updated
  • A texture is created

The scenarios where Renoir will generate explicit resource barriers are:

  • a texture will be used as a shader resource
  • a texture will be used as a render target
  • a texture will be used as a target for multi-sampled resolve operation
  • a depth stencil texture will be used