Add basic support for UeLL

Proper AL2 injection to UE games
This commit is contained in:
FakeMichau
2026-05-15 01:06:18 +02:00
parent 1d7508d709
commit 7b785ddfb0
9 changed files with 163 additions and 2 deletions
+1
View File
@@ -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)
{
+2
View File
@@ -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" />
+18
View File
@@ -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" />
+1
View File
@@ -169,6 +169,7 @@ class State
bool reflexShowWarning = false;
bool rtssReflexInjection = false;
bool fakenvapiReloadLowLatency = false;
bool usingUeLL = false;
UINT64 reflexFrameId = 0;
UINT64 frameCount = 0;
+23
View File
@@ -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;
+28 -1
View File
@@ -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)
{
+1 -1
View File
@@ -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);
};
+73
View File
@@ -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);
}
+16
View File
@@ -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);
};