This commit is contained in:
cdozdil
2024-10-25 17:14:53 +03:00
7 changed files with 148 additions and 11 deletions
+6 -2
View File
@@ -7,6 +7,7 @@
#include <vulkan/vulkan.hpp>
#include "nvapi/nvapi.h"
#include "fakenvapi.h"
#include <filesystem>
#include "detours/detours.h"
@@ -77,11 +78,12 @@ inline static uint32_t __stdcall HookedNvAPI_GPU_GetArchInfo(void* GPUHandle, NV
inline static void* __stdcall HookedNvAPI_QueryInterface(NV_INTERFACE InterfaceId)
{
LOG_FUNC();
const auto result = OriginalNvAPI_QueryInterface(InterfaceId);
if (result)
{
if (InterfaceId == NV_INTERFACE::GPU_GetArchInfo)
if (InterfaceId == NV_INTERFACE::GPU_GetArchInfo && !Config::Instance()->DE_Available)
{
OriginalNvAPI_GPU_GetArchInfo = static_cast<PfnNvAPI_GPU_GetArchInfo>(result);
return &HookedNvAPI_GPU_GetArchInfo;
@@ -155,6 +157,7 @@ inline static void HookNvApi()
if (OriginalNvAPI_QueryInterface != nullptr)
{
LOG_INFO("NvAPI_QueryInterface found, hooking!");
fakenvapi::Init((fakenvapi::PFN_Fake_QueryInterface&)OriginalNvAPI_QueryInterface);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
@@ -378,6 +381,8 @@ public:
if (_dll != nullptr)
return;
HookNvApi();
LOG_INFO("");
Config::Instance()->upscalerDisableHook = true;
@@ -490,7 +495,6 @@ public:
{
if (!Config::Instance()->DE_Available)
{
HookNvApi();
HookNgxApi(_dll);
}
+1
View File
@@ -207,6 +207,7 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\</Command>
<ClInclude Include="bias\Bias_Dx12.h" />
<ClInclude Include="bias\Bias_Dx11.h" />
<ClInclude Include="bias\precompile\Bias_Shader.h" />
<ClInclude Include="fakenvapi.h" />
<ClInclude Include="format_transfer\FT_Common.h" />
<ClInclude Include="format_transfer\FT_Dx12.h" />
<ClInclude Include="FfxApi_Proxy.h" />
+34 -7
View File
@@ -170,9 +170,6 @@
<ClInclude Include="dllmain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="imgui\wrapped_swapchain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NVNGX_Proxy.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -248,7 +245,31 @@
<ClInclude Include="format_transfer\FT_Dx12.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NVNGX_Local_Proxy.h">
<ClInclude Include="FfxApi_Proxy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="format_transfer\precompile\B8R8G8A8_Shader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="format_transfer\precompile\R10G10B10A2_Shader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="format_transfer\precompile\R8G8B8A8_Shader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hooks\HooksDx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hooks\HooksVk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hooks\wrapped_swapchain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="XeSS_Proxy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="fakenvapi.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
@@ -392,9 +413,6 @@
<ClCompile Include="imgui\imgui_dx12.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\wrapped_swapchain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="backends\dlssd\DLSSDFeature.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -449,6 +467,15 @@
<ClCompile Include="XeSS_Dx12.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="hooks\HooksDx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="hooks\HooksVk.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="hooks\wrapped_swapchain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Library Include="vulkan\vulkan-1.lib" />
+84
View File
@@ -0,0 +1,84 @@
#pragma once
#include "NVNGX_Proxy.h"
#include "FfxApi_Proxy.h"
#include <dxgi.h>
enum class FN_INTERFACE : uint32_t
{
Fake_InformFGState = 0x21382138,
Fake_InformPresentFG = 0x21392139,
Fake_GetAntiLagCtx = 0x21402140
};
using PFN_Fake_InformFGState = uint32_t(__stdcall*)(bool fg_state);
using PFN_Fake_InformPresentFG = uint32_t(__stdcall*)(bool frame_interpolated, uint64_t reflex_frame_id);
using PFN_Fake_GetAntiLagCtx = uint32_t(__stdcall*)(void* al2_context);
class fakenvapi
{
private:
inline static struct AntiLag2Data
{
void* context;
bool enabled;
} antilag2_data;
inline static PFN_Fake_InformFGState Fake_InformFGState = nullptr;
inline static PFN_Fake_InformPresentFG Fake_InformPresentFG = nullptr;
inline static PFN_Fake_GetAntiLagCtx Fake_GetAntiLagCtx = nullptr;
inline static bool _inited = false;
public:
typedef void* (__stdcall* PFN_Fake_QueryInterface)(FN_INTERFACE InterfaceId);
inline static const GUID IID_IFfxAntiLag2Data = { 0x5083ae5b, 0x8070, 0x4fca, {0x8e, 0xe5, 0x35, 0x82, 0xdd, 0x36, 0x7d, 0x13} };
inline static void Init(PFN_Fake_QueryInterface &queryInterface) {
if (_inited) return;
LOG_INFO("Getting fakenvapi-specific functions");
Fake_InformFGState = static_cast<PFN_Fake_InformFGState>(queryInterface(FN_INTERFACE::Fake_InformFGState));
Fake_InformPresentFG = static_cast<PFN_Fake_InformPresentFG>(queryInterface(FN_INTERFACE::Fake_InformPresentFG));
Fake_GetAntiLagCtx = static_cast<PFN_Fake_GetAntiLagCtx>(queryInterface(FN_INTERFACE::Fake_GetAntiLagCtx));
_inited = true;
}
// Inform AntiLag 2 when present of interpolated frames starts
inline static void reportFGPresent(IDXGISwapChain* pSwapChain, bool fg_state, bool frame_interpolated) {
if (Fake_InformFGState == nullptr || Fake_InformPresentFG == nullptr || Fake_GetAntiLagCtx == nullptr) return;
// Lets fakenvapi log and reset correctly
Fake_InformFGState(fg_state);
if (fg_state) {
// Starting with FSR 3.1.1 we can provide an AntiLag 2 context to FSR FG
// and it will call SetFrameGenFrameType for us
auto static ffxApiVersion = FfxApiProxy::VersionDx12();
constexpr feature_version requiredVersion = { 3, 1, 1 };
if (isVersionOrBetter(ffxApiVersion, requiredVersion)) {
void* antilag2Context = nullptr;
Fake_GetAntiLagCtx(&antilag2Context);
if (antilag2Context != nullptr) {
antilag2_data.context = antilag2Context;
antilag2_data.enabled = true;
pSwapChain->SetPrivateData(IID_IFfxAntiLag2Data, sizeof(antilag2_data), &antilag2_data);
}
}
else
{
// Tell fakenvapi to call SetFrameGenFrameType by itself
// Reflex frame id might get used in the future
Fake_InformPresentFG(frame_interpolated, 0);
}
}
else {
// Remove it or other FG mods won't work with AL2
pSwapChain->SetPrivateData(IID_IFfxAntiLag2Data, 0, nullptr);
}
}
};
+5 -2
View File
@@ -1561,9 +1561,12 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags
HooksDx::currentFrameIndex = (HooksDx::currentFrameIndex + 1) % HooksDx::QUERY_BUFFER_COUNT;
}
ImGuiOverlayDx::Present(pSwapChain, SyncInterval, Flags, pPresentParameters, pDevice, hWnd);
if (Config::Instance()->FGUseFGSwapChain.value_or(true)) {
fakenvapi::reportFGPresent(pSwapChain, FrameGen_Dx12::fgIsActive, frameCounter % 2);
}
frameCounter++;
// swapchain present
+1
View File
@@ -9,6 +9,7 @@
#include <dxgi1_6.h>
#include "../FfxApi_Proxy.h"
#include "../NVNGX_Proxy.h"
#include <dx12/ffx_api_dx12.h>
#include <ffx_framegeneration.h>
+17
View File
@@ -74,6 +74,23 @@ typedef struct _feature_version
unsigned int patch;
} feature_version;
inline static bool isVersionOrBetter(const feature_version& current, const feature_version& required) {
if (current.major > required.major) {
return true;
}
if (current.major == required.major) {
if (current.minor > required.minor) {
return true;
}
if (current.minor == required.minor) {
if (current.patch >= required.patch) {
return true;
}
}
}
return false;
}
inline static std::string wstring_to_string(const std::wstring& wide_str)
{
std::string str(wide_str.length(), 0);