mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-08-25 15:46:45 +00:00
Add basic support for UeLL
Proper AL2 injection to UE games
This commit is contained in:
@@ -145,6 +145,7 @@ DEFINE_NAME_VECTORS(ffxDx12FG, "amd_fidelityfx_framegeneration_dx12");
|
||||
DEFINE_NAME_VECTORS(ffxDx12Denoiser, "amd_fidelityfx_denoiser_dx12");
|
||||
DEFINE_NAME_VECTORS(ffxDx12Radiance, "amd_fidelityfx_radiancecache_dx12");
|
||||
DEFINE_NAME_VECTORS(ffxVk, "amd_fidelityfx_vk");
|
||||
DEFINE_NAME_VECTORS(uell, "main");
|
||||
|
||||
inline static bool CompareFileName(std::string* first, std::string* second)
|
||||
{
|
||||
|
||||
@@ -399,6 +399,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClInclude Include="shaders\Shader_Dx12Utils.h" />
|
||||
<ClInclude Include="shaders\Shader_Vk.h" />
|
||||
<ClInclude Include="shaders\Shader_VkUtils.h" />
|
||||
<ClInclude Include="misc\UeLowLatency.h" />
|
||||
<ClInclude Include="upscalers\fsr2_212\FSR2Feature_VkOnDx12_212.h" />
|
||||
<ClInclude Include="upscalers\ffx\FFXFeature_VkOn12.h" />
|
||||
<ClInclude Include="upscalers\fsr31\FSR31Feature.h" />
|
||||
@@ -623,6 +624,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClCompile Include="spoofing\Dxgi_Spoofing.cpp" />
|
||||
<ClCompile Include="spoofing\User32_Spoofing.cpp" />
|
||||
<ClCompile Include="spoofing\Vulkan_Spoofing.cpp" />
|
||||
<ClCompile Include="misc\UeLowLatency.cpp" />
|
||||
<ClCompile Include="upscalers\fsr2_212\FSR2Feature_VkOnDx12_212.cpp" />
|
||||
<ClCompile Include="upscalers\ffx\FFXFeature_VkOn12.cpp" />
|
||||
<ClCompile Include="upscalers\fsr31\FSR31Feature.cpp" />
|
||||
|
||||
@@ -845,6 +845,18 @@
|
||||
<ClInclude Include="shaders\hudless_compare_compute\HCC_Dx12.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shaders\rcas\precompile\lc_da_sharpen_Shader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shaders\rcas\precompile\lc_da_sharpen_Shader_Dx11.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shaders\rcas\precompile\lc_da_sharpen_Shader_Vk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="misc\UeLowLatency.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Config.cpp">
|
||||
@@ -1316,6 +1328,12 @@
|
||||
<ClCompile Include="shaders\hudless_compare_compute\HCC_Dx12.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="shaders\rcas\RCAS_Common.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="misc\UeLowLatency.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="OptiScaler.rc" />
|
||||
|
||||
@@ -169,6 +169,7 @@ class State
|
||||
bool reflexShowWarning = false;
|
||||
bool rtssReflexInjection = false;
|
||||
bool fakenvapiReloadLowLatency = false;
|
||||
bool usingUeLL = false;
|
||||
UINT64 reflexFrameId = 0;
|
||||
UINT64 frameCount = 0;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <fsr4/FSR4ModelSelection.h>
|
||||
#include <misc/IdentifyGpu.h>
|
||||
#include <misc/UeLowLatency.h>
|
||||
|
||||
// #define LOG_LIB_OPERATIONS
|
||||
|
||||
@@ -524,6 +525,28 @@ HMODULE LibraryLoadHooks::LoadLibraryCheckW(std::wstring libName, LPCWSTR lpLibF
|
||||
return module;
|
||||
}
|
||||
|
||||
// UeLL
|
||||
// This will try to hook all UE4SS dll mods but only our one should be exporting those functions
|
||||
if (CheckDllNameW(&libName, &uellNamesW))
|
||||
{
|
||||
LOG_INFO("{} call!", libNameA);
|
||||
|
||||
auto module = NtdllProxy::LoadLibraryExW_Ldr(libName.c_str(), NULL, NULL);
|
||||
|
||||
auto setTickStartCallback =
|
||||
(PFN_setTickCallback) KernelBaseProxy::GetProcAddress_()(module, "setTickStartCallback");
|
||||
auto setTickEndCallback =
|
||||
(PFN_setTickCallback) KernelBaseProxy::GetProcAddress_()(module, "setTickEndCallback");
|
||||
|
||||
if (setTickStartCallback)
|
||||
setTickStartCallback(UeLowLatency::tickStart);
|
||||
|
||||
if (setTickEndCallback)
|
||||
setTickEndCallback(UeLowLatency::tickEnd);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
CheckModulesInMemory();
|
||||
|
||||
return nullptr;
|
||||
|
||||
@@ -33,6 +33,13 @@ NvAPI_Status ReflexHooks::hkNvAPI_D3D_SetSleepMode(IUnknown* pDev, NV_SET_SLEEP_
|
||||
if (_minimumIntervalUs != 0)
|
||||
pSetSleepModeParams->minimumIntervalUs = _minimumIntervalUs;
|
||||
|
||||
if (State::Instance().usingUeLL)
|
||||
{
|
||||
pSetSleepModeParams->minimumIntervalUs = 0;
|
||||
pSetSleepModeParams->bLowLatencyMode = false;
|
||||
pSetSleepModeParams->bLowLatencyBoost = false;
|
||||
}
|
||||
|
||||
if (State::Instance().activeFgOutput == FGOutput::XeFG)
|
||||
return nvapi_calls::NvAPI_D3D_SetSleepMode(pDev, pSetSleepModeParams);
|
||||
|
||||
@@ -45,6 +52,11 @@ NvAPI_Status ReflexHooks::hkNvAPI_D3D_Sleep(IUnknown* pDev)
|
||||
LOG_FUNC();
|
||||
#endif
|
||||
|
||||
if (State::Instance().usingUeLL)
|
||||
{
|
||||
return NVAPI_OK;
|
||||
}
|
||||
|
||||
static bool skip = false;
|
||||
if ((State::Instance().activeFgOutput == FGOutput::DLSSG ||
|
||||
State::Instance().activeFgOutput == FGOutput::DLSSGWithNvngx) &&
|
||||
@@ -64,7 +76,7 @@ NvAPI_Status ReflexHooks::hkNvAPI_D3D_Sleep(IUnknown* pDev)
|
||||
StreamlineProxy::ReflexSleep()(*frameToken);
|
||||
skip = false;
|
||||
|
||||
return NvAPI_Status::NVAPI_OK;
|
||||
return NVAPI_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -86,6 +98,11 @@ NvAPI_Status ReflexHooks::hkNvAPI_D3D_GetLatency(IUnknown* pDev, NV_LATENCY_RESU
|
||||
LOG_FUNC();
|
||||
#endif
|
||||
|
||||
if (State::Instance().usingUeLL)
|
||||
{
|
||||
return NVAPI_OK;
|
||||
}
|
||||
|
||||
if (State::Instance().activeFgOutput == FGOutput::XeFG)
|
||||
return nvapi_calls::NvAPI_D3D_GetLatency(pDev, pGetLatencyParams);
|
||||
|
||||
@@ -120,6 +137,11 @@ NvAPI_Status ReflexHooks::hkNvAPI_D3D_SetLatencyMarker(IUnknown* pDev,
|
||||
_lastFrameId[pSetLatencyMarkerParams->markerType] = pSetLatencyMarkerParams->frameID;
|
||||
_lastDev[pSetLatencyMarkerParams->markerType] = pDev;
|
||||
|
||||
if (State::Instance().usingUeLL)
|
||||
{
|
||||
return NVAPI_OK;
|
||||
}
|
||||
|
||||
static bool skip[20] = {};
|
||||
|
||||
if (pSetLatencyMarkerParams->markerType == SIMULATION_START)
|
||||
@@ -297,6 +319,11 @@ NvAPI_Status ReflexHooks::hkNvAPI_D3D12_SetAsyncFrameMarker(ID3D12CommandQueue*
|
||||
|
||||
_lastAsyncMarkerFrameId = pSetAsyncFrameMarkerParams->frameID;
|
||||
|
||||
if (State::Instance().usingUeLL)
|
||||
{
|
||||
return NVAPI_OK;
|
||||
}
|
||||
|
||||
if (pSetAsyncFrameMarkerParams->markerType == OUT_OF_BAND_PRESENT_START &&
|
||||
State::Instance().streamlineVersion.major < 2)
|
||||
{
|
||||
|
||||
@@ -90,5 +90,5 @@ class ReflexHooks
|
||||
static void update(bool optiFg_FgState, bool isVulkan);
|
||||
|
||||
// 0 - disables the fps cap
|
||||
inline static void setFPSLimit(float fps);
|
||||
static void setFPSLimit(float fps);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "pch.h"
|
||||
#include "UeLowLatency.h"
|
||||
#include <hooks/Reflex_Hooks.h>
|
||||
|
||||
#include "nvapi/fakenvapi/low_latency_tech/ll_antilag2.h"
|
||||
// #include "nvapi/fakenvapi/low_latency_tech/ll_xell.h"
|
||||
#include "nvapi/fakenvapi/low_latency_tech/ll_latencyflex.h"
|
||||
|
||||
void UeLowLatency::init()
|
||||
{
|
||||
if (lowLatencyFeature)
|
||||
return;
|
||||
|
||||
lowLatencyFeature = new AntiLag2();
|
||||
|
||||
// lowLatencyFeature = new LatencyFlex();
|
||||
// Config::Instance()->FN_LatencyFlexMode.set_volatile_value(LFXMode::ReflexIDs);
|
||||
|
||||
bool inited = false;
|
||||
|
||||
if (auto dx11device = State::Instance().currentD3D11Device; dx11device)
|
||||
{
|
||||
inited = lowLatencyFeature->init(dx11device);
|
||||
}
|
||||
|
||||
if (auto dx12device = State::Instance().currentD3D12Device; !inited && dx12device)
|
||||
{
|
||||
inited = lowLatencyFeature->init(dx12device);
|
||||
}
|
||||
|
||||
State::Instance().usingUeLL = inited;
|
||||
|
||||
if (inited)
|
||||
{
|
||||
LOG_DEBUG("Inited UeLowLatency");
|
||||
|
||||
SleepMode mode {};
|
||||
mode.low_latency_enabled = true;
|
||||
lowLatencyFeature->set_sleep_mode(&mode);
|
||||
|
||||
ReflexHooks::setFPSLimit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete lowLatencyFeature;
|
||||
lowLatencyFeature = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void UeLowLatency::tickStart(int64_t frameId, float DeltaSeconds, bool bIdleMode)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
if (!lowLatencyFeature)
|
||||
UeLowLatency::init();
|
||||
|
||||
lowLatencyFeature->sleep();
|
||||
|
||||
MarkerParams marker {};
|
||||
marker.marker_type = MarkerType::SIMULATION_START;
|
||||
marker.frame_id = frameId;
|
||||
lowLatencyFeature->set_marker(State::Instance().currentD3D12Device, &marker);
|
||||
}
|
||||
|
||||
void UeLowLatency::tickEnd(int64_t frameId, float DeltaSeconds, bool bIdleMode)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
MarkerParams marker {};
|
||||
marker.marker_type = MarkerType::SIMULATION_END;
|
||||
marker.frame_id = frameId;
|
||||
lowLatencyFeature->set_marker(State::Instance().currentD3D12Device, &marker);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "nvapi/fakenvapi/low_latency_tech/low_latency_tech.h"
|
||||
|
||||
typedef void (*PFN_FLTickExternal)(int64_t frameId, float DeltaSeconds, bool bIdleMode);
|
||||
typedef void (*PFN_setTickCallback)(PFN_FLTickExternal callback);
|
||||
|
||||
class UeLowLatency
|
||||
{
|
||||
inline static LowLatencyTech* lowLatencyFeature = nullptr;
|
||||
|
||||
public:
|
||||
static void init();
|
||||
static void tickEnd(int64_t frameId, float DeltaSeconds, bool bIdleMode);
|
||||
static void tickStart(int64_t frameId, float DeltaSeconds, bool bIdleMode);
|
||||
};
|
||||
Reference in New Issue
Block a user