Files
UnrealEngineUWP/Engine/Source/Developer/Windows/WindowsTargetPlatform/Private/GenericWindowsTargetPlatform.h
krzysztof narkowicz 2cdfb99ef8 Added per platform setting to toggle distance field support. If it's disabled then no distance data will be cooked and distance fields will be disabled on the target platform.
Renamed FDataDrivenPlatformInfo::AudioCompressionSettingsIniSectionName to TargetSettingsIniSectionName. It's now used to populate PlatformMask at runtime, to make sure that it matches between cook and runtime. Before it was possible to cook with e.g. GRayTracingPlaformMask=0, but then the cooked game would run with GRayTracingPlaformMask=1.

#rb Patrick.Kelly
[FYI] Patrick.Kelly, Daniel.Wright, Josh.Adams

#ROBOMERGE-OWNER: krzysztof.narkowicz
#ROBOMERGE-AUTHOR: krzysztof.narkowicz
#ROBOMERGE-SOURCE: CL 16825469 via CL 16825718
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v836-16769935)

[CL 16825756 by krzysztof narkowicz in ue5-release-engine-test branch]
2021-07-12 11:23:28 -04:00

510 lines
15 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Common/TargetPlatformBase.h"
#include "Misc/ConfigCacheIni.h"
#include "LocalPcTargetDevice.h"
#include "Serialization/MemoryLayout.h"
#if WITH_ENGINE
#include "Sound/SoundWave.h"
#include "TextureResource.h"
#include "Engine/VolumeTexture.h"
#include "StaticMeshResources.h"
#include "RHI.h"
#include "AudioCompressionSettings.h"
#endif // WITH_ENGINE
#define LOCTEXT_NAMESPACE "TGenericWindowsTargetPlatform"
/**
* Template for Windows target platforms
*/
template<bool HAS_EDITOR_DATA, bool IS_DEDICATED_SERVER, bool IS_CLIENT_ONLY>
class TGenericWindowsTargetPlatform
: public TTargetPlatformBase<FWindowsPlatformProperties<HAS_EDITOR_DATA, IS_DEDICATED_SERVER, IS_CLIENT_ONLY> >
{
public:
typedef FWindowsPlatformProperties<HAS_EDITOR_DATA, IS_DEDICATED_SERVER, IS_CLIENT_ONLY> TProperties;
typedef TTargetPlatformBase<TProperties> TSuper;
/**
* Default constructor.
*/
TGenericWindowsTargetPlatform( )
{
#if PLATFORM_WINDOWS
// only add local device if actually running on Windows
LocalDevice = MakeShareable(new TLocalPcTargetDevice<PLATFORM_64BITS>(*this));
#endif
#if WITH_ENGINE
TextureLODSettings = nullptr; // These are registered by the device profile system.
StaticMeshLODSettings.Initialize(this);
// Get the Target RHIs for this platform, we do not always want all those that are supported.
TArray<FName> TargetedShaderFormats;
GetAllTargetedShaderFormats(TargetedShaderFormats);
static FName NAME_PCD3D_SM6(TEXT("PCD3D_SM6"));
static FName NAME_PCD3D_SM5(TEXT("PCD3D_SM5"));
static FName NAME_VULKAN_SM5(TEXT("SF_VULKAN_SM5"));
bSupportDX11TextureFormats = true;
bSupportCompressedVolumeTexture = true;
for (FName TargetedShaderFormat : TargetedShaderFormats)
{
EShaderPlatform ShaderPlatform = SP_NumPlatforms;
// Can't use ShaderFormatToLegacyShaderPlatform() because of link dependency
{
if (TargetedShaderFormat == NAME_PCD3D_SM6)
{
ShaderPlatform = SP_PCD3D_SM6;
}
else if (TargetedShaderFormat == NAME_PCD3D_SM5)
{
ShaderPlatform = SP_PCD3D_SM5;
}
else if (TargetedShaderFormat == NAME_VULKAN_SM5)
{
ShaderPlatform = SP_VULKAN_SM5;
}
}
// If we're targeting only DX11 we can use DX11 texture formats. Otherwise we'd have to compress fallbacks and increase the size of cooked content significantly.
if (ShaderPlatform != SP_PCD3D_SM6 && ShaderPlatform != SP_PCD3D_SM5 && ShaderPlatform != SP_VULKAN_SM5)
{
bSupportDX11TextureFormats = false;
}
}
// If we are targeting ES3.1, we also must cook encoded HDR reflection captures
static FName NAME_SF_VULKAN_ES31(TEXT("SF_VULKAN_ES31"));
static FName NAME_OPENGL_150_ES3_1(TEXT("GLSL_150_ES31"));
static FName NAME_PCD3D_ES3_1(TEXT("PCD3D_ES31"));
bRequiresEncodedHDRReflectionCaptures = TargetedShaderFormats.Contains(NAME_SF_VULKAN_ES31)
|| TargetedShaderFormats.Contains(NAME_OPENGL_150_ES3_1)
|| TargetedShaderFormats.Contains(NAME_PCD3D_ES3_1);
#endif
}
public:
//~ Begin ITargetPlatform Interface
virtual void EnableDeviceCheck(bool OnOff) override {}
virtual void GetAllDevices( TArray<ITargetDevicePtr>& OutDevices ) const override
{
OutDevices.Reset();
if (LocalDevice.IsValid())
{
OutDevices.Add(LocalDevice);
}
}
virtual bool GenerateStreamingInstallManifest(const TMultiMap<FString, int32>& PakchunkMap, const TSet<int32>& PakchunkIndicesInUse) const override
{
return true;
}
virtual ITargetDevicePtr GetDefaultDevice( ) const override
{
if (LocalDevice.IsValid())
{
return LocalDevice;
}
return nullptr;
}
virtual ITargetDevicePtr GetDevice( const FTargetDeviceId& DeviceId )
{
if (LocalDevice.IsValid() && (DeviceId == LocalDevice->GetId()))
{
return LocalDevice;
}
return nullptr;
}
virtual bool IsRunningPlatform( ) const override
{
// Must be Windows platform as editor for this to be considered a running platform
return PLATFORM_WINDOWS && !UE_SERVER && !UE_GAME && WITH_EDITOR && HAS_EDITOR_DATA;
}
virtual void GetShaderCompilerDependencies(TArray<FString>& OutDependencies) const override
{
FTargetPlatformBase::AddDependencySCArrayHelper(OutDependencies, TEXT("Binaries/ThirdParty/Windows/DirectX/x64/d3dcompiler_47.dll"));
FTargetPlatformBase::AddDependencySCArrayHelper(OutDependencies, TEXT("Binaries/ThirdParty/ShaderConductor/Win64/ShaderConductor.dll"));
FTargetPlatformBase::AddDependencySCArrayHelper(OutDependencies, TEXT("Binaries/ThirdParty/ShaderConductor/Win64/dxcompiler.dll"));
FTargetPlatformBase::AddDependencySCArrayHelper(OutDependencies, TEXT("Binaries/ThirdParty/ShaderConductor/Win64/dxil.dll"));
}
virtual bool SupportsFeature( ETargetPlatformFeatures Feature ) const override
{
// we currently do not have a build target for WindowsServer
if (Feature == ETargetPlatformFeatures::Packaging)
{
return (HAS_EDITOR_DATA || !IS_DEDICATED_SERVER);
}
if ( Feature == ETargetPlatformFeatures::ShouldSplitPaksIntoSmallerSizes )
{
return IS_CLIENT_ONLY;
}
if (Feature == ETargetPlatformFeatures::MobileRendering)
{
static bool bCachedSupportsMobileRendering = false;
#if WITH_ENGINE
static bool bHasCachedValue = false;
if (!bHasCachedValue)
{
TArray<FName> TargetedShaderFormats;
GetAllTargetedShaderFormats(TargetedShaderFormats);
for (const FName& Format : TargetedShaderFormats)
{
if (IsMobilePlatform(ShaderFormatToLegacyShaderPlatform(Format)))
{
bCachedSupportsMobileRendering = true;
break;
}
}
bHasCachedValue = true;
}
#endif
return bCachedSupportsMobileRendering;
}
return TSuper::SupportsFeature(Feature);
}
virtual void GetBuildProjectSettingKeys(FString& OutSection, TArray<FString>& InBoolKeys, TArray<FString>& InIntKeys, TArray<FString>& InStringKeys) const override
{
OutSection = TEXT("/Script/WindowsTargetPlatform.WindowsTargetSettings");
InStringKeys.Add(TEXT("MinimumOSVersion"));
}
#if WITH_ENGINE
virtual void GetReflectionCaptureFormats(TArray<FName>& OutFormats) const override
{
if (bRequiresEncodedHDRReflectionCaptures)
{
OutFormats.Add(FName(TEXT("EncodedHDR")));
}
OutFormats.Add(FName(TEXT("FullHDR")));
}
virtual void GetAllPossibleShaderFormats( TArray<FName>& OutFormats ) const override
{
// no shaders needed for dedicated server target
if (!IS_DEDICATED_SERVER)
{
static FName NAME_PCD3D_SM6(TEXT("PCD3D_SM6"));
static FName NAME_PCD3D_SM5(TEXT("PCD3D_SM5"));
static FName NAME_VULKAN_ES31(TEXT("SF_VULKAN_ES31"));
static FName NAME_OPENGL_150_ES3_1(TEXT("GLSL_150_ES31"));
static FName NAME_VULKAN_SM5(TEXT("SF_VULKAN_SM5"));
static FName NAME_PCD3D_ES3_1(TEXT("PCD3D_ES31"));
OutFormats.AddUnique(NAME_PCD3D_SM5);
OutFormats.AddUnique(NAME_PCD3D_SM6);
OutFormats.AddUnique(NAME_VULKAN_ES31);
OutFormats.AddUnique(NAME_OPENGL_150_ES3_1);
OutFormats.AddUnique(NAME_VULKAN_SM5);
OutFormats.AddUnique(NAME_PCD3D_ES3_1);
}
}
virtual void GetAllTargetedShaderFormats( TArray<FName>& OutFormats ) const override
{
// Get the Target RHIs for this platform, we do not always want all those that are supported. (reload in case user changed in the editor)
TArray<FString>TargetedShaderFormats;
GConfig->GetArray(TEXT("/Script/WindowsTargetPlatform.WindowsTargetSettings"), TEXT("TargetedRHIs"), TargetedShaderFormats, GEngineIni);
// Gather the list of Target RHIs and filter out any that may be invalid.
TArray<FName> PossibleShaderFormats;
GetAllPossibleShaderFormats(PossibleShaderFormats);
for (int32 ShaderFormatIdx = TargetedShaderFormats.Num() - 1; ShaderFormatIdx >= 0; ShaderFormatIdx--)
{
FString ShaderFormat = TargetedShaderFormats[ShaderFormatIdx];
if (PossibleShaderFormats.Contains(FName(*ShaderFormat)) == false)
{
TargetedShaderFormats.RemoveAt(ShaderFormatIdx);
}
}
for(const FString& ShaderFormat : TargetedShaderFormats)
{
OutFormats.AddUnique(FName(*ShaderFormat));
}
}
virtual const class FStaticMeshLODSettings& GetStaticMeshLODSettings( ) const override
{
return StaticMeshLODSettings;
}
virtual void GetTextureFormats( const UTexture* InTexture, TArray< TArray<FName> >& OutFormats) const override
{
if (!IS_DEDICATED_SERVER)
{
GetDefaultTextureFormatNamePerLayer(OutFormats.AddDefaulted_GetRef(), this, InTexture, bSupportDX11TextureFormats, bSupportCompressedVolumeTexture);
}
}
virtual void GetAllTextureFormats(TArray<FName>& OutFormats) const override
{
if (!IS_DEDICATED_SERVER)
{
GetAllDefaultTextureFormats(this, OutFormats, bSupportDX11TextureFormats);
}
}
FName GetVirtualTextureLayerFormat(int32 SourceFormat, bool bAllowCompression, bool bNoAlpha, bool bDX11TextureFormatsSupported, int32 Settings) const override
{
FName TextureFormatName = NAME_None;
// Supported texture format names.
static FName NameDXT1(TEXT("DXT1"));
static FName NameDXT3(TEXT("DXT3"));
static FName NameDXT5(TEXT("DXT5"));
static FName NameDXT5n(TEXT("DXT5n"));
static FName NameBC4(TEXT("BC4"));
static FName NameBC5(TEXT("BC5"));
static FName NameBGRA8(TEXT("BGRA8"));
static FName NameXGXR8(TEXT("XGXR8"));
static FName NameG8(TEXT("G8"));
static FName NameG16(TEXT("G16"));
static FName NameVU8(TEXT("VU8"));
static FName NameRGBA16F(TEXT("RGBA16F"));
static FName NameR16F(TEXT("R16F"));
static FName NameBC6H(TEXT("BC6H"));
static FName NameBC7(TEXT("BC7"));
// Note: We can't use things here like autoDXT here which defer the exact choice to the compressor as it would mean that
// some textures on a VT layer may get a different format than others.
// We need to guarantee the format to be the same for all textures on the layer so we need to decide on the exact final format here.
bool bUseDXT5NormalMap = false;
FString UseDXT5NormalMapsString;
if (this->GetConfigSystem()->GetString(TEXT("SystemSettings"), TEXT("Compat.UseDXT5NormalMaps"), UseDXT5NormalMapsString, GEngineIni))
{
bUseDXT5NormalMap = FCString::ToBool(*UseDXT5NormalMapsString);
}
// Determine the pixel format of the (un/)compressed texture
if (!bAllowCompression)
{
if (SourceFormat == TSF_RGBA16F)
{
TextureFormatName = NameRGBA16F;
}
else if (SourceFormat == TSF_G16)
{
TextureFormatName = NameG16;
}
else if (SourceFormat == TSF_G8 || Settings == TC_Grayscale)
{
TextureFormatName = NameG8;
}
else if (Settings == TC_Normalmap && bUseDXT5NormalMap)
{
TextureFormatName = NameXGXR8;
}
else
{
TextureFormatName = NameBGRA8;
}
}
else if (Settings == TC_HDR)
{
TextureFormatName = NameRGBA16F;
}
else if (Settings == TC_Normalmap)
{
TextureFormatName = bUseDXT5NormalMap ? NameDXT5n : NameBC5;
}
else if (Settings == TC_Displacementmap)
{
TextureFormatName = NameG8;
}
else if (Settings == TC_VectorDisplacementmap)
{
TextureFormatName = NameBGRA8;
}
else if (Settings == TC_Grayscale)
{
TextureFormatName = NameG8;
}
else if (Settings == TC_Alpha)
{
TextureFormatName = NameBC4;
}
else if (Settings == TC_DistanceFieldFont)
{
TextureFormatName = NameG8;
}
else if (Settings == TC_HDR_Compressed)
{
TextureFormatName = NameBC6H;
}
else if (Settings == TC_BC7)
{
TextureFormatName = NameBC7;
}
else if (Settings == TC_HalfFloat)
{
TextureFormatName = NameR16F;
}
else if (bNoAlpha)
{
TextureFormatName = NameDXT1;
}
else
{
TextureFormatName = NameDXT5;
}
/*
FIXME: IS this still relevant for VT ? comes from the texture variant
// Some PC GPUs don't support sRGB read from G8 textures (e.g. AMD DX10 cards on ShaderModel3.0)
// This solution requires 4x more memory but a lot of PC HW emulate the format anyway
if ((TextureFormatName == NameG8) && Texture->SRGB && !SupportsFeature(ETargetPlatformFeatures::GrayscaleSRGB))
{
TextureFormatName = NameBGRA8;
}*/
// fallback to non-DX11 formats if one was chosen, but we can't use it
if (!bDX11TextureFormatsSupported)
{
if (TextureFormatName == NameBC6H)
{
TextureFormatName = NameRGBA16F;
}
else if (TextureFormatName == NameBC7)
{
TextureFormatName = NameDXT5;
}
}
return TextureFormatName;
}
virtual const UTextureLODSettings& GetTextureLODSettings() const override
{
return *TextureLODSettings;
}
virtual void RegisterTextureLODSettings(const UTextureLODSettings* InTextureLODSettings) override
{
TextureLODSettings = InTextureLODSettings;
}
virtual FName GetWaveFormat( const class USoundWave* Wave ) const override
{
static const FName NAME_ADPCM(TEXT("ADPCM"));
static const FName NAME_OGG(TEXT("OGG"));
static const FName NAME_OPUS(TEXT("OPUS"));
static const FName NAME_BINKA(TEXT("BINKA"));
if (Wave->bUseBinkAudio)
{
return NAME_BINKA;
}
// Seekable streams need to pick a codec which allows fixed-sized frames so we can compute stream chunk index to load
if (Wave->IsSeekableStreaming())
{
return NAME_ADPCM;
}
#if !USE_VORBIS_FOR_STREAMING
if (Wave->IsStreaming())
{
return NAME_OPUS;
}
#endif
return NAME_OGG;
}
virtual void GetAllWaveFormats(TArray<FName>& OutFormats) const override
{
static const FName NAME_ADPCM(TEXT("ADPCM"));
static const FName NAME_OGG(TEXT("OGG"));
static const FName NAME_OPUS(TEXT("OPUS"));
static const FName NAME_BINKA(TEXT("BINKA"));
OutFormats.Add(NAME_BINKA);
OutFormats.Add(NAME_ADPCM);
OutFormats.Add(NAME_OGG);
OutFormats.Add(NAME_OPUS);
}
#endif //WITH_ENGINE
virtual bool SupportsVariants() const override
{
return true;
}
virtual float GetVariantPriority() const override
{
return TProperties::GetVariantPriority();
}
virtual bool UsesDistanceFields() const override
{
bool bEnableDistanceFields = false;
GConfig->GetBool(TEXT("/Script/WindowsTargetPlatform.WindowsTargetSettings"), TEXT("bEnableDistanceFields"), bEnableDistanceFields, GEngineIni);
return bEnableDistanceFields && TSuper::UsesDistanceFields();
}
virtual bool UsesRayTracing() const override
{
bool bEnableRayTracing = false;
GConfig->GetBool(TEXT("/Script/WindowsTargetPlatform.WindowsTargetSettings"), TEXT("bEnableRayTracing"), bEnableRayTracing, GEngineIni);
return bEnableRayTracing && TSuper::UsesRayTracing();
}
//~ End ITargetPlatform Interface
private:
// Holds the local device.
ITargetDevicePtr LocalDevice;
#if WITH_ENGINE
// Holds the texture LOD settings.
const UTextureLODSettings* TextureLODSettings;
// Holds static mesh LOD settings.
FStaticMeshLODSettings StaticMeshLODSettings;
// True if the project supports non-DX11 texture formats.
bool bSupportDX11TextureFormats;
// True if the project requires encoded HDR reflection captures
bool bRequiresEncodedHDRReflectionCaptures;
// True if the project supports only compressed volume texture formats.
bool bSupportCompressedVolumeTexture;
#endif // WITH_ENGINE
};
#undef LOCTEXT_NAMESPACE