XinJiangBBH_LBE/Plugins/Streamline/Source/StreamlineBlueprint/Private/StreamlineLibrary.cpp

246 lines
8.9 KiB
C++
Raw Permalink Normal View History

2025-03-13 11:09:44 +08:00
/*
* Copyright (c) 2022 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
* property and proprietary rights in and to this material, related
* documentation and any modifications thereto. Any use, reproduction,
* disclosure or distribution of this material and related documentation
* without an express license agreement from NVIDIA CORPORATION or
* its affiliates is strictly prohibited.
*/
#include "StreamlineLibrary.h"
#include "StreamlineLibraryPrivate.h"
#include "StreamlineLibraryReflex.h"
#include "StreamlineLibraryDLSSG.h"
//#include "StreamlineLibraryDeepDVC.h"
#include "HAL/IConsoleManager.h"
#if WITH_STREAMLINE
#include "StreamlineCore.h"
#include "StreamlineDLSSG.h"
#include "StreamlineReflex.h"
#include "StreamlineDeepDVC.h"
#include "StreamlineRHI.h"
#include "StreamlineAPI.h"
#include "sl.h"
#include "sl_dlss_g.h"
#include "sl_reflex.h"
#include "sl_deepdvc.h"
#endif
#define LOCTEXT_NAMESPACE "FStreamlineBlueprintModule"
DEFINE_LOG_CATEGORY(LogStreamlineBlueprint);
TStaticArray<FStreamlineFeatureRequirements, static_cast<uint8>(UStreamlineFeature::Count)> UStreamlineLibrary::Features;
bool UStreamlineLibrary::bStreamlineLibraryInitialized = false;
#if WITH_STREAMLINE
UStreamlineFeatureSupport ToUStreamlineFeatureSupport(EStreamlineFeatureSupport Support)
{
static_assert(int32(EStreamlineFeatureSupport::NumValues) == 7, "dear NVIDIA plugin developer, please update this code to handle the new enum values ");
switch (Support)
{
case EStreamlineFeatureSupport::Supported: return UStreamlineFeatureSupport::Supported;
default:
/* Gotta catch them all*/
case EStreamlineFeatureSupport::NotSupported: return UStreamlineFeatureSupport::NotSupported;
case EStreamlineFeatureSupport::NotSupportedIncompatibleHardware: return UStreamlineFeatureSupport::NotSupportedIncompatibleHardware;
case EStreamlineFeatureSupport::NotSupportedDriverOutOfDate: return UStreamlineFeatureSupport::NotSupportedDriverOutOfDate;
case EStreamlineFeatureSupport::NotSupportedOperatingSystemOutOfDate: return UStreamlineFeatureSupport::NotSupportedOperatingSystemOutOfDate;
case EStreamlineFeatureSupport::NotSupportedHardwareSchedulingDisabled: return UStreamlineFeatureSupport::NotSupportedHardewareSchedulingDisabled;
case EStreamlineFeatureSupport::NotSupportedIncompatibleRHI: return UStreamlineFeatureSupport::NotSupportedByRHI;
}
}
namespace
{
FStreamlineVersion FromStreamlineVersion(const sl::Version& SLVersion)
{
return FStreamlineVersion{ static_cast<int32>(SLVersion.major), static_cast<int32>(SLVersion.minor), static_cast<int32>(SLVersion.build) };
}
uint32 FromUStreamlineFeature(UStreamlineFeature InFeature)
{
static_assert(int32(UStreamlineFeature::Count) == 3, "dear NVIDIA plugin developer, please update this code to handle the new enum values ");
switch (InFeature)
{
case UStreamlineFeature::DLSSG: return sl::kFeatureDLSS_G;
case UStreamlineFeature::Reflex: return sl::kFeatureReflex;
case UStreamlineFeature::DeepDVC: return sl::kFeatureDeepDVC;
default:
return 0;
}
}
}
#endif
namespace
{
uint32 SanitizeFeatureEnum(UStreamlineFeature Feature)
{
// TODO check range of Feature
return static_cast<uint32>(Feature);
}
}
void UStreamlineLibrary::BreakStreamlineFeatureRequirements(UStreamlineFeatureRequirementsFlags Requirements, bool& D3D11Supported, bool& D3D12Supported, bool& VulkanSupported, bool& VSyncOffRequired, bool& HardwareSchedulingRequired)
{
D3D11Supported = EnumHasAllFlags(Requirements, UStreamlineFeatureRequirementsFlags::D3D11Supported);
D3D12Supported = EnumHasAllFlags(Requirements, UStreamlineFeatureRequirementsFlags::D3D12Supported);
VulkanSupported = EnumHasAllFlags(Requirements, UStreamlineFeatureRequirementsFlags::VulkanSupported);
VSyncOffRequired = EnumHasAllFlags(Requirements, UStreamlineFeatureRequirementsFlags::VSyncOffRequired);
HardwareSchedulingRequired = EnumHasAllFlags(Requirements, UStreamlineFeatureRequirementsFlags::HardwareSchedulingRequired);
}
FStreamlineFeatureRequirements UStreamlineLibrary::GetStreamlineFeatureInformation(UStreamlineFeature Feature)
{
return Features[SanitizeFeatureEnum(Feature)];
}
bool UStreamlineLibrary::IsStreamlineFeatureSupported(UStreamlineFeature Feature)
{
TRY_INIT_STREAMLINE_LIBRARY_AND_RETURN(false)
return QueryStreamlineFeatureSupport(Feature) == UStreamlineFeatureSupport::Supported;
}
UStreamlineFeatureSupport UStreamlineLibrary::QueryStreamlineFeatureSupport(UStreamlineFeature Feature)
{
TRY_INIT_STREAMLINE_LIBRARY_AND_RETURN(UStreamlineFeatureSupport::NotSupported)
return Features[SanitizeFeatureEnum(Feature)].Support;
}
void UStreamlineLibrary::Startup()
{
#if WITH_STREAMLINE
// This initialization will likely not succeed unless this module has been moved to PostEngineInit, and that's ok
TryInitStreamlineLibrary();
#else
UE_LOG(LogStreamlineBlueprint, Log, TEXT("Streamline is not supported on this platform at build time. The Streamline Blueprint library however is supported and stubbed out to ignore any calls to enable DLSS-G and will always return UStreamlineDLSSGSupport::NotSupportedByPlatformAtBuildTime, regardless of the underlying hardware. This can be used to e.g. to turn off DLSS-G related UI elements."));
#endif
}
void UStreamlineLibrary::Shutdown()
{
#if WITH_STREAMLINE && !UE_BUILD_SHIPPING
#endif
}
void UStreamlineLibrary::RegisterFeatureSupport(UStreamlineFeature InFeature, UStreamlineFeatureSupport InSupport)
{
#if WITH_STREAMLINE
sl::Feature SLFeature = FromUStreamlineFeature(InFeature);
FStreamlineFeatureRequirements& Requirements = Features[SanitizeFeatureEnum(InFeature)];
if (IsStreamlineSupported())
{
sl::FeatureRequirements SLRequirements;
SLgetFeatureRequirements(SLFeature, SLRequirements);
Requirements.RequiredDriverVersion = FromStreamlineVersion(SLRequirements.driverVersionRequired);
Requirements.DetectedDriverVersion = FromStreamlineVersion(SLRequirements.driverVersionDetected);
Requirements.RequiredOperatingSystemVersion = FromStreamlineVersion(SLRequirements.osVersionRequired);
Requirements.DetectedOperatingSystemVersion = FromStreamlineVersion(SLRequirements.osVersionDetected);
// static_assert and static_cast are best friends
#define UE_SL_ENUM_CHECK(A,B) static_assert(uint32(sl::FeatureRequirementFlags::A) == uint32(UStreamlineFeatureRequirementsFlags::B), "sl::FeatureRequirementFlags vs UStreamlineFeatureRequirementsFlags enum mismatch");
UE_SL_ENUM_CHECK(eD3D11Supported, D3D11Supported)
UE_SL_ENUM_CHECK(eD3D12Supported, D3D12Supported)
UE_SL_ENUM_CHECK(eVulkanSupported, VulkanSupported)
UE_SL_ENUM_CHECK(eVSyncOffRequired, VSyncOffRequired)
UE_SL_ENUM_CHECK(eHardwareSchedulingRequired, HardwareSchedulingRequired)
#undef UE_SL_ENUM_CHECK
// strip the API support bits for those that are not implemented, but keep the other flags intact
const sl::FeatureRequirementFlags ImplementedAPIFlags = PlatformGetAllImplementedStreamlineRHIs();
const sl::FeatureRequirementFlags AllAPIFlags = sl::FeatureRequirementFlags::eD3D11Supported | sl::FeatureRequirementFlags::eD3D12Supported | sl::FeatureRequirementFlags::eVulkanSupported;
const sl::FeatureRequirementFlags SLRequirementFlags = sl::FeatureRequirementFlags(SLBitwiseAnd(SLRequirements.flags, ImplementedAPIFlags) | SLBitwiseAnd(SLRequirements.flags, ~AllAPIFlags));
Requirements.Requirements = static_cast<UStreamlineFeatureRequirementsFlags>(SLRequirementFlags);
Requirements.Support = InSupport;
}
#endif
}
#if WITH_STREAMLINE
// Delayed initialization, which allows this module to be available early so blueprints can be loaded before DLSS is available in PostEngineInit
bool UStreamlineLibrary::TryInitStreamlineLibrary()
{
if (bStreamlineLibraryInitialized)
{
// TODO
return true;
}
// // Register this before we bail out so we can show error messages
//#if !UE_BUILD_SHIPPING
// if (!DLSSOnScreenMessagesDelegateHandle.IsValid())
// {
// DLSSOnScreenMessagesDelegateHandle = FCoreDelegates::OnGetOnScreenMessages.AddStatic(&GetDLSSOnScreenMessages);
// }
//#endif
bStreamlineLibraryInitialized = true;
return true;
}
#endif // WITH_STREAMLINE
void FStreamlineBlueprintModule::StartupModule()
{
auto CVarInitializePlugin = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Streamline.InitializePlugin"));
if (CVarInitializePlugin && !CVarInitializePlugin->GetBool())
{
UE_LOG(LogStreamlineBlueprint, Log, TEXT("Initialization of StreamlineBlueprint is disabled."));
return;
}
UStreamlineLibrary::Startup();
UStreamlineLibraryReflex::Startup();
UStreamlineLibraryDLSSG::Startup();
}
void FStreamlineBlueprintModule::ShutdownModule()
{
auto CVarInitializePlugin = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Streamline.InitializePlugin"));
if (CVarInitializePlugin && !CVarInitializePlugin->GetBool())
{
return;
}
UStreamlineLibrary::Shutdown();
UStreamlineLibraryDLSSG::Shutdown();
UStreamlineLibraryReflex::Shutdown();
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FStreamlineBlueprintModule, StreamlineBlueprint)