861 lines
37 KiB
C++
861 lines
37 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=======================================================================================
|
|
SceneViewState.cpp: FSceneViewState and GetGPUSizeBytes implementation functions.
|
|
=======================================================================================*/
|
|
|
|
#include "Lumen/LumenSceneData.h"
|
|
#include "RendererModule.h"
|
|
#include "ScenePrivate.h"
|
|
#include "SceneViewStateSystemMemory.h"
|
|
#include "VirtualShadowMaps/VirtualShadowMapCacheManager.h"
|
|
|
|
DECLARE_GPU_STAT_NAMED(SystemMemoryBackup, TEXT("SystemMemoryBackup"));
|
|
DECLARE_GPU_STAT_NAMED(SystemMemoryRestore, TEXT("SystemMemoryRestore"));
|
|
|
|
static uint64 GetTextureGPUSizeBytes(const FTextureRHIRef& Target, bool bLogSizes)
|
|
{
|
|
uint64 Size = Target.IsValid() ? Target->GetDesc().CalcMemorySizeEstimate() : 0;
|
|
if (bLogSizes && Size)
|
|
{
|
|
UE_LOG(LogRenderer, Log, TEXT("LogSizes\tTexture\t0x%p\t%s\t%llu"), Target.GetReference(), *Target->GetName().ToString(), Size);
|
|
}
|
|
return Size;
|
|
}
|
|
|
|
static uint64 GetRenderTargetGPUSizeBytes(const TRefCountPtr<IPooledRenderTarget>& Target, bool bLogSizes)
|
|
{
|
|
uint64 Size = Target.IsValid() ? Target->ComputeMemorySize() : 0;
|
|
if (bLogSizes && Size)
|
|
{
|
|
UE_LOG(LogRenderer, Log, TEXT("LogSizes\tRenderTarget\t0x%p\t%s\t%llu"), Target.GetReference(), Target->GetDesc().DebugName, Size);
|
|
}
|
|
return Size;
|
|
}
|
|
|
|
static uint64 GetBufferGPUSizeBytes(const TRefCountPtr<FRDGPooledBuffer>& Buffer, bool bLogSizes)
|
|
{
|
|
uint64 Size = Buffer.IsValid() ? Buffer->GetSize() : 0;
|
|
if (bLogSizes && Size)
|
|
{
|
|
const TCHAR* Name = Buffer->GetName();
|
|
UE_LOG(LogRenderer, Log, TEXT("LogSizes\tBuffer\t0x%p\t%s\t%llu"), Buffer.GetReference(), Name ? Name : TEXT("UNKNOWN"), Size);
|
|
}
|
|
return Size;
|
|
}
|
|
|
|
static uint64 GetGPUSizeBytes(const TRefCountPtr<IPooledRenderTarget>& Target, bool bLogSizes)
|
|
{
|
|
uint64 Size = Target.IsValid() ? Target->ComputeMemorySize() : 0;
|
|
if (bLogSizes && Size)
|
|
{
|
|
UE_LOG(LogRenderer, Log, TEXT("LogSizes\tRenderTarget\t0x%p\t%s\t%llu"), Target.GetReference(), Target->GetDesc().DebugName, Size);
|
|
}
|
|
return Size;
|
|
}
|
|
|
|
static uint64 GetGPUSizeBytes(const TRefCountPtr<FRDGPooledBuffer>& Buffer, bool bLogSizes)
|
|
{
|
|
uint64 Size = Buffer.IsValid() ? Buffer->GetSize() : 0;
|
|
if (bLogSizes && Size)
|
|
{
|
|
const TCHAR* Name = Buffer->GetName();
|
|
UE_LOG(LogRenderer, Log, TEXT("LogSizes\tBuffer\t0x%p\t%s\t%llu"), Buffer.GetReference(), Name ? Name : TEXT("UNKNOWN"), Size);
|
|
}
|
|
return Size;
|
|
}
|
|
|
|
static uint64 GetTextureReadbackGPUSizeBytes(const FRHIGPUTextureReadback* TextureReadback, bool bLogSizes)
|
|
{
|
|
uint64 Size = TextureReadback ? TextureReadback->GetGPUSizeBytes() : 0;
|
|
if (bLogSizes && Size)
|
|
{
|
|
UE_LOG(LogRenderer, Log, TEXT("LogSizes\tTextureReadback\t0x%p\t%s\t%llu"), TextureReadback, *TextureReadback->GetName().ToString(), Size);
|
|
}
|
|
return Size;
|
|
}
|
|
|
|
static uint64 GetBufferReadbackGPUSizeBytes(const FRHIGPUBufferReadback* BufferReadback, bool bLogSizes)
|
|
{
|
|
uint64 Size = BufferReadback ? BufferReadback->GetGPUSizeBytes() : 0;
|
|
if (bLogSizes && Size)
|
|
{
|
|
UE_LOG(LogRenderer, Log, TEXT("LogSizes\tBufferReadback\t%p\t%s\t%llu"), BufferReadback, *BufferReadback->GetName().ToString(), Size);
|
|
}
|
|
return Size;
|
|
}
|
|
|
|
uint64 FHZBOcclusionTester::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return ResultsReadback.IsValid() ? GetTextureReadbackGPUSizeBytes(ResultsReadback.Get(), bLogSizes) : 0;
|
|
}
|
|
|
|
uint64 FPersistentSkyAtmosphereData::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
for (int32 VolumeIndex = 0; VolumeIndex < UE_ARRAY_COUNT(CameraAerialPerspectiveVolumes); VolumeIndex++)
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(CameraAerialPerspectiveVolumes[VolumeIndex], bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(CameraAerialPerspectiveVolumesMieOnly[VolumeIndex], bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(CameraAerialPerspectiveVolumesRayOnly[VolumeIndex], bLogSizes);
|
|
}
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FSceneViewState::FEyeAdaptationManager::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
|
for (int32 TargetIndex = 0; TargetIndex < UE_ARRAY_COUNT(PooledRenderTarget); TargetIndex++)
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(PooledRenderTarget[TargetIndex], bLogSizes);
|
|
}
|
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
|
for (int32 BufferIndex = 0; BufferIndex < UE_ARRAY_COUNT(ExposureBufferData); BufferIndex++)
|
|
{
|
|
TotalSize += GetBufferGPUSizeBytes(ExposureBufferData[BufferIndex], bLogSizes);
|
|
}
|
|
for (FRHIGPUBufferReadback* ReadbackBuffer : ExposureReadbackBuffers)
|
|
{
|
|
TotalSize += GetBufferReadbackGPUSizeBytes(ReadbackBuffer, bLogSizes);
|
|
}
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FTemporalAAHistory::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
for (int32 TargetIndex = 0; TargetIndex < kRenderTargetCount; TargetIndex++)
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(RT[TargetIndex], bLogSizes);
|
|
}
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FTSRHistory::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize =
|
|
GetRenderTargetGPUSizeBytes(ColorArray, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(MetadataArray, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(GuideArray, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(MoireArray, bLogSizes);
|
|
|
|
if (CoverageArray.IsValid())
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(CoverageArray, bLogSizes);
|
|
}
|
|
|
|
for (const TRefCountPtr <IPooledRenderTarget>& Texture : DistortingDisplacementTextures)
|
|
{
|
|
if (Texture.IsValid())
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(Texture, bLogSizes);
|
|
}
|
|
}
|
|
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FScreenSpaceDenoiserHistory::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
for (int32 TargetIndex = 0; TargetIndex < RTCount; TargetIndex++)
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(RT[TargetIndex], bLogSizes);
|
|
}
|
|
TotalSize += GetRenderTargetGPUSizeBytes(TileClassification, bLogSizes);
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FPreviousViewInfo::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize =
|
|
GetRenderTargetGPUSizeBytes(DepthBuffer, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(GBufferA, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(GBufferB, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(GBufferC, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(HZB, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(NaniteHZB, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(DistortingDisplacementTexture, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(CompressedDepthViewNormal, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(CompressedOpaqueDepth, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(CompressedOpaqueShadingModel, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(ScreenSpaceRayTracingInput, bLogSizes) +
|
|
TemporalAAHistory.GetGPUSizeBytes(bLogSizes) +
|
|
TSRHistory.GetGPUSizeBytes(bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(HalfResTemporalAAHistory, bLogSizes) +
|
|
DOFSetupHistory.GetGPUSizeBytes(bLogSizes) +
|
|
SSRHistory.GetGPUSizeBytes(bLogSizes) +
|
|
WaterSSRHistory.GetGPUSizeBytes(bLogSizes) +
|
|
RoughRefractionHistory.GetGPUSizeBytes(bLogSizes) +
|
|
HairHistory.GetGPUSizeBytes(bLogSizes) +
|
|
#if UE_ENABLE_DEBUG_DRAWING
|
|
CompositePrimitiveDepthHistory.GetGPUSizeBytes(bLogSizes) +
|
|
#endif
|
|
CustomSSRInput.GetGPUSizeBytes(bLogSizes) +
|
|
ReflectionsHistory.GetGPUSizeBytes(bLogSizes) +
|
|
WaterReflectionsHistory.GetGPUSizeBytes(bLogSizes) +
|
|
AmbientOcclusionHistory.GetGPUSizeBytes(bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(GTAOHistory.RT, bLogSizes) +
|
|
DiffuseIndirectHistory.GetGPUSizeBytes(bLogSizes) +
|
|
SkyLightHistory.GetGPUSizeBytes(bLogSizes) +
|
|
ReflectedSkyLightHistory.GetGPUSizeBytes(bLogSizes) +
|
|
PolychromaticPenumbraHarmonicsHistory.GetGPUSizeBytes(bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(MobileBloomSetup_EyeAdaptation, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(MobileAmbientOcclusion, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(VisualizeMotionVectors, bLogSizes);
|
|
|
|
for (auto ShadowHistoryIt = ShadowHistories.begin(); ShadowHistoryIt; ++ShadowHistoryIt)
|
|
{
|
|
if (ShadowHistoryIt.Value().IsValid())
|
|
{
|
|
TotalSize += ShadowHistoryIt.Value()->GetGPUSizeBytes(bLogSizes);
|
|
}
|
|
}
|
|
|
|
if (ThirdPartyTemporalUpscalerHistory)
|
|
{
|
|
TotalSize += ThirdPartyTemporalUpscalerHistory->GetGPUSizeBytes();
|
|
if (bLogSizes)
|
|
{
|
|
UE_LOG(LogRenderer, Log, TEXT("LogSizes\tThirdPartyTemporalUpscaler\t%s\t%llu"), ThirdPartyTemporalUpscalerHistory->GetDebugName(), ThirdPartyTemporalUpscalerHistory->GetGPUSizeBytes());
|
|
}
|
|
}
|
|
|
|
return TotalSize;
|
|
}
|
|
|
|
/** FLumenViewState GPU size queries */
|
|
uint64 FScreenProbeGatherTemporalState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return
|
|
GetRenderTargetGPUSizeBytes(DiffuseIndirectHistoryRT, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(RoughSpecularIndirectHistoryRT, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(FastUpdateMode_NumFramesAccumulatedHistoryRT, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(HistoryScreenProbeSceneDepth, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(HistoryScreenProbeTranslatedWorldPosition, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(ProbeHistoryScreenProbeRadiance, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(ImportanceSamplingHistoryScreenProbeRadiance, bLogSizes);
|
|
}
|
|
|
|
uint64 FReflectionTemporalState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return
|
|
GetRenderTargetGPUSizeBytes(SpecularAndSecondMomentHistory, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(NumFramesAccumulatedHistory, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(LayerSceneDepthHistory, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(LayerSceneNormalHistory, bLogSizes);
|
|
}
|
|
|
|
uint64 FRadianceCacheState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return
|
|
GetRenderTargetGPUSizeBytes(RadianceProbeIndirectionTexture, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(RadianceProbeAtlasTexture, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(SkyVisibilityProbeAtlasTexture, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(FinalRadianceAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(FinalSkyVisibilityAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(FinalIrradianceAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(ProbeOcclusionAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(DepthProbeAtlasTexture, bLogSizes) +
|
|
GetBufferGPUSizeBytes(ProbeAllocator, bLogSizes) +
|
|
GetBufferGPUSizeBytes(ProbeFreeListAllocator, bLogSizes) +
|
|
GetBufferGPUSizeBytes(ProbeFreeList, bLogSizes) +
|
|
GetBufferGPUSizeBytes(ProbeLastUsedFrame, bLogSizes) +
|
|
GetBufferGPUSizeBytes(ProbeLastTracedFrame, bLogSizes) +
|
|
GetBufferGPUSizeBytes(ProbeWorldOffset, bLogSizes);
|
|
}
|
|
|
|
uint64 FLumenViewState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return
|
|
ScreenProbeGatherState.GetGPUSizeBytes(bLogSizes) +
|
|
ReflectionState.GetGPUSizeBytes(bLogSizes) +
|
|
TranslucentReflectionState.GetGPUSizeBytes(bLogSizes) +
|
|
WaterReflectionState.GetGPUSizeBytes(bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(TranslucencyVolume0, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(TranslucencyVolume1, bLogSizes) +
|
|
RadianceCacheState.GetGPUSizeBytes(bLogSizes) +
|
|
TranslucencyVolumeRadianceCacheState.GetGPUSizeBytes(bLogSizes);
|
|
}
|
|
|
|
/** FLumenSceneData GPU size queries */
|
|
uint64 FLumenSurfaceCacheFeedback::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
for (const FRHIGPUBufferReadback* ReadbackBuffer : ReadbackBuffers)
|
|
{
|
|
TotalSize += GetBufferReadbackGPUSizeBytes(ReadbackBuffer, bLogSizes);
|
|
}
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FLumenSceneData::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return
|
|
GetBufferGPUSizeBytes(CardBuffer, bLogSizes) +
|
|
CardUploadBuffer.GetNumBytes() +
|
|
GetBufferGPUSizeBytes(MeshCardsBuffer, bLogSizes) +
|
|
MeshCardsUploadBuffer.GetNumBytes() +
|
|
GetBufferGPUSizeBytes(HeightfieldBuffer, bLogSizes) +
|
|
HeightfieldUploadBuffer.GetNumBytes() +
|
|
GetBufferGPUSizeBytes(SceneInstanceIndexToMeshCardsIndexBuffer, bLogSizes) +
|
|
SceneInstanceIndexToMeshCardsIndexUploadBuffer.GetNumBytes() +
|
|
GetBufferGPUSizeBytes(CardPageBuffer, bLogSizes) +
|
|
CardPageUploadBuffer.GetNumBytes() +
|
|
GetBufferGPUSizeBytes(CardPageLastUsedBuffer, bLogSizes) +
|
|
GetBufferGPUSizeBytes(CardPageHighResLastUsedBuffer, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(AlbedoAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(OpacityAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(NormalAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(EmissiveAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(DepthAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(DirectLightingAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(DiffuseLightingAndSecondMomentHistoryAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(NumFramesAccumulatedHistoryAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(IndirectLightingAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(RadiosityNumFramesAccumulatedAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(FinalLightingAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(RadiosityTraceRadianceAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(RadiosityTraceHitDistanceAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(RadiosityProbeSHRedAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(RadiosityProbeSHGreenAtlas, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(RadiosityProbeSHBlueAtlas, bLogSizes) +
|
|
SurfaceCacheFeedback.GetGPUSizeBytes(bLogSizes) +
|
|
GetBufferGPUSizeBytes(PageTableBuffer, bLogSizes) +
|
|
PageTableUploadBuffer.GetNumBytes();
|
|
}
|
|
|
|
uint64 FMegaLightsViewState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return
|
|
GetRenderTargetGPUSizeBytes(DiffuseLightingAndSecondMomentHistory, bLogSizes)
|
|
+ GetRenderTargetGPUSizeBytes(SpecularLightingAndSecondMomentHistory, bLogSizes)
|
|
+ GetRenderTargetGPUSizeBytes(NumFramesAccumulatedHistory, bLogSizes)
|
|
+ GetBufferGPUSizeBytes(VisibleLightHashHistory, bLogSizes)
|
|
+ GetBufferGPUSizeBytes(VisibleLightMaskHashHistory, bLogSizes)
|
|
+ GetBufferGPUSizeBytes(VolumeVisibleLightHashHistory, bLogSizes);
|
|
}
|
|
|
|
uint64 FStochasticLightingViewState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return
|
|
GetRenderTargetGPUSizeBytes(SceneDepthHistory, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(SceneNormalHistory, bLogSizes);
|
|
}
|
|
|
|
uint64 FTranslucencyLightingViewState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
|
|
for (int32 Index = 0; Index < TVC_MAX; Index++)
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(HistoryAmbient[Index], bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(HistoryDirectional[Index], bLogSizes);
|
|
|
|
TotalSize += GetRenderTargetGPUSizeBytes(HistoryMark[Index], bLogSizes);
|
|
}
|
|
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FPersistentGlobalDistanceFieldData::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize =
|
|
GetBufferGPUSizeBytes(PageFreeListAllocatorBuffer, bLogSizes) +
|
|
GetBufferGPUSizeBytes(PageFreeListBuffer, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(PageAtlasTexture, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(CoverageAtlasTexture, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(PageTableCombinedTexture, bLogSizes) +
|
|
GetRenderTargetGPUSizeBytes(MipTexture, bLogSizes);
|
|
|
|
for (int32 GDFIndex = 0; GDFIndex < UE_ARRAY_COUNT(PageTableLayerTextures); GDFIndex++)
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(PageTableLayerTextures[GDFIndex], bLogSizes);
|
|
}
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FVolumetricRenderTargetViewStateData::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
for (uint32 TargetIndex = 0; TargetIndex < kRenderTargetCount; TargetIndex++)
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(VolumetricReconstructRT[TargetIndex], bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(VolumetricReconstructRTDepth[TargetIndex], bLogSizes);
|
|
}
|
|
TotalSize += GetRenderTargetGPUSizeBytes(VolumetricTracingRT, bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(VolumetricTracingRTDepth, bLogSizes);
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FTemporalRenderTargetState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
for (int32 TargetIndex = 0; TargetIndex < UE_ARRAY_COUNT(RenderTargets); TargetIndex++)
|
|
{
|
|
TotalSize += GetRenderTargetGPUSizeBytes(RenderTargets[TargetIndex], bLogSizes);
|
|
}
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FGlintShadingLUTsStateData::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return GetTextureGPUSizeBytes(RHIGlintShadingLUTs, bLogSizes);
|
|
}
|
|
|
|
uint64 FVirtualShadowMapArrayFrameData::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
return
|
|
::GetGPUSizeBytes(PageTable, bLogSizes) +
|
|
::GetGPUSizeBytes(PageFlags, bLogSizes) +
|
|
::GetGPUSizeBytes(ProjectionData, bLogSizes) +
|
|
::GetGPUSizeBytes(UncachedPageRectBounds, bLogSizes) +
|
|
::GetGPUSizeBytes(AllocatedPageRectBounds, bLogSizes);
|
|
};
|
|
|
|
uint64 FVirtualShadowMapArrayCacheManager::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = PrevBuffers.GetGPUSizeBytes(bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(PhysicalPagePool, bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(HZBPhysicalPagePoolArray, bLogSizes);
|
|
TotalSize += GetBufferGPUSizeBytes(PhysicalPageMetaData, bLogSizes);
|
|
TotalSize += GetBufferGPUSizeBytes(AccumulatedStatsBuffer, bLogSizes);
|
|
TotalSize += GetBufferReadbackGPUSizeBytes(GPUBufferReadback, bLogSizes);
|
|
return TotalSize;
|
|
}
|
|
|
|
uint64 FSceneViewState::GetGPUSizeBytes(bool bLogSizes) const
|
|
{
|
|
uint64 TotalSize = 0;
|
|
|
|
// Todo, not currently computing GPU memory usage for queries or sampler states. Are these important? Should be small...
|
|
// ShadowOcclusionQueryMaps
|
|
// OcclusionQueryPool
|
|
// PrimitiveOcclusionQueryPool
|
|
// PlanarReflectionOcclusionHistories
|
|
// MaterialTextureBilinearWrapedSamplerCache
|
|
// MaterialTextureBilinearClampedSamplerCache
|
|
|
|
TotalSize += HZBOcclusionTests.GetGPUSizeBytes(bLogSizes);
|
|
TotalSize += PersistentSkyAtmosphereData.GetGPUSizeBytes(bLogSizes);
|
|
TotalSize += EyeAdaptationManager.GetGPUSizeBytes(bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(CombinedLUTRenderTarget, bLogSizes);
|
|
TotalSize += PrevFrameViewInfo.GetGPUSizeBytes(bLogSizes);
|
|
TotalSize += LightShaftOcclusionHistory.GetGPUSizeBytes(bLogSizes);
|
|
for (auto LightShaftBloomIt = LightShaftBloomHistoryRTs.begin(); LightShaftBloomIt; ++LightShaftBloomIt)
|
|
{
|
|
if (LightShaftBloomIt.Value().IsValid())
|
|
{
|
|
TotalSize += LightShaftBloomIt.Value()->GetGPUSizeBytes(bLogSizes);
|
|
}
|
|
}
|
|
TotalSize += GetRenderTargetGPUSizeBytes(DistanceFieldAOHistoryRT, bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(DistanceFieldIrradianceHistoryRT, bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(SubsurfaceScatteringQualityHistoryRT, bLogSizes);
|
|
TotalSize += Lumen.GetGPUSizeBytes(bLogSizes);
|
|
TotalSize += MegaLights.GetGPUSizeBytes(bLogSizes);
|
|
TotalSize += TranslucencyLighting.GetGPUSizeBytes(bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(BloomFFTKernel.Spectral, bLogSizes);
|
|
TotalSize += GetBufferGPUSizeBytes(BloomFFTKernel.ConstantsBuffer, bLogSizes);
|
|
TotalSize += GetBufferGPUSizeBytes(FilmGrainCache.ConstantsBuffer, bLogSizes);
|
|
#if RHI_RAYTRACING
|
|
TotalSize += GetBufferGPUSizeBytes(SkyLightVisibilityRaysBuffer, bLogSizes);
|
|
#endif
|
|
TotalSize += GetRenderTargetGPUSizeBytes(LightScatteringHistory, bLogSizes);
|
|
TotalSize += GetRenderTargetGPUSizeBytes(PrevLightScatteringConservativeDepthTexture, bLogSizes);
|
|
if (GlobalDistanceFieldData.IsValid())
|
|
{
|
|
TotalSize += GlobalDistanceFieldData->GetGPUSizeBytes(bLogSizes);
|
|
}
|
|
TotalSize += VolumetricCloudRenderTarget.GetGPUSizeBytes(bLogSizes);
|
|
for (int32 LightIndex = 0; LightIndex < UE_ARRAY_COUNT(VolumetricCloudShadowRenderTarget); LightIndex++)
|
|
{
|
|
TotalSize += VolumetricCloudShadowRenderTarget[LightIndex].GetGPUSizeBytes(bLogSizes);
|
|
}
|
|
TotalSize += GetBufferGPUSizeBytes(HairStrandsViewStateData.VoxelFeedbackBuffer, bLogSizes);
|
|
TotalSize += GetBufferGPUSizeBytes(ShaderPrintStateData.EntryBuffer, bLogSizes);
|
|
TotalSize += GetBufferGPUSizeBytes(ShaderPrintStateData.StateBuffer, bLogSizes);
|
|
TotalSize += GlintShadingLUTsData.GetGPUSizeBytes(bLogSizes);
|
|
|
|
// Per-view Lumen scene data is stored in a map in the FScene
|
|
if (Scene && bLumenSceneDataAdded)
|
|
{
|
|
FLumenSceneDataKey ByViewKey = { GetViewKey(), (uint32)INDEX_NONE };
|
|
FLumenSceneData** SceneData = Scene->PerViewOrGPULumenSceneData.Find(ByViewKey);
|
|
|
|
if (SceneData)
|
|
{
|
|
TotalSize += (*SceneData)->GetGPUSizeBytes(bLogSizes);
|
|
}
|
|
}
|
|
|
|
return TotalSize;
|
|
}
|
|
|
|
void FSceneViewState::AddLumenSceneData(FSceneInterface* InScene, float InSurfaceCacheResolution)
|
|
{
|
|
check(InScene);
|
|
if (!Scene)
|
|
{
|
|
Scene = (FScene*)InScene;
|
|
|
|
// Modification of scene structure needs to happen on render thread
|
|
ENQUEUE_RENDER_COMMAND(SceneViewStateAdd)(
|
|
[RenderScene = Scene, RenderViewState = this](FRHICommandListBase&)
|
|
{
|
|
RenderScene->ViewStates.Add(RenderViewState);
|
|
});
|
|
}
|
|
|
|
if (Scene == InScene && Scene->DefaultLumenSceneData)
|
|
{
|
|
// Don't allocate if one already exists
|
|
if (!bLumenSceneDataAdded)
|
|
{
|
|
bLumenSceneDataAdded = true;
|
|
LumenSurfaceCacheResolution = InSurfaceCacheResolution;
|
|
|
|
FLumenSceneData* SceneData = new FLumenSceneData(Scene->DefaultLumenSceneData->bTrackAllPrimitives);
|
|
SceneData->bViewSpecific = true;
|
|
SceneData->SurfaceCacheResolution = FMath::Clamp(InSurfaceCacheResolution, 0.5f, 1.0f);
|
|
|
|
// Need to add reference to Lumen scene data in render thread
|
|
ENQUEUE_RENDER_COMMAND(LinkLumenSceneData)(
|
|
[this, SceneData](FRHICommandListBase&)
|
|
{
|
|
SceneData->CopyInitialData(*Scene->DefaultLumenSceneData);
|
|
|
|
// Key shouldn't already exist in Scene, because the bLumenSceneDataAdded flag should only allow it to be added once.
|
|
FLumenSceneDataKey ByViewKey = { GetViewKey(), (uint32)INDEX_NONE };
|
|
check(Scene->PerViewOrGPULumenSceneData.Find(ByViewKey) == nullptr);
|
|
|
|
Scene->PerViewOrGPULumenSceneData.Emplace(ByViewKey, SceneData);
|
|
});
|
|
} //-V773
|
|
else if (LumenSurfaceCacheResolution != InSurfaceCacheResolution)
|
|
{
|
|
LumenSurfaceCacheResolution = InSurfaceCacheResolution;
|
|
|
|
ENQUEUE_RENDER_COMMAND(ChangeLumenSceneDataQuality)(
|
|
[this, InSurfaceCacheResolution](FRHICommandListBase&)
|
|
{
|
|
FLumenSceneDataKey ByViewKey = { GetViewKey(), (uint32)INDEX_NONE };
|
|
FLumenSceneData** SceneData = Scene->PerViewOrGPULumenSceneData.Find(ByViewKey);
|
|
|
|
check(SceneData);
|
|
|
|
(*SceneData)->SurfaceCacheResolution = FMath::Clamp(InSurfaceCacheResolution, 0.5f, 1.0f);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
void FSceneViewState::RemoveLumenSceneData(FSceneInterface* InScene)
|
|
{
|
|
check(InScene);
|
|
if (Scene == InScene && bLumenSceneDataAdded)
|
|
{
|
|
bLumenSceneDataAdded = false;
|
|
|
|
ENQUEUE_RENDER_COMMAND(RemoveLumenSceneData)(
|
|
[this](FRHICommandListBase&)
|
|
{
|
|
FLumenSceneDataKey ByViewKey = { GetViewKey(), (uint32)INDEX_NONE };
|
|
FLumenSceneData** SceneData = Scene->PerViewOrGPULumenSceneData.Find(ByViewKey);
|
|
|
|
check(SceneData);
|
|
delete* SceneData;
|
|
|
|
Scene->PerViewOrGPULumenSceneData.Remove(ByViewKey);
|
|
});
|
|
}
|
|
}
|
|
|
|
bool FSceneViewState::HasLumenSceneData() const
|
|
{
|
|
return bLumenSceneDataAdded;
|
|
}
|
|
|
|
static bool SystemMemoryBackupTextureSupported(const FRHITextureDesc& Desc)
|
|
{
|
|
// Long term, it might be useful to support array textures and mips, but it would require multiple readbacks. On high end systems most
|
|
// likely to do very high resolution rendering, system memory limits are hit before GPU memory limits, so it works for now.
|
|
return (Desc.Dimension == ETextureDimension::Texture2D || (Desc.Dimension == ETextureDimension::Texture2DArray && Desc.ArraySize == 1)) && Desc.NumMips == 1 && Desc.NumSamples == 1;
|
|
}
|
|
|
|
static void SystemMemoryBackupTextureBegin(FRHICommandListImmediate& RHICmdList, FSceneViewStateSystemMemoryMirror& SystemMemoryMirror, FSceneViewState& ViewState, TRefCountPtr<IPooledRenderTarget>& Texture)
|
|
{
|
|
if (Texture.IsValid())
|
|
{
|
|
FRHITexture* TextureRHI = Texture->GetRHI();
|
|
|
|
if (TextureRHI && SystemMemoryBackupTextureSupported(TextureRHI->GetDesc()))
|
|
{
|
|
int64 StructureOffset = (uint8*)&Texture - (uint8*)&ViewState;
|
|
TArray<FSceneViewStateSystemMemoryTexture>& TextureMirrorArray = SystemMemoryMirror.TextureMirrors.FindOrAdd(StructureOffset);
|
|
|
|
// Enable Dynamic so staging buffers are cached (except depth stencil textures, which use a PF_R32_FLOAT format intermediate, with flag added to that below).
|
|
FRHITextureDesc Desc = TextureRHI->GetDesc();
|
|
if (Desc.Format != PF_DepthStencil)
|
|
{
|
|
Desc.Flags |= ETextureCreateFlags::Dynamic;
|
|
}
|
|
|
|
int32 MatchingIndex;
|
|
for (MatchingIndex = 0; MatchingIndex < TextureMirrorArray.Num(); MatchingIndex++)
|
|
{
|
|
if (TextureMirrorArray[MatchingIndex].Desc == Desc)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (MatchingIndex == TextureMirrorArray.Num())
|
|
{
|
|
FSceneViewStateSystemMemoryTexture& TextureMirror = TextureMirrorArray.AddDefaulted_GetRef();
|
|
TextureMirror.Desc = Desc;
|
|
TextureMirror.DebugName = Texture->GetDesc().DebugName;
|
|
TextureMirror.Readback = MakeUnique<FRHIGPUTextureReadback>(TextureMirror.DebugName);
|
|
}
|
|
|
|
FSceneViewStateSystemMemoryTexture& TextureMirror = TextureMirrorArray[MatchingIndex];
|
|
|
|
if (Desc.Format == PF_DepthStencil)
|
|
{
|
|
// Depth stencil doesn't support readback -- need to copy through an intermediate float texture. Also, we are
|
|
// only copying the depth, not stencil, assuming previous frame stencil isn't used.
|
|
FRHITextureDesc TemporaryTextureDesc = TextureMirror.Desc;
|
|
TemporaryTextureDesc.Flags = ETextureCreateFlags::Dynamic;
|
|
TemporaryTextureDesc.Format = PF_R32_FLOAT;
|
|
|
|
TRefCountPtr<IPooledRenderTarget> TemporaryTexture;
|
|
GRenderTargetPool.FindFreeElement(RHICmdList, TemporaryTextureDesc, TemporaryTexture, TextureMirror.DebugName);
|
|
|
|
// Ensure texture isn't destroyed until commands finish
|
|
SystemMemoryMirror.TemporaryTextures.Add(TemporaryTexture);
|
|
|
|
RHICmdList.CopyTexture(Texture->GetRHI(), TemporaryTexture->GetRHI(), {});
|
|
TextureMirror.Readback->EnqueueCopy(RHICmdList, TemporaryTexture->GetRHI(), FIntVector(0, 0, 0), 0, FIntVector(0, 0, 0));
|
|
}
|
|
else
|
|
{
|
|
TextureMirror.Readback->EnqueueCopy(RHICmdList, TextureRHI, FIntVector(0, 0, 0), 0, FIntVector(0, 0, 0));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SystemMemoryBackupTextureEnd(FRHICommandListImmediate& RHICmdList, FSceneViewStateSystemMemoryMirror& SystemMemoryMirror, FSceneViewState& ViewState, TRefCountPtr<IPooledRenderTarget>& Texture)
|
|
{
|
|
if (Texture.IsValid())
|
|
{
|
|
FRHITexture* TextureRHI = Texture->GetRHI();
|
|
|
|
if (TextureRHI && SystemMemoryBackupTextureSupported(TextureRHI->GetDesc()))
|
|
{
|
|
int64 StructureOffset = (uint8*)&Texture - (uint8*)&ViewState;
|
|
TArray<FSceneViewStateSystemMemoryTexture>& TextureMirrorArray = SystemMemoryMirror.TextureMirrors.FindOrAdd(StructureOffset);
|
|
|
|
// Enable Dynamic so staging buffers are cached (except depth stencil textures, which use a PF_R32_FLOAT format intermediate, with the array element not having the flag set).
|
|
FRHITextureDesc Desc = TextureRHI->GetDesc();
|
|
if (Desc.Format != PF_DepthStencil)
|
|
{
|
|
Desc.Flags |= ETextureCreateFlags::Dynamic;
|
|
}
|
|
|
|
int32 MatchingIndex;
|
|
for (MatchingIndex = 0; MatchingIndex < TextureMirrorArray.Num(); MatchingIndex++)
|
|
{
|
|
if (TextureMirrorArray[MatchingIndex].Desc == Desc)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
check(MatchingIndex < TextureMirrorArray.Num());
|
|
|
|
FSceneViewStateSystemMemoryTexture& TextureMirror = TextureMirrorArray[MatchingIndex];
|
|
int32 SrcPitchInPixels;
|
|
void* TextureBuffer = TextureMirror.Readback->Lock(SrcPitchInPixels);
|
|
|
|
// Align destination width to block size. Depth is copied through a 32-bit float temporary.
|
|
EPixelFormat CopyFormat = Desc.Format == PF_DepthStencil ? PF_R32_FLOAT : Desc.Format;
|
|
const FPixelFormatInfo& FormatInfo = GPixelFormats[CopyFormat];
|
|
int32 DestPitchInPixels = (Desc.Extent.X + FormatInfo.BlockSizeX - 1) / FormatInfo.BlockSizeX * FormatInfo.BlockSizeX;
|
|
|
|
// Allocate storage
|
|
SIZE_T ImageSize = CalcTextureMipMapSize(DestPitchInPixels, Desc.Extent.Y, CopyFormat, 0);
|
|
TArray<uint8>& ImageBuffer = TextureMirror.Instances.FindOrAdd(ViewState.GetViewKey());
|
|
ImageBuffer.SetNumUninitialized(ImageSize);
|
|
|
|
// Compute stride in bytes
|
|
int32 SrcStrideInBytes = SrcPitchInPixels / FormatInfo.BlockSizeX * FormatInfo.BlockBytes;
|
|
int32 DestStrideInBytes = DestPitchInPixels / FormatInfo.BlockSizeX * FormatInfo.BlockBytes;
|
|
|
|
CopyTextureData2D(TextureBuffer, ImageBuffer.GetData(), Desc.Extent.Y, CopyFormat, SrcStrideInBytes, DestStrideInBytes);
|
|
|
|
TextureMirror.Readback->Unlock();
|
|
|
|
Texture = nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Uses Lock / Unlock, rather than UpdateTexture2D, in case we want to extend the function to support array textures in the future (used by TSR).
|
|
// UpdateTexture2D only works on the first array element.
|
|
static void SystemMemoryUpdateTexture(FRHICommandListImmediate& RHICmdList, FRHITexture* TextureRHI, const FRHITextureDesc& Desc, const uint8* CopySrc)
|
|
{
|
|
FIntPoint Extent = Desc.Extent;
|
|
const FPixelFormatInfo& FormatInfo = GPixelFormats[Desc.Format];
|
|
|
|
// Align source width to block size
|
|
uint32 SourcePitchInPixels = (Extent.X + FormatInfo.BlockSizeX - 1) / FormatInfo.BlockSizeX * FormatInfo.BlockSizeX;
|
|
uint32 WidthInBlocks = (Extent.X + FormatInfo.BlockSizeX - 1) / FormatInfo.BlockSizeX;
|
|
uint32 HeightInBlocks = (Extent.Y + FormatInfo.BlockSizeY - 1) / FormatInfo.BlockSizeY;
|
|
uint32 SourcePitchInBytes = SourcePitchInPixels / FormatInfo.BlockSizeX * FormatInfo.BlockBytes;
|
|
|
|
FRHILockTextureArgs LockArgs = FRHILockTextureArgs::Lock2D(TextureRHI, 0, EResourceLockMode::RLM_WriteOnly, false, false);
|
|
FRHILockTextureResult LockResult = RHICmdList.LockTexture(LockArgs);
|
|
|
|
uint8* CopyDst = (uint8*)LockResult.Data;
|
|
for (uint32 BlockRow = 0; BlockRow < HeightInBlocks; BlockRow++)
|
|
{
|
|
FMemory::Memcpy(CopyDst, CopySrc, WidthInBlocks * FormatInfo.BlockBytes);
|
|
CopySrc += SourcePitchInBytes;
|
|
CopyDst += LockResult.Stride;
|
|
}
|
|
|
|
RHICmdList.UnlockTexture(LockArgs);
|
|
}
|
|
|
|
static void SystemMemoryRestoreTexture(FRHICommandListImmediate& RHICmdList, FSceneViewStateSystemMemoryMirror& SystemMemoryMirror, FSceneViewState& ViewState, TRefCountPtr<IPooledRenderTarget>& Texture)
|
|
{
|
|
int64 StructureOffset = (uint8*)&Texture - (uint8*)&ViewState;
|
|
TArray<FSceneViewStateSystemMemoryTexture>* TextureMirrorArray = SystemMemoryMirror.TextureMirrors.Find(StructureOffset);
|
|
|
|
if (TextureMirrorArray)
|
|
{
|
|
int32 MatchingIndex;
|
|
for (MatchingIndex = 0; MatchingIndex < TextureMirrorArray->Num(); MatchingIndex++)
|
|
{
|
|
if ((*TextureMirrorArray)[MatchingIndex].Instances.Contains(ViewState.GetViewKey()))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (MatchingIndex < TextureMirrorArray->Num())
|
|
{
|
|
const FRHITextureDesc& Desc = (*TextureMirrorArray)[MatchingIndex].Desc;
|
|
|
|
GRenderTargetPool.FindFreeElement(RHICmdList, Desc, Texture, (*TextureMirrorArray)[MatchingIndex].DebugName);
|
|
|
|
TArray<uint8>* ImageBuffer = (*TextureMirrorArray)[MatchingIndex].Instances.Find(ViewState.GetViewKey());
|
|
check(ImageBuffer);
|
|
|
|
if (Desc.Format == PF_DepthStencil)
|
|
{
|
|
// For depth stencil, we only copy depth, assuming previous frame stencil isn't used
|
|
FRHITextureDesc TemporaryTextureDesc = (*TextureMirrorArray)[MatchingIndex].Desc;
|
|
TemporaryTextureDesc.Flags = ETextureCreateFlags::Dynamic;
|
|
TemporaryTextureDesc.Format = PF_R32_FLOAT;
|
|
|
|
TRefCountPtr<IPooledRenderTarget> TemporaryTexture;
|
|
GRenderTargetPool.FindFreeElement(RHICmdList, TemporaryTextureDesc, TemporaryTexture, (*TextureMirrorArray)[MatchingIndex].DebugName);
|
|
|
|
SystemMemoryUpdateTexture(RHICmdList, TemporaryTexture->GetRHI(), TemporaryTextureDesc, ImageBuffer->GetData());
|
|
RHICmdList.CopyTexture(TemporaryTexture->GetRHI(), Texture->GetRHI(), {});
|
|
}
|
|
else
|
|
{
|
|
SystemMemoryUpdateTexture(RHICmdList, Texture->GetRHI(), Desc, ImageBuffer->GetData());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SystemMemoryForEachTexture(FRHICommandListImmediate& RHICmdList, FSceneViewStateSystemMemoryMirror& SystemMemoryMirror, FSceneViewState& ViewState,
|
|
void (*TextureFunction)(FRHICommandListImmediate&, FSceneViewStateSystemMemoryMirror&, FSceneViewState&, TRefCountPtr<IPooledRenderTarget>&))
|
|
{
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.DepthBuffer);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.GBufferA);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.GBufferB);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.GBufferC);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.DistortingDisplacementTexture);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.CompressedDepthViewNormal);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.CompressedOpaqueDepth);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.CompressedOpaqueShadingModel);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.PrevFrameViewInfo.ScreenSpaceRayTracingInput);
|
|
|
|
// NOTE: not bothering to cache the numerous Temporal AA related render targets from PrevFrameViewInfo, as TAA is not supported with tiled rendering,
|
|
// which is the use case for system memory mirroring of view state.
|
|
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.DiffuseIndirectHistoryRT);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.BackfaceDiffuseIndirectHistoryRT);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.RoughSpecularIndirectHistoryRT);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.FastUpdateMode_NumFramesAccumulatedHistoryRT);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.ShortRangeAOHistoryRT);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.HistoryScreenProbeSceneDepth);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.HistoryScreenProbeTranslatedWorldPosition);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.ProbeHistoryScreenProbeRadiance);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ScreenProbeGatherState.ImportanceSamplingHistoryScreenProbeRadiance);
|
|
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ReflectionState.SpecularAndSecondMomentHistory);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.ReflectionState.NumFramesAccumulatedHistory);
|
|
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.TranslucentReflectionState.SpecularAndSecondMomentHistory);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.TranslucentReflectionState.NumFramesAccumulatedHistory);
|
|
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.WaterReflectionState.SpecularAndSecondMomentHistory);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.WaterReflectionState.NumFramesAccumulatedHistory);
|
|
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.RadianceCacheState.RadianceProbeAtlasTexture);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.RadianceCacheState.SkyVisibilityProbeAtlasTexture);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.RadianceCacheState.FinalRadianceAtlas);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.RadianceCacheState.FinalSkyVisibilityAtlas);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.RadianceCacheState.DepthProbeAtlasTexture);
|
|
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.TranslucencyVolumeRadianceCacheState.RadianceProbeAtlasTexture);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.TranslucencyVolumeRadianceCacheState.SkyVisibilityProbeAtlasTexture);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.TranslucencyVolumeRadianceCacheState.FinalRadianceAtlas);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.TranslucencyVolumeRadianceCacheState.FinalSkyVisibilityAtlas);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.Lumen.TranslucencyVolumeRadianceCacheState.DepthProbeAtlasTexture);
|
|
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.StochasticLighting.SceneDepthHistory);
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.StochasticLighting.SceneNormalHistory);
|
|
|
|
TextureFunction(RHICmdList, SystemMemoryMirror, ViewState, ViewState.BloomFFTKernel.Spectral);
|
|
}
|
|
|
|
void FSceneViewState::SystemMemoryMirrorBackup(FSceneViewStateSystemMemoryMirror* SystemMemoryMirror)
|
|
{
|
|
ENQUEUE_RENDER_COMMAND(ViewStateSystemMemoryBackup)([&](FRHICommandListImmediate& RHICmdList)
|
|
{
|
|
{
|
|
SCOPED_GPU_STAT(RHICmdList, SystemMemoryBackup);
|
|
SystemMemoryForEachTexture(RHICmdList, *SystemMemoryMirror, *this, SystemMemoryBackupTextureBegin);
|
|
}
|
|
|
|
RHICmdList.BlockUntilGPUIdle();
|
|
RHICmdList.FlushResources();
|
|
|
|
// Clear out any temporary textures used to copy depth
|
|
SystemMemoryMirror->TemporaryTextures.Reset();
|
|
|
|
SystemMemoryForEachTexture(RHICmdList, *SystemMemoryMirror, *this, SystemMemoryBackupTextureEnd);
|
|
});
|
|
|
|
FlushRenderingCommands();
|
|
}
|
|
|
|
void FSceneViewState::SystemMemoryMirrorRestore(FSceneViewStateSystemMemoryMirror* SystemMemoryMirror)
|
|
{
|
|
ENQUEUE_RENDER_COMMAND(ViewStateSystemMemoryRestore)([&](FRHICommandListImmediate& RHICmdList)
|
|
{
|
|
SCOPED_GPU_STAT(RHICmdList, SystemMemoryRestore);
|
|
SystemMemoryForEachTexture(RHICmdList, *SystemMemoryMirror, *this, SystemMemoryRestoreTexture);
|
|
});
|
|
|
|
FlushRenderingCommands();
|
|
}
|