LiteFX::Rendering::IBarrier¶
The interface for a barrier.
Synopsis¶
Declared in <litefx/rendering_api.hpp>
class [[dllimport, dllexport]] IBarrier;
Description¶
Barriers are used to synchronize the GPU with itself in a command buffer. They are basically used to control the GPU command flow and ensure that resources are in he right state before using them. Generally speaking, there are two related types of barriers:
- Execution barriers are enforcing command order by telling the GPU to wait for certain pipeline stages or which stages to block until an operation has finished. - Memory barriers are used to transition resources between states and are a subset of execution barriers. Each memory barrier is always also an execution barrier, but the opposite is not true.
An execution barrier is simply a barrier without any resource transitions happening. The only properties that are set for an execution barrier are two pipeline stages defined by IBarrier::syncBefore and IBarrier::syncAfter. The first value defines the pipeline stages, all previous commands in a command buffer need to finish before execution is allowed to continue. Similarly, the second value defines the stage, all subsequent commands need to wait for, before they are allowed to continue execution. For example, setting syncBefore to Compute and syncAfter to Vertex logically translates to: All subsequent commands that want to pass the vertex stage need to wait there before all previous commands passed the compute stage. To synchronize reads in previous commands with writes in subsequent commands, this is sufficient. However, in order to do the opposite, this is not enough. Instead resource memory needs to be transitioned by specifying the desired ResourceAccess, alongside the ImageLayout for images (note that buffers always share a common layout that can not be changed). This is done using memory barriers. There are two types of memory barriers used for state transitions:
- Global barriers apply to all resource memory. - Image and buffer barriers apply to individual images or buffers or a sub-resource of those.
Any IBarrier can contain an arbitrary mix of one or more global and/or image/buffer barriers. A global barrier is inserted by calling IBarrier::wait. This method accepts two parameters: a before and an after access mode. Those parameters specify the ResourceAccess for the previous and subsequent commands. This makes it possible to describe scenarios like wait for certain writes to finish before continuing with certain reads. Note that a resource can be accessed in different ways at the same time (for example as copy source and shader resource) and specifying an access state will only wait for the specified subset. As a rule of thumb, you should always specify as little access as possible in order to leave most room for optimization.
Image and buffer barriers additionally describe which (sub-)resources to apply the barrier to. For buffers this only applies to individual elements in a buffer array. However, due to [driver] restrictions](https://microsoft.github.io/DirectX-Specs/d3d/D3D12EnhancedBarriers.html#buffer-barriers), buffers are always transitioned as a whole. This is different from image resources, which have addressable sub-resources (mip levels, planes and array elements). For images, it is possible to transition individual sub-resources into different ImageLayout "ImageLayouts" to indicate when and how a texture is used. An image in a certain layout poses restrictions on how it can be accessed. For example, a ReadWrite image written by a compute shader must be transitioned into a proper layout to be read by a graphics shader. To facilitate such a transition, a barrier is required. Image barriers can be inserted by calling one of the overloads of IBarrier::transition that accepts an IImage parameter.
Member Functions¶
| Name | Description |
|---|---|
~IBarrier [destructor] [virtual] | Destructor |
syncAfter [virtual] | Returns the stage all subsequent commands need to wait for before continuing execution. |
syncBefore [virtual] | Returns the stage that all previous commands need to reach before continuing execution. |
transition | transition overloads |
wait [virtual] | Inserts a global barrier that waits for previous commands to finish accesses described by accessBefore before subsequent commands can continue with accesses described by accessAfter. |
Protected Member Functions¶
Derived Classes¶
| Name | Description |
|---|---|
Barrier | A barrier used for GPU resource synchronization. |
See Also¶
PipelineStage
IBuffer
ResourceAccess
IImage
ImageLayout
ICommandBuffer