UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
GPUSkinCache.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2// Copyright (C) Microsoft. All rights reserved.
3
4/*=============================================================================
5 GPUSkinCache.h: Performs skinning on a compute shader into a buffer to avoid vertex buffer skinning.
6=============================================================================*/
7
8// Requirements
9// * Compute shader support (with Atomics)
10// * Project settings needs to be enabled (r.SkinCache.CompileShaders)
11// * feature need to be enabled (r.SkinCache.Mode)
12
13// Features
14// * Skeletal mesh, 4 / 8 weights per vertex, 16/32 index buffer
15// * Supports Morph target animation (morph target blending is not done by this code)
16// * Saves vertex shader computations when we render an object multiple times (EarlyZ, velocity, shadow, BasePass, CustomDepth, Shadow masking)
17// * Fixes velocity rendering (needed for MotionBlur and TemporalAA) for WorldPosOffset animation and morph target animation
18// * RecomputeTangents results in improved tangent space for WorldPosOffset animation and morph target animation
19// * fixed amount of memory per Scene (r.SkinCache.SceneMemoryLimitInMB)
20// * Velocity Rendering for MotionBlur and TemporalAA (test Velocity in BasePass)
21// * r.SkinCache.Mode and r.SkinCache.RecomputeTangents can be toggled at runtime
22
23// TODO:
24// * Test: Tessellation
25// * Quality/Optimization: increase TANGENT_RANGE for better quality or accumulate two components in one 32bit value
26// * Bug: UpdateMorphVertexBuffer needs to handle SkinCacheObjects that have been rejected by the SkinCache (e.g. because it was running out of memory)
27// * Refactor: Unify the 3 compute shaders to use the same C++ setup code for the variables
28// * Optimization: Dispatch calls can be merged for better performance, stalls between Dispatch calls can be avoided (DX11 back door, DX12, console API)
29// * Feature: Cloth is not supported yet (Morph targets is a similar code)
30// * Feature: Support Static Meshes ?
31
32#pragma once
33
34#include "CoreMinimal.h"
35#include "Stats/Stats.h"
36#include "HAL/IConsoleManager.h"
37#include "RHI.h"
38#include "RHIUtilities.h"
40#include "RenderResource.h"
41#include "ShaderParameters.h"
42#include "UniformBuffer.h"
43#include "GPUSkinPublicDefs.h"
44#include "VertexFactory.h"
45#include "CanvasTypes.h"
46#include "CachedGeometry.h"
49
52
62struct FClothSimulData;
67
69
70UE_DEPRECATED(5.6, "Use GPUSkinCacheStoreDuplicatedVertices instead to check if duplicate vertices need to be stored.")
72
74
76
77// Is it actually enabled?
80
82
84{
87
96 {
97 Ar << V.Position
98 << V.Normal;
99 return Ar;
100 }
101};
102
104{
105 Raster,
107};
108
111 SHADER_PARAMETER_SRV(StructuredBuffer<int4>, DynamicMeshBoundsBuffer)
113
114// Get the dynamic mesh bounds assigned by GPU skin cache on this graph builder, or dummy values otherwise.
116
117// Set required shader defines for any shader using the dynamic mesh bounds (through FDynamicMeshBoundsShaderParameters),
118// without this the operations are compiled out as well as if r.SkinCache.DynamicMeshBounds is off.
120
121UE_DEPRECATED(5.7, "This is just a stub. Use the above version that takes a FGlobalShaderPermutationParameters argument.")
123
124
126{
127public:
129 {
130 // max 256 bones as we use a byte to index
132 // Controls the output format on GpuSkinCacheComputeShader.usf
133 RWTangentXOffsetInFloats = 0, // Packed U8x4N
134 RWTangentZOffsetInFloats = 1, // Packed U8x4N
135
136 // 3 ints for normal, 3 ints for tangent, 1 for orientation = 7, rounded up to 8 as it should result in faster math and caching
138 };
139
140 UE_DEPRECATED(5.7, "SkinCache no longer requires a memory limit")
144
147
148 static void UpdateSkinWeightBuffer(FGPUSkinCacheEntry* Entry);
149 static void SetEntryGPUSkin(FGPUSkinCacheEntry* Entry, FSkeletalMeshObject* Skin);
150
159
174
176
178 static void Dequeue(FGPUSkinCacheEntry* SkinCacheEntry);
179 static void Release(FGPUSkinCacheEntry*& SkinCacheEntry);
180
181 static bool IsEntryValid(FGPUSkinCacheEntry* SkinCacheEntry, int32 Section);
184
186
187 static FRWBuffer* GetPositionBuffer(FRDGBuilder& GraphBuilder, FGPUSkinCacheEntry const* Entry, uint32 SectionIndex);
188 static FRWBuffer* GetPreviousPositionBuffer(FRDGBuilder& GraphBuilder, FGPUSkinCacheEntry const* Entry, uint32 SectionIndex);
189 static FRWBuffer* GetTangentBuffer(FRDGBuilder& GraphBuilder, FGPUSkinCacheEntry const* Entry, uint32 SectionIndex);
190
191#if RHI_RAYTRACING
193#endif // RHI_RAYTRACING
194
196
197 ENGINE_API UE::Tasks::FTask Dispatch(FRDGBuilder& GraphBuilder, const UE::Tasks::FTask& PrerequisitesTask, ERHIPipeline Pipeline);
198
199 ENGINE_API static void AddAsyncComputeSignal(FRDGBuilder& GraphBuilder);
200 ENGINE_API static void AddAsyncComputeWait(FRDGBuilder& GraphBuilder);
201
203 {
204 return FeatureLevel;
205 }
206
207 inline bool HasWork() const
208 {
209 return !BatchDispatches.IsEmpty();
210 }
211
212 UE_DEPRECATED(5.6, "Use Dispatch instead.")
214
215 UE_DEPRECATED(5.6, "GetUpdatedFrame is no longer used")
217
218 UE_DEPRECATED(5.7, "Skin Cache no longer has an explicit budget.")
220
221 UE_DEPRECATED(5.7, "Use FProcessEntryInputs")
224 FRHICommandList& RHICmdList,
225 FGPUBaseSkinVertexFactory* VertexFactory,
226 FGPUSkinPassthroughVertexFactory* TargetVertexFactory,
229 const FMorphVertexBuffer* MorphVertexBuffer,
230 const FSkeletalMeshVertexClothBuffer* ClothVertexBuffer,
231 const FClothSimulData* SimData,
232 const FMatrix44f& ClothToLocal,
233 float ClothBlendWeight,
235 uint32 RevisionNumber,
236 int32 Section,
237 int32 LOD,
238 bool& bRecreating,
240 {
241 return false;
242 }
243
244 // Allocates a new slot for dynamic bounds for a mesh with NumSlots sections.
246
247 // Releases the dynamic mesh bounds slot associated with a mesh.
249
250private:
251 friend FGPUSkinCacheEntry;
252
253 struct FDispatchEntry
254 {
255 FGPUSkinCacheEntry* SkinCacheEntry = nullptr;
256 uint32 Section = 0;
257 };
258
259 struct FSortedDispatchEntry
260 {
261 int32 ShaderIndex;
262 int32 BatchIndex;
263 };
264
265 enum
266 {
267 NUM_BUFFERS = 2,
268 };
269
270 struct FSkinCacheRWBuffer;
271 struct FRWBuffersAllocationInitializer;
272 struct FRWBuffersAllocation;
273 struct FRWBufferTracker;
274
275 struct FTaskData;
276 void DispatchPassSetup(FTaskData& TaskData);
277 void DispatchPassExecute(FTaskData& TaskData);
278
279 void TransitionBuffers(FRHICommandList& RHICmdList, TArray<FSkinCacheRWBuffer*>& Buffers, ERHIAccess ToState);
282
285 TSet<FGPUSkinCacheEntry*> PendingProcessRTGeometryEntries;
286 TArray<FDispatchEntry> BatchDispatches;
287
288 void DispatchUpdateSkinTangentsVertexPass(FRHICommandList& RHICmdList, FGPUSkinCacheEntry* Entry, int32 SectionIndex, FSkinCacheRWBuffer*& StagingBuffer);
289 void DispatchUpdateSkinTangentsTrianglePass(FRHICommandList& RHICmdList, FGPUSkinCacheEntry* Entry, int32 SectionIndex, FSkinCacheRWBuffer*& StagingBuffer);
290
291 void Cleanup();
292 static void ReleaseSkinCacheEntry(FGPUSkinCacheEntry* SkinCacheEntry);
293 void InvalidateAllEntries();
294
295 uint64 UsedMemoryInBytes = 0;
296 int32 FlushCounter = 0;
297
298 TPimplPtr<FDynamicMeshBoundsBuffer> DynamicMeshBoundsBuffer;
299
300 // For recompute tangents, holds the data required between compute shaders
301 TArray<FSkinCacheRWBuffer> StagingBuffers;
302 int32 CurrentStagingBufferIndex = 0;
303
304 ERHIFeatureLevel::Type FeatureLevel;
305 UWorld* World;
306
307 static void CVarSinkFunction();
308 static FAutoConsoleVariableSink CVarSink;
309
310 uint32 GetNextTransitionFence() { return ++TransitionFence; }
311 uint32 TransitionFence = 0;
312
313 void PrintMemorySummary() const;
314 FString GetSkeletalMeshObjectName(const FSkeletalMeshObject* GPUSkin) const;
315 FDebugName GetSkeletalMeshObjectDebugName(const FSkeletalMeshObject* GPUSkin) const;
316};
317
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
#define DECLARE_DWORD_COUNTER_STAT_EXTERN(CounterName, StatId, GroupId, API)
Definition Stats.h:682
#define DECLARE_STATS_GROUP(GroupDesc, GroupId, GroupCat)
Definition Stats.h:689
#define DECLARE_MEMORY_STAT_EXTERN(CounterName, StatId, GroupId, API)
Definition Stats.h:687
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
EGPUSkinCacheBufferBits
Definition GPUSkinCache.cpp:309
EGPUSkinCacheDispatchFlags
Definition GPUSkinCache.cpp:300
ENGINE_API bool GPUSkinCacheNeedsDuplicatedVertices()
Definition GPUSkinCache.cpp:283
ENGINE_API void DynamicMeshBoundsModifyCompilationEnvironment(const FGlobalShaderPermutationParameters &Parameters, FShaderCompilerEnvironment &OutEnvironment)
Definition GPUSkinCache.cpp:1121
ENGINE_API ESkinCacheDefaultBehavior GetSkinCacheDefaultBehavior()
Definition GPUSkinCache.cpp:276
ENGINE_API FDynamicMeshBoundsShaderParameters GetDynamicMeshBoundsShaderParameters(FRDGBuilder &GraphBuilder)
Definition GPUSkinCache.cpp:1101
ENGINE_API int32 GEnableGPUSkinCache
Definition GPUSkinCache.cpp:106
EGPUSkinCacheEntryMode
Definition GPUSkinCache.h:104
bool ShouldWeCompileGPUSkinVFShaders(EShaderPlatform Platform, ERHIFeatureLevel::Type FeatureLevel)
Definition GPUSkinCache.cpp:242
ENGINE_API bool GPUSkinCacheStoreDuplicatedVertices()
Definition GPUSkinCache.cpp:292
int32 GSkinCacheRecomputeTangents
Definition GPUSkinCache.cpp:126
UE::Math::TVector< float > FVector3f
Definition MathFwd.h:73
const bool
Definition NetworkReplayStreaming.h:178
ERHIAccess
Definition RHIAccess.h:11
ERHIPipeline
Definition RHIPipeline.h:13
EShaderPlatform
Definition RHIShaderPlatform.h:11
#define SHADER_PARAMETER_SRV(ShaderType, MemberName)
Definition ShaderParameterMacros.h:1720
#define BEGIN_SHADER_PARAMETER_STRUCT(StructTypeName, DllStorage)
Definition ShaderParameterMacros.h:1482
#define END_SHADER_PARAMETER_STRUCT()
Definition ShaderParameterMacros.h:1485
#define SHADER_PARAMETER(MemberType, MemberName)
Definition ShaderParameterMacros.h:1684
ESkinCacheDefaultBehavior
Definition SkinnedAssetCommon.h:46
uint32 Offset
Definition VulkanMemory.cpp:4033
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition IConsoleManager.h:1397
Definition RHIDefinitions.h:95
Definition GPUSkinCache.cpp:1008
Definition GPUSkinVertexFactory.h:202
Definition GPUSkinCache.cpp:584
Definition GPUSkinCache.h:126
static ENGINE_API void AddAsyncComputeSignal(FRDGBuilder &GraphBuilder)
Definition GPUSkinCache.cpp:1599
static void SetEntryGPUSkin(FGPUSkinCacheEntry *Entry, FSkeletalMeshObject *Skin)
Definition GPUSkinCache.cpp:2506
static bool IsEntryValid(FGPUSkinCacheEntry *SkinCacheEntry, int32 Section)
Definition GPUSkinCache.cpp:2440
static bool IsGPUSkinCacheRayTracingSupported()
Definition GPUSkinCache.cpp:2337
static FColor GetVisualizationDebugColor(const FName &GPUSkinCacheVisualizationMode, FGPUSkinCacheEntry *Entry, FGPUSkinCacheEntry *RayTracingEntry, uint32 SectionIndex)
Definition GPUSkinCache.cpp:2669
static void Dequeue(FGPUSkinCacheEntry *SkinCacheEntry)
Definition GPUSkinCache.cpp:2370
ERHIFeatureLevel::Type GetFeatureLevel() const
Definition GPUSkinCache.h:202
ENGINE_API int32 AllocateDynamicMeshBoundsSlot(int32 NumSlots)
Definition GPUSkinCache.cpp:1126
static FRWBuffer * GetPositionBuffer(FRDGBuilder &GraphBuilder, FGPUSkinCacheEntry const *Entry, uint32 SectionIndex)
Definition GPUSkinCache.cpp:2460
ENGINE_API ~FGPUSkinCache()
Definition GPUSkinCache.cpp:1156
static ENGINE_API void AddAsyncComputeWait(FRDGBuilder &GraphBuilder)
Definition GPUSkinCache.cpp:1613
uint64 GetExtraRequiredMemoryAndReset()
Definition GPUSkinCache.h:219
static ENGINE_API ERHIPipeline GetDispatchPipeline(FRDGBuilder &GraphBuilder)
Definition GPUSkinCache.cpp:1480
static void UpdateSkinWeightBuffer(FGPUSkinCacheEntry *Entry)
Definition GPUSkinCache.cpp:2493
ENGINE_API void DrawVisualizationInfoText(const FName &GPUSkinCacheVisualizationMode, FScreenMessageWriter &ScreenMessageWriter) const
Definition GPUSkinCache.cpp:2717
static uint32 GetUpdatedFrame(FGPUSkinCacheEntry const *, uint32)
Definition GPUSkinCache.h:216
void ProcessEntry(FRHICommandList &RHICmdList, const FProcessEntryInputs &Inputs, FGPUSkinCacheEntry *&InOutEntry)
Definition GPUSkinCache.cpp:2083
void DoDispatch(FRHICommandList &RHICmdList)
Definition GPUSkinCache.h:213
bool HasWork() const
Definition GPUSkinCache.h:207
ENGINE_API void ReleaseDynamicMeshBoundsSlot(int32 Offset, int32 NumSlots)
Definition GPUSkinCache.cpp:1132
ESkinCacheInitSettings
Definition GPUSkinCache.h:129
@ RWTangentZOffsetInFloats
Definition GPUSkinCache.h:134
@ RWTangentXOffsetInFloats
Definition GPUSkinCache.h:133
@ MaxUniformBufferBones
Definition GPUSkinCache.h:131
@ IntermediateAccumBufferNumInts
Definition GPUSkinCache.h:137
static FRWBuffer * GetPreviousPositionBuffer(FRDGBuilder &GraphBuilder, FGPUSkinCacheEntry const *Entry, uint32 SectionIndex)
Definition GPUSkinCache.cpp:2471
ENGINE_API UE::Tasks::FTask Dispatch(FRDGBuilder &GraphBuilder, const UE::Tasks::FTask &PrerequisitesTask, ERHIPipeline Pipeline)
Definition GPUSkinCache.cpp:1566
static FRWBuffer * GetTangentBuffer(FRDGBuilder &GraphBuilder, FGPUSkinCacheEntry const *Entry, uint32 SectionIndex)
Definition GPUSkinCache.cpp:2482
Definition GPUSkinVertexFactory.h:785
Definition SkeletalRenderGPUSkin.h:198
Definition NameTypes.h:617
Definition RenderGraphBuilder.h:49
Definition RHICommandList.h:3819
Definition SkeletalMeshLODRenderData.h:128
Definition SkeletalRenderGPUSkin.h:376
Definition SkeletalRenderPublic.h:85
Definition SkeletalMeshVertexClothBuffer.h:15
Definition Array.h:670
UE_REWRITE bool IsEmpty() const
Definition Array.h:1133
Definition World.h:918
Definition SceneComponent.h:24
Type
Definition RHIFeatureLevel.h:20
Definition SceneManagement.h:73
Definition ClothingSystemRuntimeTypes.h:15
Definition GPUSkinCache.h:84
friend FArchive & operator<<(FArchive &Ar, FClothSimulEntry &V)
Definition GPUSkinCache.h:95
FVector3f Normal
Definition GPUSkinCache.h:86
FVector3f Position
Definition GPUSkinCache.h:85
Definition Color.h:486
Definition GPUSkinCache.h:161
FMorphVertexBuffer * MorphVertexBuffer
Definition GPUSkinCache.h:166
const FSkeletalMeshVertexClothBuffer * ClothVertexBuffer
Definition GPUSkinCache.h:167
TConstArrayView< FProcessEntrySection > Sections
Definition GPUSkinCache.h:163
int32 LODIndex
Definition GPUSkinCache.h:171
float ClothBlendWeight
Definition GPUSkinCache.h:169
EGPUSkinCacheEntryMode Mode
Definition GPUSkinCache.h:162
FSkeletalMeshObject * Skin
Definition GPUSkinCache.h:164
bool bRecreating
Definition GPUSkinCache.h:172
uint32 CurrentRevisionNumber
Definition GPUSkinCache.h:170
FVector3f ClothWorldScale
Definition GPUSkinCache.h:168
FGPUSkinPassthroughVertexFactory * TargetVertexFactory
Definition GPUSkinCache.h:165
Definition GPUSkinCache.h:152
const FSkelMeshRenderSection * Section
Definition GPUSkinCache.h:154
FGPUBaseSkinVertexFactory * SourceVertexFactory
Definition GPUSkinCache.h:153
FMatrix44f ClothToLocal
Definition GPUSkinCache.h:157
int32 SectionIndex
Definition GPUSkinCache.h:155
const FClothSimulData * ClothSimulationData
Definition GPUSkinCache.h:156
Definition GlobalShader.h:73
Definition RHIUtilities.h:181
Definition RHIResources.h:3463
Definition CanvasTypes.h:854
Definition ShaderCore.h:544
Definition SkeletalMeshLODRenderData.h:28
Definition GPUSkinVertexFactory.h:59
Definition PimplPtr.h:50
static CORE_API const TMatrix Identity
Definition Matrix.h:52