UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
GPUSortManager.h File Reference
#include "CoreMinimal.h"
#include "Templates/RefCounting.h"
#include "RHI.h"
#include "RenderResource.h"

Go to the source code of this file.

Classes

class  FParticleSortBuffers
 
class  FGPUSortManager
 
struct  FGPUSortManager::FAllocationInfo
 
struct  FGPUSortManager::FKeyGenInfo
 

Enumerations

enum class  EGPUSortFlags : uint32 {
  None = 0x00 , LowPrecisionKeys = 0x01 , HighPrecisionKeys = 0x02 , AnyKeyPrecision = 0x03 ,
  KeyGenAfterPreRender = 0x04 , KeyGenAfterPostRenderOpaque = 0x08 , AnyKeyGenLocation = 0x0C , SortAfterPreRender = 0x10 ,
  SortAfterPostRenderOpaque = 0x20 , AnySortLocation = 0x30 , ValuesAsG16R16F = 0x40 , ValuesAsInt32 = 0x80 ,
  AnyValueFormat = 0xC0
}
 

Functions

ENGINE_API void CopyUIntBufferToTargets (FRHICommandList &RHICmdList, ERHIFeatureLevel::Type FeatureLevel, FRHIShaderResourceView *SourceSRV, FRHIUnorderedAccessView *const *TargetUAVs, int32 *TargetSizes, int32 StartingOffset, int32 NumTargets)
 
 DECLARE_DELEGATE_SixParams (FGPUSortKeyGenDelegate, FRHICommandListImmediate &, int32, int32, EGPUSortFlags, FRHIUnorderedAccessView *, FRHIUnorderedAccessView *)
 

Enumeration Type Documentation

◆ EGPUSortFlags

enum class EGPUSortFlags : uint32
strong

Different sort flags used to define constraint for FGPUSortManager tasks.

Enumerator
None 
LowPrecisionKeys 

Sorting happens on either 16 bit keys or 32 bit uint keys. Those can come from float point formats being converted to uint. Because sort tasks are grouped into batches, the keys also have to start with the batch element index, which ends up either increasing the 16 bit keys or taking space in the 32 bit keys (by the number of bits required to store the element indices). The more task are created, the more bits are required to encode the element index (up to a limit of 16^2 elements). Low precision keys have the advantage of being quicker on the GPU when performing the radix sort, which is affected by the number of bits.

HighPrecisionKeys 
AnyKeyPrecision 
KeyGenAfterPreRender 

The sort task are created in FPrimitiveSceneProxy::GetDynamicMeshElements() but have different requirements in terms of when the keys can be generated, and when the sorted values are required within the frame. Cascade renders the particles after GPU simulation (either in PreRender(), or in PostRenderOpaque() see ::CollisionDepthBuffer). Niagara, on the other hand, renders the particle before they get updated by simulation (either in PreInitViews() or PostRenderOpaque()) For Niagara emitters updated in PreInitViews(), this happens before GetDynamicMeshElements() so doesn't impose any restriction in the end. This means each system has some flexibility on when the sort keys can be generated depending on the simulation point for each emitter.

KeyGenAfterPostRenderOpaque 
AnyKeyGenLocation 
SortAfterPreRender 

Once keys are generated, they must be sorted and the indices only need to be ready before the primitive are rendered. The (frame) location only depends on whether the emitter uses opaque materials or translucent materials. It is possible to have an incorrect setup if the keys can only be generated after PostRenderOpaque() but the sorting must be ready after PreRender(). This happens with opaque Cascade emitters when simulation needs the depth buffer to do collision tests. A sort requests can have both SortIndicesAfterPreRender and SortIndicesAfterPostRenderOpaque when it is allowed to sort keys at either point.

SortAfterPostRenderOpaque 
AnySortLocation 
ValuesAsG16R16F 

The sorted values can either be read as 1D or 2D, but doesn't otherwise affect the sorting implementation as long as the storage size is the same. Currently it is 32 bits in both cases. Note that the sorting shader reads the indices as UInt32 (see FParticleSortBuffers::InitRHI()).

ValuesAsInt32 
AnyValueFormat 

Function Documentation

◆ CopyUIntBufferToTargets()

ENGINE_API void CopyUIntBufferToTargets ( FRHICommandList RHICmdList,
ERHIFeatureLevel::Type  FeatureLevel,
FRHIShaderResourceView SourceSRV,
FRHIUnorderedAccessView *const *  TargetUAVs,
int32 TargetSizes,
int32  StartingOffset,
int32  NumTargets 
)

Copy one uint buffer into several overlapping targets. Each target is expected to be bigger than the previous one, so that copy resumes where it left. Ex : (ABCDEFGHIJK) -> (ABC–, —DEFGHI-, ------—JK—) This is essentially used to manage growable buffers in cases the binding needs to be set before the final size required is known. In this scenario, the smaller buffers are temporary and only the final (biggest) buffer becomes persistent, this is why it has apparently unused space at the beginning but it will be used the next frame to hold all of the data. Note that required calls to RHICmdList.Transition need to be handled before and after this function.

Parameters
RHICmdList- The command list used to issue the dispatch.
FeatureLevel- The current feature level, used to access the global shadermap.
SourceSRV- The source uint buffer to be copied into the others.
TargetUAVs- The destination overlapping uint buffers.
TargetSizes- The copy size of each of the buffers. Once a buffer size is reached, the copy targets the next buffer.
StartingOffset- The starting position at which the copy starts. Applies for both the source and targets.
NumTargets- The number of elements in TargetUAVs and TargetSizes.

◆ DECLARE_DELEGATE_SixParams()

Callback used by the FGPUSortManager to make each client system initialize the sort keys for a specific sort batch. Sort batches are created when GPU sort tasks are registered in FGPUSortManager::AddTask(). Note that the system that is getting this callback must only initialize the data for the elements is has registered in this batch.

Parameters
RHICmdList- The command list used to initiate the keys and values on GPU.
BatchId- The GPUSortManager batch id (regrouping several similar sort tasks).
NumElementsInBatch- The number of elements grouped in the batch (each element maps to a sort task)
Flags- Details about the key precision (see EGPUSortFlags::AnyKeyPrecision) and the keygen location (see EGPUSortFlags::AnyKeyGenLocation).
KeysUAV- The UAV that holds all the initial keys used to sort the values.
ValuesUAV- The UAV that holds the initial values to be sorted accordingly to the keys.