Files
OptiScaler/OptiScaler/State.h
T

456 lines
11 KiB
C++

#pragma once
#include "upscalers/IFeature.h"
#include "framegen/IFGFeature_Dx12.h"
#include <inputs/FG/Streamline_Inputs_Dx12.h>
#include "misc/Quirks.h"
#include <set>
#include <deque>
#include <vulkan/vulkan.h>
#include <ankerl/unordered_dense.h>
#include <mutex>
typedef enum API
{
NotSelected = 0,
DX11,
DX12,
Vulkan,
} API;
enum class FGPreset : uint32_t
{
NoFG,
OptiFG,
Nukems,
};
enum class FrameTimeSource : uint32_t
{
Input,
Opti,
Zero,
};
enum class FGInput : uint32_t
{
NoFG,
Nukems,
FSRFG,
DLSSG, // technically Streamline inputs
XeFG,
Upscaler, // OptiFG
FSRFG30,
};
enum class FGOutput : uint32_t
{
NoFG,
Nukems,
FSRFG,
DLSSG,
XeFG
};
enum class WorkingMode : uint32_t
{
Dxgi,
D3d12,
Nvngx,
Other,
};
typedef struct CapturedHudlessInfo
{
UINT64 usageCount = 1;
UINT captureInfo = 0;
bool enabled = true;
} captured_hudless_info;
class State
{
public:
static State& Instance()
{
static State instance;
return instance;
}
std::string GameName;
std::string GameExe;
ankerl::unordered_dense::map<void*, std::string> DeviceAdapterNames;
bool NvngxDx11Inited = false;
bool NvngxDx12Inited = false;
bool NvngxVkInited = false;
flag_set<GameQuirk> gameQuirks;
bool isOptiPatcherSucceed = false;
// Reseting on creation of new feature
std::optional<bool> AutoExposure;
// FG
UINT64 FGLastFrame = 0;
// DLSSG
bool NukemsFilesAvailable = false;
bool DLSSGDebugView = false;
bool DLSSGInterpolatedOnly = false;
uint32_t delayMenuRenderBy = 0;
UINT64 DLSSGLastFrame = 0;
// FSR Common
float lastFsrCameraNear = 0.0f;
float lastFsrCameraFar = 0.0f;
// Frame Generation
FGInput activeFgInput = FGInput::NoFG;
FGOutput activeFgOutput = FGOutput::NoFG;
// Streamline FG inputs
Sl_Inputs_Dx12 slFGInputs = {};
// OptiFG
bool FGPresentIsCalled = false;
bool FGonlyGenerated = false;
bool FGHudlessCompare = false;
bool FGchanged = false;
bool SCchanged = false;
bool skipHeapCapture = false;
bool FGcaptureResources = false;
size_t FGcapturedResourceCount = false;
bool FGresetCapturedResources = false;
bool FGonlyUseCapturedResources = false;
bool FSRFGFTPchanged = false;
bool FSRFGInputActive = false;
bool FGResizing = false;
ankerl::unordered_dense::map<void*, CapturedHudlessInfo> CapturedHudlesses;
bool ClearCapturedHudlesses = false;
// NVNGX init parameters
uint64_t NVNGX_ApplicationId = 1337;
std::wstring NVNGX_ApplicationDataPath;
std::string NVNGX_ProjectId;
NVSDK_NGX_Version NVNGX_Version {};
const NVSDK_NGX_FeatureCommonInfo* NVNGX_FeatureInfo = nullptr;
std::vector<std::wstring> NVNGX_FeatureInfo_Paths;
NVSDK_NGX_LoggingInfo NVNGX_Logger { nullptr, NVSDK_NGX_LOGGING_LEVEL_OFF, false };
NVSDK_NGX_EngineType NVNGX_Engine = NVSDK_NGX_ENGINE_TYPE_CUSTOM;
std::string NVNGX_EngineVersion;
std::optional<std::wstring> NVNGX_DLSS_Path;
std::optional<std::wstring> NVNGX_DLSSD_Path;
std::optional<std::wstring> NVNGX_DLSSG_Path;
// NGX OTA
std::string NGX_OTA_Dlss;
std::string NGX_OTA_Dlssd;
feature_version streamlineVersion = { 0, 0, 0 };
API api = API::NotSelected;
API swapchainApi = API::NotSelected;
// Framerate
bool reflexLimitsFps = false;
bool reflexShowWarning = false;
bool rtssReflexInjection = false;
UINT64 reflexFrameId = 0;
UINT64 frameCount = 0;
// for realtime changes
ankerl::unordered_dense::map<unsigned int, bool> changeBackend;
std::string newBackend = "";
// XeSS debug stuff
bool xessDebug = false;
int xessDebugFrames = 5;
float lastMipBias = 100.0f;
float lastMipBiasMax = -100.0f;
int xefgMaxInterpolationCount = 1;
bool WAR_xefgRequestFGToggle = false;
// DLSS
bool dlssPresetsOverriddenExternally = false;
bool dlssPresetsOverridenByOpti = false;
uint32_t dlssRenderPresetExternal = 0;
uint32_t dlssRenderPresetDLAA = 0;
uint32_t dlssRenderPresetUltraQuality = 0;
uint32_t dlssRenderPresetQuality = 0;
uint32_t dlssRenderPresetBalanced = 0;
uint32_t dlssRenderPresetPerformance = 0;
uint32_t dlssRenderPresetUltraPerformance = 0;
// DLSSD
bool dlssdPresetsOverriddenExternally = false;
bool dlssdPresetsOverridenByOpti = false;
uint32_t dlssdRenderPresetExternal = 0;
uint32_t dlssdRenderPresetDLAA = 0;
uint32_t dlssdRenderPresetUltraQuality = 0;
uint32_t dlssdRenderPresetQuality = 0;
uint32_t dlssdRenderPresetBalanced = 0;
uint32_t dlssdRenderPresetPerformance = 0;
uint32_t dlssdRenderPresetUltraPerformance = 0;
// Spoofing
bool skipSpoofing = false;
// For DXVK, it calls DXGI which cause softlock
bool skipDxgiLoadChecks = false;
bool skipParentWrapping = false;
// quirks
std::vector<std::string> detectedQuirks {};
// FFX
std::vector<const char*> ffxUpscalerVersionNames {};
std::vector<uint64_t> ffxUpscalerVersionIds {};
std::vector<const char*> ffxFGVersionNames {};
std::vector<uint64_t> ffxFGVersionIds {};
std::optional<uint32_t> currentFsr4Model {};
// Linux checks
bool isRunningOnLinux = false;
bool isRunningOnDXVK = false;
// Other checks
bool isRunningOnNvidia = false;
std::optional<bool> isRunningOnRDNA4;
bool isPascalOrOlder = false;
WorkingMode workingMode = WorkingMode::Other;
// Vulkan stuff
bool vulkanCreatingSC = false;
bool creatingD3DDevice = false;
bool vulkanSkipHooks = false;
VkInstance VulkanInstance = nullptr;
// Framegraph
std::deque<double> upscaleTimes;
std::deque<double> frameTimes;
double lastFGFrameTime = 0.0;
double presentFrameTime = 0.0;
std::mutex frameTimeMutex;
// Version check
std::mutex versionCheckMutex;
bool versionCheckInProgress = false;
bool versionCheckCompleted = false;
bool updateAvailable = false;
std::string latestVersionTag;
std::string latestVersionUrl;
std::string versionCheckError;
// Swapchain info
float screenWidth = 800.0;
float screenHeight = 450.0;
bool realExclusiveFullscreen = false;
bool SCExclusiveFullscreen = false;
bool SCAllowTearing = false;
UINT SCLastFlags = 0;
// HDR
std::vector<IUnknown*> SCbuffers;
bool isHdrActive = false;
std::string setInputApiName;
std::string currentInputApiName;
bool isShuttingDown = false;
std::set<PVOID> modulesToFree;
// menu warnings
bool fgSettingsChanged = false;
bool nvngxIniDetected = false;
bool nvngxExists = false;
std::optional<std::wstring> nvngxReplacement = std::nullopt;
bool libxessExists = false;
bool fsrHooks = false;
IFeature* currentFeature = nullptr;
IFGFeature_Dx12* currentFG = nullptr;
IDXGISwapChain* currentSwapchain = nullptr;
IDXGISwapChain* currentWrappedSwapchain = nullptr;
IDXGISwapChain* currentRealSwapchain = nullptr;
IDXGISwapChain* currentFGSwapchain = nullptr;
ID3D12Device* currentD3D12Device = nullptr;
DXGI_ADAPTER_DESC currentD3D12AdepterDesc = {};
ID3D11Device* currentD3D11Device = nullptr;
DXGI_ADAPTER_DESC currentD3D11AdepterDesc = {};
ID3D12CommandQueue* currentCommandQueue = nullptr;
VkDevice currentVkDevice = nullptr;
DXGI_SWAP_CHAIN_DESC currentSwapchainDesc {};
std::vector<ID3D12Device*> d3d12Devices;
std::vector<ID3D11Device*> d3d11Devices;
std::unordered_map<UINT64, std::string> adapterDescs;
// Moved checks here to prevent circular includes
/// <summary>
/// Enables skipping of LoadLibrary checks
/// </summary>
/// <param name="dllName">Lower case dll name without `.dll` at the end. Leave blank for skipping all dll's</param>
static void DisableChecks(UINT owner, std::string dllName = "")
{
if (_skipOwner == 0)
{
_skipOwner = owner;
_skipChecks = true;
_skipDllName = dllName;
}
else
{
_skipDllName = ""; // Hack for multiple skip calls
}
};
static void EnableChecks(UINT owner)
{
if (_skipOwner == 0 || _skipOwner == owner)
{
_skipChecks = false;
_skipDllName = "";
_skipOwner = 0;
}
};
static void DisableServeOriginal(UINT owner)
{
if (_serveOwner == 0 || _serveOwner == owner)
{
_serveOriginal = false;
_skipOwner = 0;
}
};
static void EnableServeOriginal(UINT owner)
{
if (_serveOwner == 0 || _serveOwner == owner)
{
_serveOriginal = true;
_skipOwner = owner;
}
};
static bool SkipDllChecks() { return _skipChecks; }
static std::string SkipDllName() { return _skipDllName; }
static bool ServeOriginal() { return _serveOriginal; }
private:
inline static bool _skipChecks = false;
inline static std::string _skipDllName = "";
inline static UINT _skipOwner = 0;
inline static bool _serveOriginal = false;
inline static UINT _serveOwner = 0;
State() = default;
};
class ScopedSkipSpoofing
{
private:
bool previousState;
public:
ScopedSkipSpoofing()
{
previousState = State::Instance().skipSpoofing;
State::Instance().skipSpoofing = true;
}
~ScopedSkipSpoofing() { State::Instance().skipSpoofing = previousState; }
};
class ScopedSkipDxgiLoadChecks
{
private:
bool previousState;
public:
ScopedSkipDxgiLoadChecks()
{
previousState = State::Instance().skipDxgiLoadChecks;
State::Instance().skipDxgiLoadChecks = true;
}
~ScopedSkipDxgiLoadChecks() { State::Instance().skipDxgiLoadChecks = previousState; }
};
class ScopedSkipParentWrapping
{
private:
bool previousState;
public:
ScopedSkipParentWrapping()
{
previousState = State::Instance().skipParentWrapping;
State::Instance().skipParentWrapping = true;
}
~ScopedSkipParentWrapping() { State::Instance().skipParentWrapping = previousState; }
};
class ScopedSkipHeapCapture
{
private:
bool previousState;
public:
ScopedSkipHeapCapture()
{
previousState = State::Instance().skipHeapCapture;
State::Instance().skipHeapCapture = true;
}
~ScopedSkipHeapCapture() { State::Instance().skipHeapCapture = previousState; }
};
class ScopedSkipVulkanHooks
{
private:
bool previousState;
public:
ScopedSkipVulkanHooks()
{
previousState = State::Instance().vulkanSkipHooks;
State::Instance().vulkanSkipHooks = true;
}
~ScopedSkipVulkanHooks() { State::Instance().vulkanSkipHooks = previousState; }
};
class ScopedVulkanCreatingSC
{
private:
bool previousState;
public:
ScopedVulkanCreatingSC()
{
previousState = State::Instance().vulkanCreatingSC;
State::Instance().vulkanCreatingSC = true;
}
~ScopedVulkanCreatingSC() { State::Instance().vulkanCreatingSC = previousState; }
};
class ScopedCreatingD3DDevice
{
private:
bool previousState;
public:
ScopedCreatingD3DDevice()
{
previousState = State::Instance().creatingD3DDevice;
State::Instance().creatingD3DDevice = true;
}
~ScopedCreatingD3DDevice() { State::Instance().creatingD3DDevice = previousState; }
};