2019-12-26 14:45:42 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-01-28 17:35:18 -05:00
# include "RendererUtils.h"
# include "RenderTargetPool.h"
2021-02-05 11:29:40 -04:00
# include "RHIDefinitions.h"
2020-01-28 13:58:02 -05:00
# include "VisualizeTexture.h"
2019-01-28 17:35:18 -05:00
2020-09-24 00:43:27 -04:00
class FRTWriteMaskDecodeCS : public FGlobalShader
2019-01-28 17:35:18 -05:00
{
public :
2020-09-24 00:43:27 -04:00
DECLARE_GLOBAL_SHADER ( FRTWriteMaskDecodeCS ) ;
2020-10-09 22:42:26 -04:00
static const uint32 MaxRenderTargetCount = 4 ;
2019-01-28 17:35:18 -05:00
static const uint32 ThreadGroupSizeX = 8 ;
static const uint32 ThreadGroupSizeY = 8 ;
2020-10-09 22:42:26 -04:00
class FNumRenderTargets : SHADER_PERMUTATION_RANGE_INT ( " NUM_RENDER_TARGETS " , 1 , MaxRenderTargetCount ) ;
2020-09-24 00:43:27 -04:00
using FPermutationDomain = TShaderPermutationDomain < FNumRenderTargets > ;
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_RDG_TEXTURE ( Texture2D , ReferenceInput )
2021-02-18 19:06:25 -04:00
SHADER_PARAMETER_RDG_TEXTURE_SRV_ARRAY ( TextureMetadata , RTWriteMaskInputs , [ MaxRenderTargetCount ] )
2020-09-24 00:43:27 -04:00
SHADER_PARAMETER_RDG_TEXTURE_UAV ( RWTexture2D < uint > , OutCombinedRTWriteMask )
END_SHADER_PARAMETER_STRUCT ( )
static bool IsSupported ( uint32 NumRenderTargets )
{
return NumRenderTargets = = 1 | | NumRenderTargets = = 3 ;
}
2019-01-28 17:35:18 -05:00
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
2020-09-24 00:43:27 -04:00
const FPermutationDomain PermutationVector ( Parameters . PermutationId ) ;
const uint32 NumRenderTargets = PermutationVector . Get < FNumRenderTargets > ( ) ;
if ( ! IsSupported ( NumRenderTargets ) )
{
return false ;
}
2019-10-11 15:33:31 -04:00
return RHISupportsRenderTargetWriteMask ( Parameters . Platform ) ;
2019-01-28 17:35:18 -05:00
}
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZEX " ) , ThreadGroupSizeX ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZEY " ) , ThreadGroupSizeY ) ;
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
}
2020-09-24 00:43:27 -04:00
FRTWriteMaskDecodeCS ( ) = default ;
FRTWriteMaskDecodeCS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
2019-01-28 17:35:18 -05:00
: FGlobalShader ( Initializer )
{
2019-10-11 15:33:31 -04:00
PlatformDataParam . Bind ( Initializer . ParameterMap , TEXT ( " PlatformData " ) , SPF_Mandatory ) ;
2020-09-24 00:43:27 -04:00
BindForLegacyShaderParameters < FParameters > ( this , Initializer . PermutationId , Initializer . ParameterMap ) ;
2019-01-28 17:35:18 -05:00
}
2020-09-24 00:43:27 -04:00
// Shader parameter structs don't have a way to push variable sized data yet. So the we use the old shader parameter API.
void SetPlatformData ( FRHIComputeCommandList & RHICmdList , const void * PlatformDataPtr , uint32 PlatformDataSize )
2019-01-28 17:35:18 -05:00
{
2020-02-06 13:13:41 -05:00
RHICmdList . SetShaderParameter ( RHICmdList . GetBoundComputeShader ( ) , PlatformDataParam . GetBufferIndex ( ) , PlatformDataParam . GetBaseIndex ( ) , PlatformDataSize , PlatformDataPtr ) ;
2019-10-11 15:33:31 -04:00
}
2020-09-24 00:43:27 -04:00
private :
LAYOUT_FIELD ( FShaderParameter , PlatformDataParam ) ;
2019-01-28 17:35:18 -05:00
} ;
2020-09-24 00:43:27 -04:00
IMPLEMENT_GLOBAL_SHADER ( FRTWriteMaskDecodeCS , " /Engine/Private/RTWriteMaskDecode.usf " , " RTWriteMaskDecodeMain " , SF_Compute ) ;
2019-01-28 17:35:18 -05:00
2020-09-24 00:43:27 -04:00
void FRenderTargetWriteMask : : Decode (
FRHICommandListImmediate & RHICmdList ,
FGlobalShaderMap * ShaderMap ,
TArrayView < IPooledRenderTarget * const > InRenderTargets ,
TRefCountPtr < IPooledRenderTarget > & OutRTWriteMask ,
ETextureCreateFlags RTWriteMaskFastVRamConfig ,
const TCHAR * RTWriteMaskDebugName )
2019-01-28 17:35:18 -05:00
{
2021-05-10 23:54:25 -04:00
FMemMark MemMark ( FMemStack : : Get ( ) ) ;
2020-09-24 00:43:27 -04:00
FRDGBuilder GraphBuilder ( RHICmdList ) ;
2019-01-28 17:35:18 -05:00
2020-09-24 00:43:27 -04:00
TArray < FRDGTextureRef , SceneRenderingAllocator > InputTextures ;
InputTextures . Reserve ( InRenderTargets . Num ( ) ) ;
for ( IPooledRenderTarget * RenderTarget : InRenderTargets )
2019-01-28 17:35:18 -05:00
{
2020-09-24 00:43:27 -04:00
InputTextures . Add ( GraphBuilder . RegisterExternalTexture ( RenderTarget ) ) ;
2019-01-28 17:35:18 -05:00
}
2020-09-24 00:43:27 -04:00
FRDGTextureRef OutputTexture = nullptr ;
Decode ( GraphBuilder , ShaderMap , InputTextures , OutputTexture , RTWriteMaskFastVRamConfig , RTWriteMaskDebugName ) ;
2020-02-06 13:13:41 -05:00
2020-09-24 00:43:27 -04:00
GraphBuilder . QueueTextureExtraction ( OutputTexture , & OutRTWriteMask ) ;
GraphBuilder . Execute ( ) ;
2019-10-11 15:33:31 -04:00
}
2019-01-28 17:35:18 -05:00
2020-09-24 00:43:27 -04:00
void FRenderTargetWriteMask : : Decode (
FRDGBuilder & GraphBuilder ,
FGlobalShaderMap * ShaderMap ,
TArrayView < FRDGTextureRef const > RenderTargets ,
FRDGTextureRef & OutRTWriteMask ,
ETextureCreateFlags RTWriteMaskFastVRamConfig ,
const TCHAR * RTWriteMaskDebugName )
{
const uint32 NumRenderTargets = RenderTargets . Num ( ) ;
2020-02-06 13:13:41 -05:00
2020-09-24 00:43:27 -04:00
check ( RHISupportsRenderTargetWriteMask ( GMaxRHIShaderPlatform ) ) ;
checkf ( FRTWriteMaskDecodeCS : : IsSupported ( NumRenderTargets ) , TEXT ( " FRenderTargetWriteMask::Decode does not currently support decoding %d render targets. " ) , RenderTargets . Num ( ) ) ;
FRDGTextureRef Texture0 = RenderTargets [ 0 ] ;
const FIntPoint RTWriteMaskDims (
FMath : : DivideAndRoundUp ( Texture0 - > Desc . Extent . X , ( int32 ) FRTWriteMaskDecodeCS : : ThreadGroupSizeX ) ,
FMath : : DivideAndRoundUp ( Texture0 - > Desc . Extent . Y , ( int32 ) FRTWriteMaskDecodeCS : : ThreadGroupSizeY ) ) ;
// Allocate the Mask from the render target pool.
const FRDGTextureDesc MaskDesc = FRDGTextureDesc : : Create2D (
RTWriteMaskDims ,
NumRenderTargets < = 2 ? PF_R8_UINT : PF_R16_UINT ,
FClearValueBinding : : None ,
RTWriteMaskFastVRamConfig | TexCreate_UAV | TexCreate_RenderTargetable | TexCreate_ShaderResource ) ;
OutRTWriteMask = GraphBuilder . CreateTexture ( MaskDesc , RTWriteMaskDebugName ) ;
auto * PassParameters = GraphBuilder . AllocParameters < FRTWriteMaskDecodeCS : : FParameters > ( ) ;
PassParameters - > ReferenceInput = Texture0 ;
PassParameters - > OutCombinedRTWriteMask = GraphBuilder . CreateUAV ( OutRTWriteMask ) ;
for ( uint32 Index = 0 ; Index < NumRenderTargets ; + + Index )
{
2020-10-09 22:42:26 -04:00
PassParameters - > RTWriteMaskInputs [ Index ] = GraphBuilder . CreateSRV ( FRDGTextureSRVDesc : : CreateForMetaData ( RenderTargets [ Index ] , ERDGTextureMetaDataAccess : : CMask ) ) ;
2020-09-24 00:43:27 -04:00
}
FRTWriteMaskDecodeCS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FRTWriteMaskDecodeCS : : FNumRenderTargets > ( NumRenderTargets ) ;
TShaderMapRef < FRTWriteMaskDecodeCS > DecodeCS ( ShaderMap , PermutationVector ) ;
GraphBuilder . AddPass (
RDG_EVENT_NAME ( " DecodeWriteMask[%d] " , NumRenderTargets ) ,
PassParameters ,
ERDGPassFlags : : Compute ,
[ DecodeCS , PassParameters , ShaderMap , RTWriteMaskDims ] ( FRHIComputeCommandList & RHICmdList )
{
FRHITexture * Texture0RHI = PassParameters - > ReferenceInput - > GetRHI ( ) ;
// Retrieve the platform specific data that the decode shader needs.
void * PlatformDataPtr = nullptr ;
uint32 PlatformDataSize = 0 ;
Texture0RHI - > GetWriteMaskProperties ( PlatformDataPtr , PlatformDataSize ) ;
check ( PlatformDataSize > 0 ) ;
if ( PlatformDataPtr = = nullptr )
{
// If the returned pointer was null, the platform RHI wants us to allocate the memory instead.
PlatformDataPtr = alloca ( PlatformDataSize ) ;
Texture0RHI - > GetWriteMaskProperties ( PlatformDataPtr , PlatformDataSize ) ;
}
2022-02-08 13:19:37 -05:00
SetComputePipelineState ( RHICmdList , DecodeCS . GetComputeShader ( ) ) ;
2020-09-24 00:43:27 -04:00
SetShaderParameters ( RHICmdList , DecodeCS , DecodeCS . GetComputeShader ( ) , * PassParameters ) ;
DecodeCS - > SetPlatformData ( RHICmdList , PlatformDataPtr , PlatformDataSize ) ;
RHICmdList . DispatchComputeShader (
FMath : : DivideAndRoundUp ( ( uint32 ) RTWriteMaskDims . X , FRTWriteMaskDecodeCS : : ThreadGroupSizeX ) ,
FMath : : DivideAndRoundUp ( ( uint32 ) RTWriteMaskDims . Y , FRTWriteMaskDecodeCS : : ThreadGroupSizeY ) ,
1 ) ;
} ) ;
2021-02-05 11:29:40 -04:00
}
FDepthBounds : : FDepthBoundsValues FDepthBounds : : CalculateNearFarDepthExcludingSky ( )
{
FDepthBounds : : FDepthBoundsValues Values ;
if ( bool ( ERHIZBuffer : : IsInverted ) )
{
//const float SmallestFloatAbove0 = 1.1754943508e-38; // 32bit float depth
const float SmallestFloatAbove0 = 1.0f / 16777215.0f ; // 24bit norm depth
Values . MinDepth = SmallestFloatAbove0 ;
Values . MaxDepth = float ( ERHIZBuffer : : NearPlane ) ;
}
else
{
//const float SmallestFloatBelow1 = 0.9999999404; // 32bit float depth
const float SmallestFloatBelow1 = 16777214.0f / 16777215.0f ; // 24bit norm depth
Values . MinDepth = float ( ERHIZBuffer : : NearPlane ) ;
Values . MaxDepth = SmallestFloatBelow1 ;
}
return Values ;
}