2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
/*=============================================================================
SceneRenderTargets . cpp : Scene render target implementation .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "RendererPrivate.h"
# include "ScenePrivate.h"
# include "SceneFilterRendering.h"
# include "ReflectionEnvironment.h"
# include "LightPropagationVolume.h"
2014-08-21 06:03:00 -04:00
# include "SceneUtils.h"
2014-08-22 16:25:40 -04:00
# include "HdrCustomResolveShaders.h"
2014-03-14 14:13:41 -04:00
// for LightPropagationVolume feature, could be exposed
const int ReflectiveShadowMapResolution = 256 ;
2014-06-05 16:38:54 -04:00
IMPLEMENT_UNIFORM_BUFFER_STRUCT ( FGBufferResourceStruct , TEXT ( " GBuffers " ) ) ;
2015-02-02 18:00:05 -05:00
static TAutoConsoleVariable < int32 > CVarBasePassOutputsVelocityDebug (
TEXT ( " r.BasePassOutputsVelocityDebug " ) ,
0 ,
TEXT ( " Debug settings for Base Pass outputting velocity. \n " ) \
TEXT ( " 0 - Regular rendering \n " ) \
TEXT ( " 1 - Skip setting GBufferVelocity RT \n " ) \
TEXT ( " 2 - Set Color Mask 0 for GBufferVelocity RT \n " ) ,
ECVF_RenderThreadSafe ) ;
static int32 GBasePassOutputsVelocityDebug = 0 ;
2014-03-14 14:13:41 -04:00
/*-----------------------------------------------------------------------------
FSceneRenderTargets
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int32 GDownsampledOcclusionQueries = 0 ;
static FAutoConsoleVariableRef CVarDownsampledOcclusionQueries (
TEXT ( " r.DownsampledOcclusionQueries " ) ,
GDownsampledOcclusionQueries ,
TEXT ( " Whether to issue occlusion queries to a downsampled depth buffer " ) ,
ECVF_RenderThreadSafe
) ;
static TAutoConsoleVariable < int32 > CVarSceneTargetsResizingMethod (
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.) \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
) ;
2014-05-08 16:33:07 -04:00
static TAutoConsoleVariable < int32 > CVarOptimizeForUAVPerformance (
TEXT ( " r.OptimizeForUAVPerformance " ) ,
0 ,
2014-05-08 16:47:58 -04:00
TEXT ( " Allows to profile if hardware has a performance cost due to render target reuse (more info: search for GCNPerformanceTweets.pdf Tip 37) \n " )
TEXT ( " If we see a noticeable difference on some hardware we can add another option like -1 (meaning auto) and make it the new default. \n " )
TEXT ( " 0: Optimize for GPU memory savings and reuse render targets (default) \n " )
TEXT ( " 1: Optimize for GPU performance (might render faster but can require more GPU memory) " ) ,
2014-05-08 16:33:07 -04:00
ECVF_RenderThreadSafe
) ;
2014-05-08 17:58:14 -04:00
static TAutoConsoleVariable < int32 > CVarCustomDepth (
TEXT ( " r.CustomDepth " ) ,
1 ,
TEXT ( " 0: feature is disabled \n " )
TEXT ( " 1: feature is enabled, texture is created on demand \n " )
TEXT ( " 2: feature is enabled, texture is not released until required (should be the project setting if the feature should not stall) " ) ,
ECVF_RenderThreadSafe
) ;
2014-05-08 16:33:07 -04:00
2014-06-25 05:47:33 -04:00
static TAutoConsoleVariable < int32 > CVarMobileMSAA (
2014-05-12 08:37:11 -04:00
TEXT ( " r.MobileMSAA " ) ,
0 ,
2014-06-17 18:27:26 -04:00
TEXT ( " Use MSAA instead of Temporal AA on mobile: \n " )
2014-08-25 16:47:22 -04:00
TEXT ( " 1: Use Temporal AA (MSAA disabled) \n " )
TEXT ( " 2: Use 2x MSAA (Temporal AA disabled) \n " )
2014-11-20 12:36:32 -05:00
TEXT ( " 4: Use 4x MSAA (Temporal AA disabled) " ) ,
2014-05-12 08:37:11 -04:00
ECVF_RenderThreadSafe
) ;
2014-06-25 05:47:33 -04:00
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 ( " 5: high precision " ) ,
ECVF_RenderThreadSafe ) ;
2014-03-14 14:13:41 -04:00
/** The global render targets used for scene rendering. */
TGlobalResource < FSceneRenderTargets > GSceneRenderTargets ;
2014-09-18 17:01:15 -04:00
inline const TCHAR * GetReflectionBrightnessTargetName ( uint32 Index )
{
const TCHAR * Names [ 2 ] =
{
TEXT ( " ReflectionBrightness0 " ) ,
TEXT ( " ReflectionBrightness1 " )
} ;
check ( Index < sizeof ( Names ) ) ;
return Names [ Index ] ;
}
inline const TCHAR * GetSceneColorTargetName ( FSceneRenderTargets : : EShadingPath ShadingPath )
{
const TCHAR * SceneColorNames [ ( uint32 ) FSceneRenderTargets : : EShadingPath : : Num ] =
{
TEXT ( " SceneColorForward " ) ,
TEXT ( " SceneColorDeferred " )
} ;
check ( ( uint32 ) ShadingPath < sizeof ( SceneColorNames ) ) ;
return SceneColorNames [ ( uint32 ) ShadingPath ] ;
}
2014-12-02 17:56:35 -05:00
FIntPoint FSceneRenderTargets : : ComputeDesiredSize ( const FSceneViewFamily & ViewFamily )
2014-03-14 14:13:41 -04:00
{
// Don't expose Clamped to the cvar since you need to at least grow to the initial state.
2014-11-20 16:56:13 -05:00
enum ESizingMethods { RequestedSize , ScreenRes , Grow , VisibleSizingMethodsCount , Clamped } ;
2014-03-14 14:13:41 -04:00
ESizingMethods SceneTargetsSizingMethod = Grow ;
2014-11-20 16:56:13 -05:00
bool bIsSceneCapture = false ;
bool bIsReflectionCapture = false ;
for ( int32 ViewIndex = 0 , ViewCount = ViewFamily . Views . Num ( ) ; ViewIndex < ViewCount ; + + ViewIndex )
2014-03-14 14:13:41 -04:00
{
2014-10-02 17:19:02 -04:00
const FSceneView * View = ViewFamily . Views [ ViewIndex ] ;
2014-11-20 16:56:13 -05:00
bIsSceneCapture | = View - > bIsSceneCapture ;
bIsReflectionCapture | = View - > bIsReflectionCapture ;
2014-03-14 14:13:41 -04:00
}
if ( ! FPlatformProperties : : SupportsWindowedMode ( ) )
{
// Force ScreenRes on non windowed platforms.
SceneTargetsSizingMethod = RequestedSize ;
}
else if ( GIsEditor )
{
// Always grow scene render targets in the editor.
SceneTargetsSizingMethod = Grow ;
}
else
{
// Otherwise use the setting specified by the console variable.
SceneTargetsSizingMethod = ( ESizingMethods ) FMath : : Clamp ( CVarSceneTargetsResizingMethod . GetValueOnRenderThread ( ) , 0 , ( int32 ) VisibleSizingMethodsCount ) ;
}
2014-11-20 16:56:13 -05:00
2014-12-02 17:56:35 -05:00
FIntPoint DesiredBufferSize = FIntPoint : : ZeroValue ;
2014-03-14 14:13:41 -04:00
switch ( SceneTargetsSizingMethod )
{
case RequestedSize :
2014-12-02 17:56:35 -05:00
DesiredBufferSize = FIntPoint ( ViewFamily . FamilySizeX , ViewFamily . FamilySizeY ) ;
break ;
2014-03-14 14:13:41 -04:00
case ScreenRes :
2014-12-02 17:56:35 -05:00
DesiredBufferSize = FIntPoint ( GSystemResolution . ResX , GSystemResolution . ResY ) ;
break ;
2014-03-14 14:13:41 -04:00
case Grow :
2014-12-02 17:56:35 -05:00
DesiredBufferSize = FIntPoint ( FMath : : Max ( ( uint32 ) GetBufferSizeXY ( ) . X , ViewFamily . FamilySizeX ) ,
2014-03-14 14:13:41 -04:00
FMath : : Max ( ( uint32 ) GetBufferSizeXY ( ) . Y , ViewFamily . FamilySizeY ) ) ;
2014-12-02 17:56:35 -05:00
break ;
2014-03-14 14:13:41 -04:00
case Clamped :
if ( ( ( uint32 ) BufferSize . X < ViewFamily . FamilySizeX ) | | ( ( uint32 ) BufferSize . Y < ViewFamily . FamilySizeY ) )
{
UE_LOG ( LogRenderer , Warning , TEXT ( " Capture target size: %ux%u clamped to %ux%u. " ) , ViewFamily . FamilySizeX , ViewFamily . FamilySizeY , BufferSize . X , BufferSize . Y ) ;
}
2014-12-02 17:56:35 -05:00
DesiredBufferSize = FIntPoint ( GetBufferSizeXY ( ) . X , GetBufferSizeXY ( ) . Y ) ;
break ;
2014-03-14 14:13:41 -04:00
default :
checkNoEntry ( ) ;
}
2014-12-02 17:56:35 -05:00
// we want to shrink the buffer but as we can have multiple scenecaptures per frame we have to delay that a frame to get all size requests
{
// this allows The BufferSize to not grow below the SceneCapture requests (happen before scene rendering, in the same frame with a Grow request)
LargestDesiredSizeThisFrame = LargestDesiredSizeThisFrame . ComponentMax ( DesiredBufferSize ) ;
uint32 FrameNumber = ViewFamily . FrameNumber ;
// this could be refined to be some time or multiple frame if we have SceneCaptures not running each frame any more
if ( ThisFrameNumber ! = FrameNumber )
{
// this allows the BufferSize to shrink each frame (in game)
ThisFrameNumber = FrameNumber ;
LargestDesiredSizeLastFrame = LargestDesiredSizeThisFrame ;
LargestDesiredSizeThisFrame = FIntPoint ( 0 , 0 ) ;
}
DesiredBufferSize = DesiredBufferSize . ComponentMax ( LargestDesiredSizeLastFrame ) ;
}
return DesiredBufferSize ;
2014-03-14 14:13:41 -04:00
}
void FSceneRenderTargets : : Allocate ( const FSceneViewFamily & ViewFamily )
{
check ( IsInRenderingThread ( ) ) ;
2014-12-02 17:56:35 -05:00
// ViewFamily setup wasn't complete
check ( ViewFamily . FrameNumber ! = UINT_MAX ) ;
2014-03-14 14:13:41 -04:00
2014-08-19 10:41:34 -04:00
// If feature level has changed, release all previously allocated targets to the pool. If feature level has changed but
const auto NewFeatureLevel = ViewFamily . Scene - > GetFeatureLevel ( ) ;
2014-09-18 17:01:15 -04:00
CurrentShadingPath = ViewFamily . Scene - > ShouldUseDeferredRenderer ( ) ? EShadingPath : : Deferred : EShadingPath : : Forward ;
2014-08-19 10:41:34 -04:00
2014-11-20 16:56:13 -05:00
FIntPoint DesiredBufferSize = ComputeDesiredSize ( ViewFamily ) ;
2014-03-14 14:13:41 -04:00
check ( DesiredBufferSize . X > 0 & & DesiredBufferSize . Y > 0 ) ;
QuantizeBufferSize ( DesiredBufferSize . X , DesiredBufferSize . Y ) ;
2014-06-25 05:47:33 -04:00
int GBufferFormat = CVarGBufferFormat . GetValueOnRenderThread ( ) ;
2014-03-14 14:13:41 -04:00
int SceneColorFormat ;
{
static const auto CVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.SceneColorFormat " ) ) ;
2014-06-25 05:47:33 -04:00
2014-03-14 14:13:41 -04:00
SceneColorFormat = CVar - > GetValueOnRenderThread ( ) ;
}
bool bNewAllowStaticLighting ;
{
static const auto CVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.AllowStaticLighting " ) ) ;
bNewAllowStaticLighting = CVar - > GetValueOnRenderThread ( ) ! = 0 ;
}
bool bDownsampledOcclusionQueries = GDownsampledOcclusionQueries ! = 0 ;
int32 MaxShadowResolution = GetCachedScalabilityCVars ( ) . MaxShadowResolution ;
2015-03-02 08:00:04 -05:00
if ( ViewFamily . Scene - > ShouldUseDeferredRenderer ( ) = = false )
{
// ensure there is always enough space for forward renderer's tiled shadow maps
// by reducing the shadow map resolution.
int32 MaxShadowDepthBufferDim = FMath : : Max ( GMaxShadowDepthBufferSizeX , GMaxShadowDepthBufferSizeY ) ;
if ( MaxShadowResolution * 2 > MaxShadowDepthBufferDim )
{
MaxShadowResolution = MaxShadowDepthBufferDim / 2 ;
}
}
2014-03-14 14:13:41 -04:00
int32 TranslucencyLightingVolumeDim = GTranslucencyLightingVolumeDim ;
uint32 Mobile32bpp = ! IsMobileHDR ( ) | | IsMobileHDR32bpp ( ) ;
2014-05-12 08:37:11 -04:00
static const auto CVarMobileMSAA = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.MobileMSAA " ) ) ;
2014-08-19 10:41:34 -04:00
int32 MobileMSAA = GShaderPlatformForFeatureLevel [ NewFeatureLevel ] = = SP_OPENGL_ES2_IOS ? 1 : CVarMobileMSAA - > GetValueOnRenderThread ( ) ;
2014-05-12 08:37:11 -04:00
2014-08-19 10:41:34 -04:00
bool bLightPropagationVolume = UseLightPropagationVolumeRT ( NewFeatureLevel ) ;
2014-03-14 14:13:41 -04:00
uint32 MinShadowResolution ;
{
static const auto CVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.Shadow.MinResolution " ) ) ;
MinShadowResolution = CVar - > GetValueOnRenderThread ( ) ;
}
if ( ( BufferSize . X ! = DesiredBufferSize . X ) | |
( BufferSize . Y ! = DesiredBufferSize . Y ) | |
( CurrentGBufferFormat ! = GBufferFormat ) | |
( CurrentSceneColorFormat ! = SceneColorFormat ) | |
( bAllowStaticLighting ! = bNewAllowStaticLighting ) | |
( bUseDownsizedOcclusionQueries ! = bDownsampledOcclusionQueries ) | |
2014-08-25 16:47:22 -04:00
( CurrentMaxShadowResolution ! = MaxShadowResolution ) | |
2014-03-14 14:13:41 -04:00
( CurrentTranslucencyLightingVolumeDim ! = TranslucencyLightingVolumeDim ) | |
( CurrentMobile32bpp ! = Mobile32bpp ) | |
2014-05-12 08:37:11 -04:00
( CurrentMobileMSAA ! = MobileMSAA ) | |
2014-03-14 14:13:41 -04:00
( bCurrentLightPropagationVolume ! = bLightPropagationVolume ) | |
2014-09-18 17:01:15 -04:00
( CurrentMinShadowResolution ! = MinShadowResolution ) )
2014-03-14 14:13:41 -04:00
{
CurrentGBufferFormat = GBufferFormat ;
CurrentSceneColorFormat = SceneColorFormat ;
bAllowStaticLighting = bNewAllowStaticLighting ;
bUseDownsizedOcclusionQueries = bDownsampledOcclusionQueries ;
CurrentMaxShadowResolution = MaxShadowResolution ;
CurrentTranslucencyLightingVolumeDim = TranslucencyLightingVolumeDim ;
CurrentMobile32bpp = Mobile32bpp ;
2014-05-12 08:37:11 -04:00
CurrentMobileMSAA = MobileMSAA ;
2014-03-14 14:13:41 -04:00
CurrentMinShadowResolution = MinShadowResolution ;
bCurrentLightPropagationVolume = bLightPropagationVolume ;
2015-02-09 15:01:09 -05:00
2014-03-14 14:13:41 -04:00
// Reinitialize the render targets for the given size.
SetBufferSize ( DesiredBufferSize . X , DesiredBufferSize . Y ) ;
2015-01-05 13:48:58 -05:00
UE_LOG ( LogRenderer , Log , TEXT ( " Reallocating scene render targets to support %ux%u (Frame:%u). " ) , BufferSize . X , BufferSize . Y , ViewFamily . FrameNumber ) ;
2014-03-14 14:13:41 -04:00
UpdateRHI ( ) ;
}
2014-09-18 17:01:15 -04:00
// Do allocation of render targets if they aren't available for the current shading path
CurrentFeatureLevel = NewFeatureLevel ;
AllocateRenderTargets ( ) ;
2014-03-14 14:13:41 -04:00
}
2015-04-08 15:33:28 -04:00
void FSceneRenderTargets : : BeginRenderingSceneColor ( FRHICommandList & RHICmdList , ESimpleRenderTargetMode RenderTargetMode /*=EUninitializedColorExistingDepth*/ , FExclusiveDepthStencil DepthStencilAccess )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , BeginRenderingSceneColor ) ;
2014-03-14 14:13:41 -04:00
2014-05-06 11:27:50 -04:00
AllocSceneColor ( ) ;
2014-06-27 11:07:13 -04:00
2015-04-08 15:33:28 -04:00
SetRenderTarget ( RHICmdList , GetSceneColorSurface ( ) , GetSceneDepthSurface ( ) , RenderTargetMode , DepthStencilAccess ) ;
2014-10-23 16:31:43 -04:00
}
2015-01-29 11:49:48 -05:00
int32 FSceneRenderTargets : : GetGBufferRenderTargets ( ERenderTargetLoadAction ColorLoadAction , FRHIRenderTargetView OutRenderTargets [ MaxSimultaneousRenderTargets ] , int32 & OutVelocityRTIndex )
2015-01-27 16:14:50 -05:00
{
2015-01-29 11:49:48 -05:00
OutRenderTargets [ 0 ] = FRHIRenderTargetView ( GetSceneColorSurface ( ) , 0 , - 1 , ColorLoadAction , ERenderTargetStoreAction : : EStore ) ;
OutRenderTargets [ 1 ] = FRHIRenderTargetView ( GSceneRenderTargets . GBufferA - > GetRenderTargetItem ( ) . TargetableTexture , 0 , - 1 , ColorLoadAction , ERenderTargetStoreAction : : EStore ) ;
OutRenderTargets [ 2 ] = FRHIRenderTargetView ( GSceneRenderTargets . GBufferB - > GetRenderTargetItem ( ) . TargetableTexture , 0 , - 1 , ColorLoadAction , ERenderTargetStoreAction : : EStore ) ;
OutRenderTargets [ 3 ] = FRHIRenderTargetView ( GSceneRenderTargets . GBufferC - > GetRenderTargetItem ( ) . TargetableTexture , 0 , - 1 , ColorLoadAction , ERenderTargetStoreAction : : EStore ) ;
OutRenderTargets [ 4 ] = FRHIRenderTargetView ( GSceneRenderTargets . GBufferD - > GetRenderTargetItem ( ) . TargetableTexture , 0 , - 1 , ColorLoadAction , ERenderTargetStoreAction : : EStore ) ;
2015-01-27 16:14:50 -05:00
int32 MRTCount = 5 ; // Derived from previously used RenderTargets[]; would have been nice to keep a pointer while filling it but it's more confusing to use
2015-01-29 11:49:48 -05:00
OutVelocityRTIndex = - 1 ;
2015-01-27 16:14:50 -05:00
if ( bAllowStaticLighting )
{
2015-02-09 15:01:09 -05:00
check ( MRTCount = = GetGBufferEIndex ( ) ) ;
2015-01-29 11:49:48 -05:00
OutRenderTargets [ MRTCount ] = FRHIRenderTargetView ( GSceneRenderTargets . GBufferE - > GetRenderTargetItem ( ) . TargetableTexture , 0 , - 1 , ColorLoadAction , ERenderTargetStoreAction : : EStore ) ;
2015-01-27 16:14:50 -05:00
+ + MRTCount ;
}
2015-02-02 18:00:05 -05:00
if ( bAllocateVelocityGBuffer )
2015-01-27 16:14:50 -05:00
{
2015-01-29 11:49:48 -05:00
OutVelocityRTIndex = MRTCount ;
2015-01-27 16:14:50 -05:00
+ + MRTCount ;
2015-02-09 15:01:09 -05:00
check ( OutVelocityRTIndex = = GetGBufferVelocityIndex ( ) ) ;
2015-01-29 11:49:48 -05:00
OutRenderTargets [ OutVelocityRTIndex ] = FRHIRenderTargetView ( GSceneRenderTargets . GBufferVelocity - > GetRenderTargetItem ( ) . TargetableTexture , 0 , - 1 , ColorLoadAction , ERenderTargetStoreAction : : EStore ) ;
2015-01-27 16:14:50 -05:00
}
2015-01-29 11:49:48 -05:00
check ( MRTCount < = MaxSimultaneousRenderTargets ) ;
2015-01-27 16:14:50 -05:00
return MRTCount ;
}
2014-10-23 16:31:43 -04:00
void FSceneRenderTargets : : BeginRenderingGBuffer ( FRHICommandList & RHICmdList , ERenderTargetLoadAction ColorLoadAction , ERenderTargetLoadAction DepthLoadAction , const FLinearColor & ClearColor /*=(0,0,0,1)*/ )
{
SCOPED_DRAW_EVENT ( RHICmdList , BeginRenderingSceneColor ) ;
if ( IsSimpleDynamicLightingEnabled ( ) )
2014-03-14 14:13:41 -04:00
{
2014-10-23 16:31:43 -04:00
// in this non-standard case, just render to scene color with default mode
BeginRenderingSceneColor ( RHICmdList ) ;
return ;
}
AllocSceneColor ( ) ;
// Set the scene color surface as the render target, and the scene depth surface as the depth-stencil target.
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM4 )
{
2015-01-27 16:14:50 -05:00
int32 VelocityRTIndex ;
2015-01-29 11:49:48 -05:00
FRHIRenderTargetView RenderTargets [ MaxSimultaneousRenderTargets ] ;
int32 MRTCount = GetGBufferRenderTargets ( ColorLoadAction , RenderTargets , VelocityRTIndex ) ;
2015-01-20 20:14:07 -05:00
2015-03-31 14:02:45 -04:00
const float DepthClearValue = ( float ) ERHIZBuffer : : FarPlane ;
2015-01-27 16:14:50 -05:00
bool bClearColor = ColorLoadAction = = ERenderTargetLoadAction : : EClear ;
bool bClearDepth = DepthLoadAction = = ERenderTargetLoadAction : : EClear ;
2014-10-23 16:31:43 -04:00
FRHIDepthRenderTargetView DepthView ( GetSceneDepthSurface ( ) , DepthLoadAction , ERenderTargetStoreAction : : EStore ) ;
FRHISetRenderTargetsInfo Info ( MRTCount , RenderTargets , DepthView ) ;
2015-01-27 16:14:50 -05:00
if ( bClearColor )
2014-10-23 16:31:43 -04:00
{
2015-01-27 16:14:50 -05:00
bGBuffersCleared = true ;
GBufferClearColor = ClearColor ;
2014-10-23 16:31:43 -04:00
}
2015-01-27 16:14:50 -05:00
Info . ClearColors [ 0 ] = GBufferClearColor ;
Info . ClearColors [ 1 ] = Info . ClearColors [ 2 ] = Info . ClearColors [ 3 ] = FLinearColor : : Transparent ;
Info . ClearColors [ 4 ] = FLinearColor ( 0 , 1 , 1 , 1 ) ;
Info . ClearColors [ 5 ] = FLinearColor ( 1 , 1 , 1 , 1 ) ;
if ( VelocityRTIndex ! = - 1 )
{
Info . ClearColors [ VelocityRTIndex ] = FLinearColor ( 0 , 0 , 0 , 0 ) ;
}
if ( bClearDepth )
{
bSceneDepthCleared = true ;
SceneDepthClearValue = DepthClearValue ;
}
Info . DepthClearValue = DepthClearValue ;
2014-10-23 16:31:43 -04:00
// set the render target
RHICmdList . SetRenderTargetsAndClear ( Info ) ;
2015-01-27 16:14:50 -05:00
//bind any clear data that won't be bound automatically by the preceding SetRenderTargetsAndClear
bool bBindClearColor = ! bClearColor & & bGBuffersCleared ;
bool bBindClearDepth = ! bClearDepth & & bSceneDepthCleared ;
RHICmdList . BindClearMRTValues ( bBindClearColor , MRTCount , Info . ClearColors , bBindClearDepth , SceneDepthClearValue , bBindClearDepth , Info . StencilClearValue ) ;
2014-03-14 14:13:41 -04:00
}
2014-10-23 16:31:43 -04:00
}
2014-03-14 14:13:41 -04:00
2015-01-27 16:14:50 -05:00
void FSceneRenderTargets : : FinishRenderingGBuffer ( FRHICommandListImmediate & RHICmdList )
{
if ( IsSimpleDynamicLightingEnabled ( ) )
{
// in this non-standard case, just render to scene color with default mode
FinishRenderingSceneColor ( RHICmdList , true ) ;
return ;
}
int32 VelocityRTIndex ;
2015-01-29 11:49:48 -05:00
FRHIRenderTargetView RenderTargets [ MaxSimultaneousRenderTargets ] ;
int32 NumMRTs = GetGBufferRenderTargets ( ERenderTargetLoadAction : : ELoad , RenderTargets , VelocityRTIndex ) ;
2015-01-27 16:14:50 -05:00
FResolveParams ResolveParams ;
for ( int32 i = 0 ; i < NumMRTs ; + + i )
{
RHICmdList . CopyToResolveTarget ( RenderTargets [ i ] . Texture , RenderTargets [ i ] . Texture , true , ResolveParams ) ;
}
FTextureRHIParamRef DepthSurface = GetSceneDepthSurface ( ) ;
RHICmdList . CopyToResolveTarget ( DepthSurface , DepthSurface , true , ResolveParams ) ;
}
2014-03-14 14:13:41 -04:00
int32 FSceneRenderTargets : : GetNumGBufferTargets ( ) const
{
int32 NumGBufferTargets = 1 ;
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM4 & & ! IsSimpleDynamicLightingEnabled ( ) )
2014-03-14 14:13:41 -04:00
{
2015-02-09 14:33:09 -05:00
// This needs to match TBasePassPixelShaderBaseType::ModifyCompilationEnvironment()
2014-03-14 14:13:41 -04:00
NumGBufferTargets = bAllowStaticLighting ? 6 : 5 ;
2015-01-20 20:14:07 -05:00
2015-02-02 18:00:05 -05:00
if ( bAllocateVelocityGBuffer )
2015-01-20 20:14:07 -05:00
{
+ + NumGBufferTargets ;
}
2014-03-14 14:13:41 -04:00
}
return NumGBufferTargets ;
}
2014-09-18 17:01:15 -04:00
inline uint16 GetNumSceneColorMSAASamples ( ERHIFeatureLevel : : Type InFeatureLevel )
{
//@todo-rco: Fix when OpenGL supports MSAA
uint16 NumSamples = GShaderPlatformForFeatureLevel [ InFeatureLevel ] = = SP_OPENGL_ES2_IOS ? 1 : CVarMobileMSAA . GetValueOnRenderThread ( ) ;
if ( NumSamples ! = 1 & & NumSamples ! = 2 & & NumSamples ! = 4 )
{
NumSamples = 1 ;
}
return NumSamples ;
}
2014-05-06 11:27:50 -04:00
void FSceneRenderTargets : : AllocSceneColor ( )
{
2014-09-18 17:01:15 -04:00
if ( GetSceneColorForCurrentShadingPath ( ) )
2014-05-06 11:27:50 -04:00
{
// no work needed
return ;
}
// create SceneColor on demand so it can be shared with other pooled RT
EPixelFormat SceneColorBufferFormat = GetSceneColorFormat ( ) ;
// Create the scene color.
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , SceneColorBufferFormat , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
2014-05-06 18:30:14 -04:00
2014-05-06 11:27:50 -04:00
Desc . Flags | = TexCreate_FastVRAM ;
2014-05-06 18:30:14 -04:00
2014-05-08 16:33:07 -04:00
int32 OptimizeForUAVPerformance = CVarOptimizeForUAVPerformance . GetValueOnRenderThread ( ) ;
2014-05-06 18:30:14 -04:00
// with TexCreate_UAV it would allow better sharing with later elements but it might come at a high cost:
// GCNPerformanceTweets.pdf Tip 37: Warning: Causes additional synchronization between draw calls when using a render target allocated with this flag, use sparingly
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM5 & & ! OptimizeForUAVPerformance )
2014-05-07 11:04:46 -04:00
{
Desc . TargetableFlags | = TexCreate_UAV ;
}
2014-05-06 18:30:14 -04:00
2014-08-25 16:47:22 -04:00
if ( CurrentFeatureLevel < ERHIFeatureLevel : : SM4 )
2014-05-21 15:07:18 -04:00
{
2014-09-18 17:01:15 -04:00
Desc . NumSamples = GetNumSceneColorMSAASamples ( CurrentFeatureLevel ) ;
2014-05-21 15:07:18 -04:00
}
2014-09-18 17:01:15 -04:00
GRenderTargetPool . FindFreeElement ( Desc , GetSceneColorForCurrentShadingPath ( ) , GetSceneColorTargetName ( CurrentShadingPath ) ) ;
2014-05-06 11:27:50 -04:00
}
// otherwise we have a severe problem
2014-09-18 17:01:15 -04:00
check ( GetSceneColorForCurrentShadingPath ( ) ) ;
2014-05-06 11:27:50 -04:00
}
void FSceneRenderTargets : : AllocLightAttenuation ( )
{
if ( LightAttenuation )
{
// no work needed
return ;
}
2014-08-07 09:41:54 -04:00
check ( IsInRenderingThread ( ) ) ;
2014-05-06 11:27:50 -04:00
// create LightAttenuation on demand so it can be shared with other pooled RT
// Create a texture to store the resolved light attenuation values, and a render-targetable surface to hold the unresolved light attenuation values.
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_B8G8R8A8 , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
Desc . Flags | = TexCreate_FastVRAM ;
GRenderTargetPool . FindFreeElement ( Desc , LightAttenuation , TEXT ( " LightAttenuation " ) ) ;
// the channel assignment is documented in ShadowRendering.cpp (look for Light Attenuation channel assignment)
}
// otherwise we have a severe problem
check ( LightAttenuation ) ;
}
2014-09-18 17:01:15 -04:00
TRefCountPtr < IPooledRenderTarget > & FSceneRenderTargets : : GetReflectionBrightnessTarget ( )
{
bool bSupportsR32Float = CurrentFeatureLevel > ERHIFeatureLevel : : ES2 ;
int32 ReflectionBrightnessIndex = bSupportsR32Float ? 0 : 1 ;
return ReflectionBrightness [ ReflectionBrightnessIndex ] ;
}
2014-07-10 10:39:54 -04:00
void FSceneRenderTargets : : ReleaseGBufferTargets ( )
2014-05-08 17:58:14 -04:00
{
2014-06-05 16:38:54 -04:00
GBufferResourcesUniformBuffer . SafeRelease ( ) ;
2014-05-08 17:58:14 -04:00
GBufferA . SafeRelease ( ) ;
GBufferB . SafeRelease ( ) ;
GBufferC . SafeRelease ( ) ;
GBufferD . SafeRelease ( ) ;
GBufferE . SafeRelease ( ) ;
2015-01-20 20:14:07 -05:00
GBufferVelocity . SafeRelease ( ) ;
2014-05-08 17:58:14 -04:00
}
2015-02-02 18:00:05 -05:00
void FSceneRenderTargets : : PreallocGBufferTargets ( bool bShouldRenderVelocities )
{
if ( GBasePassOutputsVelocityDebug = = 1 )
{
bAllocateVelocityGBuffer = false ;
}
else
{
bAllocateVelocityGBuffer = bShouldRenderVelocities & & FVelocityRendering : : OutputsToGBuffer ( ) ;
}
}
2014-05-08 17:58:14 -04:00
void FSceneRenderTargets : : AllocGBufferTargets ( )
{
2014-05-16 17:29:16 -04:00
// AdjustGBufferRefCount +1 doesn't match -1 (within the same frame)
ensure ( GBufferRefCount = = 0 ) ;
2015-02-02 18:00:05 -05:00
if ( GBufferA )
2014-05-08 17:58:14 -04:00
{
// no work needed
return ;
}
// create GBuffer on demand so it can be shared with other pooled RT
// good to see the quality loss due to precision in the gbuffer
const bool bHighPrecisionGBuffers = ( CurrentGBufferFormat > = 5 ) ;
// good to profile the impact of non 8 bit formats
const bool bEnforce8BitPerChannel = ( CurrentGBufferFormat = = 0 ) ;
// Create the world-space normal g-buffer.
{
EPixelFormat NormalGBufferFormat = bHighPrecisionGBuffers ? PF_FloatRGBA : PF_A2B10G10R10 ;
if ( bEnforce8BitPerChannel )
{
NormalGBufferFormat = PF_B8G8R8A8 ;
}
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , NormalGBufferFormat , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , GBufferA , TEXT ( " GBufferA " ) ) ;
}
// Create the specular color and power g-buffer.
{
const EPixelFormat SpecularGBufferFormat = bHighPrecisionGBuffers ? PF_FloatRGBA : PF_B8G8R8A8 ;
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , SpecularGBufferFormat , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , GBufferB , TEXT ( " GBufferB " ) ) ;
}
// Create the diffuse color g-buffer.
{
const EPixelFormat DiffuseGBufferFormat = bHighPrecisionGBuffers ? PF_FloatRGBA : PF_B8G8R8A8 ;
uint32 DiffuseGBufferFlags = TexCreate_SRGB ;
# if PLATFORM_MAC // @todo: remove once Apple fixes radr://16754329 AMD Cards don't always perform FRAMEBUFFER_SRGB if the draw FBO has mixed sRGB & non-SRGB colour attachments
static const auto CVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.Mac.UseFrameBufferSRGB " ) ) ;
DiffuseGBufferFlags = CVar & & CVar - > GetValueOnRenderThread ( ) ? TexCreate_SRGB : TexCreate_None ;
# endif
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , DiffuseGBufferFormat , DiffuseGBufferFlags , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , GBufferC , TEXT ( " GBufferC " ) ) ;
}
// Create the mask g-buffer (e.g. SSAO, subsurface scattering, wet surface mask, skylight mask, ...).
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_B8G8R8A8 , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , GBufferD , TEXT ( " GBufferD " ) ) ;
}
if ( bAllowStaticLighting )
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_B8G8R8A8 , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , GBufferE , TEXT ( " GBufferE " ) ) ;
}
2015-02-02 18:00:05 -05:00
GBasePassOutputsVelocityDebug = CVarBasePassOutputsVelocityDebug . GetValueOnRenderThread ( ) ;
if ( bAllocateVelocityGBuffer )
2015-01-20 20:14:07 -05:00
{
FPooledRenderTargetDesc VelocityRTDesc = FVelocityRendering : : GetRenderTargetDesc ( ) ;
GRenderTargetPool . FindFreeElement ( VelocityRTDesc , GBufferVelocity , TEXT ( " GBufferVelocity " ) ) ;
}
2014-05-08 17:58:14 -04:00
// otherwise we have a severe problem
check ( GBufferA ) ;
2014-05-16 17:29:16 -04:00
2014-06-05 16:38:54 -04:00
// Create the required render targets if running Highend.
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-06-05 16:38:54 -04:00
{
// Allocate the Gbuffer resource uniform buffer.
2015-04-10 11:23:49 -04:00
const FSceneRenderTargetItem & GBufferAToUse = GBufferA ? GBufferA - > GetRenderTargetItem ( ) : GSystemTextures . BlackDummy - > GetRenderTargetItem ( ) ;
const FSceneRenderTargetItem & GBufferBToUse = GBufferB ? GBufferB - > GetRenderTargetItem ( ) : GSystemTextures . BlackDummy - > GetRenderTargetItem ( ) ;
const FSceneRenderTargetItem & GBufferCToUse = GBufferC ? GBufferC - > GetRenderTargetItem ( ) : GSystemTextures . BlackDummy - > GetRenderTargetItem ( ) ;
const FSceneRenderTargetItem & GBufferDToUse = GBufferD ? GBufferD - > GetRenderTargetItem ( ) : GSystemTextures . BlackDummy - > GetRenderTargetItem ( ) ;
const FSceneRenderTargetItem & GBufferEToUse = GBufferE ? GBufferE - > GetRenderTargetItem ( ) : GSystemTextures . BlackDummy - > GetRenderTargetItem ( ) ;
const FSceneRenderTargetItem & GBufferVelocityToUse = GBufferVelocity ? GBufferVelocity - > GetRenderTargetItem ( ) : GSystemTextures . BlackDummy - > GetRenderTargetItem ( ) ;
2014-06-05 16:38:54 -04:00
FGBufferResourceStruct GBufferResourceStruct ;
2015-04-10 11:23:49 -04:00
GBufferResourceStruct . GBufferATexture = GBufferAToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferBTexture = GBufferBToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferCTexture = GBufferCToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferDTexture = GBufferDToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferETexture = GBufferEToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferVelocityTexture = GBufferVelocityToUse . ShaderResourceTexture ;
2014-06-05 16:38:54 -04:00
2015-04-10 11:23:49 -04:00
GBufferResourceStruct . GBufferATextureNonMS = GBufferAToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferBTextureNonMS = GBufferBToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferCTextureNonMS = GBufferCToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferDTextureNonMS = GBufferDToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferETextureNonMS = GBufferEToUse . ShaderResourceTexture ;
GBufferResourceStruct . GBufferVelocityTextureNonMS = GBufferVelocityToUse . ShaderResourceTexture ;
2014-06-05 16:38:54 -04:00
2015-04-10 11:23:49 -04:00
GBufferResourceStruct . GBufferATextureMS = GBufferAToUse . TargetableTexture ;
GBufferResourceStruct . GBufferBTextureMS = GBufferBToUse . TargetableTexture ;
GBufferResourceStruct . GBufferCTextureMS = GBufferCToUse . TargetableTexture ;
GBufferResourceStruct . GBufferDTextureMS = GBufferDToUse . TargetableTexture ;
GBufferResourceStruct . GBufferETextureMS = GBufferEToUse . TargetableTexture ;
GBufferResourceStruct . GBufferVelocityTextureMS = GBufferVelocityToUse . TargetableTexture ;
2014-06-05 16:38:54 -04:00
GBufferResourceStruct . GBufferATextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
GBufferResourceStruct . GBufferBTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
GBufferResourceStruct . GBufferCTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
GBufferResourceStruct . GBufferDTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
GBufferResourceStruct . GBufferETextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
2015-01-20 20:14:07 -05:00
GBufferResourceStruct . GBufferVelocityTextureSampler = TStaticSamplerState < > : : GetRHI ( ) ;
2014-06-05 16:38:54 -04:00
GBufferResourcesUniformBuffer = FGBufferResourceStruct : : CreateUniformBuffer ( GBufferResourceStruct , UniformBuffer_SingleFrame ) ;
}
2014-05-16 17:29:16 -04:00
// so that
GBufferRefCount = 1 ;
2014-05-08 17:58:14 -04:00
}
2014-05-06 11:27:50 -04:00
const TRefCountPtr < IPooledRenderTarget > & FSceneRenderTargets : : GetSceneColor ( ) const
{
2014-09-18 17:01:15 -04:00
if ( ! GetSceneColorForCurrentShadingPath ( ) )
2014-05-06 11:27:50 -04:00
{
// to avoid log/ensure spam
static bool bFirst = true ;
if ( bFirst )
{
bFirst = false ;
// the first called should be AllocSceneColor(), contact MartinM if that happens
2014-09-18 17:01:15 -04:00
ensure ( GetSceneColorForCurrentShadingPath ( ) ) ;
2014-05-06 11:27:50 -04:00
}
return GSystemTextures . BlackDummy ;
}
2014-09-18 17:01:15 -04:00
return GetSceneColorForCurrentShadingPath ( ) ;
2014-05-06 11:27:50 -04:00
}
2014-10-24 11:35:45 -04:00
bool FSceneRenderTargets : : IsSceneColorAllocated ( ) const
{
return GetSceneColorForCurrentShadingPath ( ) ! = 0 ;
}
2014-05-06 11:27:50 -04:00
TRefCountPtr < IPooledRenderTarget > & FSceneRenderTargets : : GetSceneColor ( )
{
2014-09-18 17:01:15 -04:00
if ( ! GetSceneColorForCurrentShadingPath ( ) )
2014-05-06 11:27:50 -04:00
{
// to avoid log/ensure spam
static bool bFirst = true ;
if ( bFirst )
{
bFirst = false ;
// the first called should be AllocSceneColor(), contact MartinM if that happens
2014-09-18 17:01:15 -04:00
ensure ( GetSceneColorForCurrentShadingPath ( ) ) ;
2014-05-06 11:27:50 -04:00
}
return GSystemTextures . BlackDummy ;
}
2014-09-18 17:01:15 -04:00
return GetSceneColorForCurrentShadingPath ( ) ;
2014-05-06 11:27:50 -04:00
}
void FSceneRenderTargets : : SetSceneColor ( IPooledRenderTarget * In )
{
2014-09-18 17:01:15 -04:00
check ( CurrentShadingPath < EShadingPath : : Num ) ;
SceneColor [ ( int32 ) CurrentShadingPath ] = In ;
2014-05-06 11:27:50 -04:00
}
void FSceneRenderTargets : : SetLightAttenuation ( IPooledRenderTarget * In )
{
LightAttenuation = In ;
}
const TRefCountPtr < IPooledRenderTarget > & FSceneRenderTargets : : GetLightAttenuation ( ) const
{
if ( ! LightAttenuation )
{
// to avoid log/ensure spam
static bool bFirst = true ;
if ( bFirst )
{
bFirst = false ;
// First we need to call AllocLightAttenuation(), contact MartinM if that happens
ensure ( LightAttenuation ) ;
}
return GSystemTextures . WhiteDummy ;
}
return LightAttenuation ;
}
TRefCountPtr < IPooledRenderTarget > & FSceneRenderTargets : : GetLightAttenuation ( )
{
if ( ! LightAttenuation )
{
// to avoid log/ensure spam
static bool bFirst = true ;
if ( bFirst )
{
bFirst = false ;
// the first called should be AllocLightAttenuation(), contact MartinM if that happens
ensure ( LightAttenuation ) ;
}
return GSystemTextures . WhiteDummy ;
}
return LightAttenuation ;
}
2014-05-16 17:29:16 -04:00
void FSceneRenderTargets : : AdjustGBufferRefCount ( int Delta )
{
2015-02-09 10:42:04 -05:00
if ( Delta > 0 & & GBufferRefCount = = 0 )
2014-05-16 17:29:16 -04:00
{
AllocGBufferTargets ( ) ;
}
2015-02-09 10:42:04 -05:00
else
2014-05-16 17:29:16 -04:00
{
2015-02-09 10:42:04 -05:00
GBufferRefCount + = Delta ;
if ( GBufferRefCount = = 0 )
{
ReleaseGBufferTargets ( ) ;
}
2014-05-16 17:29:16 -04:00
}
}
2014-05-06 11:27:50 -04:00
2014-06-27 11:07:13 -04:00
void FSceneRenderTargets : : FinishRenderingSceneColor ( FRHICommandListImmediate & RHICmdList , bool bKeepChanges , const FResolveRect & ResolveRect )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , FinishRenderingSceneColor ) ;
2014-03-14 14:13:41 -04:00
if ( bKeepChanges )
{
2014-06-27 11:07:13 -04:00
ResolveSceneColor ( RHICmdList ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-06-27 11:07:13 -04:00
bool FSceneRenderTargets : : BeginRenderingCustomDepth ( FRHICommandListImmediate & RHICmdList , bool bPrimitives )
2014-03-14 14:13:41 -04:00
{
2015-04-10 11:23:49 -04:00
IPooledRenderTarget * CustomDepthRenderTarget = RequestCustomDepth ( bPrimitives ) ;
2014-03-14 14:13:41 -04:00
2015-04-10 11:23:49 -04:00
if ( CustomDepthRenderTarget )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , BeginRenderingCustomDepth ) ;
2014-06-27 11:07:13 -04:00
2015-04-10 11:23:49 -04:00
SetRenderTarget ( RHICmdList , FTextureRHIRef ( ) , CustomDepthRenderTarget - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
2014-03-14 14:13:41 -04:00
return true ;
}
return false ;
}
2014-06-27 11:07:13 -04:00
void FSceneRenderTargets : : FinishRenderingCustomDepth ( FRHICommandListImmediate & RHICmdList , const FResolveRect & ResolveRect )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , FinishRenderingCustomDepth ) ;
2014-03-14 14:13:41 -04:00
2014-09-18 17:01:15 -04:00
auto & CurrentSceneColor = GetSceneColor ( ) ;
RHICmdList . CopyToResolveTarget ( CurrentSceneColor - > GetRenderTargetItem ( ) . TargetableTexture , CurrentSceneColor - > GetRenderTargetItem ( ) . ShaderResourceTexture , true , FResolveParams ( ResolveRect ) ) ;
2014-03-14 14:13:41 -04:00
bCustomDepthIsValid = true ;
}
/**
* Saves a previously rendered scene color target
*/
2014-07-09 11:02:23 -04:00
void FSceneRenderTargets : : ResolveSceneColor ( FRHICommandList & RHICmdList , const FResolveRect & ResolveRect )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , ResolveSceneColor ) ;
2014-03-14 14:13:41 -04:00
2014-09-18 17:01:15 -04:00
auto & CurrentSceneColor = GetSceneColor ( ) ;
2014-08-22 16:25:40 -04:00
2014-09-18 17:01:15 -04:00
uint32 samples = CurrentSceneColor - > GetDesc ( ) . NumSamples ;
if ( samples < = 1 | | GShaderPlatformForFeatureLevel [ CurrentFeatureLevel ] = = SP_METAL )
2014-08-22 16:25:40 -04:00
{
RHICmdList . CopyToResolveTarget ( GetSceneColorSurface ( ) , GetSceneColorTexture ( ) , true , FResolveParams ( ResolveRect ) ) ;
}
else
{
// Custom shader based color resolve for HDR color to emulate mobile.
SetRenderTarget ( RHICmdList , GetSceneColorTexture ( ) , FTextureRHIParamRef ( ) ) ;
2014-08-25 13:26:32 -04:00
if ( ResolveRect . IsValid ( ) )
{
RHICmdList . SetScissorRect ( true , ResolveRect . X1 , ResolveRect . Y1 , ResolveRect . X2 , ResolveRect . Y2 ) ;
}
else
{
RHICmdList . SetScissorRect ( false , 0 , 0 , 0 , 0 ) ;
}
2014-08-22 16:25:40 -04:00
RHICmdList . SetBlendState ( TStaticBlendState < > : : GetRHI ( ) ) ;
RHICmdList . SetRasterizerState ( TStaticRasterizerState < > : : GetRHI ( ) ) ;
RHICmdList . SetDepthStencilState ( TStaticDepthStencilState < false , CF_Always > : : GetRHI ( ) ) ;
2014-08-28 06:22:54 -04:00
auto ShaderMap = GetGlobalShaderMap ( CurrentFeatureLevel ) ;
TShaderMapRef < FHdrCustomResolveVS > VertexShader ( ShaderMap ) ;
2014-08-22 16:25:40 -04:00
if ( samples = = 2 )
{
2014-08-28 06:22:54 -04:00
TShaderMapRef < FHdrCustomResolve2xPS > PixelShader ( ShaderMap ) ;
2014-08-22 16:25:40 -04:00
static FGlobalBoundShaderState BoundShaderState ;
SetGlobalBoundShaderState ( RHICmdList , CurrentFeatureLevel , BoundShaderState , GetVertexDeclarationFVector4 ( ) , * VertexShader , * PixelShader ) ;
2014-09-18 17:01:15 -04:00
PixelShader - > SetParameters ( RHICmdList , CurrentSceneColor - > GetRenderTargetItem ( ) . TargetableTexture ) ;
2014-08-22 16:25:40 -04:00
RHICmdList . DrawPrimitive ( PT_TriangleList , 0 , 1 , 1 ) ;
}
else if ( samples = = 4 )
{
2014-08-28 06:22:54 -04:00
TShaderMapRef < FHdrCustomResolve4xPS > PixelShader ( ShaderMap ) ;
2014-08-22 16:25:40 -04:00
static FGlobalBoundShaderState BoundShaderState ;
SetGlobalBoundShaderState ( RHICmdList , CurrentFeatureLevel , BoundShaderState , GetVertexDeclarationFVector4 ( ) , * VertexShader , * PixelShader ) ;
2014-09-18 17:01:15 -04:00
PixelShader - > SetParameters ( RHICmdList , CurrentSceneColor - > GetRenderTargetItem ( ) . TargetableTexture ) ;
2014-08-22 16:25:40 -04:00
RHICmdList . DrawPrimitive ( PT_TriangleList , 0 , 1 , 1 ) ;
}
else if ( samples = = 8 )
{
2014-08-28 06:22:54 -04:00
TShaderMapRef < FHdrCustomResolve8xPS > PixelShader ( ShaderMap ) ;
2014-08-22 16:25:40 -04:00
static FGlobalBoundShaderState BoundShaderState ;
SetGlobalBoundShaderState ( RHICmdList , CurrentFeatureLevel , BoundShaderState , GetVertexDeclarationFVector4 ( ) , * VertexShader , * PixelShader ) ;
2014-09-18 17:01:15 -04:00
PixelShader - > SetParameters ( RHICmdList , CurrentSceneColor - > GetRenderTargetItem ( ) . TargetableTexture ) ;
2014-08-22 16:25:40 -04:00
RHICmdList . DrawPrimitive ( PT_TriangleList , 0 , 1 , 1 ) ;
}
else
{
// Everything other than 2,4,8 samples is not implemented.
check ( 0 ) ;
}
}
2014-03-14 14:13:41 -04:00
}
/** Resolves the GBuffer targets so that their resolved textures can be sampled. */
2014-07-09 11:02:23 -04:00
void FSceneRenderTargets : : ResolveGBufferSurfaces ( FRHICommandList & RHICmdList , const FResolveRect & ResolveRect )
2014-03-14 14:13:41 -04:00
{
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , ResolveGBufferSurfaces ) ;
2014-03-14 14:13:41 -04:00
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( GSceneRenderTargets . GBufferA - > GetRenderTargetItem ( ) . TargetableTexture , GSceneRenderTargets . GBufferA - > GetRenderTargetItem ( ) . ShaderResourceTexture , true , FResolveParams ( ResolveRect ) ) ;
RHICmdList . CopyToResolveTarget ( GSceneRenderTargets . GBufferB - > GetRenderTargetItem ( ) . TargetableTexture , GSceneRenderTargets . GBufferB - > GetRenderTargetItem ( ) . ShaderResourceTexture , true , FResolveParams ( ResolveRect ) ) ;
RHICmdList . CopyToResolveTarget ( GSceneRenderTargets . GBufferC - > GetRenderTargetItem ( ) . TargetableTexture , GSceneRenderTargets . GBufferC - > GetRenderTargetItem ( ) . ShaderResourceTexture , true , FResolveParams ( ResolveRect ) ) ;
RHICmdList . CopyToResolveTarget ( GSceneRenderTargets . GBufferD - > GetRenderTargetItem ( ) . TargetableTexture , GSceneRenderTargets . GBufferD - > GetRenderTargetItem ( ) . ShaderResourceTexture , true , FResolveParams ( ResolveRect ) ) ;
2014-03-14 14:13:41 -04:00
if ( bAllowStaticLighting )
{
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( GSceneRenderTargets . GBufferE - > GetRenderTargetItem ( ) . TargetableTexture , GSceneRenderTargets . GBufferE - > GetRenderTargetItem ( ) . ShaderResourceTexture , true , FResolveParams ( ResolveRect ) ) ;
2014-03-14 14:13:41 -04:00
}
2015-01-20 20:14:07 -05:00
2015-02-02 18:00:05 -05:00
if ( bAllocateVelocityGBuffer )
2015-01-20 20:14:07 -05:00
{
RHICmdList . CopyToResolveTarget ( GSceneRenderTargets . GBufferVelocity - > GetRenderTargetItem ( ) . TargetableTexture , GSceneRenderTargets . GBufferVelocity - > GetRenderTargetItem ( ) . ShaderResourceTexture , true , FResolveParams ( ResolveRect ) ) ;
}
2014-03-14 14:13:41 -04:00
}
}
2015-01-27 16:14:50 -05:00
void FSceneRenderTargets : : BeginRenderingPrePass ( FRHICommandList & RHICmdList , bool bPerformClear )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , BeginRenderingPrePass ) ;
2014-03-14 14:13:41 -04:00
2015-01-27 16:14:50 -05:00
FTextureRHIRef ColorTarget ;
FTexture2DRHIRef DepthTarget = GetSceneDepthSurface ( ) ;
2015-03-31 14:02:45 -04:00
const float DepthClearValue = ( float ) ERHIZBuffer : : FarPlane ;
2015-01-27 16:14:50 -05:00
const uint32 StencilClearValue = 0 ;
if ( bPerformClear )
{
FRHIRenderTargetView ColorView ( ColorTarget , 0 , - 1 , ERenderTargetLoadAction : : ENoAction , ERenderTargetStoreAction : : ENoAction ) ;
FRHIDepthRenderTargetView DepthView ( DepthTarget , ERenderTargetLoadAction : : EClear , ERenderTargetStoreAction : : EStore ) ;
// Clear the depth buffer.
// Note, this is a reversed Z depth surface, so 0.0f is the far plane.
FRHISetRenderTargetsInfo Info ( 1 , & ColorView , DepthView ) ;
Info . DepthClearValue = DepthClearValue ;
Info . StencilClearValue = StencilClearValue ;
RHICmdList . SetRenderTargetsAndClear ( Info ) ;
bSceneDepthCleared = true ;
SceneDepthClearValue = DepthClearValue ;
}
else
{
// Set the scene depth surface and a DUMMY buffer as color buffer
// (as long as it's the same dimension as the depth buffer),
SetRenderTarget ( RHICmdList , FTextureRHIRef ( ) , GetSceneDepthSurface ( ) ) ;
RHICmdList . BindClearMRTValues ( false , 0 , nullptr , true , DepthClearValue , true , StencilClearValue ) ;
}
2014-03-14 14:13:41 -04:00
}
2014-06-27 11:07:13 -04:00
void FSceneRenderTargets : : FinishRenderingPrePass ( FRHICommandListImmediate & RHICmdList )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , FinishRenderingPrePass ) ;
2014-06-12 07:13:34 -04:00
GRenderTargetPool . VisualizeTexture . SetCheckPoint ( RHICmdList , SceneDepthZ ) ;
2014-03-14 14:13:41 -04:00
}
2014-10-02 11:20:07 -04:00
void FSceneRenderTargets : : BeginRenderingShadowDepth ( FRHICommandList & RHICmdList , bool bClear )
2014-03-14 14:13:41 -04:00
{
2014-06-12 07:13:34 -04:00
GRenderTargetPool . VisualizeTexture . SetCheckPoint ( RHICmdList , ShadowDepthZ ) ;
2014-10-27 13:57:37 -04:00
//All of the shadow passes are written using 'clear stencil after', so keep stencil as-is
FRHISetRenderTargetsInfo Info ( 0 , nullptr , FRHIDepthRenderTargetView ( GetShadowDepthZSurface ( ) ,
bClear ? ERenderTargetLoadAction : : EClear : ERenderTargetLoadAction : : ELoad ,
ERenderTargetStoreAction : : EStore ,
ERenderTargetLoadAction : : ELoad ,
ERenderTargetStoreAction : : EStore ) ) ;
2014-10-23 16:31:43 -04:00
Info . DepthClearValue = 1.0f ;
2014-09-16 14:51:25 -04:00
Info . ColorRenderTarget [ 0 ] . StoreAction = ERenderTargetStoreAction : : ENoAction ;
if ( ! GSupportsDepthRenderTargetWithoutColorRenderTarget )
2014-09-10 18:24:48 -04:00
{
2014-09-16 14:51:25 -04:00
Info . NumColorRenderTargets = 1 ;
Info . ColorRenderTarget [ 0 ] . Texture = GetOptionalShadowDepthColorSurface ( ) ;
2014-09-10 18:24:48 -04:00
}
2014-09-16 14:51:25 -04:00
RHICmdList . SetRenderTargetsAndClear ( Info ) ;
2014-03-14 14:13:41 -04:00
}
2014-10-02 11:20:07 -04:00
void FSceneRenderTargets : : BeginRenderingCubeShadowDepth ( FRHICommandList & RHICmdList , int32 ShadowResolution )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , BeginRenderingCubeShadowDepth ) ;
2014-06-12 07:13:34 -04:00
SetRenderTarget ( RHICmdList , FTextureRHIRef ( ) , GetCubeShadowDepthZSurface ( ShadowResolution ) ) ;
2014-03-14 14:13:41 -04:00
}
2014-07-09 11:02:23 -04:00
void FSceneRenderTargets : : FinishRenderingShadowDepth ( FRHICommandList & RHICmdList , const FResolveRect & ResolveRect )
2014-03-14 14:13:41 -04:00
{
// Resolve the shadow depth z surface.
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( GetShadowDepthZSurface ( ) , GetShadowDepthZTexture ( ) , false , FResolveParams ( ResolveRect ) ) ;
2014-03-14 14:13:41 -04:00
}
2014-10-02 11:20:07 -04:00
void FSceneRenderTargets : : BeginRenderingReflectiveShadowMap ( FRHICommandList & RHICmdList , FLightPropagationVolume * Lpv )
2014-03-14 14:13:41 -04:00
{
FTextureRHIParamRef RenderTargets [ 2 ] ;
RenderTargets [ 0 ] = GetReflectiveShadowMapNormalSurface ( ) ;
RenderTargets [ 1 ] = GetReflectiveShadowMapDiffuseSurface ( ) ;
// Hook up the geometry volume UAVs
FUnorderedAccessViewRHIParamRef Uavs [ 4 ] ;
Uavs [ 0 ] = Lpv - > GetGvListBufferUav ( ) ;
Uavs [ 1 ] = Lpv - > GetGvListHeadBufferUav ( ) ;
Uavs [ 2 ] = Lpv - > GetVplListBufferUav ( ) ;
Uavs [ 3 ] = Lpv - > GetVplListHeadBufferUav ( ) ;
2014-06-27 11:07:13 -04:00
2014-06-12 07:13:34 -04:00
SetRenderTargets ( RHICmdList , ARRAY_COUNT ( RenderTargets ) , RenderTargets , GetReflectiveShadowMapDepthSurface ( ) , 4 , Uavs ) ;
2014-03-14 14:13:41 -04:00
}
2014-07-09 11:02:23 -04:00
void FSceneRenderTargets : : FinishRenderingReflectiveShadowMap ( FRHICommandList & RHICmdList , const FResolveRect & ResolveRect )
2014-03-14 14:13:41 -04:00
{
// Resolve the shadow depth z surface.
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( GetReflectiveShadowMapDepthSurface ( ) , GetReflectiveShadowMapDepthTexture ( ) , false , FResolveParams ( ResolveRect ) ) ;
RHICmdList . CopyToResolveTarget ( GetReflectiveShadowMapDiffuseSurface ( ) , GetReflectiveShadowMapDiffuseTexture ( ) , false , FResolveParams ( ResolveRect ) ) ;
RHICmdList . CopyToResolveTarget ( GetReflectiveShadowMapNormalSurface ( ) , GetReflectiveShadowMapNormalTexture ( ) , false , FResolveParams ( ResolveRect ) ) ;
2014-03-14 14:13:41 -04:00
// Unset render targets
FTextureRHIParamRef RenderTargets [ 2 ] = { NULL } ;
FUnorderedAccessViewRHIParamRef Uavs [ 2 ] = { NULL } ;
2014-06-12 07:13:34 -04:00
SetRenderTargets ( RHICmdList , ARRAY_COUNT ( RenderTargets ) , RenderTargets , FTextureRHIParamRef ( ) , 2 , Uavs ) ;
2014-03-14 14:13:41 -04:00
}
2015-01-27 16:14:50 -05:00
void FSceneRenderTargets : : FinishRenderingCubeShadowDepth ( FRHICommandList & RHICmdList , int32 ShadowResolution )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , FinishRenderingCubeShadowDepth ) ;
2015-01-27 16:14:50 -05:00
RHICmdList . CopyToResolveTarget ( GetCubeShadowDepthZSurface ( ShadowResolution ) , GetCubeShadowDepthZTexture ( ShadowResolution ) , false , FResolveParams ( FResolveRect ( ) , CubeFace_PosX , - 1 , - 1 , 0 ) ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-27 11:07:13 -04:00
void FSceneRenderTargets : : BeginRenderingSceneAlphaCopy ( FRHICommandListImmediate & RHICmdList )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , BeginRenderingSceneAlphaCopy ) ;
2014-06-12 07:13:34 -04:00
GRenderTargetPool . VisualizeTexture . SetCheckPoint ( RHICmdList , GSceneRenderTargets . SceneAlphaCopy ) ;
SetRenderTarget ( RHICmdList , GetSceneAlphaCopySurface ( ) , 0 ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-27 11:07:13 -04:00
void FSceneRenderTargets : : FinishRenderingSceneAlphaCopy ( FRHICommandListImmediate & RHICmdList )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , FinishRenderingSceneAlphaCopy ) ;
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( GetSceneAlphaCopySurface ( ) , SceneAlphaCopy - > GetRenderTargetItem ( ) . ShaderResourceTexture , false , FResolveParams ( FResolveRect ( ) ) ) ;
2014-06-12 07:13:34 -04:00
GRenderTargetPool . VisualizeTexture . SetCheckPoint ( RHICmdList , GSceneRenderTargets . SceneAlphaCopy ) ;
2014-03-14 14:13:41 -04:00
}
2014-10-23 16:31:43 -04:00
void FSceneRenderTargets : : BeginRenderingLightAttenuation ( FRHICommandList & RHICmdList , bool bClearToWhite )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , BeginRenderingLightAttenuation ) ;
2014-03-14 14:13:41 -04:00
2014-05-06 11:27:50 -04:00
AllocLightAttenuation ( ) ;
2014-06-12 07:13:34 -04:00
GRenderTargetPool . VisualizeTexture . SetCheckPoint ( RHICmdList , GSceneRenderTargets . GetLightAttenuation ( ) ) ;
2014-03-14 14:13:41 -04:00
// Set the light attenuation surface as the render target, and the scene depth buffer as the depth-stencil surface.
2015-04-08 15:33:28 -04:00
SetRenderTarget ( RHICmdList , GetLightAttenuationSurface ( ) , GetSceneDepthSurface ( ) , bClearToWhite ? ESimpleRenderTargetMode : : EClearColorToWhite : ESimpleRenderTargetMode : : EExistingColorAndDepth , FExclusiveDepthStencil : : DepthRead_StencilWrite ) ;
2014-03-14 14:13:41 -04:00
}
2014-08-04 12:04:27 -04:00
void FSceneRenderTargets : : FinishRenderingLightAttenuation ( FRHICommandList & RHICmdList )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , FinishRenderingLightAttenuation ) ;
2014-03-14 14:13:41 -04:00
// Resolve the light attenuation surface.
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( GetLightAttenuationSurface ( ) , LightAttenuation - > GetRenderTargetItem ( ) . ShaderResourceTexture , false , FResolveParams ( FResolveRect ( ) ) ) ;
2014-03-14 14:13:41 -04:00
2014-06-12 07:13:34 -04:00
GRenderTargetPool . VisualizeTexture . SetCheckPoint ( RHICmdList , GSceneRenderTargets . GetLightAttenuation ( ) ) ;
2014-03-14 14:13:41 -04:00
}
2014-08-04 12:04:27 -04:00
void FSceneRenderTargets : : BeginRenderingTranslucency ( FRHICommandList & RHICmdList , const FViewInfo & View )
2014-03-14 14:13:41 -04:00
{
// Use the scene color buffer.
2015-04-08 15:33:28 -04:00
GSceneRenderTargets . BeginRenderingSceneColor ( RHICmdList , ESimpleRenderTargetMode : : EExistingColorAndDepth , FExclusiveDepthStencil : : DepthRead_StencilWrite ) ;
2014-03-14 14:13:41 -04:00
// viewport to match view size
2014-06-27 11:07:13 -04:00
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
2014-03-14 14:13:41 -04:00
}
2015-01-27 16:14:50 -05:00
void FSceneRenderTargets : : FinishRenderingTranslucency ( FRHICommandListImmediate & RHICmdList , const class FViewInfo & View )
{
GSceneRenderTargets . FinishRenderingSceneColor ( RHICmdList , true ) ;
}
2014-03-14 14:13:41 -04:00
2014-08-04 12:04:27 -04:00
bool FSceneRenderTargets : : BeginRenderingSeparateTranslucency ( FRHICommandList & RHICmdList , const FViewInfo & View , bool bFirstTimeThisFrame )
2014-03-14 14:13:41 -04:00
{
if ( IsSeparateTranslucencyActive ( View ) )
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , BeginSeparateTranslucency ) ;
2014-03-14 14:13:41 -04:00
FSceneViewState * ViewState = ( FSceneViewState * ) View . State ;
// the RT should only be available for a short period during rendering
if ( bFirstTimeThisFrame )
{
check ( ! ViewState - > SeparateTranslucencyRT ) ;
}
TRefCountPtr < IPooledRenderTarget > & SeparateTranslucency = ViewState - > GetSeparateTranslucency ( View ) ;
2014-10-23 16:31:43 -04:00
// clear the render target the first time, re-use afterwards
SetRenderTarget ( RHICmdList , SeparateTranslucency - > GetRenderTargetItem ( ) . TargetableTexture , GetSceneDepthSurface ( ) ,
2015-04-08 15:33:28 -04:00
bFirstTimeThisFrame ? ESimpleRenderTargetMode : : EClearColorToBlackWithFullAlpha : ESimpleRenderTargetMode : : EExistingColorAndDepth , FExclusiveDepthStencil : : DepthRead_StencilWrite ) ;
2015-01-27 16:14:50 -05:00
if ( ! bFirstTimeThisFrame )
{
FLinearColor ClearColor ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
2015-03-31 14:02:45 -04:00
RHICmdList . BindClearMRTValues ( true , 1 , & ClearColor , false , ( float ) ERHIZBuffer : : FarPlane , false , 0 ) ;
2015-01-27 16:14:50 -05:00
}
2014-03-14 14:13:41 -04:00
2014-06-27 11:07:13 -04:00
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
2014-03-14 14:13:41 -04:00
return true ;
}
return false ;
}
2014-07-09 11:02:23 -04:00
void FSceneRenderTargets : : FinishRenderingSeparateTranslucency ( FRHICommandList & RHICmdList , const FViewInfo & View )
2014-03-14 14:13:41 -04:00
{
if ( IsSeparateTranslucencyActive ( View ) )
{
2015-01-27 16:14:50 -05:00
SCOPED_DRAW_EVENT ( RHICmdList , FinishSeparateTranslucency ) ;
2014-03-14 14:13:41 -04:00
FSceneViewState * ViewState = ( FSceneViewState * ) View . State ;
TRefCountPtr < IPooledRenderTarget > & SeparateTranslucency = ViewState - > GetSeparateTranslucency ( View ) ;
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( SeparateTranslucency - > GetRenderTargetItem ( ) . TargetableTexture , SeparateTranslucency - > GetRenderTargetItem ( ) . ShaderResourceTexture , true , FResolveParams ( ) ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-07-09 11:02:23 -04:00
void FSceneRenderTargets : : ResolveSceneDepthTexture ( FRHICommandList & RHICmdList )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , ResolveSceneDepthTexture ) ;
2014-03-14 14:13:41 -04:00
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( GetSceneDepthSurface ( ) , GetSceneDepthTexture ( ) , true , FResolveParams ( ) ) ;
2014-03-14 14:13:41 -04:00
}
2014-07-09 11:02:23 -04:00
void FSceneRenderTargets : : ResolveSceneDepthToAuxiliaryTexture ( FRHICommandList & RHICmdList )
2014-03-14 14:13:41 -04:00
{
2014-04-02 18:09:23 -04:00
// Resolve the scene depth to an auxiliary texture when SM3/SM4 is in use. This needs to happen so the auxiliary texture can be bound as a shader parameter
// while the primary scene depth texture can be bound as the target. Simultaneously binding a single DepthStencil resource as a parameter and target
// is unsupported in d3d feature level 10.
if ( ! GSupportsDepthFetchDuringDepthTest )
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , ResolveSceneDepthToAuxiliaryTexture ) ;
2014-03-14 14:13:41 -04:00
2014-06-27 11:07:13 -04:00
RHICmdList . CopyToResolveTarget ( GetSceneDepthSurface ( ) , GetAuxiliarySceneDepthTexture ( ) , true , FResolveParams ( ) ) ;
2014-04-02 18:09:23 -04:00
}
2014-03-14 14:13:41 -04:00
}
void FSceneRenderTargets : : CleanUpEditorPrimitiveTargets ( )
{
EditorPrimitivesDepth . SafeRelease ( ) ;
EditorPrimitivesColor . SafeRelease ( ) ;
}
int32 FSceneRenderTargets : : GetEditorMSAACompositingSampleCount ( ) const
{
int32 Value = 1 ;
// only supported on SM5 yet (SM4 doesn't have MSAA sample load functionality which makes it harder to implement)
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM5 )
2014-03-14 14:13:41 -04:00
{
static const auto CVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.MSAA.CompositingSampleCount " ) ) ;
Value = CVar - > GetValueOnRenderThread ( ) ;
if ( Value < = 1 )
{
Value = 1 ;
}
else if ( Value < = 2 )
{
Value = 2 ;
}
else if ( Value < = 4 )
{
Value = 4 ;
}
else
{
Value = 8 ;
}
}
return Value ;
}
const FTexture2DRHIRef & FSceneRenderTargets : : GetEditorPrimitivesColor ( )
{
const bool bIsValid = IsValidRef ( EditorPrimitivesColor ) ;
if ( ! bIsValid | | EditorPrimitivesColor - > GetDesc ( ) . NumSamples ! = GetEditorMSAACompositingSampleCount ( ) )
{
// If the target is does not match the MSAA settings it needs to be recreated
InitEditorPrimitivesColor ( ) ;
}
return ( const FTexture2DRHIRef & ) EditorPrimitivesColor - > GetRenderTargetItem ( ) . TargetableTexture ;
}
const FTexture2DRHIRef & FSceneRenderTargets : : GetEditorPrimitivesDepth ( )
{
const bool bIsValid = IsValidRef ( EditorPrimitivesDepth ) ;
if ( ! bIsValid | | EditorPrimitivesDepth - > GetDesc ( ) . NumSamples ! = GetEditorMSAACompositingSampleCount ( ) )
{
// If the target is does not match the MSAA settings it needs to be recreated
InitEditorPrimitivesDepth ( ) ;
}
return ( const FTexture2DRHIRef & ) EditorPrimitivesDepth - > GetRenderTargetItem ( ) . TargetableTexture ;
}
2014-06-25 05:47:33 -04:00
static TAutoConsoleVariable < int32 > CVarSetSeperateTranslucencyEnabled (
TEXT ( " r.SeparateTranslucency " ) ,
1 ,
TEXT ( " Allows to disable the separate translucency feature (all translucency is rendered in separate RT and composited \n " )
TEXT ( " after DOF, if not specified otherwise in the material). \n " )
TEXT ( " 0: off (translucency is affected by depth of field) \n " )
2015-03-02 08:09:46 -05:00
TEXT ( " 1: on costs GPU performance and memory but keeps translucency unaffected by Depth of Field. (default) " ) ,
2014-06-25 05:47:33 -04:00
ECVF_RenderThreadSafe ) ;
2014-03-14 14:13:41 -04:00
bool FSceneRenderTargets : : IsSeparateTranslucencyActive ( const FViewInfo & View ) const
{
static const auto CVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.SeparateTranslucency " ) ) ;
int32 Value = CVar - > GetValueOnRenderThread ( ) ;
2014-07-10 10:39:54 -04:00
return ( Value ! = 0 ) & & CurrentFeatureLevel > = ERHIFeatureLevel : : SM4
2014-03-14 14:13:41 -04:00
& & View . Family - > EngineShowFlags . PostProcessing
& & View . Family - > EngineShowFlags . SeparateTranslucency
& & View . State ! = NULL ; // We require a ViewState in order for separate translucency to work (it keeps track of our SeparateTranslucencyRT)
}
void FSceneRenderTargets : : InitEditorPrimitivesColor ( )
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize ,
PF_B8G8R8A8 ,
TexCreate_None ,
TexCreate_ShaderResource | TexCreate_RenderTargetable ,
false ) ) ;
Desc . NumSamples = GetEditorMSAACompositingSampleCount ( ) ;
GRenderTargetPool . FindFreeElement ( Desc , EditorPrimitivesColor , TEXT ( " EditorPrimitivesColor " ) ) ;
}
void FSceneRenderTargets : : InitEditorPrimitivesDepth ( )
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize ,
PF_DepthStencil ,
TexCreate_None ,
TexCreate_ShaderResource | TexCreate_DepthStencilTargetable ,
false ) ) ;
Desc . NumSamples = GetEditorMSAACompositingSampleCount ( ) ;
GRenderTargetPool . FindFreeElement ( Desc , EditorPrimitivesDepth , TEXT ( " EditorPrimitivesDepth " ) ) ;
}
void FSceneRenderTargets : : QuantizeBufferSize ( int32 & InOutBufferSizeX , int32 & InOutBufferSizeY ) const
{
// ensure sizes are dividable by DividableBy to get post processing effects with lower resolution working well
const uint32 DividableBy = 8 ;
const uint32 Mask = ~ ( DividableBy - 1 ) ;
InOutBufferSizeX = ( InOutBufferSizeX + DividableBy - 1 ) & Mask ;
InOutBufferSizeY = ( InOutBufferSizeY + DividableBy - 1 ) & Mask ;
}
void FSceneRenderTargets : : SetBufferSize ( int32 InBufferSizeX , int32 InBufferSizeY )
{
QuantizeBufferSize ( InBufferSizeX , InBufferSizeY ) ;
BufferSize . X = InBufferSizeX ;
BufferSize . Y = InBufferSizeY ;
}
void FSceneRenderTargets : : AllocateForwardShadingPathRenderTargets ( )
{
2014-05-21 14:57:15 -04:00
// on ES2 we don't do on demand allocation of SceneColor yet (in non ES2 it's released in the Tonemapper Process())
AllocSceneColor ( ) ;
2014-09-18 17:01:15 -04:00
AllocateCommonDepthTargets ( ) ;
AllocateReflectionTargets ( ) ;
2014-05-21 14:57:15 -04:00
2014-09-18 17:01:15 -04:00
EPixelFormat Format = GetSceneColor ( ) - > GetDesc ( ) . Format ;
2014-05-21 15:07:18 -04:00
2014-03-14 14:13:41 -04:00
// For 64-bit ES2 without framebuffer fetch, create extra render target for copy of alpha channel.
if ( ( Format = = PF_FloatRGBA ) & & ( GSupportsShaderFramebufferFetch = = false ) )
{
# if PLATFORM_HTML5 || PLATFORM_ANDROID
// creating a PF_R16F (a true one-channel renderable fp texture) is only supported on GL if EXT_texture_rg is available. It's present
// on iOS, but not in WebGL or Android.
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_FloatRGBA , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
# else
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_R16F , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
# endif
GRenderTargetPool . FindFreeElement ( Desc , SceneAlphaCopy , TEXT ( " SceneAlphaCopy " ) ) ;
}
else
{
SceneAlphaCopy = GSystemTextures . MaxFP16Depth ;
}
2014-08-25 16:47:22 -04:00
}
void FSceneRenderTargets : : AllocateForwardShadingShadowDepthTarget ( const FIntPoint & ShadowBufferResolution )
{
2015-04-10 11:23:49 -04:00
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( ShadowBufferResolution , PF_ShadowDepth , TexCreate_None , TexCreate_DepthStencilTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , ShadowDepthZ , TEXT ( " ShadowDepthZ " ) ) ;
}
2014-09-10 18:24:48 -04:00
if ( ! GSupportsDepthRenderTargetWithoutColorRenderTarget )
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( ShadowBufferResolution , PF_B8G8R8A8 , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , OptionalShadowDepthColor , TEXT ( " OptionalShadowDepthColor " ) ) ;
}
2014-03-14 14:13:41 -04:00
}
// for easier use of "VisualizeTexture"
static TCHAR * const GetVolumeName ( uint32 Id , bool bDirectional )
{
// (TCHAR*) for non VisualStudio
switch ( Id )
{
case 0 : return bDirectional ? ( TCHAR * ) TEXT ( " TranslucentVolumeDir0 " ) : ( TCHAR * ) TEXT ( " TranslucentVolume0 " ) ;
case 1 : return bDirectional ? ( TCHAR * ) TEXT ( " TranslucentVolumeDir1 " ) : ( TCHAR * ) TEXT ( " TranslucentVolume1 " ) ;
case 2 : return bDirectional ? ( TCHAR * ) TEXT ( " TranslucentVolumeDir2 " ) : ( TCHAR * ) TEXT ( " TranslucentVolume2 " ) ;
default :
check ( 0 ) ;
}
return ( TCHAR * ) TEXT ( " InvalidName " ) ;
}
2014-05-07 11:04:46 -04:00
// for easier use of "VisualizeTexture"
static TCHAR * const GetTranslucencyShadowTransmissionName ( uint32 Id )
{
// (TCHAR*) for non VisualStudio
switch ( Id )
{
case 0 : return ( TCHAR * ) TEXT ( " TranslucencyShadowTransmission0 " ) ;
case 1 : return ( TCHAR * ) TEXT ( " TranslucencyShadowTransmission1 " ) ;
default :
check ( 0 ) ;
}
return ( TCHAR * ) TEXT ( " InvalidName " ) ;
}
2014-08-25 16:47:22 -04:00
void FSceneRenderTargets : : AllocateReflectionTargets ( )
{
2014-09-12 17:21:49 -04:00
if ( GSupportsRenderTargetFormat_PF_FloatRGBA )
2014-08-25 16:47:22 -04:00
{
2014-09-18 17:01:15 -04:00
// Reflection targets are shared between both forward and deferred shading paths. If we have already allocated for one and are now allocating for the other,
// we can skip these targets.
bool bSharedReflectionTargetsAllocated = ReflectionColorScratchCubemap [ 0 ] ! = nullptr ;
2014-08-25 16:47:22 -04:00
2014-09-18 17:01:15 -04:00
if ( ! bSharedReflectionTargetsAllocated )
2014-08-25 16:47:22 -04:00
{
2014-09-18 17:01:15 -04:00
extern ENGINE_API int32 GReflectionCaptureSize ;
const int32 NumReflectionCaptureMips = FMath : : CeilLogTwo ( GReflectionCaptureSize ) + 1 ;
2014-08-25 16:47:22 -04:00
2014-09-18 17:01:15 -04:00
// We write to these cubemap faces individually during filtering
uint32 CubeTexFlags = TexCreate_TargetArraySlicesIndependently ;
{
// Create scratch cubemaps for filtering passes
FPooledRenderTargetDesc Desc2 ( FPooledRenderTargetDesc : : CreateCubemapDesc ( GReflectionCaptureSize , PF_FloatRGBA , CubeTexFlags , TexCreate_RenderTargetable , false , 1 , NumReflectionCaptureMips ) ) ;
GRenderTargetPool . FindFreeElement ( Desc2 , ReflectionColorScratchCubemap [ 0 ] , TEXT ( " ReflectionColorScratchCubemap0 " ) ) ;
GRenderTargetPool . FindFreeElement ( Desc2 , ReflectionColorScratchCubemap [ 1 ] , TEXT ( " ReflectionColorScratchCubemap1 " ) ) ;
}
extern int32 GDiffuseIrradianceCubemapSize ;
const int32 NumDiffuseIrradianceMips = FMath : : CeilLogTwo ( GDiffuseIrradianceCubemapSize ) + 1 ;
{
FPooledRenderTargetDesc Desc2 ( FPooledRenderTargetDesc : : CreateCubemapDesc ( GDiffuseIrradianceCubemapSize , PF_FloatRGBA , CubeTexFlags , TexCreate_RenderTargetable , false , 1 , NumDiffuseIrradianceMips ) ) ;
GRenderTargetPool . FindFreeElement ( Desc2 , DiffuseIrradianceScratchCubemap [ 0 ] , TEXT ( " DiffuseIrradianceScratchCubemap0 " ) ) ;
GRenderTargetPool . FindFreeElement ( Desc2 , DiffuseIrradianceScratchCubemap [ 1 ] , TEXT ( " DiffuseIrradianceScratchCubemap1 " ) ) ;
}
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( FIntPoint ( FSHVector3 : : MaxSHBasis , 1 ) , PF_FloatRGBA , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , SkySHIrradianceMap , TEXT ( " SkySHIrradianceMap " ) ) ;
}
}
auto & ReflectionBrightnessTarget = GetReflectionBrightnessTarget ( ) ;
if ( ! ReflectionBrightnessTarget )
{
bool bSupportsR32Float = CurrentFeatureLevel > ERHIFeatureLevel : : ES2 ;
2015-01-08 17:57:40 -05:00
//@todo: FScene::UpdateSkyCaptureContents() is called before FSceneRenderTargets::AllocateRenderTargets()
// so CurrentFeatureLevel == ERHIFeatureLevel::Num and that crashes OpenGL ES2 as R32F is not valid
if ( CurrentFeatureLevel = = ERHIFeatureLevel : : Num )
{
bSupportsR32Float = GMaxRHIFeatureLevel > ERHIFeatureLevel : : ES2 ;
}
2014-09-18 17:01:15 -04:00
int32 ReflectionBrightnessIndex = bSupportsR32Float ? 0 : 1 ;
EPixelFormat BrightnessFormat = bSupportsR32Float ? PF_R32_FLOAT : PF_FloatRGBA ;
2014-08-25 16:47:22 -04:00
FPooledRenderTargetDesc Desc3 ( FPooledRenderTargetDesc : : Create2DDesc ( FIntPoint ( 1 , 1 ) , BrightnessFormat , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
2014-09-18 17:01:15 -04:00
GRenderTargetPool . FindFreeElement ( Desc3 , ReflectionBrightnessTarget , GetReflectionBrightnessTargetName ( ReflectionBrightnessIndex ) ) ;
2014-08-25 16:47:22 -04:00
}
}
}
2014-05-07 11:04:46 -04:00
2014-09-18 17:01:15 -04:00
void FSceneRenderTargets : : AllocateCommonDepthTargets ( )
2014-03-14 14:13:41 -04:00
{
2014-09-18 17:01:15 -04:00
if ( ! SceneDepthZ )
2014-03-14 14:13:41 -04:00
{
// Create a texture to store the resolved scene depth, and a render-targetable surface to hold the unresolved scene depth.
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_DepthStencil , TexCreate_None , TexCreate_DepthStencilTargetable , false ) ) ;
2014-09-18 17:01:15 -04:00
Desc . NumSamples = GetNumSceneColorMSAASamples ( CurrentFeatureLevel ) ;
2014-03-14 14:13:41 -04:00
Desc . Flags | = TexCreate_FastVRAM ;
GRenderTargetPool . FindFreeElement ( Desc , SceneDepthZ , TEXT ( " SceneDepthZ " ) ) ;
}
2014-05-06 11:27:50 -04:00
2014-03-14 14:13:41 -04:00
// When targeting DX Feature Level 10, create an auxiliary texture to store the resolved scene depth, and a render-targetable surface to hold the unresolved scene depth.
2014-09-18 17:01:15 -04:00
if ( ! AuxiliarySceneDepthZ & & ! GSupportsDepthFetchDuringDepthTest )
2014-03-14 14:13:41 -04:00
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_DepthStencil , TexCreate_None , TexCreate_DepthStencilTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , AuxiliarySceneDepthZ , TEXT ( " AuxiliarySceneDepthZ " ) ) ;
}
2014-09-18 17:01:15 -04:00
}
void FSceneRenderTargets : : AllocateDeferredShadingPathRenderTargets ( )
{
AllocateCommonDepthTargets ( ) ;
2014-03-14 14:13:41 -04:00
// Create a quarter-sized version of the scene depth.
{
FIntPoint SmallDepthZSize ( FMath : : Max < uint32 > ( BufferSize . X / SmallColorDepthDownsampleFactor , 1 ) , FMath : : Max < uint32 > ( BufferSize . Y / SmallColorDepthDownsampleFactor , 1 ) ) ;
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( SmallDepthZSize , PF_DepthStencil , TexCreate_None , TexCreate_DepthStencilTargetable , true ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , SmallDepthZ , TEXT ( " SmallDepthZ " ) ) ;
}
// Set up quarter size scene color shared texture
const FIntPoint ShadowBufferResolution = GetShadowDepthTextureResolution ( ) ;
const FIntPoint TranslucentShadowBufferResolution = GetTranslucentShadowDepthTextureResolution ( ) ;
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-03-14 14:13:41 -04:00
{
for ( int32 SurfaceIndex = 0 ; SurfaceIndex < NumTranslucencyShadowSurfaces ; SurfaceIndex + + )
{
if ( ! TranslucencyShadowTransmission [ SurfaceIndex ] )
{
// Using PF_FloatRGBA because Fourier coefficients used by Fourier opacity maps have a large range and can be negative
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( TranslucentShadowBufferResolution , PF_FloatRGBA , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
2014-05-07 11:04:46 -04:00
GRenderTargetPool . FindFreeElement ( Desc , TranslucencyShadowTransmission [ SurfaceIndex ] , GetTranslucencyShadowTransmissionName ( SurfaceIndex ) ) ;
2014-03-14 14:13:41 -04:00
}
}
}
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-03-14 14:13:41 -04:00
{
// Create several shadow depth cube maps with different resolutions, to handle different sized shadows on the screen
for ( int32 SurfaceIndex = 0 ; SurfaceIndex < NumCubeShadowDepthSurfaces ; SurfaceIndex + + )
{
const int32 SurfaceResolution = GetCubeShadowDepthZResolution ( SurfaceIndex ) ;
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : CreateCubemapDesc ( SurfaceResolution , PF_ShadowDepth , TexCreate_None , TexCreate_DepthStencilTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , CubeShadowDepthZ [ SurfaceIndex ] , TEXT ( " CubeShadowDepthZ[] " ) ) ;
}
}
//create the shadow depth texture and/or surface
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( ShadowBufferResolution , PF_ShadowDepth , TexCreate_None , TexCreate_DepthStencilTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , ShadowDepthZ , TEXT ( " ShadowDepthZ " ) ) ;
}
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( GetPreShadowCacheTextureResolution ( ) , PF_ShadowDepth , TexCreate_None , TexCreate_DepthStencilTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , PreShadowCacheDepthZ , TEXT ( " PreShadowCacheDepthZ " ) ) ;
// Mark the preshadow cache as newly allocated, so the cache will know to update
bPreshadowCacheNewlyAllocated = true ;
}
// Create the required render targets if running Highend.
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-03-14 14:13:41 -04:00
{
// Create the screen space ambient occlusion buffer
{
2014-04-02 18:09:23 -04:00
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_G8 , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
2014-03-14 14:13:41 -04:00
GRenderTargetPool . FindFreeElement ( Desc , ScreenSpaceAO , TEXT ( " ScreenSpaceAO " ) ) ;
}
{
for ( int32 RTSetIndex = 0 ; RTSetIndex < NumTranslucentVolumeRenderTargetSets ; RTSetIndex + + )
{
GRenderTargetPool . FindFreeElement (
FPooledRenderTargetDesc ( FPooledRenderTargetDesc : : CreateVolumeDesc (
GTranslucencyLightingVolumeDim ,
GTranslucencyLightingVolumeDim ,
GTranslucencyLightingVolumeDim ,
PF_FloatRGBA ,
0 ,
TexCreate_ShaderResource | TexCreate_RenderTargetable ,
false ) ) ,
TranslucencyLightingVolumeAmbient [ RTSetIndex ] ,
GetVolumeName ( RTSetIndex , false )
) ;
GRenderTargetPool . FindFreeElement (
FPooledRenderTargetDesc ( FPooledRenderTargetDesc : : CreateVolumeDesc (
GTranslucencyLightingVolumeDim ,
GTranslucencyLightingVolumeDim ,
GTranslucencyLightingVolumeDim ,
PF_FloatRGBA ,
0 ,
TexCreate_ShaderResource | TexCreate_RenderTargetable ,
false ) ) ,
TranslucencyLightingVolumeDirectional [ RTSetIndex ] ,
GetVolumeName ( RTSetIndex , true )
) ;
}
}
}
2014-08-25 16:47:22 -04:00
AllocateReflectionTargets ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-10 10:39:54 -04:00
if ( CurrentFeatureLevel > = ERHIFeatureLevel : : SM5 )
2014-03-14 14:13:41 -04:00
{
// Create the reflective shadow map textures for LightPropagationVolume feature
if ( bCurrentLightPropagationVolume )
{
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( GetReflectiveShadowMapTextureResolution ( ) , PF_R8G8B8A8 , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , ReflectiveShadowMapNormal , TEXT ( " RSMNormal " ) ) ;
}
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( GetReflectiveShadowMapTextureResolution ( ) , PF_FloatR11G11B10 , TexCreate_None , TexCreate_RenderTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , ReflectiveShadowMapDiffuse , TEXT ( " RSMDiffuse " ) ) ;
}
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( GetReflectiveShadowMapTextureResolution ( ) , PF_DepthStencil , TexCreate_None , TexCreate_DepthStencilTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , ReflectiveShadowMapDepth , TEXT ( " RSMDepth " ) ) ;
}
}
}
2015-01-20 20:14:07 -05:00
2015-02-02 18:00:05 -05:00
if ( bAllocateVelocityGBuffer )
2015-01-20 20:14:07 -05:00
{
FPooledRenderTargetDesc VelocityRTDesc = FVelocityRendering : : GetRenderTargetDesc ( ) ;
GRenderTargetPool . FindFreeElement ( VelocityRTDesc , GBufferVelocity , TEXT ( " GBufferVelocity " ) ) ;
}
2014-03-14 14:13:41 -04:00
}
2014-05-06 11:27:50 -04:00
EPixelFormat FSceneRenderTargets : : GetSceneColorFormat ( ) const
{
EPixelFormat SceneColorBufferFormat = PF_FloatRGBA ;
2014-08-25 16:47:22 -04:00
if ( CurrentFeatureLevel < ERHIFeatureLevel : : SM4 )
2014-05-21 04:19:03 -04:00
{
2014-05-21 15:02:18 -04:00
// Potentially allocate an alpha channel in th -fe scene color texture to store the resolved scene depth.
2014-05-21 14:57:15 -04:00
SceneColorBufferFormat = GSupportsRenderTargetFormat_PF_FloatRGBA ? PF_FloatRGBA : PF_B8G8R8A8 ;
if ( ! IsMobileHDR ( ) | | IsMobileHDR32bpp ( ) )
2014-05-21 04:19:03 -04:00
{
SceneColorBufferFormat = PF_B8G8R8A8 ;
}
}
2014-05-21 14:57:15 -04:00
else
{
2014-06-05 16:38:54 -04:00
switch ( CurrentSceneColorFormat )
{
case 0 :
SceneColorBufferFormat = PF_R8G8B8A8 ; break ;
case 1 :
SceneColorBufferFormat = PF_A2B10G10R10 ; break ;
case 2 :
SceneColorBufferFormat = PF_FloatR11G11B10 ; break ;
case 3 :
SceneColorBufferFormat = PF_FloatRGB ; break ;
case 4 :
// default
break ;
case 5 :
SceneColorBufferFormat = PF_A32B32G32R32F ; break ;
}
2014-05-21 14:57:15 -04:00
}
2014-05-21 04:19:03 -04:00
2014-05-06 11:27:50 -04:00
return SceneColorBufferFormat ;
}
2014-09-18 17:01:15 -04:00
void FSceneRenderTargets : : AllocateRenderTargets ( )
2014-03-14 14:13:41 -04:00
{
2014-09-18 17:01:15 -04:00
if ( BufferSize . X > 0 & & BufferSize . Y > 0 & & ! AreShadingPathRenderTargetsAllocated ( CurrentShadingPath ) )
2014-03-14 14:13:41 -04:00
{
// start with a defined state for the scissor rect (D3D11 was returning (0,0,0,0) which caused a clear to not execute correctly)
// todo: move this to an earlier place (for dx9 is has to be after device creation which is after window creation)
2014-09-18 17:01:15 -04:00
// todo: potentially redundant now? Seems like a strange thing to have here anyway???
2014-06-27 11:07:13 -04:00
FRHICommandListImmediate & RHICmdList = FRHICommandListExecutor : : GetImmediateCommandList ( ) ;
RHICmdList . SetScissorRect ( false , 0 , 0 , 0 , 0 ) ;
2014-03-14 14:13:41 -04:00
2014-09-18 17:01:15 -04:00
if ( ( EShadingPath ) CurrentShadingPath = = EShadingPath : : Forward )
2014-03-14 14:13:41 -04:00
{
AllocateForwardShadingPathRenderTargets ( ) ;
}
else
{
AllocateDeferredShadingPathRenderTargets ( ) ;
}
}
}
2014-07-10 10:39:54 -04:00
void FSceneRenderTargets : : ReleaseAllTargets ( )
2014-05-08 17:58:14 -04:00
{
2014-07-10 10:39:54 -04:00
ReleaseGBufferTargets ( ) ;
2014-05-08 17:58:14 -04:00
2014-09-18 17:01:15 -04:00
for ( auto i = 0 ; i < ( int32 ) EShadingPath : : Num ; + + i )
{
SceneColor [ i ] . SafeRelease ( ) ;
}
2014-03-14 14:13:41 -04:00
SceneAlphaCopy . SafeRelease ( ) ;
SceneDepthZ . SafeRelease ( ) ;
AuxiliarySceneDepthZ . SafeRelease ( ) ;
SmallDepthZ . SafeRelease ( ) ;
DBufferA . SafeRelease ( ) ;
DBufferB . SafeRelease ( ) ;
DBufferC . SafeRelease ( ) ;
ScreenSpaceAO . SafeRelease ( ) ;
LightAttenuation . SafeRelease ( ) ;
CustomDepth . SafeRelease ( ) ;
ReflectiveShadowMapNormal . SafeRelease ( ) ;
ReflectiveShadowMapDiffuse . SafeRelease ( ) ;
ReflectiveShadowMapDepth . SafeRelease ( ) ;
for ( int32 SurfaceIndex = 0 ; SurfaceIndex < NumTranslucencyShadowSurfaces ; SurfaceIndex + + )
{
TranslucencyShadowTransmission [ SurfaceIndex ] . SafeRelease ( ) ;
}
ShadowDepthZ . SafeRelease ( ) ;
PreShadowCacheDepthZ . SafeRelease ( ) ;
for ( int32 Index = 0 ; Index < NumCubeShadowDepthSurfaces ; + + Index )
{
CubeShadowDepthZ [ Index ] . SafeRelease ( ) ;
}
for ( int32 i = 0 ; i < ARRAY_COUNT ( ReflectionColorScratchCubemap ) ; i + + )
{
ReflectionColorScratchCubemap [ i ] . SafeRelease ( ) ;
}
2014-09-18 17:01:15 -04:00
ReflectionBrightness [ 0 ] . SafeRelease ( ) ;
ReflectionBrightness [ 1 ] . SafeRelease ( ) ;
2014-03-14 14:13:41 -04:00
for ( int32 i = 0 ; i < ARRAY_COUNT ( DiffuseIrradianceScratchCubemap ) ; i + + )
{
DiffuseIrradianceScratchCubemap [ i ] . SafeRelease ( ) ;
}
SkySHIrradianceMap . SafeRelease ( ) ;
for ( int32 RTSetIndex = 0 ; RTSetIndex < NumTranslucentVolumeRenderTargetSets ; RTSetIndex + + )
{
TranslucencyLightingVolumeAmbient [ RTSetIndex ] . SafeRelease ( ) ;
TranslucencyLightingVolumeDirectional [ RTSetIndex ] . SafeRelease ( ) ;
}
EditorPrimitivesColor . SafeRelease ( ) ;
EditorPrimitivesDepth . SafeRelease ( ) ;
2014-07-10 10:39:54 -04:00
}
2014-03-14 14:13:41 -04:00
2014-07-10 10:39:54 -04:00
void FSceneRenderTargets : : ReleaseDynamicRHI ( )
{
ReleaseAllTargets ( ) ;
2014-03-14 14:13:41 -04:00
GRenderTargetPool . FreeUnusedResources ( ) ;
}
/** Returns the size of the shadow depth buffer, taking into account platform limitations and game specific resolution limits. */
FIntPoint FSceneRenderTargets : : GetShadowDepthTextureResolution ( ) const
{
2014-11-10 15:40:54 -05:00
int32 MaxShadowRes = CurrentMaxShadowResolution ;
2014-03-14 14:13:41 -04:00
const FIntPoint ShadowBufferResolution (
FMath : : Clamp ( MaxShadowRes , 1 , GMaxShadowDepthBufferSizeX ) ,
FMath : : Clamp ( MaxShadowRes , 1 , GMaxShadowDepthBufferSizeY ) ) ;
return ShadowBufferResolution ;
}
FIntPoint FSceneRenderTargets : : GetReflectiveShadowMapTextureResolution ( ) const
{
return FIntPoint ( ReflectiveShadowMapResolution , ReflectiveShadowMapResolution ) ;
}
FIntPoint FSceneRenderTargets : : GetPreShadowCacheTextureResolution ( ) const
{
const FIntPoint ShadowDepthResolution = GetShadowDepthTextureResolution ( ) ;
// Higher numbers increase cache hit rate but also memory usage
const int32 ExpandFactor = 2 ;
2014-06-17 11:39:57 -04:00
static auto CVarPreShadowResolutionFactor = IConsoleManager : : Get ( ) . FindTConsoleVariableDataFloat ( TEXT ( " r.Shadow.PreShadowResolutionFactor " ) ) ;
2014-05-06 06:26:25 -04:00
return FIntPoint ( FMath : : TruncToInt ( ShadowDepthResolution . X * CVarPreShadowResolutionFactor - > GetValueOnRenderThread ( ) ) , FMath : : TruncToInt ( ShadowDepthResolution . Y * CVarPreShadowResolutionFactor - > GetValueOnRenderThread ( ) ) ) * ExpandFactor ;
2014-03-14 14:13:41 -04:00
}
FIntPoint FSceneRenderTargets : : GetTranslucentShadowDepthTextureResolution ( ) const
{
2014-11-10 15:40:54 -05:00
FIntPoint ShadowDepthResolution = GetShadowDepthTextureResolution ( ) ;
ShadowDepthResolution . X = FMath : : Max < int32 > ( ShadowDepthResolution . X / GetTranslucentShadowDownsampleFactor ( ) , 1 ) ;
ShadowDepthResolution . Y = FMath : : Max < int32 > ( ShadowDepthResolution . Y / GetTranslucentShadowDownsampleFactor ( ) , 1 ) ;
2014-03-14 14:13:41 -04:00
return ShadowDepthResolution ;
}
2014-05-06 11:27:50 -04:00
const FTextureRHIRef & FSceneRenderTargets : : GetSceneColorSurface ( ) const
{
2014-09-18 17:01:15 -04:00
if ( ! GetSceneColorForCurrentShadingPath ( ) )
2014-05-06 11:27:50 -04:00
{
return GBlackTexture - > TextureRHI ;
}
2014-09-18 17:01:15 -04:00
return ( const FTextureRHIRef & ) GetSceneColor ( ) - > GetRenderTargetItem ( ) . TargetableTexture ;
2014-05-06 11:27:50 -04:00
}
const FTextureRHIRef & FSceneRenderTargets : : GetSceneColorTexture ( ) const
{
2014-09-18 17:01:15 -04:00
if ( ! GetSceneColorForCurrentShadingPath ( ) )
2014-05-06 11:27:50 -04:00
{
return GBlackTexture - > TextureRHI ;
}
return ( const FTextureRHIRef & ) GetSceneColor ( ) - > GetRenderTargetItem ( ) . ShaderResourceTexture ;
}
2015-01-20 20:14:07 -05:00
IPooledRenderTarget * FSceneRenderTargets : : GetGBufferVelocityRT ( )
{
2015-02-02 18:00:05 -05:00
if ( ! bAllocateVelocityGBuffer )
2015-01-20 20:14:07 -05:00
{
return nullptr ;
}
return GBufferVelocity ;
}
2014-03-14 14:13:41 -04:00
IPooledRenderTarget * FSceneRenderTargets : : RequestCustomDepth ( bool bPrimitives )
{
2014-05-08 17:58:14 -04:00
int Value = CVarCustomDepth . GetValueOnRenderThread ( ) ;
2014-03-14 14:13:41 -04:00
if ( ( Value = = 1 & & bPrimitives ) | | Value = = 2 )
{
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_DepthStencil , TexCreate_None , TexCreate_DepthStencilTargetable , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , CustomDepth , TEXT ( " CustomDepth " ) ) ;
return CustomDepth ;
}
return 0 ;
}
/** Returns an index in the range [0, NumCubeShadowDepthSurfaces) given an input resolution. */
int32 FSceneRenderTargets : : GetCubeShadowDepthZIndex ( int32 ShadowResolution ) const
{
static auto CVarMinShadowResolution = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.Shadow.MinResolution " ) ) ;
FIntPoint ObjectShadowBufferResolution = GetShadowDepthTextureResolution ( ) ;
// Use a lower resolution because cubemaps use a lot of memory
ObjectShadowBufferResolution . X / = 2 ;
ObjectShadowBufferResolution . Y / = 2 ;
const int32 SurfaceSizes [ NumCubeShadowDepthSurfaces ] =
{
ObjectShadowBufferResolution . X ,
ObjectShadowBufferResolution . X / 2 ,
ObjectShadowBufferResolution . X / 4 ,
ObjectShadowBufferResolution . X / 8 ,
CVarMinShadowResolution - > GetValueOnRenderThread ( )
} ;
for ( int32 SearchIndex = 0 ; SearchIndex < NumCubeShadowDepthSurfaces ; SearchIndex + + )
{
if ( ShadowResolution > = SurfaceSizes [ SearchIndex ] )
{
return SearchIndex ;
}
}
check ( 0 ) ;
return 0 ;
}
/** Returns the appropriate resolution for a given cube shadow index. */
int32 FSceneRenderTargets : : GetCubeShadowDepthZResolution ( int32 ShadowIndex ) const
{
checkSlow ( ShadowIndex > = 0 & & ShadowIndex < NumCubeShadowDepthSurfaces ) ;
static auto CVarMinShadowResolution = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.Shadow.MinResolution " ) ) ;
FIntPoint ObjectShadowBufferResolution = GetShadowDepthTextureResolution ( ) ;
// Use a lower resolution because cubemaps use a lot of memory
ObjectShadowBufferResolution . X = FMath : : Max ( ObjectShadowBufferResolution . X / 2 , 1 ) ;
ObjectShadowBufferResolution . Y = FMath : : Max ( ObjectShadowBufferResolution . Y / 2 , 1 ) ;
const int32 SurfaceSizes [ NumCubeShadowDepthSurfaces ] =
{
ObjectShadowBufferResolution . X ,
FMath : : Max ( ObjectShadowBufferResolution . X / 2 , 1 ) ,
FMath : : Max ( ObjectShadowBufferResolution . X / 4 , 1 ) ,
FMath : : Max ( ObjectShadowBufferResolution . X / 8 , 1 ) ,
CVarMinShadowResolution - > GetValueOnRenderThread ( )
} ;
return SurfaceSizes [ ShadowIndex ] ;
}
2014-09-18 17:01:15 -04:00
bool FSceneRenderTargets : : AreShadingPathRenderTargetsAllocated ( EShadingPath InShadingPath ) const
{
switch ( InShadingPath )
{
case EShadingPath : : Forward :
{
return ( SceneColor [ ( int32 ) EShadingPath : : Forward ] ! = nullptr ) ;
}
case EShadingPath : : Deferred :
{
return ( ShadowDepthZ ! = nullptr ) ;
}
default :
{
checkNoEntry ( ) ;
return false ;
}
}
}
2014-03-14 14:13:41 -04:00
/*-----------------------------------------------------------------------------
FSceneTextureShaderParameters
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
void FSceneTextureShaderParameters : : Bind ( const FShaderParameterMap & ParameterMap )
{
// only used if Material has an expression that requires SceneColorTexture
SceneColorTextureParameter . Bind ( ParameterMap , TEXT ( " SceneColorTexture " ) ) ;
SceneColorTextureParameterSampler . Bind ( ParameterMap , TEXT ( " SceneColorTextureSampler " ) ) ;
// only used if Material has an expression that requires SceneDepthTexture
SceneDepthTextureParameter . Bind ( ParameterMap , TEXT ( " SceneDepthTexture " ) ) ;
SceneDepthTextureParameterSampler . Bind ( ParameterMap , TEXT ( " SceneDepthTextureSampler " ) ) ;
// Only used if Material has an expression that requires SceneAlphaCopyTexture
SceneAlphaCopyTextureParameter . Bind ( ParameterMap , TEXT ( " SceneAlphaCopyTexture " ) ) ;
SceneAlphaCopyTextureParameterSampler . Bind ( ParameterMap , TEXT ( " SceneAlphaCopyTextureSampler " ) ) ;
//
SceneDepthTextureNonMS . Bind ( ParameterMap , TEXT ( " SceneDepthTextureNonMS " ) ) ;
SceneColorSurfaceParameter . Bind ( ParameterMap , TEXT ( " SceneColorSurface " ) ) ;
// only used if Material has an expression that requires SceneColorTextureMSAA
SceneDepthSurfaceParameter . Bind ( ParameterMap , TEXT ( " SceneDepthSurface " ) ) ;
}
2014-06-24 14:37:21 -04:00
template < typename ShaderRHIParamRef >
void FSceneTextureShaderParameters : : Set (
FRHICommandList & RHICmdList ,
const ShaderRHIParamRef & ShaderRHI ,
const FSceneView & View ,
ESceneRenderTargetsMode : : Type TextureMode ,
ESamplerFilter ColorFilter ) const
{
if ( TextureMode = = ESceneRenderTargetsMode : : SetTextures )
{
// optimization possible: TShaderRHIParamRef is no param Ref
if ( SceneColorTextureParameter . IsBound ( ) )
{
FSamplerStateRHIRef Filter ;
switch ( ColorFilter )
{
case SF_Bilinear :
Filter = TStaticSamplerState < SF_Bilinear , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
break ;
case SF_Trilinear :
Filter = TStaticSamplerState < SF_Trilinear , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
break ;
case SF_AnisotropicPoint :
Filter = TStaticSamplerState < SF_AnisotropicPoint , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
break ;
case SF_AnisotropicLinear :
Filter = TStaticSamplerState < SF_AnisotropicLinear , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
break ;
case SF_Point :
default :
Filter = TStaticSamplerState < SF_Point , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
break ;
}
SetTextureParameter (
RHICmdList ,
ShaderRHI ,
SceneColorTextureParameter ,
SceneColorTextureParameterSampler ,
Filter ,
GSceneRenderTargets . GetSceneColorTexture ( )
) ;
}
if ( SceneAlphaCopyTextureParameter . IsBound ( ) & & GSceneRenderTargets . HasSceneAlphaCopyTexture ( ) )
{
FSamplerStateRHIRef Filter ;
Filter = TStaticSamplerState < SF_Point , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
SetTextureParameter (
RHICmdList ,
ShaderRHI ,
SceneAlphaCopyTextureParameter ,
SceneAlphaCopyTextureParameterSampler ,
Filter ,
GSceneRenderTargets . GetSceneAlphaCopyTexture ( )
) ;
}
if ( SceneDepthTextureParameter . IsBound ( ) | | SceneDepthTextureParameterSampler . IsBound ( ) )
{
const FTexture2DRHIRef * DepthTexture = GSceneRenderTargets . GetActualDepthTexture ( ) ;
SetTextureParameter (
RHICmdList ,
ShaderRHI ,
SceneDepthTextureParameter ,
SceneDepthTextureParameterSampler ,
TStaticSamplerState < SF_Point , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ,
* DepthTexture
) ;
}
2014-07-10 10:39:54 -04:00
const auto FeatureLevel = View . GetFeatureLevel ( ) ;
if ( FeatureLevel > = ERHIFeatureLevel : : SM5 )
2014-06-24 14:37:21 -04:00
{
SetTextureParameter ( RHICmdList , ShaderRHI , SceneColorSurfaceParameter , GSceneRenderTargets . GetSceneColorSurface ( ) ) ;
}
2014-07-10 10:39:54 -04:00
if ( FeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-06-24 14:37:21 -04:00
{
if ( GSupportsDepthFetchDuringDepthTest )
{
if ( SceneDepthSurfaceParameter . IsBound ( ) )
{
SetTextureParameter ( RHICmdList , ShaderRHI , SceneDepthSurfaceParameter , GSceneRenderTargets . GetSceneDepthSurface ( ) ) ;
}
if ( SceneDepthTextureNonMS . IsBound ( ) )
{
SetTextureParameter ( RHICmdList , ShaderRHI , SceneDepthTextureNonMS , GSceneRenderTargets . GetSceneDepthTexture ( ) ) ;
}
}
else
{
if ( SceneDepthSurfaceParameter . IsBound ( ) )
{
SetTextureParameter ( RHICmdList , ShaderRHI , SceneDepthSurfaceParameter , GSceneRenderTargets . GetAuxiliarySceneDepthSurface ( ) ) ;
}
if ( SceneDepthTextureNonMS . IsBound ( ) )
{
SetTextureParameter ( RHICmdList , ShaderRHI , SceneDepthTextureNonMS , GSceneRenderTargets . GetAuxiliarySceneDepthSurface ( ) ) ;
}
}
}
}
else if ( TextureMode = = ESceneRenderTargetsMode : : DontSet )
{
// Verify that none of these were bound if we were told not to set them
checkSlow ( ! SceneColorTextureParameter . IsBound ( )
& & ! SceneDepthTextureParameter . IsBound ( )
& & ! SceneColorSurfaceParameter . IsBound ( )
& & ! SceneDepthSurfaceParameter . IsBound ( )
& & ! SceneDepthTextureNonMS . IsBound ( ) ) ;
}
else if ( TextureMode = = ESceneRenderTargetsMode : : DontSetIgnoreBoundByEditorCompositing )
{
// Verify that none of these were bound if we were told not to set them
// ignore SceneDepthTextureNonMS
checkSlow ( ! SceneColorTextureParameter . IsBound ( )
& & ! SceneDepthTextureParameter . IsBound ( )
& & ! SceneColorSurfaceParameter . IsBound ( )
& & ! SceneDepthSurfaceParameter . IsBound ( ) ) ;
}
else if ( TextureMode = = ESceneRenderTargetsMode : : NonSceneAlignedPass )
{
FSamplerStateRHIParamRef DefaultSampler = TStaticSamplerState < SF_Point , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , SceneColorTextureParameter , SceneColorTextureParameterSampler , DefaultSampler , GBlackTexture - > TextureRHI ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , SceneDepthTextureParameter , SceneDepthTextureParameterSampler , DefaultSampler , GBlackTexture - > TextureRHI ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , SceneColorSurfaceParameter , GBlackTexture - > TextureRHI ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , SceneDepthSurfaceParameter , GBlackTexture - > TextureRHI ) ;
}
}
# define IMPLEMENT_SCENE_TEXTURE_PARAM_SET( ShaderRHIParamRef ) \
template void FSceneTextureShaderParameters : : Set < ShaderRHIParamRef > ( \
FRHICommandList & RHICmdList , \
const ShaderRHIParamRef & ShaderRHI , \
const FSceneView & View , \
ESceneRenderTargetsMode : : Type TextureMode , \
ESamplerFilter ColorFilter \
) const ;
IMPLEMENT_SCENE_TEXTURE_PARAM_SET ( FVertexShaderRHIParamRef ) ;
IMPLEMENT_SCENE_TEXTURE_PARAM_SET ( FHullShaderRHIParamRef ) ;
IMPLEMENT_SCENE_TEXTURE_PARAM_SET ( FDomainShaderRHIParamRef ) ;
IMPLEMENT_SCENE_TEXTURE_PARAM_SET ( FGeometryShaderRHIParamRef ) ;
IMPLEMENT_SCENE_TEXTURE_PARAM_SET ( FPixelShaderRHIParamRef ) ;
IMPLEMENT_SCENE_TEXTURE_PARAM_SET ( FComputeShaderRHIParamRef ) ;
2014-03-14 14:13:41 -04:00
FArchive & operator < < ( FArchive & Ar , FSceneTextureShaderParameters & Parameters )
{
Ar < < Parameters . SceneColorTextureParameter ;
Ar < < Parameters . SceneColorTextureParameterSampler ;
Ar < < Parameters . SceneAlphaCopyTextureParameter ;
Ar < < Parameters . SceneAlphaCopyTextureParameterSampler ;
Ar < < Parameters . SceneColorSurfaceParameter ;
Ar < < Parameters . SceneDepthTextureParameter ;
Ar < < Parameters . SceneDepthTextureParameterSampler ;
Ar < < Parameters . SceneDepthSurfaceParameter ;
Ar < < Parameters . SceneDepthTextureNonMS ;
return Ar ;
}
// Note this is not just for Deferred rendering, it also applies to mobile forward rendering.
void FDeferredPixelShaderParameters : : Bind ( const FShaderParameterMap & ParameterMap )
{
SceneTextureParameters . Bind ( ParameterMap ) ;
2014-06-05 16:38:54 -04:00
GBufferResources . Bind ( ParameterMap , TEXT ( " GBuffers " ) ) ;
2014-03-14 14:13:41 -04:00
DBufferATextureMS . Bind ( ParameterMap , TEXT ( " DBufferATextureMS " ) ) ;
DBufferBTextureMS . Bind ( ParameterMap , TEXT ( " DBufferBTextureMS " ) ) ;
DBufferCTextureMS . Bind ( ParameterMap , TEXT ( " DBufferCTextureMS " ) ) ;
ScreenSpaceAOTextureMS . Bind ( ParameterMap , TEXT ( " ScreenSpaceAOTextureMS " ) ) ;
DBufferATextureNonMS . Bind ( ParameterMap , TEXT ( " DBufferATextureNonMS " ) ) ;
DBufferBTextureNonMS . Bind ( ParameterMap , TEXT ( " DBufferBTextureNonMS " ) ) ;
DBufferCTextureNonMS . Bind ( ParameterMap , TEXT ( " DBufferCTextureNonMS " ) ) ;
ScreenSpaceAOTextureNonMS . Bind ( ParameterMap , TEXT ( " ScreenSpaceAOTextureNonMS " ) ) ;
CustomDepthTextureNonMS . Bind ( ParameterMap , TEXT ( " CustomDepthTextureNonMS " ) ) ;
DBufferATexture . Bind ( ParameterMap , TEXT ( " DBufferATexture " ) ) ;
DBufferATextureSampler . Bind ( ParameterMap , TEXT ( " DBufferATextureSampler " ) ) ;
DBufferBTexture . Bind ( ParameterMap , TEXT ( " DBufferBTexture " ) ) ;
DBufferBTextureSampler . Bind ( ParameterMap , TEXT ( " DBufferBTextureSampler " ) ) ;
DBufferCTexture . Bind ( ParameterMap , TEXT ( " DBufferCTexture " ) ) ;
DBufferCTextureSampler . Bind ( ParameterMap , TEXT ( " DBufferCTextureSampler " ) ) ;
ScreenSpaceAOTexture . Bind ( ParameterMap , TEXT ( " ScreenSpaceAOTexture " ) ) ;
ScreenSpaceAOTextureSampler . Bind ( ParameterMap , TEXT ( " ScreenSpaceAOTextureSampler " ) ) ;
CustomDepthTexture . Bind ( ParameterMap , TEXT ( " CustomDepthTexture " ) ) ;
CustomDepthTextureSampler . Bind ( ParameterMap , TEXT ( " CustomDepthTextureSampler " ) ) ;
}
2014-06-24 14:37:21 -04:00
bool IsDBufferEnabled ( ) ;
template < typename ShaderRHIParamRef >
void FDeferredPixelShaderParameters : : Set ( FRHICommandList & RHICmdList , const ShaderRHIParamRef ShaderRHI , const FSceneView & View , ESceneRenderTargetsMode : : Type TextureMode ) const
{
// This is needed on PC ES2 for SceneAlphaCopy, probably should be refactored for performance.
SceneTextureParameters . Set ( RHICmdList , ShaderRHI , View , TextureMode , SF_Point ) ;
// if() is purely an optimization and could be removed
if ( IsDBufferEnabled ( ) )
{
IPooledRenderTarget * DBufferA = GSceneRenderTargets . DBufferA ? GSceneRenderTargets . DBufferA : GSystemTextures . BlackDummy ;
IPooledRenderTarget * DBufferB = GSceneRenderTargets . DBufferB ? GSceneRenderTargets . DBufferB : GSystemTextures . BlackDummy ;
IPooledRenderTarget * DBufferC = GSceneRenderTargets . DBufferC ? GSceneRenderTargets . DBufferC : GSystemTextures . BlackDummy ;
// todo: optimize out when not needed
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferATexture , DBufferATextureSampler , TStaticSamplerState < > : : GetRHI ( ) , DBufferA - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferBTexture , DBufferBTextureSampler , TStaticSamplerState < > : : GetRHI ( ) , DBufferB - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferCTexture , DBufferCTextureSampler , TStaticSamplerState < > : : GetRHI ( ) , DBufferC - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferATextureMS , DBufferA - > GetRenderTargetItem ( ) . TargetableTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferBTextureMS , DBufferB - > GetRenderTargetItem ( ) . TargetableTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferCTextureMS , DBufferC - > GetRenderTargetItem ( ) . TargetableTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferATextureNonMS , DBufferA - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferBTextureNonMS , DBufferB - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , DBufferCTextureNonMS , DBufferC - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
}
2014-07-10 10:39:54 -04:00
const auto FeatureLevel = View . GetFeatureLevel ( ) ;
2014-08-25 16:47:22 -04:00
if ( TextureMode = = ESceneRenderTargetsMode : : SetTextures & & FeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-06-24 14:37:21 -04:00
{
// if there is no ambient occlusion it's better to have white there
IPooledRenderTarget * ScreenSpaceAO = GSceneRenderTargets . ScreenSpaceAO ;
if ( ! GSceneRenderTargets . bScreenSpaceAOIsValid )
{
ScreenSpaceAO = GSystemTextures . WhiteDummy ;
}
// if there is no custom depth it's better to have the far distance there
2015-01-16 10:46:42 -05:00
IPooledRenderTarget * CustomDepth = GSceneRenderTargets . bCustomDepthIsValid ? GSceneRenderTargets . CustomDepth . GetReference ( ) : 0 ;
2014-06-24 14:37:21 -04:00
if ( ! CustomDepth )
{
CustomDepth = GSystemTextures . BlackDummy ;
}
2014-07-10 10:39:54 -04:00
if ( FeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-06-24 14:37:21 -04:00
{
if ( GBufferResources . IsBound ( ) )
{
SetUniformBufferParameter ( RHICmdList , ShaderRHI , GBufferResources , GSceneRenderTargets . GetGBufferResourcesUniformBuffer ( ) ) ;
}
SetTextureParameter ( RHICmdList , ShaderRHI , ScreenSpaceAOTexture , ScreenSpaceAOTextureSampler , TStaticSamplerState < > : : GetRHI ( ) , ScreenSpaceAO - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , ScreenSpaceAOTextureMS , ScreenSpaceAO - > GetRenderTargetItem ( ) . TargetableTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , ScreenSpaceAOTextureNonMS , ScreenSpaceAO - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , CustomDepthTexture , CustomDepthTextureSampler , TStaticSamplerState < > : : GetRHI ( ) , CustomDepth - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , CustomDepthTextureNonMS , CustomDepth - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
}
}
else if ( TextureMode = = ESceneRenderTargetsMode : : DontSet | |
TextureMode = = ESceneRenderTargetsMode : : DontSetIgnoreBoundByEditorCompositing )
{
// Verify that none of these are actually bound
checkSlow ( ! GBufferResources . IsBound ( ) ) ;
}
}
# define IMPLEMENT_DEFERRED_PARAMETERS_SET( ShaderRHIParamRef ) \
template void FDeferredPixelShaderParameters : : Set < ShaderRHIParamRef > ( \
FRHICommandList & RHICmdList , \
const ShaderRHIParamRef ShaderRHI , \
const FSceneView & View , \
ESceneRenderTargetsMode : : Type TextureMode \
) const ;
IMPLEMENT_DEFERRED_PARAMETERS_SET ( FVertexShaderRHIParamRef ) ;
IMPLEMENT_DEFERRED_PARAMETERS_SET ( FHullShaderRHIParamRef ) ;
IMPLEMENT_DEFERRED_PARAMETERS_SET ( FDomainShaderRHIParamRef ) ;
IMPLEMENT_DEFERRED_PARAMETERS_SET ( FGeometryShaderRHIParamRef ) ;
IMPLEMENT_DEFERRED_PARAMETERS_SET ( FPixelShaderRHIParamRef ) ;
IMPLEMENT_DEFERRED_PARAMETERS_SET ( FComputeShaderRHIParamRef ) ;
2014-03-14 14:13:41 -04:00
FArchive & operator < < ( FArchive & Ar , FDeferredPixelShaderParameters & Parameters )
{
Ar < < Parameters . SceneTextureParameters ;
2014-06-05 16:38:54 -04:00
Ar < < Parameters . GBufferResources ;
2014-03-14 14:13:41 -04:00
Ar < < Parameters . DBufferATextureMS ;
Ar < < Parameters . DBufferBTextureMS ;
Ar < < Parameters . DBufferCTextureMS ;
Ar < < Parameters . ScreenSpaceAOTextureMS ;
Ar < < Parameters . DBufferATextureNonMS ;
Ar < < Parameters . DBufferBTextureNonMS ;
Ar < < Parameters . DBufferCTextureNonMS ;
Ar < < Parameters . ScreenSpaceAOTextureNonMS ;
Ar < < Parameters . CustomDepthTextureNonMS ;
Ar < < Parameters . DBufferATexture ;
Ar < < Parameters . DBufferATextureSampler ;
Ar < < Parameters . DBufferBTexture ;
Ar < < Parameters . DBufferBTextureSampler ;
Ar < < Parameters . DBufferCTexture ;
Ar < < Parameters . DBufferCTextureSampler ;
Ar < < Parameters . ScreenSpaceAOTexture ;
Ar < < Parameters . ScreenSpaceAOTextureSampler ;
Ar < < Parameters . CustomDepthTexture ;
Ar < < Parameters . CustomDepthTextureSampler ;
return Ar ;
2014-09-18 17:01:15 -04:00
}