2021-01-11 14:49:16 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "SceneTextures.h"
# include "Shader.h"
# include "SceneUtils.h"
# include "SceneRenderTargetParameters.h"
# include "SceneTextureParameters.h"
# include "VelocityRendering.h"
# include "RenderUtils.h"
# include "EngineGlobals.h"
# include "UnrealEngine.h"
# include "RendererModule.h"
2023-02-09 16:49:22 -05:00
# include "SceneRendering.h"
2021-01-11 14:49:16 -04:00
# include "StereoRendering.h"
# include "StereoRenderTargetManager.h"
# include "CompositionLighting/PostProcessAmbientOcclusion.h"
2022-09-09 00:53:22 -04:00
# include "PostProcess/PostProcessCompositeEditorPrimitives.h"
2021-01-11 14:49:16 -04:00
# include "ShaderCompiler.h"
# include "SystemTextures.h"
2021-03-09 00:23:43 -04:00
# include "PostProcess/PostProcessAmbientOcclusionMobile.h"
# include "PostProcess/PostProcessPixelProjectedReflectionMobile.h"
2021-04-29 19:32:06 -04:00
# include "IHeadMountedDisplayModule.h"
2023-08-31 04:48:32 -04:00
# include "Substrate/Substrate.h"
Visualize Texture: Performance and feature upgrades.
* Visualize texture system starts out in an inactive state until a command is issued, avoiding overhead of tracking views and scene textures, saving 1.4% on the render thread.
* Visualization overhead eliminated for views besides the one currently being visualized.
* Support for visualization of textures from scene captures, via "view=N" option (specifying the unique ID of the view), with "view=?" displaying a list of views for reference.
* Improved visualization for cube maps. PIP uses 2:1 aspect for the longitudinal render to match resource viewer display, and pixel perfect option shows tiled flat cube map faces (actual pixels) rather than running a projection.
* Padding for scene or screen pass textures is removed in the visualization -- the padding otherwise shows up as garbage or blank space.
To remove scene texture padding, it's necessary to add a field to RDG textures to provide an option to track the viewport sizes that were rendered for a given texture. If not set, the assumption is the whole texture was rendered. The field is set for FSceneTextures and FScreenPassTexture, covering the vast majority of cases, plus the denoiser was spot fixed -- worst case if any other cases are missed, you still see the padding. You can tell padding was present when visualizing by contrasting the texture size with the viewport size.
Padding was always a potential issue for the visualizer, but is exacerbated by scene captures, as the padded scene textures are set to a size that's a union of the main view and any scene captures. Padding is also exacerbated by dynamic resolution scaling, as the buffers will be padded to the maximum resolution. For example, a cube map rendering at 512x512 will have 93% of the pixel area as padding if the front buffer is at 1440p, or the default dynamic resolution setup will have 70% of the pixels as padding at minimum res.
#rb Jason.Nadro
[CL 31160232 by jason hoerner in ue5-main branch]
2024-02-03 16:07:46 -05:00
# include "VisualizeTexture.h"
2021-01-11 14:49:16 -04:00
static TAutoConsoleVariable < int32 > CVarSceneTargetsResizeMethod (
TEXT ( " r.SceneRenderTargetResizeMethod " ) ,
0 ,
TEXT ( " Control the scene render target resize method: \n " )
TEXT ( " (This value is only used in game mode and on windowing platforms unless 'r.SceneRenderTargetsResizingMethodForceOverride' is enabled.) \n " )
TEXT ( " 0: Resize to match requested render size (Default) (Least memory use, can cause stalls when size changes e.g. ScreenPercentage) \n " )
TEXT ( " 1: Fixed to screen resolution. \n " )
TEXT ( " 2: Expands to encompass the largest requested render dimension. (Most memory use, least prone to allocation stalls.) " ) ,
ECVF_RenderThreadSafe
) ;
static TAutoConsoleVariable < int32 > CVarSceneTargetsResizeMethodForceOverride (
TEXT ( " r.SceneRenderTargetResizeMethodForceOverride " ) ,
0 ,
TEXT ( " Forces 'r.SceneRenderTargetResizeMethod' to be respected on all configurations. \n " )
TEXT ( " 0: Disabled. \n " )
TEXT ( " 1: Enabled. \n " ) ,
ECVF_RenderThreadSafe
) ;
static TAutoConsoleVariable < int32 > CVarMSAACount (
TEXT ( " r.MSAACount " ) ,
4 ,
TEXT ( " Number of MSAA samples to use with the forward renderer. Only used when MSAA is enabled in the rendering project settings. \n " )
TEXT ( " 0: MSAA disabled (Temporal AA enabled) \n " )
TEXT ( " 1: MSAA disabled \n " )
TEXT ( " 2: Use 2x MSAA \n " )
TEXT ( " 4: Use 4x MSAA " )
TEXT ( " 8: Use 8x MSAA " ) ,
ECVF_RenderThreadSafe | ECVF_Scalability
) ;
static TAutoConsoleVariable < int32 > CVarGBufferFormat (
TEXT ( " r.GBufferFormat " ) ,
1 ,
TEXT ( " Defines the memory layout used for the GBuffer. \n " )
TEXT ( " (affects performance, mostly through bandwidth, quality of normals and material attributes). \n " )
TEXT ( " 0: lower precision (8bit per component, for profiling) \n " )
TEXT ( " 1: low precision (default) \n " )
TEXT ( " 3: high precision normals encoding \n " )
TEXT ( " 5: high precision " ) ,
ECVF_RenderThreadSafe ) ;
static TAutoConsoleVariable < int32 > CVarDefaultBackBufferPixelFormat (
TEXT ( " r.DefaultBackBufferPixelFormat " ) ,
4 ,
TEXT ( " Defines the default back buffer pixel format. \n " )
TEXT ( " 0: 8bit RGBA \n " )
TEXT ( " 1: 16bit RGBA \n " )
TEXT ( " 2: Float RGB \n " )
TEXT ( " 3: Float RGBA \n " )
TEXT ( " 4: 10bit RGB, 2bit Alpha \n " ) ,
ECVF_ReadOnly ) ;
RDG_REGISTER_BLACKBOARD_STRUCT ( FSceneTextures ) ;
2023-07-25 08:54:03 -04:00
EPixelFormat FSceneTextures : : GetGBufferFFormatAndCreateFlags ( ETextureCreateFlags & OutCreateFlags )
2021-01-11 14:49:16 -04:00
{
2023-07-25 08:54:03 -04:00
const int32 GBufferFormat = CVarGBufferFormat . GetValueOnAnyThread ( ) ;
2021-01-11 14:49:16 -04:00
const bool bHighPrecisionGBuffers = ( GBufferFormat > = EGBufferFormat : : Force16BitsPerChannel ) ;
const bool bEnforce8BitPerChannel = ( GBufferFormat = = EGBufferFormat : : Force8BitsPerChannel ) ;
EPixelFormat NormalGBufferFormat = bHighPrecisionGBuffers ? PF_FloatRGBA : PF_B8G8R8A8 ;
if ( bEnforce8BitPerChannel )
{
NormalGBufferFormat = PF_B8G8R8A8 ;
}
else if ( GBufferFormat = = EGBufferFormat : : HighPrecisionNormals )
{
NormalGBufferFormat = PF_FloatRGBA ;
}
2023-07-25 08:54:03 -04:00
OutCreateFlags = TexCreate_RenderTargetable | TexCreate_ShaderResource | GFastVRamConfig . GBufferF ;
2021-01-11 14:49:16 -04:00
return NormalGBufferFormat ;
}
2022-04-06 01:46:34 -04:00
inline EPixelFormat GetMobileSceneDepthAuxPixelFormat ( EShaderPlatform ShaderPlatform , bool bPreciseFormat )
2021-06-11 13:47:20 -04:00
{
2022-04-06 01:46:34 -04:00
if ( IsMobileDeferredShadingEnabled ( ShaderPlatform ) | | bPreciseFormat )
2021-06-11 13:47:20 -04:00
{
return PF_R32_FLOAT ;
}
static const auto CVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.Mobile.SceneDepthAux " ) ) ;
EPixelFormat Format = PF_R16F ;
switch ( CVar - > GetValueOnAnyThread ( ) )
{
case 1 :
Format = PF_R16F ;
break ;
case 2 :
Format = PF_R32_FLOAT ;
break ;
}
return Format ;
}
2021-01-11 14:49:16 -04:00
static IStereoRenderTargetManager * FindStereoRenderTargetManager ( )
{
if ( ! GEngine - > StereoRenderingDevice . IsValid ( ) | | ! GEngine - > StereoRenderingDevice - > IsStereoEnabled ( ) )
{
return nullptr ;
}
return GEngine - > StereoRenderingDevice - > GetRenderTargetManager ( ) ;
}
2024-02-22 11:38:35 -05:00
static TRefCountPtr < FRHITexture > FindStereoDepthTexture ( uint32 bSupportsXRDepth , FIntPoint TextureExtent , ETextureCreateFlags RequestedCreateFlags )
2021-01-11 14:49:16 -04:00
{
2022-07-01 01:26:21 -04:00
if ( bSupportsXRDepth = = 1 )
2021-01-11 14:49:16 -04:00
{
2022-07-01 01:26:21 -04:00
if ( IStereoRenderTargetManager * StereoRenderTargetManager = FindStereoRenderTargetManager ( ) )
{
2024-02-22 11:38:35 -05:00
TRefCountPtr < FRHITexture > DepthTex , SRTex ;
2023-03-09 23:07:25 -05:00
constexpr uint32 NumSamples = 1 ;
StereoRenderTargetManager - > AllocateDepthTexture ( 0 , TextureExtent . X , TextureExtent . Y , PF_DepthStencil , 1 , RequestedCreateFlags , TexCreate_DepthStencilTargetable | TexCreate_ShaderResource | TexCreate_InputAttachmentRead , DepthTex , SRTex , NumSamples ) ;
2022-07-01 01:26:21 -04:00
return MoveTemp ( SRTex ) ;
}
2021-01-11 14:49:16 -04:00
}
return nullptr ;
}
/** Helper class used to track and compute a suitable scene texture extent for the renderer based on history / global configuration. */
class FSceneTextureExtentState
{
public :
static FSceneTextureExtentState & Get ( )
{
static FSceneTextureExtentState Instance ;
return Instance ;
}
FIntPoint Compute ( const FSceneViewFamily & ViewFamily )
{
enum ESizingMethods { RequestedSize , ScreenRes , Grow , VisibleSizingMethodsCount } ;
ESizingMethods SceneTargetsSizingMethod = Grow ;
bool bIsSceneCapture = false ;
bool bIsReflectionCapture = false ;
bool bIsVRScene = false ;
2023-11-21 09:55:42 -05:00
for ( const FSceneView * View : ViewFamily . AllViews )
2021-01-11 14:49:16 -04:00
{
bIsSceneCapture | = View - > bIsSceneCapture ;
bIsReflectionCapture | = View - > bIsReflectionCapture ;
bIsVRScene | = ( IStereoRendering : : IsStereoEyeView ( * View ) & & GEngine - > XRSystem . IsValid ( ) ) ;
}
FIntPoint DesiredExtent = FIntPoint : : ZeroValue ;
FIntPoint DesiredFamilyExtent = FSceneRenderer : : GetDesiredInternalBufferSize ( ViewFamily ) ;
{
bool bUseResizeMethodCVar = true ;
if ( CVarSceneTargetsResizeMethodForceOverride . GetValueOnRenderThread ( ) ! = 1 )
{
if ( ! FPlatformProperties : : SupportsWindowedMode ( ) | | bIsVRScene )
{
if ( bIsVRScene )
{
if ( ! bIsSceneCapture & & ! bIsReflectionCapture )
{
2022-09-22 18:08:17 -04:00
// If this is VR, but not a capture (only current XR capture is for Planar Reflections), then we want
// to use the requested size. Ideally, capture targets will be able to 'grow' into the VR extents.
2021-01-11 14:49:16 -04:00
if ( DesiredFamilyExtent . X ! = LastStereoExtent . X | | DesiredFamilyExtent . Y ! = LastStereoExtent . Y )
{
LastStereoExtent = DesiredFamilyExtent ;
UE_LOG ( LogRenderer , Warning , TEXT ( " Resizing VR buffer to %d by %d " ) , DesiredFamilyExtent . X , DesiredFamilyExtent . Y ) ;
}
2022-09-22 18:08:17 -04:00
SceneTargetsSizingMethod = RequestedSize ;
2021-01-11 14:49:16 -04:00
}
else
{
2022-09-22 18:08:17 -04:00
// If this is a VR scene capture (i.e planar reflection), and it's smaller than the VR view size, then don't re-allocate buffers, just use the "grow" method.
2021-01-11 14:49:16 -04:00
// If it's bigger than the VR view, then log a warning, and use resize method.
if ( DesiredFamilyExtent . X > LastStereoExtent . X | | DesiredFamilyExtent . Y > LastStereoExtent . Y )
{
if ( LastStereoExtent . X > 0 & & bIsSceneCapture )
{
static bool DisplayedCaptureSizeWarning = false ;
if ( ! DisplayedCaptureSizeWarning )
{
DisplayedCaptureSizeWarning = true ;
UE_LOG ( LogRenderer , Warning , TEXT ( " Scene capture of %d by %d is larger than the current VR target. If this is deliberate for a capture that is being done for multiple frames, consider the performance and memory implications. To disable this warning and ensure optimal behavior with this path, set r.SceneRenderTargetResizeMethod to 2, and r.SceneRenderTargetResizeMethodForceOverride to 1. " ) , DesiredFamilyExtent . X , DesiredFamilyExtent . Y ) ;
}
}
SceneTargetsSizingMethod = RequestedSize ;
}
else
{
SceneTargetsSizingMethod = Grow ;
}
}
}
else
{
// Force ScreenRes on non windowed platforms.
SceneTargetsSizingMethod = RequestedSize ;
}
bUseResizeMethodCVar = false ;
}
else if ( GIsEditor )
{
// Always grow scene render targets in the editor.
SceneTargetsSizingMethod = Grow ;
bUseResizeMethodCVar = false ;
}
}
if ( bUseResizeMethodCVar )
{
// Otherwise use the setting specified by the console variable.
2022-07-01 13:58:56 -04:00
// #jira UE-156400: The 'clamp()' includes min and max values, so the range is [0 .. Count-1]
// The checkNoEntry() macro is called from 'default:' in the switch() below, when the SceneTargetsSizingMethod is out of the supported range.
SceneTargetsSizingMethod = ( ESizingMethods ) FMath : : Clamp ( CVarSceneTargetsResizeMethod . GetValueOnRenderThread ( ) , 0 , ( int32 ) VisibleSizingMethodsCount - 1 ) ;
2021-01-11 14:49:16 -04:00
}
}
switch ( SceneTargetsSizingMethod )
{
case RequestedSize :
DesiredExtent = DesiredFamilyExtent ;
break ;
case ScreenRes :
DesiredExtent = FIntPoint ( GSystemResolution . ResX , GSystemResolution . ResY ) ;
break ;
case Grow :
DesiredExtent = FIntPoint (
FMath : : Max ( ( int32 ) LastExtent . X , DesiredFamilyExtent . X ) ,
FMath : : Max ( ( int32 ) LastExtent . Y , DesiredFamilyExtent . Y ) ) ;
break ;
default :
checkNoEntry ( ) ;
}
const uint32 FrameNumber = ViewFamily . FrameNumber ;
if ( ThisFrameNumber ! = FrameNumber )
{
ThisFrameNumber = FrameNumber ;
if ( + + DesiredExtentIndex = = ExtentHistoryCount )
{
DesiredExtentIndex - = ExtentHistoryCount ;
}
// This allows the extent to shrink each frame (in game)
LargestDesiredExtents [ DesiredExtentIndex ] = FIntPoint : : ZeroValue ;
HistoryFlags [ DesiredExtentIndex ] = ERenderTargetHistory : : None ;
}
// this allows The extent to not grow below the SceneCapture requests (happen before scene rendering, in the same frame with a Grow request)
FIntPoint & LargestDesiredExtentThisFrame = LargestDesiredExtents [ DesiredExtentIndex ] ;
LargestDesiredExtentThisFrame = LargestDesiredExtentThisFrame . ComponentMax ( DesiredExtent ) ;
bool bIsHighResScreenshot = GIsHighResScreenshot ;
UpdateHistoryFlags ( HistoryFlags [ DesiredExtentIndex ] , bIsSceneCapture , bIsReflectionCapture , bIsHighResScreenshot ) ;
// We want to shrink the buffer but as we can have multiple scene captures per frame we have to delay that a frame to get all size requests
// Don't save buffer size in history while making high-res screenshot.
// We have to use the requested size when allocating an hmd depth target to ensure it matches the hmd allocated render target size.
bool bAllowDelayResize = ! GIsHighResScreenshot & & ! bIsVRScene ;
// Don't consider the history buffer when the aspect ratio changes, the existing buffers won't make much sense at all.
// This prevents problems when orientation changes on mobile in particular.
// bIsReflectionCapture is explicitly checked on all platforms to prevent aspect ratio change detection from forcing the immediate buffer resize.
// This ensures that 1) buffers are not resized spuriously during reflection rendering 2) all cubemap faces use the same render target size.
if ( bAllowDelayResize & & ! bIsReflectionCapture & & ! AnyCaptureRenderedRecently < ExtentHistoryCount > ( ERenderTargetHistory : : MaskAll ) )
{
const bool bAspectRatioChanged =
! LastExtent . Y | |
! FMath : : IsNearlyEqual (
( float ) LastExtent . X / LastExtent . Y ,
( float ) DesiredExtent . X / DesiredExtent . Y ) ;
if ( bAspectRatioChanged )
{
bAllowDelayResize = false ;
// At this point we're assuming a simple output resize and forcing a hard swap so clear the history.
// If we don't the next frame will fail this check as the allocated aspect ratio will match the new
// frame's forced size so we end up looking through the history again, finding the previous old size
// and reallocating. Only after a few frames can the results actually settle when the history clears
for ( int32 i = 0 ; i < ExtentHistoryCount ; + + i )
{
LargestDesiredExtents [ i ] = FIntPoint : : ZeroValue ;
HistoryFlags [ i ] = ERenderTargetHistory : : None ;
}
}
}
const bool bAnyHighresScreenshotRecently = AnyCaptureRenderedRecently < ExtentHistoryCount > ( ERenderTargetHistory : : HighresScreenshot ) ;
if ( bAnyHighresScreenshotRecently ! = GIsHighResScreenshot )
{
bAllowDelayResize = false ;
}
if ( bAllowDelayResize )
{
for ( int32 i = 0 ; i < ExtentHistoryCount ; + + i )
{
DesiredExtent = DesiredExtent . ComponentMax ( LargestDesiredExtents [ i ] ) ;
}
}
check ( DesiredExtent . X > 0 & & DesiredExtent . Y > 0 ) ;
QuantizeSceneBufferSize ( DesiredExtent , DesiredExtent ) ;
LastExtent = DesiredExtent ;
return DesiredExtent ;
}
2021-03-02 19:34:59 -04:00
void ResetHistory ( )
2021-02-04 12:47:39 -04:00
{
LastStereoExtent = FIntPoint ( 0 , 0 ) ;
LastExtent = FIntPoint ( 0 , 0 ) ;
}
2021-01-11 14:49:16 -04:00
private :
enum class ERenderTargetHistory
{
None = 0 ,
SceneCapture = 1 < < 0 ,
ReflectionCapture = 1 < < 1 ,
HighresScreenshot = 1 < < 2 ,
MaskAll = 1 < < 3 ,
} ;
FRIEND_ENUM_CLASS_FLAGS ( ERenderTargetHistory ) ;
static void UpdateHistoryFlags ( ERenderTargetHistory & Flags , bool bIsSceneCapture , bool bIsReflectionCapture , bool bIsHighResScreenShot )
{
Flags | = bIsSceneCapture ? ERenderTargetHistory : : SceneCapture : ERenderTargetHistory : : None ;
Flags | = bIsReflectionCapture ? ERenderTargetHistory : : ReflectionCapture : ERenderTargetHistory : : None ;
Flags | = bIsHighResScreenShot ? ERenderTargetHistory : : HighresScreenshot : ERenderTargetHistory : : None ;
}
template < uint32 EntryCount >
bool AnyCaptureRenderedRecently ( ERenderTargetHistory Mask ) const
{
ERenderTargetHistory Result = ERenderTargetHistory : : None ;
for ( uint32 EntryIndex = 0 ; EntryIndex < EntryCount ; + + EntryIndex )
{
Result | = HistoryFlags [ EntryIndex ] & Mask ;
}
return Result ! = ERenderTargetHistory : : None ;
}
FSceneTextureExtentState ( )
{
FMemory : : Memset ( LargestDesiredExtents , 0 ) ;
FMemory : : Memset ( HistoryFlags , 0 , sizeof ( HistoryFlags ) ) ;
}
FIntPoint LastStereoExtent = FIntPoint ( 0 , 0 ) ;
FIntPoint LastExtent = FIntPoint ( 0 , 0 ) ;
/** as we might get multiple extent requests each frame for SceneCaptures and we want to avoid reallocations we can only go as low as the largest request */
static const uint32 ExtentHistoryCount = 3 ;
uint32 DesiredExtentIndex = 0 ;
FIntPoint LargestDesiredExtents [ ExtentHistoryCount ] ;
ERenderTargetHistory HistoryFlags [ ExtentHistoryCount ] ;
/** to detect when LargestDesiredSizeThisFrame is outdated */
uint32 ThisFrameNumber = 0 ;
} ;
2021-03-02 19:34:59 -04:00
void ResetSceneTextureExtentHistory ( )
2021-02-04 12:47:39 -04:00
{
2021-03-02 19:34:59 -04:00
FSceneTextureExtentState : : Get ( ) . ResetHistory ( ) ;
2021-02-04 12:47:39 -04:00
}
2021-01-11 14:49:16 -04:00
ENUM_CLASS_FLAGS ( FSceneTextureExtentState : : ERenderTargetHistory ) ;
2022-06-22 11:27:45 -04:00
void InitializeSceneTexturesConfig ( FSceneTexturesConfig & Config , const FSceneViewFamily & ViewFamily )
2021-01-11 14:49:16 -04:00
{
2022-09-08 19:34:08 -04:00
FIntPoint Extent = FSceneTextureExtentState : : Get ( ) . Compute ( ViewFamily ) ;
2023-11-14 08:32:05 -05:00
EShadingPath ShadingPath = GetFeatureLevelShadingPath ( ViewFamily . GetFeatureLevel ( ) ) ;
2021-01-11 14:49:16 -04:00
2022-09-08 19:34:08 -04:00
bool bRequiresAlphaChannel = ShadingPath = = EShadingPath : : Mobile ? IsMobilePropagateAlphaEnabled ( ViewFamily . GetShaderPlatform ( ) ) : false ;
2022-12-02 15:29:35 -05:00
int32 NumberOfViewsWithMultiviewEnabled = 0 ;
2023-11-21 09:55:42 -05:00
for ( int32 ViewIndex = 0 ; ViewIndex < ViewFamily . AllViews . Num ( ) ; ViewIndex + + )
2022-07-01 01:26:21 -04:00
{
2022-09-08 19:34:08 -04:00
// Planar reflections and scene captures use scene color alpha to keep track of where content has been rendered, for compositing into a different scene later
2023-11-21 09:55:42 -05:00
if ( ViewFamily . AllViews [ ViewIndex ] - > bIsPlanarReflection | | ViewFamily . AllViews [ ViewIndex ] - > bIsSceneCapture )
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
{
2022-09-08 19:34:08 -04:00
bRequiresAlphaChannel = true ;
2021-01-11 14:49:16 -04:00
}
2022-12-02 15:29:35 -05:00
2023-11-21 09:55:42 -05:00
NumberOfViewsWithMultiviewEnabled + = ( ViewFamily . AllViews [ ViewIndex ] - > bIsMobileMultiViewEnabled ) ? 1 : 0 ;
2021-01-11 14:49:16 -04:00
}
2022-09-08 19:34:08 -04:00
2023-11-21 09:55:42 -05:00
ensureMsgf ( NumberOfViewsWithMultiviewEnabled = = 0 | | NumberOfViewsWithMultiviewEnabled = = ViewFamily . AllViews . Num ( ) ,
2022-12-02 15:29:35 -05:00
TEXT ( " Either all or no views in a view family should have multiview enabled. Mixing views with enabled and disabled is not allowed. " ) ) ;
2023-11-21 09:55:42 -05:00
const bool bAllViewsHaveMultiviewEnabled = NumberOfViewsWithMultiviewEnabled = = ViewFamily . AllViews . Num ( ) ;
2022-12-02 15:29:35 -05:00
2023-11-21 09:55:42 -05:00
const bool bNeedsStereoAlloc = ViewFamily . AllViews . ContainsByPredicate ( [ ] ( const FSceneView * View )
2022-09-08 19:34:08 -04:00
{
return ( IStereoRendering : : IsStereoEyeView ( * View ) & & ( FindStereoRenderTargetManager ( ) ! = nullptr ) ) ;
} ) ;
FSceneTexturesConfigInitSettings SceneTexturesConfigInitSettings ;
SceneTexturesConfigInitSettings . FeatureLevel = ViewFamily . GetFeatureLevel ( ) ;
SceneTexturesConfigInitSettings . Extent = Extent ;
2022-12-02 15:29:35 -05:00
SceneTexturesConfigInitSettings . bRequireMultiView = ViewFamily . bRequireMultiView & & bAllViewsHaveMultiviewEnabled ;
2022-09-08 19:34:08 -04:00
SceneTexturesConfigInitSettings . bRequiresAlphaChannel = bRequiresAlphaChannel ;
SceneTexturesConfigInitSettings . bSupportsXRTargetManagerDepthAlloc = bNeedsStereoAlloc ? 1 : 0 ;
SceneTexturesConfigInitSettings . ExtraSceneColorCreateFlags = GFastVRamConfig . SceneColor ;
SceneTexturesConfigInitSettings . ExtraSceneDepthCreateFlags = GFastVRamConfig . SceneDepth ;
Config . Init ( SceneTexturesConfigInitSettings ) ;
2021-01-11 14:49:16 -04:00
}
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
void FMinimalSceneTextures : : InitializeViewFamily ( FRDGBuilder & GraphBuilder , FViewFamilyInfo & ViewFamily )
2021-01-11 14:49:16 -04:00
{
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FSceneTexturesConfig & Config = ViewFamily . SceneTexturesConfig ;
FSceneTextures & SceneTextures = ViewFamily . SceneTextures ;
2021-01-11 14:49:16 -04:00
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
checkf ( Config . IsValid ( ) , TEXT ( " Attempted to create scene textures with an empty config. " ) ) ;
SceneTextures . Config = Config ;
2021-01-11 14:49:16 -04:00
// Scene Depth
2021-03-18 20:41:11 -04:00
// If not using MSAA, we need to make sure to grab the stereo depth texture if appropriate.
2024-02-22 11:38:35 -05:00
FTextureRHIRef StereoDepthRHI ;
2023-03-09 23:07:25 -05:00
if ( Config . NumSamples = = 1 & & ( StereoDepthRHI = FindStereoDepthTexture ( Config . bSupportsXRTargetManagerDepthAlloc , Config . Extent , ETextureCreateFlags : : None ) ) ! = nullptr )
2021-03-18 20:41:11 -04:00
{
SceneTextures . Depth = RegisterExternalTexture ( GraphBuilder , StereoDepthRHI , TEXT ( " SceneDepthZ " ) ) ;
SceneTextures . Stencil = GraphBuilder . CreateSRV ( FRDGTextureSRVDesc : : CreateWithPixelFormat ( SceneTextures . Depth . Target , PF_X24_G8 ) ) ;
}
else
2021-01-11 14:49:16 -04:00
{
2021-03-05 20:34:50 -04:00
// TODO: Array-size could be values > 2, on upcoming XR devices. This should be part of the config.
FRDGTextureDesc Desc ( Config . bRequireMultiView ?
2022-09-08 19:34:08 -04:00
FRDGTextureDesc : : Create2DArray ( SceneTextures . Config . Extent , PF_DepthStencil , Config . DepthClearValue , Config . DepthCreateFlags , 2 ) :
FRDGTextureDesc : : Create2D ( SceneTextures . Config . Extent , PF_DepthStencil , Config . DepthClearValue , Config . DepthCreateFlags ) ) ;
2021-01-11 14:49:16 -04:00
Desc . NumSamples = Config . NumSamples ;
SceneTextures . Depth = GraphBuilder . CreateTexture ( Desc , TEXT ( " SceneDepthZ " ) ) ;
if ( Desc . NumSamples > 1 )
{
Desc . NumSamples = 1 ;
2023-03-17 14:22:05 -04:00
if ( ( StereoDepthRHI = FindStereoDepthTexture ( Config . bSupportsXRTargetManagerDepthAlloc , Config . Extent , ETextureCreateFlags : : DepthStencilResolveTarget ) ) ! = nullptr )
2021-01-11 14:49:16 -04:00
{
2022-12-02 15:29:35 -05:00
ensureMsgf ( Desc . ArraySize = = StereoDepthRHI - > GetDesc ( ) . ArraySize , TEXT ( " Resolve texture does not agree in dimensionality with Target (Resolve.ArraySize=%d, Target.ArraySize=%d) " ) ,
Desc . ArraySize , StereoDepthRHI - > GetDesc ( ) . ArraySize ) ;
2021-01-11 14:49:16 -04:00
SceneTextures . Depth . Resolve = RegisterExternalTexture ( GraphBuilder , StereoDepthRHI , TEXT ( " SceneDepthZ " ) ) ;
}
else
{
SceneTextures . Depth . Resolve = GraphBuilder . CreateTexture ( Desc , TEXT ( " SceneDepthZ " ) ) ;
}
}
SceneTextures . Stencil = GraphBuilder . CreateSRV ( FRDGTextureSRVDesc : : CreateWithPixelFormat ( SceneTextures . Depth . Target , PF_X24_G8 ) ) ;
}
// Scene Color
{
const bool bIsMobilePlatform = Config . ShadingPath = = EShadingPath : : Mobile ;
2022-03-29 19:15:38 -04:00
const ETextureCreateFlags sRGBFlag = ( bIsMobilePlatform & & IsMobileColorsRGB ( ) ) ? TexCreate_SRGB : TexCreate_None ;
2021-01-11 14:49:16 -04:00
// Create the scene color.
2021-03-05 20:34:50 -04:00
// TODO: Array-size could be values > 2, on upcoming XR devices. This should be part of the config.
FRDGTextureDesc Desc ( Config . bRequireMultiView ?
2022-09-08 19:34:08 -04:00
FRDGTextureDesc : : Create2DArray ( Config . Extent , Config . ColorFormat , Config . ColorClearValue , Config . ColorCreateFlags , 2 ) :
FRDGTextureDesc : : Create2D ( Config . Extent , Config . ColorFormat , Config . ColorClearValue , Config . ColorCreateFlags ) ) ;
2021-01-11 14:49:16 -04:00
Desc . NumSamples = Config . NumSamples ;
2023-04-07 11:52:17 -04:00
SceneTextures . Color = CreateTextureMSAA ( GraphBuilder , Desc , TEXT ( " SceneColorMS " ) , TEXT ( " SceneColor " ) , GFastVRamConfig . SceneColor | sRGBFlag ) ;
2021-01-11 14:49:16 -04:00
}
// Custom Depth
2023-04-06 18:12:00 -04:00
SceneTextures . CustomDepth = FCustomDepthTextures : : Create ( GraphBuilder , Config . Extent , Config . ShaderPlatform ) ;
2021-01-11 14:49:16 -04:00
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
ViewFamily . bIsSceneTexturesInitialized = true ;
2021-01-11 14:49:16 -04:00
}
2021-02-19 07:49:57 -04:00
FSceneTextureShaderParameters FMinimalSceneTextures : : GetSceneTextureShaderParameters ( ERHIFeatureLevel : : Type FeatureLevel ) const
{
FSceneTextureShaderParameters OutSceneTextureShaderParameters ;
if ( FeatureLevel > = ERHIFeatureLevel : : SM5 )
{
OutSceneTextureShaderParameters . SceneTextures = UniformBuffer ;
}
else
{
OutSceneTextureShaderParameters . MobileSceneTextures = MobileUniformBuffer ;
}
return OutSceneTextureShaderParameters ;
}
Visualize Texture: Performance and feature upgrades.
* Visualize texture system starts out in an inactive state until a command is issued, avoiding overhead of tracking views and scene textures, saving 1.4% on the render thread.
* Visualization overhead eliminated for views besides the one currently being visualized.
* Support for visualization of textures from scene captures, via "view=N" option (specifying the unique ID of the view), with "view=?" displaying a list of views for reference.
* Improved visualization for cube maps. PIP uses 2:1 aspect for the longitudinal render to match resource viewer display, and pixel perfect option shows tiled flat cube map faces (actual pixels) rather than running a projection.
* Padding for scene or screen pass textures is removed in the visualization -- the padding otherwise shows up as garbage or blank space.
To remove scene texture padding, it's necessary to add a field to RDG textures to provide an option to track the viewport sizes that were rendered for a given texture. If not set, the assumption is the whole texture was rendered. The field is set for FSceneTextures and FScreenPassTexture, covering the vast majority of cases, plus the denoiser was spot fixed -- worst case if any other cases are missed, you still see the padding. You can tell padding was present when visualizing by contrasting the texture size with the viewport size.
Padding was always a potential issue for the visualizer, but is exacerbated by scene captures, as the padded scene textures are set to a size that's a union of the main view and any scene captures. Padding is also exacerbated by dynamic resolution scaling, as the buffers will be padded to the maximum resolution. For example, a cube map rendering at 512x512 will have 93% of the pixel area as padding if the front buffer is at 1440p, or the default dynamic resolution setup will have 70% of the pixels as padding at minimum res.
#rb Jason.Nadro
[CL 31160232 by jason hoerner in ue5-main branch]
2024-02-03 16:07:46 -05:00
void FSceneTextures : : InitializeViewFamily ( FRDGBuilder & GraphBuilder , FViewFamilyInfo & ViewFamily , FIntPoint FamilySize )
2021-01-11 14:49:16 -04:00
{
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FSceneTexturesConfig & Config = ViewFamily . SceneTexturesConfig ;
FSceneTextures & SceneTextures = ViewFamily . SceneTextures ;
FMinimalSceneTextures : : InitializeViewFamily ( GraphBuilder , ViewFamily ) ;
2021-01-11 14:49:16 -04:00
if ( Config . ShadingPath = = EShadingPath : : Deferred )
{
// Screen Space Ambient Occlusion
SceneTextures . ScreenSpaceAO = CreateScreenSpaceAOTexture ( GraphBuilder , Config . Extent ) ;
// Small Depth
const FIntPoint SmallDepthExtent = GetDownscaledExtent ( Config . Extent , Config . SmallDepthDownsampleFactor ) ;
const FRDGTextureDesc SmallDepthDesc ( FRDGTextureDesc : : Create2D ( SmallDepthExtent , PF_DepthStencil , FClearValueBinding : : None , TexCreate_DepthStencilTargetable | TexCreate_ShaderResource ) ) ;
SceneTextures . SmallDepth = GraphBuilder . CreateTexture ( SmallDepthDesc , TEXT ( " SmallDepthZ " ) ) ;
}
else
{
// Mobile Screen Space Ambient Occlusion
2021-07-21 03:45:31 -04:00
SceneTextures . ScreenSpaceAO = CreateMobileScreenSpaceAOTexture ( GraphBuilder , Config ) ;
2021-03-09 00:23:43 -04:00
if ( Config . MobilePixelProjectedReflectionExtent ! = FIntPoint : : ZeroValue )
{
SceneTextures . PixelProjectedReflection = CreateMobilePixelProjectedReflectionTexture ( GraphBuilder , Config . MobilePixelProjectedReflectionExtent ) ;
}
2021-01-11 14:49:16 -04:00
}
2021-02-18 21:11:17 -04:00
// Velocity
SceneTextures . Velocity = GraphBuilder . CreateTexture ( FVelocityRendering : : GetRenderTargetDesc ( Config . ShaderPlatform , Config . Extent ) , TEXT ( " SceneVelocity " ) ) ;
2021-01-11 14:49:16 -04:00
if ( Config . bIsUsingGBuffers )
{
ETextureCreateFlags FlagsToAdd = TexCreate_None ;
2022-10-17 17:59:19 -04:00
const FGBufferBindings & Bindings = Config . GBufferBindings [ GBL_Default ] ;
if ( Bindings . GBufferA . Index > = 0 )
2021-01-11 14:49:16 -04:00
{
2024-03-06 07:59:50 -05:00
const FRDGTextureDesc Desc ( Config . bRequireMultiView ?
FRDGTextureDesc : : Create2DArray ( Config . Extent , Bindings . GBufferA . Format , FClearValueBinding : : Transparent , Bindings . GBufferA . Flags | FlagsToAdd | GFastVRamConfig . GBufferA , 2 ) :
FRDGTextureDesc : : Create2D ( Config . Extent , Bindings . GBufferA . Format , FClearValueBinding : : Transparent , Bindings . GBufferA . Flags | FlagsToAdd | GFastVRamConfig . GBufferA ) ) ;
2021-01-11 14:49:16 -04:00
SceneTextures . GBufferA = GraphBuilder . CreateTexture ( Desc , TEXT ( " GBufferA " ) ) ;
}
2022-10-17 17:59:19 -04:00
if ( Bindings . GBufferB . Index > = 0 )
2021-01-11 14:49:16 -04:00
{
2024-03-06 07:59:50 -05:00
const FRDGTextureDesc Desc ( Config . bRequireMultiView ?
FRDGTextureDesc : : Create2DArray ( Config . Extent , Bindings . GBufferB . Format , FClearValueBinding : : Transparent , Bindings . GBufferB . Flags | FlagsToAdd | GFastVRamConfig . GBufferB , 2 ) :
FRDGTextureDesc : : Create2D ( Config . Extent , Bindings . GBufferB . Format , FClearValueBinding : : Transparent , Bindings . GBufferB . Flags | FlagsToAdd | GFastVRamConfig . GBufferB ) ) ;
2021-01-11 14:49:16 -04:00
SceneTextures . GBufferB = GraphBuilder . CreateTexture ( Desc , TEXT ( " GBufferB " ) ) ;
}
2022-10-17 17:59:19 -04:00
if ( Bindings . GBufferC . Index > = 0 )
2021-01-11 14:49:16 -04:00
{
2024-03-06 07:59:50 -05:00
const FRDGTextureDesc Desc ( Config . bRequireMultiView ?
FRDGTextureDesc : : Create2DArray ( Config . Extent , Bindings . GBufferC . Format , FClearValueBinding : : Transparent , Bindings . GBufferC . Flags | FlagsToAdd | GFastVRamConfig . GBufferC , 2 ) :
FRDGTextureDesc : : Create2D ( Config . Extent , Bindings . GBufferC . Format , FClearValueBinding : : Transparent , Bindings . GBufferC . Flags | FlagsToAdd | GFastVRamConfig . GBufferC ) ) ;
2021-01-11 14:49:16 -04:00
SceneTextures . GBufferC = GraphBuilder . CreateTexture ( Desc , TEXT ( " GBufferC " ) ) ;
}
2022-10-17 17:59:19 -04:00
if ( Bindings . GBufferD . Index > = 0 )
2021-01-11 14:49:16 -04:00
{
2024-03-06 07:59:50 -05:00
const FRDGTextureDesc Desc ( Config . bRequireMultiView ?
FRDGTextureDesc : : Create2DArray ( Config . Extent , Bindings . GBufferD . Format , FClearValueBinding : : Transparent , Bindings . GBufferD . Flags | FlagsToAdd | GFastVRamConfig . GBufferD , 2 ) :
FRDGTextureDesc : : Create2D ( Config . Extent , Bindings . GBufferD . Format , FClearValueBinding : : Transparent , Bindings . GBufferD . Flags | FlagsToAdd | GFastVRamConfig . GBufferD ) ) ;
2021-01-11 14:49:16 -04:00
SceneTextures . GBufferD = GraphBuilder . CreateTexture ( Desc , TEXT ( " GBufferD " ) ) ;
}
2022-10-17 17:59:19 -04:00
if ( Bindings . GBufferE . Index > = 0 )
2021-01-11 14:49:16 -04:00
{
2024-03-06 07:59:50 -05:00
const FRDGTextureDesc Desc ( Config . bRequireMultiView ?
FRDGTextureDesc : : Create2DArray ( Config . Extent , Bindings . GBufferE . Format , FClearValueBinding : : Transparent , Bindings . GBufferE . Flags | FlagsToAdd | GFastVRamConfig . GBufferE , 2 ) :
FRDGTextureDesc : : Create2D ( Config . Extent , Bindings . GBufferE . Format , FClearValueBinding : : Transparent , Bindings . GBufferE . Flags | FlagsToAdd | GFastVRamConfig . GBufferE ) ) ;
2021-01-11 14:49:16 -04:00
SceneTextures . GBufferE = GraphBuilder . CreateTexture ( Desc , TEXT ( " GBufferE " ) ) ;
}
// GBufferF is not yet part of the data driven GBuffer info.
if ( Config . ShadingPath = = EShadingPath : : Deferred )
{
2023-07-25 08:54:03 -04:00
ETextureCreateFlags GBufferFCreateFlags ;
EPixelFormat GBufferFPixelFormat = GetGBufferFFormatAndCreateFlags ( GBufferFCreateFlags ) ;
2024-03-06 07:59:50 -05:00
const FRDGTextureDesc Desc ( Config . bRequireMultiView ?
FRDGTextureDesc : : Create2DArray ( Config . Extent , GBufferFPixelFormat , FClearValueBinding ( { 0.5f , 0.5f , 0.5f , 0.5f } ) , GBufferFCreateFlags | FlagsToAdd , 2 ) :
FRDGTextureDesc : : Create2D ( Config . Extent , GBufferFPixelFormat , FClearValueBinding ( { 0.5f , 0.5f , 0.5f , 0.5f } ) , GBufferFCreateFlags | FlagsToAdd ) ) ;
2021-01-11 14:49:16 -04:00
SceneTextures . GBufferF = GraphBuilder . CreateTexture ( Desc , TEXT ( " GBufferF " ) ) ;
}
}
2024-01-19 07:05:41 -05:00
if ( Config . bRequiresDepthAux )
2021-06-11 13:47:20 -04:00
{
const float FarDepth = ( float ) ERHIZBuffer : : FarPlane ;
const FLinearColor FarDepthColor ( FarDepth , FarDepth , FarDepth , FarDepth ) ;
2022-08-22 21:36:09 -04:00
ETextureCreateFlags MemorylessFlag = TexCreate_None ;
if ( IsMobileDeferredShadingEnabled ( Config . ShaderPlatform ) | | ( Config . NumSamples > 1 & & Config . bMemorylessMSAA ) )
{
2022-11-21 20:38:48 -05:00
// hotfix for a crash on a Mac mobile preview, proper fix is in 5.2
# if !PLATFORM_MAC
2022-08-22 21:36:09 -04:00
MemorylessFlag = TexCreate_Memoryless ;
2022-11-21 20:38:48 -05:00
# endif
2022-08-22 21:36:09 -04:00
}
2022-04-06 01:46:34 -04:00
EPixelFormat DepthAuxFormat = GetMobileSceneDepthAuxPixelFormat ( Config . ShaderPlatform , Config . bPreciseDepthAux ) ;
2021-10-19 15:28:06 -04:00
FRDGTextureDesc Desc = Config . bRequireMultiView ?
2022-08-22 21:36:09 -04:00
FRDGTextureDesc : : Create2DArray ( Config . Extent , DepthAuxFormat , FClearValueBinding ( FarDepthColor ) , TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_InputAttachmentRead | MemorylessFlag , 2 ) :
FRDGTextureDesc : : Create2D ( Config . Extent , DepthAuxFormat , FClearValueBinding ( FarDepthColor ) , TexCreate_RenderTargetable | TexCreate_ShaderResource | TexCreate_InputAttachmentRead | MemorylessFlag ) ;
2021-06-11 13:47:20 -04:00
Desc . NumSamples = Config . NumSamples ;
2023-04-07 11:52:17 -04:00
SceneTextures . DepthAux = CreateTextureMSAA ( GraphBuilder , Desc , TEXT ( " SceneDepthAuxMS " ) , TEXT ( " SceneDepthAux " ) ) ;
2021-06-11 13:47:20 -04:00
}
2021-01-11 14:49:16 -04:00
# if WITH_EDITOR
{
const FRDGTextureDesc ColorDesc ( FRDGTextureDesc : : Create2D ( Config . Extent , PF_B8G8R8A8 , FClearValueBinding : : Transparent , TexCreate_ShaderResource | TexCreate_RenderTargetable , 1 , Config . EditorPrimitiveNumSamples ) ) ;
2021-02-05 03:40:03 -04:00
SceneTextures . EditorPrimitiveColor = GraphBuilder . CreateTexture ( ColorDesc , TEXT ( " Editor.PrimitivesColor " ) ) ;
2021-01-11 14:49:16 -04:00
const FRDGTextureDesc DepthDesc ( FRDGTextureDesc : : Create2D ( Config . Extent , PF_DepthStencil , FClearValueBinding : : DepthFar , TexCreate_ShaderResource | TexCreate_DepthStencilTargetable , 1 , Config . EditorPrimitiveNumSamples ) ) ;
2021-02-05 03:40:03 -04:00
SceneTextures . EditorPrimitiveDepth = GraphBuilder . CreateTexture ( DepthDesc , TEXT ( " Editor.PrimitivesDepth " ) ) ;
2021-01-11 14:49:16 -04:00
}
# endif
2023-11-13 08:43:37 -05:00
extern bool MobileMergeLocalLightsInPrepassEnabled ( const FStaticShaderPlatform Platform ) ;
if ( MobileMergeLocalLightsInPrepassEnabled ( Config . ShaderPlatform ) )
2023-06-02 05:02:31 -04:00
{
2023-06-13 06:51:55 -04:00
FRDGTextureDesc MobileLocalLightTextureADesc = FRDGTextureDesc : : Create2D ( Config . Extent , PF_FloatR11G11B10 , FClearValueBinding : : Transparent , TexCreate_RenderTargetable | TexCreate_ShaderResource ) ;
SceneTextures . MobileLocalLightTextureA = GraphBuilder . CreateTexture ( MobileLocalLightTextureADesc , TEXT ( " MobileLocalLightTextureA " ) ) ;
2023-06-02 05:02:31 -04:00
2023-10-02 07:12:40 -04:00
FRDGTextureDesc MobileLocalLightTextureBDesc = FRDGTextureDesc : : Create2D ( Config . Extent , PF_B8G8R8A8 , FClearValueBinding ( { 0.5f , 0.5f , 0.5f , 0.f } ) , TexCreate_RenderTargetable | TexCreate_ShaderResource ) ;
2023-06-13 06:51:55 -04:00
SceneTextures . MobileLocalLightTextureB = GraphBuilder . CreateTexture ( MobileLocalLightTextureBDesc , TEXT ( " MobileLocalLightTextureB " ) ) ;
2023-06-02 05:02:31 -04:00
}
2021-01-11 14:49:16 -04:00
# if WITH_DEBUG_VIEW_MODES
if ( AllowDebugViewShaderMode ( DVSM_QuadComplexity , Config . ShaderPlatform , Config . FeatureLevel ) )
{
FIntPoint QuadOverdrawExtent ;
QuadOverdrawExtent . X = 2 * FMath : : Max < uint32 > ( ( Config . Extent . X + 1 ) / 2 , 1 ) ; // The size is time 2 since left side is QuadDescriptor, and right side QuadComplexity.
QuadOverdrawExtent . Y = FMath : : Max < uint32 > ( ( Config . Extent . Y + 1 ) / 2 , 1 ) ;
const FRDGTextureDesc QuadOverdrawDesc ( FRDGTextureDesc : : Create2D ( QuadOverdrawExtent , PF_R32_UINT , FClearValueBinding : : None , TexCreate_ShaderResource | TexCreate_RenderTargetable | TexCreate_UAV ) ) ;
SceneTextures . QuadOverdraw = GraphBuilder . CreateTexture ( QuadOverdrawDesc , TEXT ( " QuadOverdrawTexture " ) ) ;
}
# endif
Visualize Texture: Performance and feature upgrades.
* Visualize texture system starts out in an inactive state until a command is issued, avoiding overhead of tracking views and scene textures, saving 1.4% on the render thread.
* Visualization overhead eliminated for views besides the one currently being visualized.
* Support for visualization of textures from scene captures, via "view=N" option (specifying the unique ID of the view), with "view=?" displaying a list of views for reference.
* Improved visualization for cube maps. PIP uses 2:1 aspect for the longitudinal render to match resource viewer display, and pixel perfect option shows tiled flat cube map faces (actual pixels) rather than running a projection.
* Padding for scene or screen pass textures is removed in the visualization -- the padding otherwise shows up as garbage or blank space.
To remove scene texture padding, it's necessary to add a field to RDG textures to provide an option to track the viewport sizes that were rendered for a given texture. If not set, the assumption is the whole texture was rendered. The field is set for FSceneTextures and FScreenPassTexture, covering the vast majority of cases, plus the denoiser was spot fixed -- worst case if any other cases are missed, you still see the padding. You can tell padding was present when visualizing by contrasting the texture size with the viewport size.
Padding was always a potential issue for the visualizer, but is exacerbated by scene captures, as the padded scene textures are set to a size that's a union of the main view and any scene captures. Padding is also exacerbated by dynamic resolution scaling, as the buffers will be padded to the maximum resolution. For example, a cube map rendering at 512x512 will have 93% of the pixel area as padding if the front buffer is at 1440p, or the default dynamic resolution setup will have 70% of the pixels as padding at minimum res.
#rb Jason.Nadro
[CL 31160232 by jason hoerner in ue5-main branch]
2024-02-03 16:07:46 -05:00
# if SUPPORTS_VISUALIZE_TEXTURE
if ( GVisualizeTexture . IsRequestedView ( ) )
{
TArray < FIntRect > FamilyViewRects ;
FamilyViewRects . SetNumUninitialized ( ViewFamily . Views . Num ( ) ) ;
for ( int32 ViewIndex = 0 ; ViewIndex < ViewFamily . Views . Num ( ) ; ViewIndex + + )
{
FamilyViewRects [ ViewIndex ] = ViewFamily . Views [ ViewIndex ] - > UnconstrainedViewRect ;
}
GVisualizeTexture . SetSceneTextures ( SceneTextures . EnumerateSceneTextures ( ) , FamilySize , FamilyViewRects ) ;
}
# endif
2021-01-11 14:49:16 -04:00
}
2022-10-17 17:59:19 -04:00
uint32 FSceneTextures : : GetGBufferRenderTargets (
2023-02-13 20:06:06 -05:00
TArrayView < FTextureRenderTargetBinding > RenderTargets ,
2022-10-17 17:59:19 -04:00
EGBufferLayout Layout ) const
2021-01-11 14:49:16 -04:00
{
uint32 RenderTargetCount = 0 ;
// All configurations use scene color in the first slot.
2021-11-29 09:31:58 -05:00
RenderTargets [ RenderTargetCount + + ] = FTextureRenderTargetBinding ( Color . Target ) ;
2021-01-11 14:49:16 -04:00
if ( Config . bIsUsingGBuffers )
{
struct FGBufferEntry
{
FGBufferEntry ( const TCHAR * InName , FRDGTextureRef InTexture , int32 InIndex )
: Name ( InName )
, Texture ( InTexture )
, Index ( InIndex )
{ }
const TCHAR * Name ;
FRDGTextureRef Texture ;
int32 Index ;
} ;
2022-10-17 17:59:19 -04:00
const FGBufferBindings & Bindings = Config . GBufferBindings [ Layout ] ;
2021-01-11 14:49:16 -04:00
const FGBufferEntry GBufferEntries [ ] =
{
2022-10-17 17:59:19 -04:00
{ TEXT ( " GBufferA " ) , GBufferA , Bindings . GBufferA . Index } ,
{ TEXT ( " GBufferB " ) , GBufferB , Bindings . GBufferB . Index } ,
{ TEXT ( " GBufferC " ) , GBufferC , Bindings . GBufferC . Index } ,
{ TEXT ( " GBufferD " ) , GBufferD , Bindings . GBufferD . Index } ,
{ TEXT ( " GBufferE " ) , GBufferE , Bindings . GBufferE . Index } ,
{ TEXT ( " Velocity " ) , Velocity , Bindings . GBufferVelocity . Index }
2021-01-11 14:49:16 -04:00
} ;
for ( const FGBufferEntry & Entry : GBufferEntries )
{
checkf ( Entry . Index < = 0 | | Entry . Texture ! = nullptr , TEXT ( " Texture '%s' was requested by FGBufferInfo, but it is null. " ) , Entry . Name ) ;
if ( Entry . Index > 0 )
{
2021-11-29 09:31:58 -05:00
RenderTargets [ Entry . Index ] = FTextureRenderTargetBinding ( Entry . Texture ) ;
2021-01-11 14:49:16 -04:00
RenderTargetCount = FMath : : Max ( RenderTargetCount , uint32 ( Entry . Index + 1 ) ) ;
}
}
}
2022-07-09 14:02:06 -04:00
// Forward shading path
else if ( IsUsingBasePassVelocity ( Config . ShaderPlatform ) )
2021-01-11 14:49:16 -04:00
{
2021-11-29 09:31:58 -05:00
RenderTargets [ RenderTargetCount + + ] = FTextureRenderTargetBinding ( Velocity ) ;
2021-01-11 14:49:16 -04:00
}
return RenderTargetCount ;
}
2022-10-17 17:59:19 -04:00
uint32 FSceneTextures : : GetGBufferRenderTargets (
ERenderTargetLoadAction LoadAction ,
FRenderTargetBindingSlots & RenderTargetBindingSlots ,
EGBufferLayout Layout ) const
2021-01-11 14:49:16 -04:00
{
2021-11-29 09:31:58 -05:00
TStaticArray < FTextureRenderTargetBinding , MaxSimultaneousRenderTargets > RenderTargets ;
2022-10-17 17:59:19 -04:00
const uint32 RenderTargetCount = GetGBufferRenderTargets ( RenderTargets , Layout ) ;
2021-01-11 14:49:16 -04:00
for ( uint32 Index = 0 ; Index < RenderTargetCount ; + + Index )
{
2021-11-29 09:31:58 -05:00
RenderTargetBindingSlots [ Index ] = FRenderTargetBinding ( RenderTargets [ Index ] . Texture , LoadAction ) ;
2021-01-11 14:49:16 -04:00
}
return RenderTargetCount ;
}
Visualize Texture: Performance and feature upgrades.
* Visualize texture system starts out in an inactive state until a command is issued, avoiding overhead of tracking views and scene textures, saving 1.4% on the render thread.
* Visualization overhead eliminated for views besides the one currently being visualized.
* Support for visualization of textures from scene captures, via "view=N" option (specifying the unique ID of the view), with "view=?" displaying a list of views for reference.
* Improved visualization for cube maps. PIP uses 2:1 aspect for the longitudinal render to match resource viewer display, and pixel perfect option shows tiled flat cube map faces (actual pixels) rather than running a projection.
* Padding for scene or screen pass textures is removed in the visualization -- the padding otherwise shows up as garbage or blank space.
To remove scene texture padding, it's necessary to add a field to RDG textures to provide an option to track the viewport sizes that were rendered for a given texture. If not set, the assumption is the whole texture was rendered. The field is set for FSceneTextures and FScreenPassTexture, covering the vast majority of cases, plus the denoiser was spot fixed -- worst case if any other cases are missed, you still see the padding. You can tell padding was present when visualizing by contrasting the texture size with the viewport size.
Padding was always a potential issue for the visualizer, but is exacerbated by scene captures, as the padded scene textures are set to a size that's a union of the main view and any scene captures. Padding is also exacerbated by dynamic resolution scaling, as the buffers will be padded to the maximum resolution. For example, a cube map rendering at 512x512 will have 93% of the pixel area as padding if the front buffer is at 1440p, or the default dynamic resolution setup will have 70% of the pixels as padding at minimum res.
#rb Jason.Nadro
[CL 31160232 by jason hoerner in ue5-main branch]
2024-02-03 16:07:46 -05:00
static void AddTextureIfNonNull ( FRDGTextureRef Texture , TArray < FRDGTextureRef > & OutTextures )
{
if ( Texture )
{
OutTextures . Add ( Texture ) ;
}
}
static void AddTextureIfNonNull ( const FRDGTextureMSAA & Texture , TArray < FRDGTextureRef > & OutTextures )
{
if ( Texture . Target )
{
OutTextures . Add ( Texture . Target ) ;
}
}
TArray < FRDGTextureRef > FSceneTextures : : EnumerateSceneTextures ( ) const
{
TArray < FRDGTextureRef > Results ;
Results . Reserve ( 20 ) ;
AddTextureIfNonNull ( Color , Results ) ;
AddTextureIfNonNull ( Depth , Results ) ;
AddTextureIfNonNull ( PartialDepth , Results ) ;
AddTextureIfNonNull ( CustomDepth . Depth , Results ) ;
AddTextureIfNonNull ( SmallDepth , Results ) ;
AddTextureIfNonNull ( GBufferA , Results ) ;
AddTextureIfNonNull ( GBufferB , Results ) ;
AddTextureIfNonNull ( GBufferC , Results ) ;
AddTextureIfNonNull ( GBufferD , Results ) ;
AddTextureIfNonNull ( GBufferE , Results ) ;
AddTextureIfNonNull ( GBufferF , Results ) ;
AddTextureIfNonNull ( DepthAux , Results ) ;
AddTextureIfNonNull ( Velocity , Results ) ;
AddTextureIfNonNull ( MobileLocalLightTextureA , Results ) ;
AddTextureIfNonNull ( MobileLocalLightTextureB , Results ) ;
AddTextureIfNonNull ( ScreenSpaceAO , Results ) ;
AddTextureIfNonNull ( QuadOverdraw , Results ) ;
AddTextureIfNonNull ( PixelProjectedReflection , Results ) ;
# if WITH_EDITOR
AddTextureIfNonNull ( EditorPrimitiveColor , Results ) ;
AddTextureIfNonNull ( EditorPrimitiveDepth , Results ) ;
# endif
return Results ;
}
2021-01-11 14:49:16 -04:00
void FSceneTextureExtracts : : QueueExtractions ( FRDGBuilder & GraphBuilder , const FSceneTextures & SceneTextures )
{
// Free up the memory for reuse during the RDG execution phase.
2022-01-14 16:28:58 -05:00
Release ( ) ;
2021-01-11 14:49:16 -04:00
ESceneTextureSetupMode SetupMode = ESceneTextureSetupMode : : None ;
const auto ExtractIfProduced = [ & ] ( FRDGTextureRef Texture , TRefCountPtr < IPooledRenderTarget > & OutTarget )
{
2021-11-04 05:10:53 -04:00
if ( HasBeenProduced ( Texture ) & & ! EnumHasAnyFlags ( Texture - > Desc . Flags , TexCreate_Memoryless ) )
2021-01-11 14:49:16 -04:00
{
2022-01-06 16:44:09 +00:00
GraphBuilder . QueueTextureExtraction ( Texture , & OutTarget , ERDGResourceExtractionFlags : : AllowTransient ) ;
2021-01-11 14:49:16 -04:00
}
} ;
if ( EnumHasAnyFlags ( SceneTextures . Config . Extracts , ESceneTextureExtracts : : Depth ) )
{
SetupMode | = ESceneTextureSetupMode : : SceneDepth ;
ExtractIfProduced ( SceneTextures . Depth . Resolve , Depth ) ;
2023-03-20 18:35:18 -04:00
ExtractIfProduced ( SceneTextures . PartialDepth . Resolve , PartialDepth ) ;
2021-01-11 14:49:16 -04:00
}
if ( EnumHasAnyFlags ( SceneTextures . Config . Extracts , ESceneTextureExtracts : : CustomDepth ) )
{
SetupMode | = ESceneTextureSetupMode : : CustomDepth ;
ExtractIfProduced ( SceneTextures . CustomDepth . Depth , CustomDepth ) ;
}
// Create and extract a scene texture uniform buffer for RHI code outside of the main render graph instance. This
// uniform buffer will reference all extracted textures. No transitions will be required since the textures are left
// in a shader resource state.
auto * PassParameters = GraphBuilder . AllocParameters < FSceneTextureShaderParameters > ( ) ;
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
* PassParameters = CreateSceneTextureShaderParameters ( GraphBuilder , & SceneTextures , SceneTextures . Config . FeatureLevel , SetupMode ) ;
2021-01-11 14:49:16 -04:00
// We want these textures in a SRV Compute | Raster state.
const ERDGPassFlags PassFlags = ERDGPassFlags : : Raster | ERDGPassFlags : : SkipRenderPass | ERDGPassFlags : : Compute | ERDGPassFlags : : NeverCull ;
2021-07-22 12:43:00 -04:00
GraphBuilder . AddPass ( RDG_EVENT_NAME ( " ExtractUniformBuffer " ) , PassParameters , PassFlags ,
2021-01-11 14:49:16 -04:00
[ this , PassParameters , ShadingPath = SceneTextures . Config . ShadingPath ] ( FRHICommandList & )
{
if ( ShadingPath = = EShadingPath : : Deferred )
{
UniformBuffer = PassParameters - > SceneTextures - > GetRHIRef ( ) ;
}
else
{
MobileUniformBuffer = PassParameters - > MobileSceneTextures - > GetRHIRef ( ) ;
}
} ) ;
}
2022-01-14 16:28:58 -05:00
void FSceneTextureExtracts : : Release ( )
2021-01-11 14:49:16 -04:00
{
Depth = { } ;
CustomDepth = { } ;
UniformBuffer = { } ;
MobileUniformBuffer = { } ;
}
static TGlobalResource < FSceneTextureExtracts > GSceneTextureExtracts ;
const FSceneTextureExtracts & GetSceneTextureExtracts ( )
{
return GSceneTextureExtracts ;
}
void QueueSceneTextureExtractions ( FRDGBuilder & GraphBuilder , const FSceneTextures & SceneTextures )
{
return GSceneTextureExtracts . QueueExtractions ( GraphBuilder , SceneTextures ) ;
}
2023-02-23 14:59:47 -05:00
FRDGTextureRef GetSceneTexture ( const FSceneTextures & SceneTextures , ESceneTexture InSceneTexture )
{
switch ( InSceneTexture )
{
case ESceneTexture : : Color : return SceneTextures . Color . Resolve ;
case ESceneTexture : : Depth : return SceneTextures . Depth . Resolve ;
case ESceneTexture : : SmallDepth : return SceneTextures . SmallDepth ;
case ESceneTexture : : Velocity : return SceneTextures . Velocity ;
case ESceneTexture : : GBufferA : return SceneTextures . GBufferA ;
case ESceneTexture : : GBufferB : return SceneTextures . GBufferB ;
case ESceneTexture : : GBufferC : return SceneTextures . GBufferC ;
case ESceneTexture : : GBufferD : return SceneTextures . GBufferD ;
case ESceneTexture : : GBufferE : return SceneTextures . GBufferE ;
case ESceneTexture : : GBufferF : return SceneTextures . GBufferF ;
case ESceneTexture : : SSAO : return SceneTextures . ScreenSpaceAO ;
case ESceneTexture : : CustomDepth : return SceneTextures . CustomDepth . Depth ;
default :
checkNoEntry ( ) ;
return nullptr ;
}
}
2021-01-11 14:49:16 -04:00
void SetupSceneTextureUniformParameters (
FRDGBuilder & GraphBuilder ,
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FSceneTextures * SceneTextures ,
2021-01-11 14:49:16 -04:00
ERHIFeatureLevel : : Type FeatureLevel ,
ESceneTextureSetupMode SetupMode ,
FSceneTextureUniformParameters & SceneTextureParameters )
{
const FRDGSystemTextures & SystemTextures = FRDGSystemTextures : : Get ( GraphBuilder ) ;
SceneTextureParameters . PointClampSampler = TStaticSamplerState < SF_Point > : : GetRHI ( ) ;
SceneTextureParameters . SceneColorTexture = SystemTextures . Black ;
SceneTextureParameters . SceneDepthTexture = SystemTextures . DepthDummy ;
2023-03-20 18:35:18 -04:00
SceneTextureParameters . ScenePartialDepthTexture = SystemTextures . DepthDummy ;
2021-01-11 14:49:16 -04:00
SceneTextureParameters . GBufferATexture = SystemTextures . Black ;
SceneTextureParameters . GBufferBTexture = SystemTextures . Black ;
SceneTextureParameters . GBufferCTexture = SystemTextures . Black ;
SceneTextureParameters . GBufferDTexture = SystemTextures . Black ;
SceneTextureParameters . GBufferETexture = SystemTextures . Black ;
SceneTextureParameters . GBufferFTexture = SystemTextures . MidGrey ;
SceneTextureParameters . GBufferVelocityTexture = SystemTextures . Black ;
SceneTextureParameters . ScreenSpaceAOTexture = GetScreenSpaceAOFallback ( SystemTextures ) ;
SceneTextureParameters . CustomDepthTexture = SystemTextures . DepthDummy ;
SceneTextureParameters . CustomStencilTexture = SystemTextures . StencilDummySRV ;
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
if ( SceneTextures )
2021-01-11 14:49:16 -04:00
{
const EShaderPlatform ShaderPlatform = SceneTextures - > Config . ShaderPlatform ;
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : SceneColor ) )
{
SceneTextureParameters . SceneColorTexture = SceneTextures - > Color . Resolve ;
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : SceneDepth ) )
{
SceneTextureParameters . SceneDepthTexture = SceneTextures - > Depth . Resolve ;
2023-03-20 18:35:18 -04:00
SceneTextureParameters . ScenePartialDepthTexture = SceneTextures - > PartialDepth . Resolve ;
2021-01-11 14:49:16 -04:00
}
2022-07-09 14:02:06 -04:00
if ( IsUsingGBuffers ( ShaderPlatform ) )
2021-01-11 14:49:16 -04:00
{
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : GBufferA ) & & HasBeenProduced ( SceneTextures - > GBufferA ) )
{
SceneTextureParameters . GBufferATexture = SceneTextures - > GBufferA ;
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : GBufferB ) & & HasBeenProduced ( SceneTextures - > GBufferB ) )
{
SceneTextureParameters . GBufferBTexture = SceneTextures - > GBufferB ;
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : GBufferC ) & & HasBeenProduced ( SceneTextures - > GBufferC ) )
{
SceneTextureParameters . GBufferCTexture = SceneTextures - > GBufferC ;
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : GBufferD ) & & HasBeenProduced ( SceneTextures - > GBufferD ) )
{
SceneTextureParameters . GBufferDTexture = SceneTextures - > GBufferD ;
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : GBufferE ) & & HasBeenProduced ( SceneTextures - > GBufferE ) )
{
SceneTextureParameters . GBufferETexture = SceneTextures - > GBufferE ;
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : GBufferF ) & & HasBeenProduced ( SceneTextures - > GBufferF ) )
{
SceneTextureParameters . GBufferFTexture = SceneTextures - > GBufferF ;
}
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : SceneVelocity ) & & HasBeenProduced ( SceneTextures - > Velocity ) )
{
SceneTextureParameters . GBufferVelocityTexture = SceneTextures - > Velocity ;
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : SSAO ) & & HasBeenProduced ( SceneTextures - > ScreenSpaceAO ) )
{
SceneTextureParameters . ScreenSpaceAOTexture = SceneTextures - > ScreenSpaceAO ;
}
if ( EnumHasAnyFlags ( SetupMode , ESceneTextureSetupMode : : CustomDepth ) )
{
const FCustomDepthTextures & CustomDepthTextures = SceneTextures - > CustomDepth ;
if ( HasBeenProduced ( CustomDepthTextures . Depth ) )
{
SceneTextureParameters . CustomDepthTexture = CustomDepthTextures . Depth ;
SceneTextureParameters . CustomStencilTexture = CustomDepthTextures . Stencil ;
}
}
}
}
TRDGUniformBufferRef < FSceneTextureUniformParameters > CreateSceneTextureUniformBuffer (
FRDGBuilder & GraphBuilder ,
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FSceneTextures * SceneTextures ,
2021-01-11 14:49:16 -04:00
ERHIFeatureLevel : : Type FeatureLevel ,
ESceneTextureSetupMode SetupMode )
{
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
FSceneTextureUniformParameters * SceneTexturesParameters = GraphBuilder . AllocParameters < FSceneTextureUniformParameters > ( ) ;
SetupSceneTextureUniformParameters ( GraphBuilder , SceneTextures , FeatureLevel , SetupMode , * SceneTexturesParameters ) ;
return GraphBuilder . CreateUniformBuffer ( SceneTexturesParameters ) ;
2021-01-11 14:49:16 -04:00
}
2023-02-14 13:01:44 -05:00
TRDGUniformBufferRef < FSceneTextureUniformParameters > CreateSceneTextureUniformBuffer (
FRDGBuilder & GraphBuilder ,
const FSceneView & View ,
ESceneTextureSetupMode SetupMode )
{
if ( View . bIsViewInfo )
{
return CreateSceneTextureUniformBuffer ( GraphBuilder , ( ( const FViewInfo & ) View ) . GetSceneTexturesChecked ( ) , View . GetFeatureLevel ( ) , SetupMode ) ;
}
return nullptr ;
}
2021-01-11 14:49:16 -04:00
EMobileSceneTextureSetupMode Translate ( ESceneTextureSetupMode InSetupMode )
{
EMobileSceneTextureSetupMode OutSetupMode = EMobileSceneTextureSetupMode : : None ;
if ( EnumHasAnyFlags ( InSetupMode , ESceneTextureSetupMode : : GBuffers ) )
{
OutSetupMode | = EMobileSceneTextureSetupMode : : SceneColor ;
}
if ( EnumHasAnyFlags ( InSetupMode , ESceneTextureSetupMode : : CustomDepth ) )
{
OutSetupMode | = EMobileSceneTextureSetupMode : : CustomDepth ;
}
return OutSetupMode ;
}
void SetupMobileSceneTextureUniformParameters (
FRDGBuilder & GraphBuilder ,
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FSceneTextures * SceneTextures ,
2021-01-11 14:49:16 -04:00
EMobileSceneTextureSetupMode SetupMode ,
FMobileSceneTextureUniformParameters & SceneTextureParameters )
{
const FRDGSystemTextures & SystemTextures = FRDGSystemTextures : : Get ( GraphBuilder ) ;
SceneTextureParameters . SceneColorTexture = SystemTextures . Black ;
2021-09-29 01:08:35 -04:00
SceneTextureParameters . SceneColorTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
2021-01-11 14:49:16 -04:00
SceneTextureParameters . SceneDepthTexture = SystemTextures . DepthDummy ;
2024-03-06 06:49:06 -05:00
SceneTextureParameters . SceneDepthTextureArray = GSystemTextures . GetDefaultTexture ( GraphBuilder , ETextureDimension : : Texture2DArray , EPixelFormat : : PF_B8G8R8A8 , FClearValueBinding : : Black ) ;
2021-09-29 01:08:35 -04:00
SceneTextureParameters . SceneDepthTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
2023-03-20 18:35:18 -04:00
SceneTextureParameters . ScenePartialDepthTexture = SystemTextures . DepthDummy ;
SceneTextureParameters . ScenePartialDepthTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
2021-09-29 01:08:35 -04:00
// CustomDepthTexture is a color texture on mobile, with DeviceZ values
SceneTextureParameters . CustomDepthTexture = SystemTextures . Black ;
2021-01-11 14:49:16 -04:00
SceneTextureParameters . CustomDepthTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
2022-02-01 09:47:39 -05:00
SceneTextureParameters . CustomStencilTexture = SystemTextures . StencilDummySRV ;
2021-02-18 21:11:17 -04:00
SceneTextureParameters . SceneVelocityTexture = SystemTextures . Black ;
2021-09-29 01:08:35 -04:00
SceneTextureParameters . SceneVelocityTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
2021-01-11 14:49:16 -04:00
SceneTextureParameters . GBufferATexture = SystemTextures . Black ;
SceneTextureParameters . GBufferBTexture = SystemTextures . Black ;
SceneTextureParameters . GBufferCTexture = SystemTextures . Black ;
SceneTextureParameters . GBufferDTexture = SystemTextures . Black ;
2021-09-29 01:08:35 -04:00
// SceneDepthAuxTexture is a color texture on mobile, with DeviceZ values
SceneTextureParameters . SceneDepthAuxTexture = SystemTextures . Black ;
2024-03-06 06:49:06 -05:00
SceneTextureParameters . SceneDepthAuxTextureArray = GSystemTextures . GetDefaultTexture ( GraphBuilder , ETextureDimension : : Texture2DArray , EPixelFormat : : PF_B8G8R8A8 , FClearValueBinding : : Black ) ;
2023-06-02 05:02:31 -04:00
SceneTextureParameters . LocalLightTextureA = SystemTextures . Black ;
SceneTextureParameters . LocalLightTextureB = SystemTextures . Black ;
2021-01-11 14:49:16 -04:00
SceneTextureParameters . GBufferATextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
SceneTextureParameters . GBufferBTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
SceneTextureParameters . GBufferCTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
SceneTextureParameters . GBufferDTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
SceneTextureParameters . SceneDepthAuxTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
if ( SceneTextures )
2021-01-11 14:49:16 -04:00
{
2021-04-05 03:36:51 -04:00
if ( EnumHasAnyFlags ( SetupMode , EMobileSceneTextureSetupMode : : SceneColor ) & & HasBeenProduced ( SceneTextures - > Color . Resolve ) )
2021-01-11 14:49:16 -04:00
{
2021-04-05 03:36:51 -04:00
SceneTextureParameters . SceneColorTexture = SceneTextures - > Color . Resolve ;
2021-01-11 14:49:16 -04:00
}
2021-04-05 03:36:51 -04:00
if ( EnumHasAnyFlags ( SetupMode , EMobileSceneTextureSetupMode : : SceneDepth ) & &
HasBeenProduced ( SceneTextures - > Depth . Resolve ) & &
! EnumHasAnyFlags ( SceneTextures - > Depth . Resolve - > Desc . Flags , TexCreate_Memoryless ) )
2021-01-11 14:49:16 -04:00
{
2021-04-05 03:36:51 -04:00
SceneTextureParameters . SceneDepthTexture = SceneTextures - > Depth . Resolve ;
2024-03-06 06:49:06 -05:00
SceneTextureParameters . SceneDepthTextureArray = SceneTextures - > Depth . Resolve ;
2021-01-11 14:49:16 -04:00
}
2023-03-20 18:35:18 -04:00
if ( EnumHasAnyFlags ( SetupMode , EMobileSceneTextureSetupMode : : SceneDepth ) & &
HasBeenProduced ( SceneTextures - > PartialDepth . Resolve ) & &
! EnumHasAnyFlags ( SceneTextures - > PartialDepth . Resolve - > Desc . Flags , TexCreate_Memoryless ) )
{
SceneTextureParameters . ScenePartialDepthTexture = SceneTextures - > PartialDepth . Resolve ;
}
2021-01-11 14:49:16 -04:00
if ( SceneTextures - > Config . bIsUsingGBuffers )
{
if ( HasBeenProduced ( SceneTextures - > GBufferA ) )
{
SceneTextureParameters . GBufferATexture = SceneTextures - > GBufferA ;
}
if ( HasBeenProduced ( SceneTextures - > GBufferB ) )
{
SceneTextureParameters . GBufferBTexture = SceneTextures - > GBufferB ;
}
if ( HasBeenProduced ( SceneTextures - > GBufferC ) )
{
SceneTextureParameters . GBufferCTexture = SceneTextures - > GBufferC ;
}
if ( HasBeenProduced ( SceneTextures - > GBufferD ) )
{
SceneTextureParameters . GBufferDTexture = SceneTextures - > GBufferD ;
}
2021-06-11 13:47:20 -04:00
}
2021-01-11 14:49:16 -04:00
2021-06-11 13:47:20 -04:00
if ( EnumHasAnyFlags ( SetupMode , EMobileSceneTextureSetupMode : : SceneDepthAux ) )
{
if ( HasBeenProduced ( SceneTextures - > DepthAux . Resolve ) )
2021-01-11 14:49:16 -04:00
{
2021-06-11 13:47:20 -04:00
SceneTextureParameters . SceneDepthAuxTexture = SceneTextures - > DepthAux . Resolve ;
2024-03-06 06:49:06 -05:00
SceneTextureParameters . SceneDepthAuxTextureArray = SceneTextures - > DepthAux . Resolve ;
2021-01-11 14:49:16 -04:00
}
}
2023-06-02 05:02:31 -04:00
if ( HasBeenProduced ( SceneTextures - > MobileLocalLightTextureA ) )
{
SceneTextureParameters . LocalLightTextureA = SceneTextures - > MobileLocalLightTextureA ;
}
if ( HasBeenProduced ( SceneTextures - > MobileLocalLightTextureB ) )
{
SceneTextureParameters . LocalLightTextureB = SceneTextures - > MobileLocalLightTextureB ;
}
2021-01-11 14:49:16 -04:00
if ( EnumHasAnyFlags ( SetupMode , EMobileSceneTextureSetupMode : : CustomDepth ) )
{
const FCustomDepthTextures & CustomDepthTextures = SceneTextures - > CustomDepth ;
2022-05-11 06:10:52 -04:00
bool bCustomDepthProduced = HasBeenProduced ( CustomDepthTextures . Depth ) ;
SceneTextureParameters . CustomDepthTexture = bCustomDepthProduced ? CustomDepthTextures . Depth : SystemTextures . DepthDummy ;
SceneTextureParameters . CustomStencilTexture = bCustomDepthProduced ? CustomDepthTextures . Stencil : SystemTextures . StencilDummySRV ;
2021-01-11 14:49:16 -04:00
}
2021-02-18 21:11:17 -04:00
if ( EnumHasAnyFlags ( SetupMode , EMobileSceneTextureSetupMode : : SceneVelocity ) )
{
if ( HasBeenProduced ( SceneTextures - > Velocity ) )
{
SceneTextureParameters . SceneVelocityTexture = SceneTextures - > Velocity ;
}
}
2021-01-11 14:49:16 -04:00
}
}
TRDGUniformBufferRef < FMobileSceneTextureUniformParameters > CreateMobileSceneTextureUniformBuffer (
FRDGBuilder & GraphBuilder ,
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FSceneTextures * SceneTextures ,
2021-01-11 14:49:16 -04:00
EMobileSceneTextureSetupMode SetupMode )
{
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
FMobileSceneTextureUniformParameters * SceneTexturesParameters = GraphBuilder . AllocParameters < FMobileSceneTextureUniformParameters > ( ) ;
SetupMobileSceneTextureUniformParameters ( GraphBuilder , SceneTextures , SetupMode , * SceneTexturesParameters ) ;
return GraphBuilder . CreateUniformBuffer ( SceneTexturesParameters ) ;
2021-01-11 14:49:16 -04:00
}
2023-02-14 13:01:44 -05:00
TRDGUniformBufferRef < FMobileSceneTextureUniformParameters > CreateMobileSceneTextureUniformBuffer ( FRDGBuilder & GraphBuilder , const FSceneView & View , EMobileSceneTextureSetupMode SetupMode )
{
if ( View . bIsViewInfo )
{
return CreateMobileSceneTextureUniformBuffer ( GraphBuilder , ( ( const FViewInfo & ) View ) . GetSceneTexturesChecked ( ) , SetupMode ) ;
}
return nullptr ;
}
2021-01-11 14:49:16 -04:00
FSceneTextureShaderParameters CreateSceneTextureShaderParameters (
FRDGBuilder & GraphBuilder ,
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FSceneTextures * SceneTextures ,
2021-01-11 14:49:16 -04:00
ERHIFeatureLevel : : Type FeatureLevel ,
ESceneTextureSetupMode SetupMode )
{
FSceneTextureShaderParameters Parameters ;
2023-11-14 08:32:05 -05:00
if ( GetFeatureLevelShadingPath ( FeatureLevel ) = = EShadingPath : : Deferred )
2021-01-11 14:49:16 -04:00
{
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
Parameters . SceneTextures = CreateSceneTextureUniformBuffer ( GraphBuilder , SceneTextures , FeatureLevel , SetupMode ) ;
2021-01-11 14:49:16 -04:00
}
2023-11-14 08:32:05 -05:00
else if ( GetFeatureLevelShadingPath ( FeatureLevel ) = = EShadingPath : : Mobile )
2021-01-11 14:49:16 -04:00
{
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
Parameters . MobileSceneTextures = CreateMobileSceneTextureUniformBuffer ( GraphBuilder , SceneTextures , Translate ( SetupMode ) ) ;
2021-01-11 14:49:16 -04:00
}
return Parameters ;
}
2023-02-14 13:01:44 -05:00
FSceneTextureShaderParameters CreateSceneTextureShaderParameters ( FRDGBuilder & GraphBuilder , const FSceneView & View , ESceneTextureSetupMode SetupMode )
{
FSceneTextureShaderParameters Parameters ;
2023-11-14 08:32:05 -05:00
if ( GetFeatureLevelShadingPath ( View . FeatureLevel ) = = EShadingPath : : Deferred )
2023-02-14 13:01:44 -05:00
{
Parameters . SceneTextures = CreateSceneTextureUniformBuffer ( GraphBuilder , View , SetupMode ) ;
}
2023-11-14 08:32:05 -05:00
else if ( GetFeatureLevelShadingPath ( View . FeatureLevel ) = = EShadingPath : : Mobile )
2023-02-14 13:01:44 -05:00
{
Parameters . MobileSceneTextures = CreateMobileSceneTextureUniformBuffer ( GraphBuilder , View , Translate ( SetupMode ) ) ;
}
return Parameters ;
}
2023-02-16 01:59:33 -05:00
FSceneTextureShaderParameters GetSceneTextureShaderParameters ( const FSceneView & View )
{
check ( View . bIsViewInfo ) ;
const FMinimalSceneTextures & SceneTextures = static_cast < const FViewInfo & > ( View ) . GetSceneTextures ( ) ;
return SceneTextures . GetSceneTextureShaderParameters ( View . GetFeatureLevel ( ) ) ;
}
2023-02-09 16:49:22 -05:00
TRDGUniformBufferRef < FSceneTextureUniformParameters > GetSceneTextureUnformBuffer ( const FSceneView & View )
{
if ( const FSceneTextures * SceneTextures = static_cast < const FViewFamilyInfo * > ( View . Family ) - > GetSceneTexturesChecked ( ) )
{
return SceneTextures - > UniformBuffer ;
}
return TRDGUniformBufferRef < FSceneTextureUniformParameters > { } ;
}
2021-01-11 14:49:16 -04:00
bool IsSceneTexturesValid ( )
{
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
return FSceneTexturesConfig : : Get ( ) . IsValid ( ) ;
2021-01-11 14:49:16 -04:00
}
FIntPoint GetSceneTextureExtent ( )
{
return FSceneTexturesConfig : : Get ( ) . Extent ;
}
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
FIntPoint GetSceneTextureExtentFromView ( const FViewInfo & View )
{
return View . GetSceneTexturesConfig ( ) . Extent ;
}
2021-01-11 14:49:16 -04:00
ERHIFeatureLevel : : Type GetSceneTextureFeatureLevel ( )
{
return FSceneTexturesConfig : : Get ( ) . FeatureLevel ;
2021-03-30 16:25:21 -04:00
}
void CreateSystemTextures ( FRDGBuilder & GraphBuilder )
{
FRDGSystemTextures : : Create ( GraphBuilder ) ;
2022-02-01 09:47:39 -05:00
}