2019-12-26 15:33:43 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2018-05-23 21:04:31 -04:00
//
# include "MaterialStatsCommon.h"
# include "EngineGlobals.h"
# include "MaterialStats.h"
# include "LocalVertexFactory.h"
# include "GPUSkinVertexFactory.h"
# include "MaterialEditorSettings.h"
2019-05-24 11:51:54 -04:00
# include "RHIShaderFormatDefinitions.inl"
2020-06-23 18:40:00 -04:00
# include "ShaderCompilerCore.h"
2021-02-16 15:32:41 -04:00
# include "Styling/StyleColors.h"
2018-05-23 21:04:31 -04:00
/***********************************************************************************************************************/
/*begin FMaterialResourceStats functions*/
void FMaterialResourceStats : : SetupExtaCompilationSettings ( const EShaderPlatform Platform , FExtraShaderCompilerSettings & Settings ) const
{
Settings . bExtractShaderSource = true ;
Settings . OfflineCompilerPath = FMaterialStatsUtils : : GetPlatformOfflineCompilerPath ( Platform ) ;
}
/*end FMaterialResourceStats functions*/
/***********************************************************************************************************************/
/***********************************************************************************************************************/
/*begin FMaterialStatsUtils */
TSharedPtr < FMaterialStats > FMaterialStatsUtils : : CreateMaterialStats ( class IMaterialEditor * MaterialEditor )
{
TSharedPtr < FMaterialStats > MaterialStats = MakeShareable ( new FMaterialStats ( ) ) ;
MaterialStats - > Initialize ( MaterialEditor ) ;
return MaterialStats ;
}
FString FMaterialStatsUtils : : MaterialQualityToString ( const EMaterialQualityLevel : : Type Quality )
{
FString StrQuality ;
switch ( Quality )
{
case EMaterialQualityLevel : : High :
StrQuality = TEXT ( " High Quality " ) ;
break ;
case EMaterialQualityLevel : : Medium :
StrQuality = TEXT ( " Medium Quality " ) ;
break ;
case EMaterialQualityLevel : : Low :
StrQuality = TEXT ( " Low Quality " ) ;
break ;
2020-09-01 14:07:48 -04:00
case EMaterialQualityLevel : : Epic :
StrQuality = TEXT ( " Epic Quality " ) ;
break ;
2018-05-23 21:04:31 -04:00
}
return StrQuality ;
}
FString FMaterialStatsUtils : : MaterialQualityToShortString ( const EMaterialQualityLevel : : Type Quality )
{
FString StrQuality ;
switch ( Quality )
{
case EMaterialQualityLevel : : High :
StrQuality = TEXT ( " High " ) ;
break ;
case EMaterialQualityLevel : : Medium :
StrQuality = TEXT ( " Medium " ) ;
break ;
case EMaterialQualityLevel : : Low :
StrQuality = TEXT ( " Low " ) ;
break ;
2020-09-01 14:07:48 -04:00
case EMaterialQualityLevel : : Epic :
StrQuality = TEXT ( " Epic " ) ;
break ;
2018-05-23 21:04:31 -04:00
}
return StrQuality ;
}
EMaterialQualityLevel : : Type FMaterialStatsUtils : : StringToMaterialQuality ( const FString & StrQuality )
{
if ( StrQuality . Equals ( TEXT ( " High Quality " ) ) )
{
return EMaterialQualityLevel : : High ;
}
else if ( StrQuality . Equals ( TEXT ( " Medium Quality " ) ) )
{
return EMaterialQualityLevel : : Medium ;
}
else if ( StrQuality . Equals ( TEXT ( " Low Quality " ) ) )
{
return EMaterialQualityLevel : : Low ;
}
2020-09-01 14:07:48 -04:00
else if ( StrQuality . Equals ( TEXT ( " Epic Quality " ) ) )
{
return EMaterialQualityLevel : : Epic ;
}
2018-05-23 21:04:31 -04:00
return EMaterialQualityLevel : : Num ;
}
FString FMaterialStatsUtils : : GetPlatformTypeName ( const EPlatformCategoryType InEnumValue )
{
FString PlatformName ;
switch ( InEnumValue )
{
case EPlatformCategoryType : : Desktop :
PlatformName = FString ( " Desktop " ) ;
break ;
case EPlatformCategoryType : : Android :
PlatformName = FString ( " Android " ) ;
break ;
case EPlatformCategoryType : : IOS :
PlatformName = FString ( " IOS " ) ;
break ;
2020-01-24 18:07:01 -05:00
case EPlatformCategoryType : : Console :
PlatformName = FString ( " Console " ) ;
break ;
2018-05-23 21:04:31 -04:00
}
return PlatformName ;
}
FString FMaterialStatsUtils : : ShaderPlatformTypeName ( const EShaderPlatform PlatformID )
{
2021-11-18 14:37:34 -05:00
FString FormatName = LexToString ( PlatformID ) ;
if ( FormatName . StartsWith ( TEXT ( " SF_ " ) ) )
2018-05-23 21:04:31 -04:00
{
2021-11-18 14:37:34 -05:00
FormatName . MidInline ( 3 , MAX_int32 , false ) ;
2018-05-23 21:04:31 -04:00
}
2021-11-18 14:37:34 -05:00
return FormatName ;
2018-05-23 21:04:31 -04:00
}
FString FMaterialStatsUtils : : GetPlatformOfflineCompilerPath ( const EShaderPlatform ShaderPlatform )
{
2021-11-18 14:37:34 -05:00
if ( FDataDrivenShaderPlatformInfo : : GetNeedsOfflineCompiler ( ShaderPlatform ) )
2018-05-23 21:04:31 -04:00
{
2021-11-18 14:37:34 -05:00
if ( FDataDrivenShaderPlatformInfo : : GetIsAndroidOpenGLES ( ShaderPlatform )
| | ( FDataDrivenShaderPlatformInfo : : GetIsLanguageVulkan ( ShaderPlatform ) & & FDataDrivenShaderPlatformInfo : : GetIsMobile ( ShaderPlatform ) ) )
{
2018-05-23 21:04:31 -04:00
return FPaths : : ConvertRelativePathToFull ( GetDefault < UMaterialEditorSettings > ( ) - > MaliOfflineCompilerPath . FilePath ) ;
2021-11-18 14:37:34 -05:00
}
2018-05-23 21:04:31 -04:00
}
return FString ( ) ;
}
bool FMaterialStatsUtils : : IsPlatformOfflineCompilerAvailable ( const EShaderPlatform ShaderPlatform )
{
FString CompilerPath = GetPlatformOfflineCompilerPath ( ShaderPlatform ) ;
bool bCompilerExists = FPaths : : FileExists ( CompilerPath ) ;
return bCompilerExists ;
}
bool FMaterialStatsUtils : : PlatformNeedsOfflineCompiler ( const EShaderPlatform ShaderPlatform )
{
2021-11-18 14:37:34 -05:00
return FDataDrivenShaderPlatformInfo : : GetNeedsOfflineCompiler ( ShaderPlatform ) ;
2018-05-23 21:04:31 -04:00
}
FString FMaterialStatsUtils : : RepresentativeShaderTypeToString ( const ERepresentativeShader ShaderType )
{
switch ( ShaderType )
{
case ERepresentativeShader : : StationarySurface :
return TEXT ( " Stationary surface " ) ;
break ;
case ERepresentativeShader : : StationarySurfaceCSM :
return TEXT ( " Stationary surface + CSM " ) ;
break ;
case ERepresentativeShader : : StationarySurfaceNPointLights :
return TEXT ( " Stationary surface + Point Lights " ) ;
break ;
case ERepresentativeShader : : DynamicallyLitObject :
return TEXT ( " Dynamically lit object " ) ;
break ;
case ERepresentativeShader : : StaticMesh :
return TEXT ( " Static Mesh " ) ;
break ;
case ERepresentativeShader : : SkeletalMesh :
return TEXT ( " Skeletal Mesh " ) ;
break ;
case ERepresentativeShader : : UIDefaultFragmentShader :
return TEXT ( " UI Pixel Shader " ) ;
break ;
case ERepresentativeShader : : UIDefaultVertexShader :
return TEXT ( " UI Vertex Shader " ) ;
break ;
case ERepresentativeShader : : UIInstancedVertexShader :
return TEXT ( " UI Instanced Vertex Shader " ) ;
break ;
default :
return TEXT ( " Unknown shader name " ) ;
break ;
}
}
2021-02-16 15:32:41 -04:00
FSlateColor FMaterialStatsUtils : : PlatformTypeColor ( EPlatformCategoryType PlatformType )
2018-05-23 21:04:31 -04:00
{
2021-02-16 15:32:41 -04:00
FSlateColor Color ( FStyleColors : : Foreground ) ;
2018-05-23 21:04:31 -04:00
switch ( PlatformType )
{
case EPlatformCategoryType : : Desktop :
2021-02-16 15:32:41 -04:00
Color = FStyleColors : : AccentBlue ;
2018-05-23 21:04:31 -04:00
break ;
case EPlatformCategoryType : : Android :
2021-02-16 15:32:41 -04:00
Color = FStyleColors : : AccentGreen ;
2018-05-23 21:04:31 -04:00
break ;
case EPlatformCategoryType : : IOS :
2021-02-16 15:32:41 -04:00
Color = FStyleColors : : AccentYellow ;
2018-05-23 21:04:31 -04:00
break ;
2020-01-24 18:07:01 -05:00
case EPlatformCategoryType : : Console :
2021-02-16 15:32:41 -04:00
Color = FStyleColors : : AccentPurple ;
2020-01-24 18:07:01 -05:00
break ;
2018-05-23 21:04:31 -04:00
default :
return Color ;
break ;
}
return Color ;
}
2021-02-16 15:32:41 -04:00
FSlateColor FMaterialStatsUtils : : QualitySettingColor ( const EMaterialQualityLevel : : Type QualityType )
2018-05-23 21:04:31 -04:00
{
switch ( QualityType )
{
case EMaterialQualityLevel : : Low :
2021-02-16 15:32:41 -04:00
return FStyleColors : : AccentGreen ;
2018-05-23 21:04:31 -04:00
break ;
case EMaterialQualityLevel : : High :
2021-02-16 15:32:41 -04:00
return FStyleColors : : AccentOrange ;
2018-05-23 21:04:31 -04:00
break ;
case EMaterialQualityLevel : : Medium :
2021-02-16 15:32:41 -04:00
return FStyleColors : : Warning ;
2018-05-23 21:04:31 -04:00
break ;
2020-09-01 14:07:48 -04:00
case EMaterialQualityLevel : : Epic :
2021-02-16 15:32:41 -04:00
return FStyleColors : : Error ;
2020-09-01 14:07:48 -04:00
break ;
2018-05-23 21:04:31 -04:00
default :
2021-02-16 15:32:41 -04:00
return FStyleColors : : Foreground ;
2018-05-23 21:04:31 -04:00
break ;
}
2021-02-16 15:32:41 -04:00
return FStyleColors : : Foreground ;
2018-05-23 21:04:31 -04:00
}
2022-01-18 18:45:37 -05:00
static void MobileBasePassShaderName ( bool bVertexShader , const TCHAR * PolicyName , int32 NumPointLigts , bool bHDR , bool bSkyLight , FString & OutName )
{
OutName . Reset ( ) ;
OutName . Append ( bVertexShader ? TEXT ( " TMobileBasePassVS " ) : TEXT ( " TMobileBasePassPS " ) ) ;
OutName . Append ( PolicyName ) ;
if ( ! bVertexShader )
{
if ( NumPointLigts = = INT32_MAX )
{
OutName . Append ( TEXT ( " INT32_MAX " ) ) ;
}
else
{
OutName . AppendInt ( NumPointLigts ) ;
}
}
OutName . Append ( bHDR ? TEXT ( " HDRLinear64 " ) : TEXT ( " LDRGamma32 " ) ) ;
if ( ! bVertexShader & & bSkyLight )
{
OutName . Append ( TEXT ( " SkyLight " ) ) ;
}
}
2018-05-23 21:04:31 -04:00
void FMaterialStatsUtils : : GetRepresentativeShaderTypesAndDescriptions ( TMap < FName , TArray < FRepresentativeShaderInfo > > & ShaderTypeNamesAndDescriptions , const FMaterial * TargetMaterial )
{
static auto * MobileHDR = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.MobileHDR " ) ) ;
bool bMobileHDR = MobileHDR & & MobileHDR - > GetValueOnAnyThread ( ) = = 1 ;
static const FName FLocalVertexFactoryName = FLocalVertexFactory : : StaticType . GetFName ( ) ;
2020-08-11 01:36:57 -04:00
static const FName FGPUFactoryName = TEXT ( " TGPUSkinVertexFactoryDefault " ) ;
2018-05-23 21:04:31 -04:00
if ( TargetMaterial - > IsUIMaterial ( ) )
{
2020-02-21 20:09:03 -05:00
static FName TSlateMaterialShaderPSDefaultName = TEXT ( " TSlateMaterialShaderPSDefault " ) ;
2018-05-23 21:04:31 -04:00
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
2020-02-21 20:09:03 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : UIDefaultFragmentShader , TSlateMaterialShaderPSDefaultName , TEXT ( " Default UI Pixel Shader " ) ) ) ;
2018-05-23 21:04:31 -04:00
static FName TSlateMaterialShaderVSfalseName = TEXT ( " TSlateMaterialShaderVSfalse " ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : UIDefaultVertexShader , TSlateMaterialShaderVSfalseName , TEXT ( " Default UI Vertex Shader " ) ) ) ;
static FName TSlateMaterialShaderVStrueName = TEXT ( " TSlateMaterialShaderVStrue " ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : UIInstancedVertexShader , TSlateMaterialShaderVStrueName , TEXT ( " Instanced UI Vertex Shader " ) ) ) ;
}
2019-09-14 09:45:25 -04:00
else if ( TargetMaterial - > GetFeatureLevel ( ) > = ERHIFeatureLevel : : SM5 )
2018-05-23 21:04:31 -04:00
{
2019-05-06 06:04:18 -04:00
if ( TargetMaterial - > GetShadingModels ( ) . IsUnlit ( ) )
2018-05-23 21:04:31 -04:00
{
//unlit materials are never lightmapped
static FName TBasePassPSFNoLightMapPolicyName = TEXT ( " TBasePassPSFNoLightMapPolicy " ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StationarySurface , TBasePassPSFNoLightMapPolicyName , TEXT ( " Base pass shader without light map " ) ) ) ;
}
else
{
//also show a dynamically lit shader
static FName TBasePassPSFNoLightMapPolicyName = TEXT ( " TBasePassPSFNoLightMapPolicy " ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : DynamicallyLitObject , TBasePassPSFNoLightMapPolicyName , TEXT ( " Base pass shader " ) ) ) ;
static auto * CVarAllowStaticLighting = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.AllowStaticLighting " ) ) ;
const bool bAllowStaticLighting = CVarAllowStaticLighting - > GetValueOnAnyThread ( ) ! = 0 ;
if ( bAllowStaticLighting )
{
if ( TargetMaterial - > IsUsedWithStaticLighting ( ) )
{
static FName TBasePassPSTLightMapPolicyName = TEXT ( " TBasePassPSTDistanceFieldShadowsAndLightMapPolicyHQ " ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StationarySurface , TBasePassPSTLightMapPolicyName , TEXT ( " Base pass shader with Surface Lightmap " ) ) ) ;
}
static FName TBasePassPSFPrecomputedVolumetricLightmapLightingPolicyName = TEXT ( " TBasePassPSFPrecomputedVolumetricLightmapLightingPolicy " ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : DynamicallyLitObject , TBasePassPSFPrecomputedVolumetricLightmapLightingPolicyName , TEXT ( " Base pass shader with Volumetric Lightmap " ) ) ) ;
}
}
static FName TBasePassVSFNoLightMapPolicyName = TEXT ( " TBasePassVSFNoLightMapPolicy " ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StaticMesh , TBasePassVSFNoLightMapPolicyName , TEXT ( " Base pass vertex shader " ) ) ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FGPUFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : SkeletalMesh , TBasePassVSFNoLightMapPolicyName , TEXT ( " Base pass vertex shader " ) ) ) ;
}
else
{
const TCHAR * DescSuffix = bMobileHDR ? TEXT ( " (HDR) " ) : TEXT ( " (LDR) " ) ;
2022-01-18 18:45:37 -05:00
FString ShaderNameStr ;
2018-05-23 21:04:31 -04:00
2019-05-06 06:04:18 -04:00
if ( TargetMaterial - > GetShadingModels ( ) . IsUnlit ( ) )
2018-05-23 21:04:31 -04:00
{
//unlit materials are never lightmapped
2022-01-18 18:45:37 -05:00
MobileBasePassShaderName ( false , TEXT ( " FNoLightMapPolicy " ) , 0 , bMobileHDR , false , ShaderNameStr ) ;
2018-05-23 21:04:31 -04:00
const FString Description = FString : : Printf ( TEXT ( " Mobile base pass shader without light map%s " ) , DescSuffix ) ;
ShaderTypeNamesAndDescriptions . Add ( FLocalVertexFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StationarySurface , FName ( ShaderNameStr ) , Description ) ) ;
2020-09-24 00:43:27 -04:00
2022-01-18 18:45:37 -05:00
MobileBasePassShaderName ( true , TEXT ( " FNoLightMapPolicy " ) , 0 , bMobileHDR , false , ShaderNameStr ) ;
2020-09-24 00:43:27 -04:00
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StaticMesh , FName ( ShaderNameStr ) ,
2020-09-24 00:43:27 -04:00
FString : : Printf ( TEXT ( " Mobile base pass vertex shader%s " ) , DescSuffix ) ) ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FGPUFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : SkeletalMesh , FName ( ShaderNameStr ) ,
2020-09-24 00:43:27 -04:00
FString : : Printf ( TEXT ( " Mobile base pass vertex shader%s " ) , DescSuffix ) ) ) ;
2018-05-23 21:04:31 -04:00
}
else
{
2021-04-08 14:32:07 -04:00
static auto * CVarAllowStaticLighting = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.AllowStaticLighting " ) ) ;
const bool bAllowStaticLighting = CVarAllowStaticLighting - > GetValueOnAnyThread ( ) ! = 0 ;
2018-09-25 10:11:35 -04:00
static auto * CVarMobileSkyLightPermutation = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.Mobile.SkyLightPermutation " ) ) ;
const bool bOnlySkyPermutation = CVarMobileSkyLightPermutation - > GetValueOnAnyThread ( ) = = 2 ;
2021-04-08 14:32:07 -04:00
if ( bAllowStaticLighting & & TargetMaterial - > IsUsedWithStaticLighting ( ) )
2018-05-23 21:04:31 -04:00
{
2021-04-08 14:32:07 -04:00
static auto * CVarAllowDistanceFieldShadows = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.Mobile.AllowDistanceFieldShadows " ) ) ;
const bool bAllowDistanceFieldShadows = CVarAllowDistanceFieldShadows - > GetValueOnAnyThread ( ) ! = 0 ;
static auto * CVarPointLights = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.MobileNumDynamicPointLights " ) ) ;
const bool bPointLights = CVarPointLights - > GetValueOnAnyThread ( ) > 0 ;
2021-10-21 05:35:48 -04:00
const int32 NumPointLights = CVarPointLights - > GetValueOnAnyThread ( ) ;
2021-04-08 14:32:07 -04:00
2018-05-23 21:04:31 -04:00
if ( bAllowDistanceFieldShadows ) // distance field shadows
{
// distance field shadows only shaders
{
2022-01-18 18:45:37 -05:00
MobileBasePassShaderName ( false , TEXT ( " FMobileDistanceFieldShadowsAndLQLightMapPolicy " ) , 0 , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
2018-05-23 21:04:31 -04:00
const FString Description = FString : : Printf ( TEXT ( " Mobile base pass shader with distance field shadows%s " ) , DescSuffix ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StationarySurface , FName ( ShaderNameStr ) , Description ) ) ;
2018-05-23 21:04:31 -04:00
}
static auto * CVarAllowDistanceFieldShadowsAndCSM = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.Mobile.EnableStaticAndCSMShadowReceivers " ) ) ;
const bool bAllowDistanceFieldShadowsAndCSM = CVarAllowDistanceFieldShadowsAndCSM - > GetValueOnAnyThread ( ) ! = 0 ;
if ( bAllowDistanceFieldShadowsAndCSM )
{
// distance field shadows & CSM shaders
{
2022-01-18 18:45:37 -05:00
MobileBasePassShaderName ( false , TEXT ( " FMobileDistanceFieldShadowsLightMapAndCSMLightingPolicy " ) , 0 , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
2018-05-23 21:04:31 -04:00
const FString Description = FString : : Printf ( TEXT ( " Mobile base pass shader with distance field shadows and CSM%s " ) , DescSuffix ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StationarySurfaceCSM , FName ( ShaderNameStr ) , Description ) ) ;
2018-05-23 21:04:31 -04:00
}
if ( bPointLights ) // add point lights shaders + distance field shadows
{
2022-01-18 18:45:37 -05:00
MobileBasePassShaderName ( false , TEXT ( " FMobileDistanceFieldShadowsAndLQLightMapPolicy " ) , INT32_MAX , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
2021-10-29 05:45:24 -04:00
const FString Description = FString : : Printf ( TEXT ( " Mobile base pass shader with distance field shadows, CSM and %d point light(s) %s " ) , NumPointLights , DescSuffix ) ;
2018-05-23 21:04:31 -04:00
2022-01-18 18:45:37 -05:00
FRepresentativeShaderInfo ShaderInfo = FRepresentativeShaderInfo ( ERepresentativeShader : : StationarySurfaceNPointLights , FName ( ShaderNameStr ) , Description ) ;
2018-05-23 21:04:31 -04:00
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName ) . Add ( ShaderInfo ) ;
}
}
}
else //no shadows & lightmapped
{
2022-01-18 18:45:37 -05:00
MobileBasePassShaderName ( false , TEXT ( " TLightMapPolicyLQ " ) , 0 , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
2018-05-23 21:04:31 -04:00
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StationarySurface , FName ( ShaderNameStr ) ,
2018-05-23 21:04:31 -04:00
FString : : Printf ( TEXT ( " Mobile base pass shader with static lighting%s " ) , DescSuffix ) ) ) ;
if ( bPointLights ) // add point lights + lightmap
{
2022-01-18 18:45:37 -05:00
MobileBasePassShaderName ( false , TEXT ( " TLightMapPolicyLQ " ) , INT32_MAX , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
2021-10-29 05:45:24 -04:00
const FString Description = FString : : Printf ( TEXT ( " Mobile base pass shader with static lighting and %d point light(s) %s " ) , NumPointLights , DescSuffix ) ;
2018-05-23 21:04:31 -04:00
2022-01-18 18:45:37 -05:00
FRepresentativeShaderInfo ShaderInfo = FRepresentativeShaderInfo ( ERepresentativeShader : : StationarySurfaceNPointLights , FName ( ShaderNameStr ) , Description ) ;
2018-05-23 21:04:31 -04:00
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName ) . Add ( ShaderInfo ) ;
}
}
}
2022-01-18 18:45:37 -05:00
// only one of these 2 shader types will be displayed
2018-09-25 10:11:35 -04:00
2022-01-18 18:45:37 -05:00
// dynamically lit shader NoLightmapPolicy
MobileBasePassShaderName ( false , TEXT ( " FNoLightmapPolicy " ) , 0 , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
2018-05-23 21:04:31 -04:00
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : DynamicallyLitObject , FName ( ShaderNameStr ) ,
2018-05-23 21:04:31 -04:00
FString : : Printf ( TEXT ( " Mobile base pass shader with only dynamic lighting%s " ) , DescSuffix ) ) ) ;
2022-01-18 18:45:37 -05:00
MobileBasePassShaderName ( true , TEXT ( " FNoLightMapPolicy " ) , 0 , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
2018-05-23 21:04:31 -04:00
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StaticMesh , FName ( ShaderNameStr ) ,
2018-05-23 21:04:31 -04:00
FString : : Printf ( TEXT ( " Mobile base pass vertex shader%s " ) , DescSuffix ) ) ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FGPUFactoryName )
2022-01-18 18:45:37 -05:00
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : SkeletalMesh , FName ( ShaderNameStr ) ,
FString : : Printf ( TEXT ( " Mobile base pass vertex shader%s " ) , DescSuffix ) ) ) ;
// dynamically lit shader FMobileDirectionalLightAndCSMPolicy
MobileBasePassShaderName ( false , TEXT ( " FMobileDirectionalLightAndCSMPolicy " ) , 0 , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : DynamicallyLitObject , FName ( ShaderNameStr ) ,
FString : : Printf ( TEXT ( " Mobile base pass shader with only dynamic lighting%s " ) , DescSuffix ) ) ) ;
MobileBasePassShaderName ( true , TEXT ( " FMobileDirectionalLightAndCSMPolicy " ) , 0 , bMobileHDR , bOnlySkyPermutation , ShaderNameStr ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FLocalVertexFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : StaticMesh , FName ( ShaderNameStr ) ,
FString : : Printf ( TEXT ( " Mobile base pass vertex shader%s " ) , DescSuffix ) ) ) ;
ShaderTypeNamesAndDescriptions . FindOrAdd ( FGPUFactoryName )
. Add ( FRepresentativeShaderInfo ( ERepresentativeShader : : SkeletalMesh , FName ( ShaderNameStr ) ,
2018-05-23 21:04:31 -04:00
FString : : Printf ( TEXT ( " Mobile base pass vertex shader%s " ) , DescSuffix ) ) ) ;
}
}
}
/**
* Gets instruction counts that best represent the likely usage of this material based on shading model and other factors .
* @ param Results - an array of descriptions to be populated
*/
void FMaterialStatsUtils : : GetRepresentativeInstructionCounts ( TArray < FShaderInstructionsInfo > & Results , const FMaterialResource * Target )
{
TMap < FName , TArray < FRepresentativeShaderInfo > > ShaderTypeNamesAndDescriptions ;
Results . Empty ( ) ;
//when adding a shader type here be sure to update FPreviewMaterial::ShouldCache()
//so the shader type will get compiled with preview materials
const FMaterialShaderMap * MaterialShaderMap = Target - > GetGameThreadShaderMap ( ) ;
if ( MaterialShaderMap & & MaterialShaderMap - > IsCompilationFinalized ( ) )
{
GetRepresentativeShaderTypesAndDescriptions ( ShaderTypeNamesAndDescriptions , Target ) ;
2022-01-18 18:45:37 -05:00
TStaticArray < bool , ( int32 ) ERepresentativeShader : : Num > bShaderTypeAdded ( InPlace , false ) ;
2018-05-23 21:04:31 -04:00
if ( Target - > IsUIMaterial ( ) )
{
//for (const TPair<FName, FRepresentativeShaderInfo>& ShaderTypePair : ShaderTypeNamesAndDescriptions)
for ( auto DescriptionPair : ShaderTypeNamesAndDescriptions )
{
auto & DescriptionArray = DescriptionPair . Value ;
for ( int32 i = 0 ; i < DescriptionArray . Num ( ) ; + + i )
{
const FRepresentativeShaderInfo & ShaderInfo = DescriptionArray [ i ] ;
2022-01-18 18:45:37 -05:00
if ( ! bShaderTypeAdded [ ( int32 ) ShaderInfo . ShaderType ] )
{
FShaderType * ShaderType = FindShaderTypeByName ( ShaderInfo . ShaderName ) ;
check ( ShaderType ) ;
const int32 NumInstructions = MaterialShaderMap - > GetMaxNumInstructionsForShader ( ShaderType ) ;
2018-05-23 21:04:31 -04:00
2022-01-18 18:45:37 -05:00
FShaderInstructionsInfo Info ;
Info . ShaderType = ShaderInfo . ShaderType ;
Info . ShaderDescription = ShaderInfo . ShaderDescription ;
Info . InstructionCount = NumInstructions ;
2018-05-23 21:04:31 -04:00
2022-01-18 18:45:37 -05:00
Results . Push ( Info ) ;
2018-05-23 21:04:31 -04:00
2022-01-18 18:45:37 -05:00
bShaderTypeAdded [ ( int32 ) ShaderInfo . ShaderType ] = true ;
}
2018-05-23 21:04:31 -04:00
}
}
}
else
{
for ( auto DescriptionPair : ShaderTypeNamesAndDescriptions )
{
FVertexFactoryType * FactoryType = FindVertexFactoryType ( DescriptionPair . Key ) ;
const FMeshMaterialShaderMap * MeshShaderMap = MaterialShaderMap - > GetMeshShaderMap ( FactoryType ) ;
if ( MeshShaderMap )
{
2020-02-06 13:13:41 -05:00
TMap < FHashedName , TShaderRef < FShader > > ShaderMap ;
MeshShaderMap - > GetShaderList ( * MaterialShaderMap , ShaderMap ) ;
2018-05-23 21:04:31 -04:00
auto & DescriptionArray = DescriptionPair . Value ;
for ( int32 i = 0 ; i < DescriptionArray . Num ( ) ; + + i )
{
const FRepresentativeShaderInfo & ShaderInfo = DescriptionArray [ i ] ;
2022-01-18 18:45:37 -05:00
if ( ! bShaderTypeAdded [ ( int32 ) ShaderInfo . ShaderType ] )
2018-05-23 21:04:31 -04:00
{
2022-01-18 18:45:37 -05:00
TShaderRef < FShader > * ShaderEntry = ShaderMap . Find ( ShaderInfo . ShaderName ) ;
if ( ShaderEntry ! = nullptr )
2018-05-23 21:04:31 -04:00
{
2022-01-18 18:45:37 -05:00
FShaderType * ShaderType = ( * ShaderEntry ) . GetType ( ) ;
{
const int32 NumInstructions = MeshShaderMap - > GetMaxNumInstructionsForShader ( * MaterialShaderMap , ShaderType ) ;
2018-05-23 21:04:31 -04:00
2022-01-18 18:45:37 -05:00
FShaderInstructionsInfo Info ;
Info . ShaderType = ShaderInfo . ShaderType ;
Info . ShaderDescription = ShaderInfo . ShaderDescription ;
Info . InstructionCount = NumInstructions ;
2018-05-23 21:04:31 -04:00
2022-01-18 18:45:37 -05:00
Results . Push ( Info ) ;
bShaderTypeAdded [ ( int32 ) ShaderInfo . ShaderType ] = true ;
}
2018-05-23 21:04:31 -04:00
}
}
}
}
}
}
}
}
void FMaterialStatsUtils : : ExtractMatertialStatsInfo ( FShaderStatsInfo & OutInfo , const FMaterialResource * MaterialResource )
{
// extract potential errors
const ERHIFeatureLevel : : Type MaterialFeatureLevel = MaterialResource - > GetFeatureLevel ( ) ;
FString FeatureLevelName ;
GetFeatureLevelName ( MaterialFeatureLevel , FeatureLevelName ) ;
OutInfo . Empty ( ) ;
TArray < FString > CompileErrors = MaterialResource - > GetCompileErrors ( ) ;
for ( int32 ErrorIndex = 0 ; ErrorIndex < CompileErrors . Num ( ) ; ErrorIndex + + )
{
OutInfo . StrShaderErrors + = FString : : Printf ( TEXT ( " [%s] %s \n " ) , * FeatureLevelName , * CompileErrors [ ErrorIndex ] ) ;
}
bool bNoErrors = OutInfo . StrShaderErrors . Len ( ) = = 0 ;
if ( bNoErrors )
{
// extract instructions info
TArray < FMaterialStatsUtils : : FShaderInstructionsInfo > ShaderInstructionInfo ;
GetRepresentativeInstructionCounts ( ShaderInstructionInfo , MaterialResource ) ;
for ( int32 InstructionIndex = 0 ; InstructionIndex < ShaderInstructionInfo . Num ( ) ; InstructionIndex + + )
{
FShaderStatsInfo : : FContent Content ;
Content . StrDescription = ShaderInstructionInfo [ InstructionIndex ] . InstructionCount > 0 ? FString : : Printf ( TEXT ( " %u " ) , ShaderInstructionInfo [ InstructionIndex ] . InstructionCount ) : TEXT ( " n/a " ) ;
Content . StrDescriptionLong = ShaderInstructionInfo [ InstructionIndex ] . InstructionCount > 0 ?
FString : : Printf ( TEXT ( " %s: %u instructions " ) , * ShaderInstructionInfo [ InstructionIndex ] . ShaderDescription , ShaderInstructionInfo [ InstructionIndex ] . InstructionCount ) :
TEXT ( " Offline shader compiler not available or an error was encountered! " ) ;
OutInfo . ShaderInstructionCount . Add ( ShaderInstructionInfo [ InstructionIndex ] . ShaderType , Content ) ;
}
// extract samplers info
const int32 SamplersUsed = FMath : : Max ( MaterialResource - > GetSamplerUsage ( ) , 0 ) ;
const int32 MaxSamplers = GetExpectedFeatureLevelMaxTextureSamplers ( MaterialResource - > GetFeatureLevel ( ) ) ;
OutInfo . SamplersCount . StrDescription = FString : : Printf ( TEXT ( " %u/%u " ) , SamplersUsed , MaxSamplers ) ;
OutInfo . SamplersCount . StrDescriptionLong = FString : : Printf ( TEXT ( " %s samplers: %u/%u " ) , TEXT ( " Texture " ) , SamplersUsed , MaxSamplers ) ;
// extract esimated sample info
uint32 NumVSTextureSamples = 0 , NumPSTextureSamples = 0 ;
MaterialResource - > GetEstimatedNumTextureSamples ( NumVSTextureSamples , NumPSTextureSamples ) ;
OutInfo . TextureSampleCount . StrDescription = FString : : Printf ( TEXT ( " VS(%u), PS(%u) " ) , NumVSTextureSamples , NumPSTextureSamples ) ;
OutInfo . TextureSampleCount . StrDescriptionLong = FString : : Printf ( TEXT ( " Texture Lookups (Est.): Vertex(%u), Pixel(%u) " ) , NumVSTextureSamples , NumPSTextureSamples ) ;
2019-06-11 18:27:07 -04:00
// extract estimated VT info
const uint32 NumVirtualTextureLookups = MaterialResource - > GetEstimatedNumVirtualTextureLookups ( ) ;
OutInfo . VirtualTextureLookupCount . StrDescription = FString : : Printf ( TEXT ( " %u " ) , NumVirtualTextureLookups ) ;
2020-08-11 01:36:57 -04:00
OutInfo . VirtualTextureLookupCount . StrDescriptionLong = FString : : Printf ( TEXT ( " Virtual Texture Lookups (Est.): %u " ) , NumVirtualTextureLookups ) ;
2019-06-11 18:27:07 -04:00
2018-05-23 21:04:31 -04:00
// extract interpolators info
uint32 UVScalarsUsed , CustomInterpolatorScalarsUsed ;
MaterialResource - > GetUserInterpolatorUsage ( UVScalarsUsed , CustomInterpolatorScalarsUsed ) ;
const uint32 TotalScalars = UVScalarsUsed + CustomInterpolatorScalarsUsed ;
const uint32 MaxScalars = FMath : : DivideAndRoundUp ( TotalScalars , 4u ) * 4 ;
OutInfo . InterpolatorsCount . StrDescription = FString : : Printf ( TEXT ( " %u/%u " ) , TotalScalars , MaxScalars ) ;
OutInfo . InterpolatorsCount . StrDescriptionLong = FString : : Printf ( TEXT ( " User interpolators: %u/%u Scalars (%u/4 Vectors) (TexCoords: %i, Custom: %i) " ) ,
TotalScalars , MaxScalars , MaxScalars / 4 , UVScalarsUsed , CustomInterpolatorScalarsUsed ) ;
2021-03-03 16:24:00 -04:00
// extract total shader count info
const uint32 ShaderCount = MaterialResource - > GetGameThreadShaderMap ( ) - > GetShaderNum ( ) ;
OutInfo . ShaderCount . StrDescription = FString : : Printf ( TEXT ( " %u " ) , ShaderCount ) ;
OutInfo . ShaderCount . StrDescriptionLong = FString : : Printf ( TEXT ( " Total Shaders: %u " ) , ShaderCount ) ;
2018-05-23 21:04:31 -04:00
}
}
/*end FMaterialStatsUtils */
2018-10-18 16:47:22 -04:00
/***********************************************************************************************************************/