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
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
The two new rendering commands are
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:
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_TransferTarget (will be copying some CPU data to the GPU texture), or
TS_ResolveTarget. For depth-stencil textures, the new state can be
DSTS_DepthStencilRead (the depth-stencil won’t be updated).
BRC_TransitionTextureState). This has to be done because updating a texture is considered a resource command that is executed during
RendererBackend::ExecuteResourceCommands. Renoir has to be able to transition the to be updated texture to the correct state (
TS_TransferTarget) before updating. Hence we must also be able to transition textures states through backend resource commands.
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