Display enabler version in the menu

This commit is contained in:
FakeMichau
2026-08-13 21:35:14 +02:00
parent 257ae590d3
commit 4796249d5d
16 changed files with 182 additions and 138 deletions
+127
View File
@@ -99,6 +99,133 @@ enum class FSR4Support : uint8_t
Count
};
typedef struct _version_t
{
uint16_t major;
uint16_t minor;
uint16_t patch;
uint16_t reserved;
_version_t() : major(0), minor(0), patch(0), reserved(0) {}
constexpr _version_t(uint16_t maj, uint16_t min, uint16_t pat, uint16_t res)
: major(maj), minor(min), patch(pat), reserved(res)
{
}
bool operator==(const _version_t& other) const
{
return major == other.major && minor == other.minor && patch == other.patch && reserved == other.reserved;
}
bool operator!=(const _version_t& other) const { return !(*this == other); }
bool operator<(const _version_t& other) const
{
if (major != other.major)
return major < other.major;
if (minor != other.minor)
return minor < other.minor;
if (patch != other.patch)
return patch < other.patch;
return reserved < other.reserved;
}
bool operator>(const _version_t& other) const { return other < *this; }
bool operator<=(const _version_t& other) const { return !(other < *this); }
bool operator>=(const _version_t& other) const { return !(*this < other); }
} version_t;
struct feature_version
{
unsigned int major;
unsigned int minor;
unsigned int patch;
unsigned int reserved;
feature_version() : major(0), minor(0), patch(0), reserved(0) {}
explicit feature_version(const char* version_str) : major(0), minor(0), patch(0), reserved(0)
{
parse_version(version_str);
}
constexpr feature_version(unsigned int maj, unsigned int min, unsigned int pat, unsigned int res)
: major(maj), minor(min), patch(pat), reserved(res)
{
}
constexpr feature_version(unsigned int maj, unsigned int min, unsigned int pat)
: major(maj), minor(min), patch(pat), reserved(0)
{
}
feature_version& operator=(const version_t& other)
{
this->major = other.major;
this->minor = other.minor;
this->patch = other.patch;
this->reserved = other.reserved;
return *this;
}
bool operator==(const feature_version& other) const
{
return major == other.major && minor == other.minor && patch == other.patch && reserved == other.reserved;
}
bool operator!=(const feature_version& other) const { return !(*this == other); }
bool operator<(const feature_version& other) const
{
if (major != other.major)
return major < other.major;
if (minor != other.minor)
return minor < other.minor;
if (patch != other.patch)
return patch < other.patch;
return reserved < other.reserved;
}
bool operator>(const feature_version& other) const { return other < *this; }
bool operator<=(const feature_version& other) const { return !(other < *this); }
bool operator>=(const feature_version& other) const { return !(*this < other); }
void parse_version(const char* version_str)
{
const char* p = version_str;
// Skip non-digits at front
while (*p)
{
if (isdigit((unsigned char) p[0]))
{
if (sscanf_s(p, "%u.%u.%u", &major, &minor, &patch) == 3)
return;
}
++p;
}
LOG_WARN("can't parse {0}", version_str);
}
};
namespace VendorId
{
enum Value : uint32_t
{
Invalid = 0,
Microsoft = 0x1414, // Software Render Adapter
Nvidia = 0x10DE,
AMD = 0x1002,
Intel = 0x8086,
};
};
std::string ApiUpscalerInputName(ApiUpscalerInput upscaler);
std::string UpscalerDisplayName(Upscaler upscaler, API api = API::NotSelected);
-67
View File
@@ -140,73 +140,6 @@ inline DWORD processId;
} \
} while ((void) 0, 0)
struct feature_version
{
unsigned int major;
unsigned int minor;
unsigned int patch;
feature_version() : major(0), minor(0), patch(0) {}
explicit feature_version(const char* version_str) : major(0), minor(0), patch(0) { parse_version(version_str); }
constexpr feature_version(unsigned int maj, unsigned int min, unsigned int pat) : major(maj), minor(min), patch(pat)
{
}
bool operator==(const feature_version& other) const
{
return major == other.major && minor == other.minor && patch == other.patch;
}
bool operator!=(const feature_version& other) const { return !(*this == other); }
bool operator<(const feature_version& other) const
{
if (major != other.major)
return major < other.major;
if (minor != other.minor)
return minor < other.minor;
return patch < other.patch;
}
bool operator>(const feature_version& other) const { return other < *this; }
bool operator<=(const feature_version& other) const { return !(other < *this); }
bool operator>=(const feature_version& other) const { return !(*this < other); }
void parse_version(const char* version_str)
{
const char* p = version_str;
// Skip non-digits at front
while (*p)
{
if (isdigit((unsigned char) p[0]))
{
if (sscanf_s(p, "%u.%u.%u", &major, &minor, &patch) == 3)
return;
}
++p;
}
LOG_WARN("can't parse {0}", version_str);
}
};
namespace VendorId
{
enum Value : uint32_t
{
Invalid = 0,
Microsoft = 0x1414, // Software Render Adapter
Nvidia = 0x10DE,
AMD = 0x1002,
Intel = 0x8086,
};
};
inline static std::string wstring_to_string(const std::wstring& wide_str)
{
if (wide_str.empty())
-39
View File
@@ -9,45 +9,6 @@
namespace Util
{
typedef struct _version_t
{
uint16_t major;
uint16_t minor;
uint16_t patch;
uint16_t reserved;
_version_t() : major(0), minor(0), patch(0), reserved(0) {}
constexpr _version_t(uint16_t maj, uint16_t min, uint16_t pat, uint16_t res)
: major(maj), minor(min), patch(pat), reserved(res)
{
}
bool operator==(const _version_t& other) const
{
return major == other.major && minor == other.minor && patch == other.patch && reserved == other.reserved;
}
bool operator!=(const _version_t& other) const { return !(*this == other); }
bool operator<(const _version_t& other) const
{
if (major != other.major)
return major < other.major;
if (minor != other.minor)
return minor < other.minor;
if (patch != other.patch)
return patch < other.patch;
return reserved < other.reserved;
}
bool operator>(const _version_t& other) const { return other < *this; }
bool operator<=(const _version_t& other) const { return !(other < *this); }
bool operator>=(const _version_t& other) const { return !(*this < other); }
} version_t;
struct MonitorInfo
{
HMONITOR handle;
+2 -1
View File
@@ -14,7 +14,7 @@ class IFGNvngx
feature_version _version { 0, 0, 0 };
public:
feature_version version() const { return _version; };
virtual feature_version version() { return _version; };
virtual ~IFGNvngx() = default;
@@ -22,6 +22,7 @@ class IFGNvngx
virtual FGNvngxReplacement getType() = 0;
virtual bool isDx12Available() = 0;
virtual bool isVulkanAvailable() = 0;
virtual feature_version extraVersion() { return {}; }; // extra version the provider may want to report
// D3D12
virtual NVSDK_NGX_Result D3D12_Init(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath,
+14 -13
View File
@@ -3,33 +3,35 @@
void Nvngx_Arturs::QueryVersions()
{
if (!_DLSSG_D3D12_GetCapabilityParameters)
if (!_DLSSG_D3D12_PopulateParameters_Impl)
return;
// Main version
HMODULE hModule;
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCSTR) _DLSSG_D3D12_GetCapabilityParameters, &hModule);
(LPCSTR) _DLSSG_D3D12_PopulateParameters_Impl, &hModule);
wchar_t dllPath[MAX_PATH] = { 0 };
GetModuleFileNameW(hModule, dllPath, MAX_PATH);
Util::GetFileVersion(dllPath, &enablerVersion);
version_t tempVersion {};
Util::GetFileVersion(dllPath, &tempVersion);
_version = tempVersion;
// Antighosting version
NVSDK_NGX_Parameter* tempParams {};
_DLSSG_D3D12_GetCapabilityParameters(&tempParams);
if (tempParams)
NVNGX_Parameters tempParams(API::DX12, false);
if (_DLSSG_D3D12_PopulateParameters_Impl(&tempParams) == NVSDK_NGX_Result_Success)
{
auto result = tempParams->Get("FrameInterpolation.GhostbusterVersionMajor", &ghostbusterVersion.major);
tempParams->Get("FrameInterpolation.GhostbusterVersionMinor", &ghostbusterVersion.minor);
auto result = tempParams.Get("FrameInterpolation.GhostbusterVersionMajor", &ghostbusterVersion.major);
tempParams.Get("FrameInterpolation.GhostbusterVersionMinor", &ghostbusterVersion.minor);
if (result != NVSDK_NGX_Result_Success)
LOG_WARN("Couldn't query version");
}
LOG_INFO("DE Ver: {}.{}.{}.{}, GB Ver: {}.{}", enablerVersion.major, enablerVersion.minor, enablerVersion.patch,
enablerVersion.reserved, ghostbusterVersion.major, ghostbusterVersion.minor);
LOG_INFO("DE Ver: {}.{}.{}.{}, GB Ver: {}.{}", _version.major, _version.minor, _version.patch, _version.reserved,
ghostbusterVersion.major, ghostbusterVersion.minor);
}
void Nvngx_Arturs::LoadLibraries()
@@ -60,9 +62,6 @@ void Nvngx_Arturs::LoadLibraries()
_DLSSG_D3D12_PopulateParameters_Impl =
(PFN_D3D12_PopulateParameters_Impl) GetProcAddress(dll, "DLSSG_NVSDK_NGX_D3D12_PopulateParameters_Impl");
_DLSSG_D3D12_GetCapabilityParameters =
(PFN_D3D12_GetCapabilityParameters) GetProcAddress(dll, "NVSDK_NGX_D3D12_GetCapabilityParameters");
QueryVersions();
LOG_INFO("Artur's initialized");
@@ -72,3 +71,5 @@ void Nvngx_Arturs::LoadLibraries()
LOG_WARN("Artur's enabled but cannot be loaded");
}
}
feature_version Nvngx_Arturs::extraVersion() { return ghostbusterVersion; }
+1 -2
View File
@@ -3,8 +3,6 @@
class Nvngx_Arturs : public Nvngx_DllProxy
{
PFN_D3D12_GetCapabilityParameters _DLSSG_D3D12_GetCapabilityParameters = nullptr;
Util::version_t enablerVersion {};
feature_version ghostbusterVersion {};
void QueryVersions();
@@ -17,4 +15,5 @@ class Nvngx_Arturs : public Nvngx_DllProxy
int getMaxFakeFramesCount() override { return 5; }
FGNvngxReplacement getType() override { return FGNvngxReplacement::Arturs; }
feature_version extraVersion() override;
};
@@ -286,3 +286,6 @@ NVSDK_NGX_Result Nvngx_Combo::D3D12_PopulateParameters_Impl(NVSDK_NGX_Parameter*
return NVSDK_NGX_Result_Success;
}
feature_version Nvngx_Combo::version() { return artursProvider->version(); }
feature_version Nvngx_Combo::extraVersion() { return artursProvider->extraVersion(); }
+2
View File
@@ -66,4 +66,6 @@ class Nvngx_Combo : public IFGNvngx
int getMaxFakeFramesCount() override { return 5; }
FGNvngxReplacement getType() override { return FGNvngxReplacement::Combo; }
feature_version version() override;
feature_version extraVersion() override;
};
+10
View File
@@ -171,6 +171,16 @@ feature_version Nvngx_FG::version()
return provider->version();
}
feature_version Nvngx_FG::extraVersion()
{
auto* provider = getProvider();
if (!provider)
return {};
return provider->extraVersion();
}
void Nvngx_FG::setDebugView(bool enabled)
{
auto* provider = getProvider();
+1
View File
@@ -20,6 +20,7 @@ class Nvngx_FG
static bool isDx12Available();
static bool isVulkanAvailable();
static feature_version version();
static feature_version extraVersion();
// TODO: nukem-specific, unify
static void setDebugView(bool enabled);
+4 -4
View File
@@ -48,12 +48,12 @@ HRESULT STDMETHODCALLTYPE AmdExtFfxApi::UpdateFfxApiProvider(void* pData, uint32
wchar_t sdkDllPath[MAX_PATH] = { 0 };
GetModuleFileNameW(callerModule, sdkDllPath, MAX_PATH);
Util::version_t sdkVersion;
version_t sdkVersion;
Util::GetFileVersion(sdkDllPath, &sdkVersion, nullptr);
LOG_TRACE("sdkVersion: {}.{}.{}.{}", sdkVersion.major, sdkVersion.minor, sdkVersion.patch, sdkVersion.reserved);
sdkSupportsInt8 = sdkVersion >= Util::version_t(4, 1, 1, 0);
sdkSupportsInt8 = sdkVersion >= version_t(4, 1, 1, 0);
IdentifyGpu::updateInt8Support(sdkSupportsInt8, amdxcffx64SupportsInt8);
}
@@ -101,13 +101,13 @@ HRESULT STDMETHODCALLTYPE AmdExtFfxApi::UpdateFfxApiProvider(void* pData, uint32
wchar_t driverDllPath[MAX_PATH] = { 0 };
GetModuleFileNameW(FSR4Upgrade::moduleAmdxcffx64, driverDllPath, MAX_PATH);
Util::version_t amdxcffx64Version;
version_t amdxcffx64Version;
Util::GetFileVersion(driverDllPath, &amdxcffx64Version);
LOG_TRACE("amdxcffx64Version: {}.{}.{}.{}", amdxcffx64Version.major, amdxcffx64Version.minor,
amdxcffx64Version.patch, amdxcffx64Version.reserved);
amdxcffx64SupportsInt8 = amdxcffx64Version >= Util::version_t(2, 3, 0, 0);
amdxcffx64SupportsInt8 = amdxcffx64Version >= version_t(2, 3, 0, 0);
// Seems to happen with older Proton builds
if (!amdxcffx64SupportsInt8.value() && !wasInt8ModelSelectionHooked &&
+3 -3
View File
@@ -259,8 +259,8 @@ sl::Result StreamlineHooks::hkslInit(const sl::Preferences& pref, uint64_t sdkVe
else
{
// Compare versions
Util::version_t pluginVer, pluginProdVer;
Util::version_t localVer, localProdVer;
version_t pluginVer, pluginProdVer;
version_t localVer, localProdVer;
bool gotPluginVer = Util::GetFileVersion(entry.path().wstring(), &pluginVer, &pluginProdVer);
bool gotLocalVer = Util::GetFileVersion(localDllPath.wstring(), &localVer, &localProdVer);
@@ -1786,7 +1786,7 @@ void StreamlineHooks::hookInterposer(HMODULE slInterposer)
LOG_TRACE("slInterposer path: {}", dllPath);
Util::version_t sl_version;
version_t sl_version;
Util::GetFileVersion(string_to_wstring(dllPath), &sl_version);
State::Instance().streamlineVersion.major = sl_version.major;
+12 -6
View File
@@ -4467,12 +4467,10 @@ void MenuCommon::RenderFrameGenerationRuntimeSettings(RenderMenuContext& ctx)
{
if (activeNvngxFg == FGNvngxReplacement::Arturs || activeNvngxFg == FGNvngxReplacement::Combo)
{
if (bool showDebug = config->NvngxFGShowDebug.value_or_default();
ImGui::Checkbox("Show Debug", &showDebug))
{
config->NvngxFGShowDebug = showDebug;
}
ShowHelpMarker("Required for Debug flags to work correctly");
auto featureVer = Nvngx_FG::version();
auto antighostingVer = Nvngx_FG::extraVersion();
ImGui::Text("DE Ver: %d.%d.%d.%d GB Ver: %d.%d", featureVer.major, featureVer.minor, featureVer.patch,
featureVer.reserved, antighostingVer.major, antighostingVer.minor);
static std::vector<FlagDefinition> known_flags = {
{ "FRAME_INDEX_LINE", 0x00010000, "" },
@@ -4499,6 +4497,14 @@ void MenuCommon::RenderFrameGenerationRuntimeSettings(RenderMenuContext& ctx)
changed |= ImGui::InputScalar("##RawFlags", ImGuiDataType_U32, &temp_flags, NULL, NULL, "%08X",
ImGuiInputTextFlags_CharsHexadecimal);
ImGui::SameLine(0.0f, 20.0f * menuResScale);
if (bool showDebug = config->NvngxFGShowDebug.value_or_default();
ImGui::Checkbox("Show Debug", &showDebug))
{
config->NvngxFGShowDebug = showDebug;
}
ShowHelpMarker("Required for Debug flags to work correctly");
ImGui::Spacing();
if (auto ch = ScopedCollapsingHeader("Active DispatchFlags"); ch.IsHeaderOpen())
+1 -1
View File
@@ -87,7 +87,7 @@ class XeFGProxy
inline static xefg_swapchain_version_t GetDLLVersion(std::wstring dllPath)
{
xefg_swapchain_version_t xefgVersion {};
Util::version_t tempVersion {};
version_t tempVersion {};
auto result = Util::GetFileVersion(dllPath, &tempVersion);
// Don't assume that the structs are identical
+1 -1
View File
@@ -129,7 +129,7 @@ class XeLLProxy
inline static xell_version_t GetDLLVersion(std::wstring dllPath)
{
xell_version_t xellVersion {};
Util::version_t tempVersion {};
version_t tempVersion {};
auto result = Util::GetFileVersion(dllPath, &tempVersion);
// Don't assume that the structs are identical
+1 -1
View File
@@ -164,7 +164,7 @@ class XeSSProxy
inline static xess_version_t GetDLLVersion(std::wstring dllPath)
{
xess_version_t xessVersion {};
Util::version_t tempVersion {};
version_t tempVersion {};
auto result = Util::GetFileVersion(dllPath, &tempVersion);
// Don't assume that the structs are identical