2020-07-07 14:29:30 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
2020-07-06 18:58:26 -04:00
/*=============================================================================
VirtualShadowMap . h :
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "VirtualShadowMapCacheManager.h"
# include "RendererModule.h"
# include "RenderGraphUtils.h"
# include "RHIGPUReadback.h"
2020-08-25 10:06:54 -04:00
# include "ScenePrivate.h"
2020-07-06 18:58:26 -04:00
# include "HAL/FileManager.h"
2020-08-25 10:06:54 -04:00
# include "PrimitiveSceneInfo.h"
2020-07-06 18:58:26 -04:00
static TAutoConsoleVariable < int32 > CVarAccumulateStats (
TEXT ( " r.Shadow.v.AccumulateStats " ) ,
0 ,
TEXT ( " AccumulateStats " ) ,
ECVF_RenderThreadSafe
) ;
static TAutoConsoleVariable < int32 > CVarCacheVirtualSMs (
TEXT ( " r.Shadow.v.Cache " ) ,
0 ,
TEXT ( " Turn on to enable caching " ) ,
ECVF_RenderThreadSafe
) ;
2020-12-16 17:57:13 -04:00
void FVirtualShadowMapCacheEntry : : UpdateClipmap (
int32 VirtualShadowMapId ,
const FMatrix & WorldToLight ,
FIntPoint PageSpaceLocation ,
float GlobalDepth )
2020-07-06 18:58:26 -04:00
{
// Swap previous frame data over.
PrevVirtualShadowMapId = CurrentVirtualShadowMapId ;
PrevPageSpaceLocation = CurrentPageSpaceLocation ;
PrevShadowMapGlobalDepth = CurrentShadowMapGlobalDepth ;
if ( WorldToLight ! = ClipmapCacheValidKey . WorldToLight )
{
PrevVirtualShadowMapId = INDEX_NONE ;
ClipmapCacheValidKey . WorldToLight = WorldToLight ;
}
CurrentVirtualShadowMapId = VirtualShadowMapId ;
CurrentPageSpaceLocation = PageSpaceLocation ;
CurrentShadowMapGlobalDepth = GlobalDepth ;
}
2020-12-16 17:57:13 -04:00
void FVirtualShadowMapCacheEntry : : Update ( int32 VirtualShadowMapId , const FWholeSceneProjectedShadowInitializer & InCacheValidKey )
2020-07-06 18:58:26 -04:00
{
// Swap previous frame data over.
PrevPageSpaceLocation = CurrentPageSpaceLocation ;
PrevVirtualShadowMapId = CurrentVirtualShadowMapId ;
PrevShadowMapGlobalDepth = CurrentShadowMapGlobalDepth ;
// Check cache validity based of shadow setup
2020-12-16 17:57:13 -04:00
if ( ! CacheValidKey . IsCachedShadowValid ( InCacheValidKey ) )
2020-07-06 18:58:26 -04:00
{
2020-12-16 17:57:13 -04:00
PrevVirtualShadowMapId = INDEX_NONE ;
//UE_LOG(LogRenderer, Display, TEXT("Invalidated!"));
2020-07-06 18:58:26 -04:00
}
CacheValidKey = InCacheValidKey ;
CurrentVirtualShadowMapId = VirtualShadowMapId ;
2020-12-16 17:57:13 -04:00
PrevPageSpaceLocation = CurrentPageSpaceLocation = FIntPoint ( 0 , 0 ) ;
PrevShadowMapGlobalDepth = CurrentShadowMapGlobalDepth = 0.0f ;
2020-07-06 18:58:26 -04:00
}
TSharedPtr < FVirtualShadowMapCacheEntry > FVirtualShadowMapArrayCacheManager : : FindCreateCacheEntry ( int32 LightSceneId , int32 CascadeIndex )
{
if ( CVarCacheVirtualSMs . GetValueOnRenderThread ( ) = = 0 )
{
return nullptr ;
}
const FIntPoint Key ( LightSceneId , CascadeIndex ) ;
if ( TSharedPtr < FVirtualShadowMapCacheEntry > * VirtualShadowMapCacheEntry = CacheEntries . Find ( Key ) )
{
return * VirtualShadowMapCacheEntry ;
}
// Add to current frame / active set.
TSharedPtr < FVirtualShadowMapCacheEntry > & NewVirtualShadowMapCacheEntry = CacheEntries . Add ( Key ) ;
// Copy data if available
if ( TSharedPtr < FVirtualShadowMapCacheEntry > * PrevVirtualShadowMapCacheEntry = PrevCacheEntries . Find ( Key ) )
{
NewVirtualShadowMapCacheEntry = * PrevVirtualShadowMapCacheEntry ;
}
else
{
NewVirtualShadowMapCacheEntry = TSharedPtr < FVirtualShadowMapCacheEntry > ( new FVirtualShadowMapCacheEntry ) ;
}
// return entry
return NewVirtualShadowMapCacheEntry ;
}
class FVirtualSmCopyStatsCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FVirtualSmCopyStatsCS ) ;
SHADER_USE_PARAMETER_STRUCT ( FVirtualSmCopyStatsCS , FGlobalShader )
public :
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_RDG_BUFFER_SRV ( StructuredBuffer < uint > , InStatsBuffer )
SHADER_PARAMETER_RDG_BUFFER_UAV ( RWBuffer < uint > , AccumulatedStatsBufferOut )
SHADER_PARAMETER ( uint32 , NumStats )
END_SHADER_PARAMETER_STRUCT ( )
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return IsFeatureLevelSupported ( Parameters . Platform , ERHIFeatureLevel : : SM5 ) ;
}
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " MAX_STAT_FRAMES " ) , FVirtualShadowMapArrayCacheManager : : MaxStatFrames ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FVirtualSmCopyStatsCS , " /Engine/Private/VirtualShadowMaps/CopyStats.usf " , " CopyStatsCS " , SF_Compute ) ;
2020-09-24 00:43:27 -04:00
void FVirtualShadowMapArrayCacheManager : : ExtractFrameData ( FVirtualShadowMapArray & VirtualShadowMapArray , FRDGBuilder & GraphBuilder )
2020-07-06 18:58:26 -04:00
{
2020-12-14 14:39:11 -04:00
if ( VirtualShadowMapArray . IsAllocated ( )
& & CVarCacheVirtualSMs . GetValueOnRenderThread ( ) ! = 0 )
2020-07-06 18:58:26 -04:00
{
2020-11-09 15:47:39 -04:00
GraphBuilder . QueueBufferExtraction ( VirtualShadowMapArray . PageTableRDG , & PrevPageTable ) ;
GraphBuilder . QueueBufferExtraction ( VirtualShadowMapArray . PageFlagsRDG , & PrevPageFlags ) ;
GraphBuilder . QueueBufferExtraction ( VirtualShadowMapArray . HPageFlagsRDG , & PrevHPageFlags ) ;
2020-08-25 10:06:54 -04:00
2020-11-09 15:47:39 -04:00
GraphBuilder . QueueTextureExtraction ( VirtualShadowMapArray . PhysicalPagePoolRDG , & PrevPhysicalPagePool ) ;
2021-02-17 15:32:52 -04:00
# if ENABLE_NON_NANITE_VSM
GraphBuilder . QueueTextureExtraction ( VirtualShadowMapArray . PhysicalPagePoolHw , & PrevPhysicalPagePoolHw ) ;
# endif //ENABLE_NON_NANITE_VSM
2020-11-09 15:47:39 -04:00
GraphBuilder . QueueBufferExtraction ( VirtualShadowMapArray . PhysicalPageMetaDataRDG , & PrevPhysicalPageMetaData ) ;
GraphBuilder . QueueBufferExtraction ( VirtualShadowMapArray . DynamicCasterPageFlagsRDG , & PrevDynamicCasterPageFlags ) ;
GraphBuilder . QueueBufferExtraction ( VirtualShadowMapArray . ShadowMapProjectionDataRDG , & PrevShadowMapProjectionDataBuffer ) ;
GraphBuilder . QueueBufferExtraction ( VirtualShadowMapArray . PageRectBoundsRDG , & PrevPageRectBounds ) ;
2020-07-06 18:58:26 -04:00
// Move cache entries to previous frame, this implicitly removes any that were not used
PrevCacheEntries = CacheEntries ;
2020-08-25 10:06:54 -04:00
PrevCommonParameters = VirtualShadowMapArray . CommonParameters ;
2020-07-06 18:58:26 -04:00
}
else
{
// Drop all refs.
2020-09-24 00:43:27 -04:00
PrevPageTable = TRefCountPtr < FRDGPooledBuffer > ( ) ;
PrevPageFlags = TRefCountPtr < FRDGPooledBuffer > ( ) ;
PrevHPageFlags = TRefCountPtr < FRDGPooledBuffer > ( ) ;
2020-07-06 18:58:26 -04:00
PrevPhysicalPagePool = TRefCountPtr < IPooledRenderTarget > ( ) ;
2021-02-17 15:32:52 -04:00
# if ENABLE_NON_NANITE_VSM
PrevPhysicalPagePoolHw = TRefCountPtr < IPooledRenderTarget > ( ) ;
# endif //ENABLE_NON_NANITE_VSM
2020-09-24 00:43:27 -04:00
PrevPhysicalPageMetaData = TRefCountPtr < FRDGPooledBuffer > ( ) ;
PrevDynamicCasterPageFlags = TRefCountPtr < FRDGPooledBuffer > ( ) ;
PrevShadowMapProjectionDataBuffer = TRefCountPtr < FRDGPooledBuffer > ( ) ;
PrevPageRectBounds = TRefCountPtr < FRDGPooledBuffer > ( ) ;
2020-08-25 10:06:54 -04:00
PrevCommonParameters . NumShadowMaps = 0 ;
2020-07-06 18:58:26 -04:00
PrevCacheEntries . Empty ( ) ;
}
CacheEntries . Reset ( ) ;
2020-09-24 00:43:27 -04:00
FRDGBufferRef AccumulatedStatsBufferRDG = nullptr ;
2020-07-06 18:58:26 -04:00
// Note: stats accumulation thing is here because it needs to persist over frames.
if ( ! AccumulatedStatsBuffer . IsValid ( ) )
{
2021-02-18 13:40:42 -04:00
AccumulatedStatsBufferRDG = GraphBuilder . CreateBuffer ( FRDGBufferDesc : : CreateBufferDesc ( 4 , 1 + FVirtualShadowMapArray : : NumStats * MaxStatFrames ) , TEXT ( " VSM.AccumulatedStatsBuffer " ) ) ; // TODO: Can't be a structured buffer as EnqueueCopy is only defined for vertex buffers
2020-07-06 18:58:26 -04:00
AddClearUAVPass ( GraphBuilder , GraphBuilder . CreateUAV ( AccumulatedStatsBufferRDG , PF_R32_UINT ) , 0 ) ;
2020-09-24 00:43:27 -04:00
ConvertToExternalBuffer ( GraphBuilder , AccumulatedStatsBufferRDG , AccumulatedStatsBuffer ) ;
}
else
{
2021-02-18 13:40:42 -04:00
AccumulatedStatsBufferRDG = GraphBuilder . RegisterExternalBuffer ( AccumulatedStatsBuffer , TEXT ( " VSM.AccumulatedStatsBuffer " ) ) ;
2020-07-06 18:58:26 -04:00
}
if ( IsAccumulatingStats ( ) )
{
// Initialize/clear
if ( ! bAccumulatingStats )
{
AddClearUAVPass ( GraphBuilder , GraphBuilder . CreateUAV ( AccumulatedStatsBufferRDG , PF_R32_UINT ) , 0 ) ;
bAccumulatingStats = true ;
}
FVirtualSmCopyStatsCS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FVirtualSmCopyStatsCS : : FParameters > ( ) ;
2020-11-09 15:47:39 -04:00
PassParameters - > InStatsBuffer = GraphBuilder . CreateSRV ( VirtualShadowMapArray . StatsBufferRDG , PF_R32_UINT ) ;
2020-07-06 18:58:26 -04:00
PassParameters - > AccumulatedStatsBufferOut = GraphBuilder . CreateUAV ( AccumulatedStatsBufferRDG , PF_R32_UINT ) ;
PassParameters - > NumStats = FVirtualShadowMapArray : : NumStats ;
auto ComputeShader = GetGlobalShaderMap ( GMaxRHIFeatureLevel ) - > GetShader < FVirtualSmCopyStatsCS > ( ) ;
FComputeShaderUtils : : AddPass (
GraphBuilder ,
RDG_EVENT_NAME ( " Copy Stats " ) ,
ComputeShader ,
PassParameters ,
FIntVector ( 1 , 1 , 1 )
) ;
}
else if ( bAccumulatingStats )
{
bAccumulatingStats = false ;
2020-09-24 00:43:27 -04:00
2021-02-18 13:40:42 -04:00
GPUBufferReadback = new FRHIGPUBufferReadback ( TEXT ( " VSM.AccumulatedStatsBuffer " ) ) ;
2020-09-24 00:43:27 -04:00
AddEnqueueCopyPass ( GraphBuilder , GPUBufferReadback , AccumulatedStatsBufferRDG , 0u ) ;
2020-07-06 18:58:26 -04:00
}
if ( GPUBufferReadback & & GPUBufferReadback - > IsReady ( ) )
{
TArray < uint32 > Tmp ;
Tmp . AddDefaulted ( 1 + FVirtualShadowMapArray : : NumStats * MaxStatFrames ) ;
{
const uint32 * BufferPtr = ( const uint32 * ) GPUBufferReadback - > Lock ( ( 1 + FVirtualShadowMapArray : : NumStats * MaxStatFrames ) * sizeof ( uint32 ) ) ;
FPlatformMemory : : Memcpy ( Tmp . GetData ( ) , BufferPtr , Tmp . Num ( ) * Tmp . GetTypeSize ( ) ) ;
GPUBufferReadback - > Unlock ( ) ;
delete GPUBufferReadback ;
GPUBufferReadback = nullptr ;
}
FString FileName = TEXT ( " shadow_map_cache_stats.csv " ) ; // FString::Printf(TEXT("%s.csv"), *FileNameToUse);
FArchive * FileToLogTo = IFileManager : : Get ( ) . CreateFileWriter ( * FileName , false ) ;
ensure ( FileToLogTo ) ;
if ( FileToLogTo )
{
static const FString StatNames [ FVirtualShadowMapArray : : NumStats ] =
{
TEXT ( " Allocated " ) ,
TEXT ( " Cached " ) ,
TEXT ( " Dynamic " ) ,
TEXT ( " NumSms " ) ,
TEXT ( " RandRobin " ) ,
} ;
// Print header
FString StringToPrint ;
for ( const FString & StatName : StatNames )
{
if ( ! StringToPrint . IsEmpty ( ) )
{
StringToPrint + = TEXT ( " , " ) ;
}
StringToPrint + = StatName ;
}
StringToPrint + = TEXT ( " \n " ) ;
FileToLogTo - > Serialize ( TCHAR_TO_ANSI ( * StringToPrint ) , StringToPrint . Len ( ) ) ;
uint32 Num = Tmp [ 0 ] ;
for ( uint32 Ind = 0 ; Ind < Num ; + + Ind )
{
StringToPrint . Empty ( ) ;
for ( uint32 StatInd = 0 ; StatInd < FVirtualShadowMapArray : : NumStats ; + + StatInd )
{
if ( ! StringToPrint . IsEmpty ( ) )
{
StringToPrint + = TEXT ( " , " ) ;
}
StringToPrint + = FString : : Printf ( TEXT ( " %d " ) , Tmp [ 1 + Ind * FVirtualShadowMapArray : : NumStats + StatInd ] ) ;
}
StringToPrint + = TEXT ( " \n " ) ;
FileToLogTo - > Serialize ( TCHAR_TO_ANSI ( * StringToPrint ) , StringToPrint . Len ( ) ) ;
}
FileToLogTo - > Close ( ) ;
}
}
}
bool FVirtualShadowMapArrayCacheManager : : IsValid ( )
{
return CVarCacheVirtualSMs . GetValueOnRenderThread ( ) ! = 0
& & PrevPageTable
& & PrevPageFlags
2021-02-17 15:32:52 -04:00
# if ENABLE_NON_NANITE_VSM
& & ( PrevPhysicalPagePool | | PrevPhysicalPagePoolHw )
# else // !ENABLE_NON_NANITE_VSM
2020-07-06 18:58:26 -04:00
& & PrevPhysicalPagePool
2021-02-17 15:32:52 -04:00
# endif //ENABLE_NON_NANITE_VSM
2020-07-06 18:58:26 -04:00
& & PrevPhysicalPageMetaData
& & PrevDynamicCasterPageFlags ;
}
bool FVirtualShadowMapArrayCacheManager : : IsAccumulatingStats ( )
{
return CVarAccumulateStats . GetValueOnRenderThread ( ) ! = 0 ;
}
2020-08-25 10:06:54 -04:00
2020-10-27 13:40:36 -04:00
void FVirtualShadowMapArrayCacheManager : : ProcessRemovedPrimives ( FRDGBuilder & GraphBuilder , const FGPUScene & GPUScene , const TArray < FPrimitiveSceneInfo * > & RemovedPrimitiveSceneInfos )
2020-08-25 10:06:54 -04:00
{
if ( CVarCacheVirtualSMs . GetValueOnRenderThread ( ) ! = 0 & & RemovedPrimitiveSceneInfos . Num ( ) > 0 & & PrevDynamicCasterPageFlags . IsValid ( ) )
{
// Note: Could filter out primitives that have no nanite here (though later this might be bad anyway, when regular geo is also rendered into virtual SMs)
2021-01-21 13:38:01 -04:00
TArray < FInstanceDataRange > InstanceRangesLarge ;
TArray < FInstanceDataRange > InstanceRangesSmall ;
2020-08-25 10:06:54 -04:00
for ( const FPrimitiveSceneInfo * PrimitiveSceneInfo : RemovedPrimitiveSceneInfos )
{
if ( PrimitiveSceneInfo - > GetInstanceDataOffset ( ) ! = INDEX_NONE )
{
2021-01-21 13:38:01 -04:00
int32 NumInstanceDataEntries = PrimitiveSceneInfo - > GetNumInstanceDataEntries ( ) ;
if ( NumInstanceDataEntries > = 8U )
{
InstanceRangesLarge . Add ( FInstanceDataRange { PrimitiveSceneInfo - > GetInstanceDataOffset ( ) , NumInstanceDataEntries } ) ;
}
else
{
InstanceRangesSmall . Add ( FInstanceDataRange { PrimitiveSceneInfo - > GetInstanceDataOffset ( ) , NumInstanceDataEntries } ) ;
}
2020-08-25 10:06:54 -04:00
}
}
2021-01-21 13:38:01 -04:00
ProcessInstanceRangeInvalidation ( GraphBuilder , InstanceRangesLarge , InstanceRangesSmall , GPUScene ) ;
2020-08-25 10:06:54 -04:00
}
}
2020-10-27 13:40:36 -04:00
void FVirtualShadowMapArrayCacheManager : : ProcessPrimitivesToUpdate ( FRDGBuilder & GraphBuilder , const FScene & Scene )
2020-08-25 10:06:54 -04:00
{
const FGPUScene & GPUScene = Scene . GPUScene ;
if ( IsValid ( ) & & GPUScene . PrimitivesToUpdate . Num ( ) > 0 )
{
// TODO: As a slight CPU optimization just pass primitive ID list and use instance ranges stored in GPU scene
2021-01-21 13:38:01 -04:00
TArray < FInstanceDataRange > InstanceRangesLarge ;
TArray < FInstanceDataRange > InstanceRangesSmall ;
2020-08-25 10:06:54 -04:00
for ( const int32 PrimitiveId : GPUScene . PrimitivesToUpdate )
{
// Skip added ones (they dont need it, but must be marked as having moved).
if ( PrimitiveId < Scene . Primitives . Num ( ) & & ( PrimitiveId > = GPUScene . AddedPrimitiveFlags . Num ( ) | | ! GPUScene . AddedPrimitiveFlags [ PrimitiveId ] ) )
{
const FPrimitiveSceneInfo * PrimitiveSceneInfo = Scene . Primitives [ PrimitiveId ] ;
if ( PrimitiveSceneInfo - > GetInstanceDataOffset ( ) ! = INDEX_NONE )
{
2021-01-21 13:38:01 -04:00
int32 NumInstanceDataEntries = PrimitiveSceneInfo - > GetNumInstanceDataEntries ( ) ;
if ( NumInstanceDataEntries > = 8U )
{
InstanceRangesLarge . Add ( FInstanceDataRange { PrimitiveSceneInfo - > GetInstanceDataOffset ( ) , NumInstanceDataEntries } ) ;
}
else
{
InstanceRangesSmall . Add ( FInstanceDataRange { PrimitiveSceneInfo - > GetInstanceDataOffset ( ) , NumInstanceDataEntries } ) ;
}
2020-08-25 10:06:54 -04:00
}
}
}
2021-01-21 13:38:01 -04:00
ProcessInstanceRangeInvalidation ( GraphBuilder , InstanceRangesLarge , InstanceRangesSmall , GPUScene ) ;
2020-08-25 10:06:54 -04:00
}
}
/**
* Compute shader to project and invalidate the rectangles of given instances .
*/
class FVirtualSmInvalidateInstancePagesCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FVirtualSmInvalidateInstancePagesCS ) ;
SHADER_USE_PARAMETER_STRUCT ( FVirtualSmInvalidateInstancePagesCS , FGlobalShader )
2021-01-21 13:38:01 -04:00
class FLargeSmallDim : SHADER_PERMUTATION_BOOL ( " PROCESS_LARGE_INSTANCE_COUNT_RANGES " ) ;
using FPermutationDomain = TShaderPermutationDomain < FLargeSmallDim > ;
2020-08-25 10:06:54 -04:00
public :
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
2021-01-19 10:17:05 -04:00
SHADER_PARAMETER_RDG_UNIFORM_BUFFER ( FVirtualShadowMapCommonParameters , VirtualSmCommon )
2020-08-25 10:06:54 -04:00
SHADER_PARAMETER_RDG_BUFFER_SRV ( StructuredBuffer < FInstanceDataRange > , InstanceRanges )
SHADER_PARAMETER ( uint32 , NumRemovedItems )
SHADER_PARAMETER_RDG_BUFFER_SRV ( StructuredBuffer < FVirtualShadowMapProjectionShaderData > , ShadowMapProjectionData )
SHADER_PARAMETER_RDG_BUFFER_SRV ( StructuredBuffer < uint > , PageFlags )
SHADER_PARAMETER_RDG_BUFFER_SRV ( StructuredBuffer < uint > , HPageFlags )
SHADER_PARAMETER_RDG_BUFFER_SRV ( StructuredBuffer < uint4 > , PageRectBounds )
SHADER_PARAMETER_RDG_BUFFER_UAV ( RWStructuredBuffer < uint > , OutDynamicCasterFlags )
SHADER_PARAMETER_SRV ( StructuredBuffer < float4 > , GPUSceneInstanceSceneData )
SHADER_PARAMETER_SRV ( StructuredBuffer < float4 > , GPUScenePrimitiveSceneData )
SHADER_PARAMETER ( uint32 , GPUSceneFrameNumber )
SHADER_PARAMETER ( uint32 , InstanceDataSOAStride )
END_SHADER_PARAMETER_STRUCT ( )
static constexpr int Cs1dGroupSizeX = 64 ;
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return IsFeatureLevelSupported ( Parameters . Platform , ERHIFeatureLevel : : SM5 ) ;
}
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
FVirtualShadowMapArray : : SetShaderDefines ( OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " CS_1D_GROUP_SIZE_X " ) , Cs1dGroupSizeX ) ;
OutEnvironment . SetDefine ( TEXT ( " USE_GLOBAL_GPU_SCENE_DATA " ) , 1 ) ;
OutEnvironment . SetDefine ( TEXT ( " VF_SUPPORTS_PRIMITIVE_SCENE_DATA " ) , 1 ) ;
// OutEnvironment.SetDefine(TEXT("MAX_STAT_FRAMES"), FVirtualShadowMapArrayCacheManager::MaxStatFrames);
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FVirtualSmInvalidateInstancePagesCS , " /Engine/Private/VirtualShadowMaps/CacheManagement.usf " , " VirtualSmInvalidateInstancePagesCS " , SF_Compute ) ;
2021-01-21 13:38:01 -04:00
void FVirtualShadowMapArrayCacheManager : : ProcessInstanceRangeInvalidation ( FRDGBuilder & GraphBuilder , const TArray < FInstanceDataRange > & InstanceRangesLarge , const TArray < FInstanceDataRange > & InstanceRangesSmall , const FGPUScene & GPUScene )
2020-08-25 10:06:54 -04:00
{
2021-01-21 13:38:01 -04:00
if ( InstanceRangesSmall . Num ( ) )
2020-08-25 10:06:54 -04:00
{
2021-01-21 13:38:01 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ProcessInstanceRangeInvalidation [%d small-ranges] " , InstanceRangesSmall . Num ( ) ) ;
2020-10-27 13:40:36 -04:00
auto RegExtCreateSrv = [ & GraphBuilder ] ( const TRefCountPtr < FRDGPooledBuffer > & Buffer , const TCHAR * Name ) - > FRDGBufferSRVRef
2020-08-25 10:06:54 -04:00
{
2020-10-27 13:40:36 -04:00
return GraphBuilder . CreateSRV ( GraphBuilder . RegisterExternalBuffer ( Buffer , Name ) ) ;
} ;
2020-08-25 10:06:54 -04:00
2020-11-09 15:47:39 -04:00
FVirtualSmInvalidateInstancePagesCS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FVirtualSmInvalidateInstancePagesCS : : FParameters > ( ) ;
2021-01-19 10:17:05 -04:00
PassParameters - > VirtualSmCommon = GraphBuilder . CreateUniformBuffer ( & PrevCommonParameters ) ;
2021-02-18 13:40:42 -04:00
FRDGBufferRef InstanceRangesRDG = CreateStructuredBuffer ( GraphBuilder , TEXT ( " VSM.InstanceRangesSmall " ) , InstanceRangesSmall ) ;
2020-10-27 13:40:36 -04:00
PassParameters - > InstanceRanges = GraphBuilder . CreateSRV ( InstanceRangesRDG ) ;
2021-01-21 13:38:01 -04:00
PassParameters - > NumRemovedItems = InstanceRangesSmall . Num ( ) ;
2021-02-18 13:40:42 -04:00
PassParameters - > ShadowMapProjectionData = RegExtCreateSrv ( PrevShadowMapProjectionDataBuffer , TEXT ( " VSM.PrevShadowMapProjectionData " ) ) ;
2020-08-25 10:06:54 -04:00
2021-02-18 13:40:42 -04:00
PassParameters - > PageFlags = RegExtCreateSrv ( PrevPageFlags , TEXT ( " VSM.PrevPageFlags " ) ) ;
PassParameters - > HPageFlags = RegExtCreateSrv ( PrevHPageFlags , TEXT ( " VSM.PrevHPageFlags " ) ) ;
PassParameters - > PageRectBounds = RegExtCreateSrv ( PrevPageRectBounds , TEXT ( " VSM.PrevPageRectBounds " ) ) ;
2020-08-25 10:06:54 -04:00
2021-02-18 13:40:42 -04:00
FRDGBufferRef DynamicCasterFlagsRDG = GraphBuilder . RegisterExternalBuffer ( PrevDynamicCasterPageFlags , TEXT ( " VSM.DynamicCasterFlags " ) ) ;
2020-10-27 13:40:36 -04:00
PassParameters - > OutDynamicCasterFlags = GraphBuilder . CreateUAV ( DynamicCasterFlagsRDG ) ;
2020-08-25 10:06:54 -04:00
2020-10-27 13:40:36 -04:00
PassParameters - > GPUSceneInstanceSceneData = GPUScene . InstanceDataBuffer . SRV ;
PassParameters - > GPUScenePrimitiveSceneData = GPUScene . PrimitiveBuffer . SRV ;
2020-11-19 05:23:44 -04:00
PassParameters - > GPUSceneFrameNumber = GPUScene . GetSceneFrameNumber ( ) ;
2020-10-27 13:40:36 -04:00
PassParameters - > InstanceDataSOAStride = GPUScene . InstanceDataSOAStride ;
2020-08-25 10:06:54 -04:00
2021-01-21 13:38:01 -04:00
FVirtualSmInvalidateInstancePagesCS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FVirtualSmInvalidateInstancePagesCS : : FLargeSmallDim > ( 0 ) ;
auto ComputeShader = GetGlobalShaderMap ( GMaxRHIFeatureLevel ) - > GetShader < FVirtualSmInvalidateInstancePagesCS > ( PermutationVector ) ;
2020-08-25 10:06:54 -04:00
2020-10-27 13:40:36 -04:00
FComputeShaderUtils : : AddPass (
GraphBuilder ,
RDG_EVENT_NAME ( " VirtualSmInvalidateInstancePagesCS " ) ,
ComputeShader ,
PassParameters ,
2021-01-21 13:38:01 -04:00
FIntVector ( FMath : : DivideAndRoundUp ( InstanceRangesSmall . Num ( ) , FVirtualSmInvalidateInstancePagesCS : : Cs1dGroupSizeX ) , 1 , 1 )
) ;
}
if ( InstanceRangesLarge . Num ( ) )
{
RDG_EVENT_SCOPE ( GraphBuilder , " ProcessInstanceRangeInvalidation [%d large-ranges] " , InstanceRangesLarge . Num ( ) ) ;
auto RegExtCreateSrv = [ & GraphBuilder ] ( const TRefCountPtr < FRDGPooledBuffer > & Buffer , const TCHAR * Name ) - > FRDGBufferSRVRef
{
return GraphBuilder . CreateSRV ( GraphBuilder . RegisterExternalBuffer ( Buffer , Name ) ) ;
} ;
FVirtualSmInvalidateInstancePagesCS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FVirtualSmInvalidateInstancePagesCS : : FParameters > ( ) ;
PassParameters - > VirtualSmCommon = GraphBuilder . CreateUniformBuffer ( & PrevCommonParameters ) ;
2021-02-18 13:40:42 -04:00
FRDGBufferRef InstanceRangesRDG = CreateStructuredBuffer ( GraphBuilder , TEXT ( " VSM.InstanceRangesSmall " ) , InstanceRangesLarge ) ;
2021-01-21 13:38:01 -04:00
PassParameters - > InstanceRanges = GraphBuilder . CreateSRV ( InstanceRangesRDG ) ;
PassParameters - > NumRemovedItems = InstanceRangesLarge . Num ( ) ;
2021-02-18 13:40:42 -04:00
PassParameters - > ShadowMapProjectionData = RegExtCreateSrv ( PrevShadowMapProjectionDataBuffer , TEXT ( " VSM.PrevShadowMapProjectionData " ) ) ;
2021-01-21 13:38:01 -04:00
2021-02-18 13:40:42 -04:00
PassParameters - > PageFlags = RegExtCreateSrv ( PrevPageFlags , TEXT ( " VSM.PrevPageFlags " ) ) ;
PassParameters - > HPageFlags = RegExtCreateSrv ( PrevHPageFlags , TEXT ( " VSM.PrevHPageFlags " ) ) ;
PassParameters - > PageRectBounds = RegExtCreateSrv ( PrevPageRectBounds , TEXT ( " VSM.PrevPageRectBounds " ) ) ;
2021-01-21 13:38:01 -04:00
2021-02-18 13:40:42 -04:00
FRDGBufferRef DynamicCasterFlagsRDG = GraphBuilder . RegisterExternalBuffer ( PrevDynamicCasterPageFlags , TEXT ( " VSM.DynamicCasterFlags " ) ) ;
2021-01-21 13:38:01 -04:00
PassParameters - > OutDynamicCasterFlags = GraphBuilder . CreateUAV ( DynamicCasterFlagsRDG ) ;
PassParameters - > GPUSceneInstanceSceneData = GPUScene . InstanceDataBuffer . SRV ;
PassParameters - > GPUScenePrimitiveSceneData = GPUScene . PrimitiveBuffer . SRV ;
PassParameters - > GPUSceneFrameNumber = GPUScene . GetSceneFrameNumber ( ) ;
PassParameters - > InstanceDataSOAStride = GPUScene . InstanceDataSOAStride ;
FVirtualSmInvalidateInstancePagesCS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FVirtualSmInvalidateInstancePagesCS : : FLargeSmallDim > ( 1 ) ;
auto ComputeShader = GetGlobalShaderMap ( GMaxRHIFeatureLevel ) - > GetShader < FVirtualSmInvalidateInstancePagesCS > ( PermutationVector ) ;
FComputeShaderUtils : : AddPass (
GraphBuilder ,
RDG_EVENT_NAME ( " VirtualSmInvalidateInstancePagesCS " ) ,
ComputeShader ,
PassParameters ,
FIntVector ( InstanceRangesLarge . Num ( ) , 1 , 1 )
2020-10-27 13:40:36 -04:00
) ;
2020-08-25 10:06:54 -04:00
}
}