mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-05-29 21:13:14 +00:00
merge
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user