mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-05-04 08:41:43 +00:00
Increase compatibility of FSR 4 model preset selection
This commit is contained in:
@@ -972,7 +972,7 @@ static void CheckWorkingMode()
|
||||
if (ffxDx12SRModule != nullptr)
|
||||
{
|
||||
LOG_DEBUG("amd_fidelityfx_upscaler_dx12.dll already in memory");
|
||||
FSR4ModelSelection::Hook(ffxDx12SRModule, true);
|
||||
FSR4ModelSelection::Hook(ffxDx12SRModule, FSR4Source::SDK);
|
||||
FfxApiProxy::InitFfxDx12_SR(ffxDx12SRModule);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
#include <detours/detours.h>
|
||||
|
||||
PFN_getModelBlob FSR4ModelSelection::o_getModelBlob = nullptr;
|
||||
PFN_createModel FSR4ModelSelection::o_createModel = nullptr;
|
||||
PFN_createModel FSR4ModelSelection::o_createModelSDK = nullptr;
|
||||
PFN_createModel FSR4ModelSelection::o_createModelDriver = nullptr;
|
||||
|
||||
uint32_t getCorrectedPreset(uint32_t preset)
|
||||
{
|
||||
@@ -43,26 +44,36 @@ uint64_t FSR4ModelSelection::hkgetModelBlob(uint32_t preset, uint64_t unknown, u
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t FSR4ModelSelection::hkcreateModel(void* context, uint32_t preset)
|
||||
uint64_t FSR4ModelSelection::hkcreateModelSDK(void* context, uint32_t preset)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
preset = getCorrectedPreset(preset);
|
||||
|
||||
auto result = o_createModel(context, preset);
|
||||
auto result = o_createModelSDK(context, preset);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FSR4ModelSelection::Hook(HMODULE module, bool unhookOld)
|
||||
uint64_t FSR4ModelSelection::hkcreateModelDriver(void* context, uint32_t preset)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
preset = getCorrectedPreset(preset);
|
||||
|
||||
auto result = o_createModelDriver(context, preset);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FSR4ModelSelection::Hook(HMODULE module, FSR4Source source)
|
||||
{
|
||||
if (module == nullptr)
|
||||
return;
|
||||
|
||||
if (unhookOld && (o_getModelBlob || o_createModel))
|
||||
if (o_getModelBlob)
|
||||
{
|
||||
LOG_DEBUG("Unhooking old model selection hooks, o_getModelBlob: {:X}, o_createModel: {:X}",
|
||||
(uintptr_t) o_getModelBlob, (uintptr_t) o_createModel);
|
||||
LOG_DEBUG("Unhooking old model selection hooks");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
@@ -70,18 +81,24 @@ void FSR4ModelSelection::Hook(HMODULE module, bool unhookOld)
|
||||
if (o_getModelBlob != nullptr)
|
||||
DetourDetach(&(PVOID&) o_getModelBlob, hkgetModelBlob);
|
||||
|
||||
if (o_createModel != nullptr)
|
||||
DetourDetach(&(PVOID&) o_createModel, hkcreateModel);
|
||||
if (o_createModelSDK && source == FSR4Source::SDK)
|
||||
DetourDetach(&(PVOID&) o_createModelSDK, hkcreateModelSDK);
|
||||
else if (o_createModelDriver && source == FSR4Source::DriverDll)
|
||||
DetourDetach(&(PVOID&) o_createModelDriver, hkcreateModelDriver);
|
||||
|
||||
if (DetourTransactionCommit() == 0)
|
||||
{
|
||||
LOG_DEBUG("Unhooked old model selection hooks");
|
||||
o_getModelBlob = nullptr;
|
||||
o_createModel = nullptr;
|
||||
|
||||
if (source == FSR4Source::SDK)
|
||||
o_createModelSDK = nullptr;
|
||||
else if (source == FSR4Source::DriverDll)
|
||||
o_createModelDriver = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (o_getModelBlob == nullptr && o_createModel == nullptr)
|
||||
if (o_getModelBlob == nullptr)
|
||||
{
|
||||
const char* pattern = "83 F9 05 0F 87";
|
||||
o_getModelBlob = (PFN_getModelBlob) scanner::GetAddress(module, pattern);
|
||||
@@ -97,30 +114,57 @@ void FSR4ModelSelection::Hook(HMODULE module, bool unhookOld)
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
const char* pattern403 =
|
||||
"48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? B8 ? ? ? ? E8 ? ? ? ? 48 2B E0 0F 29 B4 24 "
|
||||
"? ? ? ? 0F 29 BC 24 ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 44 8B F2";
|
||||
|
||||
if (!o_createModelSDK && source == FSR4Source::SDK)
|
||||
{
|
||||
// From amd_fidelityfx_upscaler_dx12 4.0.3.604
|
||||
|
||||
o_createModelSDK = (PFN_createModel) scanner::GetAddress(module, pattern403);
|
||||
|
||||
LOG_DEBUG("Hooking model selection, o_createModelSDK: {:X}", (uintptr_t) o_createModelSDK);
|
||||
|
||||
if (o_createModelSDK)
|
||||
{
|
||||
// From amd_fidelityfx_upscaler_dx12 4.0.3.604
|
||||
const char* pattern =
|
||||
"48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? B8 ? ? ? ? E8 ? ? ? ? 48 2B E0 0F "
|
||||
"29 B4 24 ? ? ? ? 0F 29 BC 24 ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 44 8B F2";
|
||||
o_createModel = (PFN_createModel) scanner::GetAddress(module, pattern);
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
if (o_createModel)
|
||||
{
|
||||
LOG_DEBUG("Hooking model selection, o_createModel: {:X}", (uintptr_t) o_createModel);
|
||||
DetourAttach(&(PVOID&) o_createModelSDK, hkcreateModelSDK);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach(&(PVOID&) o_createModel, hkcreateModel);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Couldn't hook model selection");
|
||||
}
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
else
|
||||
LOG_ERROR("Couldn't hook model selection");
|
||||
}
|
||||
else if (!o_createModelDriver && source == FSR4Source::DriverDll)
|
||||
{
|
||||
o_createModelDriver = (PFN_createModel) scanner::GetAddress(module, pattern403);
|
||||
|
||||
if (!o_createModelDriver)
|
||||
{
|
||||
// From amdxcffx64 2.1.0.968
|
||||
const char* pattern = "48 8B C4 48 89 58 ? 55 56 57 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? "
|
||||
"? ? 0F 29 70 ? 0F 29 78 ? 48 8B 05";
|
||||
o_createModelDriver = (PFN_createModel) scanner::GetAddress(module, pattern);
|
||||
}
|
||||
|
||||
if (o_createModelDriver)
|
||||
{
|
||||
LOG_DEBUG("Hooking model selection, o_createModelDriver: {:X}", (uintptr_t) o_createModelDriver);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach(&(PVOID&) o_createModelDriver, hkcreateModelDriver);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
else
|
||||
LOG_ERROR("Couldn't hook model selection");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -5,13 +5,21 @@
|
||||
typedef uint64_t (*PFN_getModelBlob)(uint32_t preset, uint64_t unknown, uint64_t* source, uint64_t* size);
|
||||
typedef uint64_t (*PFN_createModel)(void* context, uint32_t preset);
|
||||
|
||||
enum class FSR4Source
|
||||
{
|
||||
SDK,
|
||||
DriverDll,
|
||||
};
|
||||
|
||||
class FSR4ModelSelection
|
||||
{
|
||||
static uint64_t hkgetModelBlob(uint32_t preset, uint64_t unknown, uint64_t* source, uint64_t* size);
|
||||
static PFN_getModelBlob o_getModelBlob;
|
||||
static uint64_t hkcreateModel(void* context, uint32_t preset);
|
||||
static PFN_createModel o_createModel;
|
||||
static uint64_t hkcreateModelSDK(void* context, uint32_t preset);
|
||||
static uint64_t hkcreateModelDriver(void* context, uint32_t preset);
|
||||
static PFN_createModel o_createModelSDK;
|
||||
static PFN_createModel o_createModelDriver;
|
||||
|
||||
public:
|
||||
static void Hook(HMODULE module, bool unhookOld = true);
|
||||
static void Hook(HMODULE module, FSR4Source source);
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#undef FFX_API_CONFIGURE_FG_SWAPCHAIN_KEY_FRAMEPACINGTUNING
|
||||
|
||||
static HMODULE moduleAmdxc64 = nullptr;
|
||||
static HMODULE fsr4Module = nullptr;
|
||||
static HMODULE moduleAmdxcffx64 = nullptr;
|
||||
|
||||
static AmdExtD3DDevice8* amdExtD3DDevice8 = nullptr;
|
||||
static AmdExtD3DShaderIntrinsics* amdExtD3DShaderIntrinsics = nullptr;
|
||||
@@ -233,21 +233,21 @@ struct AmdExtFfxApi : public IAmdExtFfxApi
|
||||
|
||||
if (o_UpdateFfxApiProvider == nullptr)
|
||||
{
|
||||
fsr4Module = NtdllProxy::LoadLibraryExW_Ldr(L"amdxcffx64.dll", NULL, 0);
|
||||
moduleAmdxcffx64 = NtdllProxy::LoadLibraryExW_Ldr(L"amdxcffx64.dll", NULL, 0);
|
||||
|
||||
if (fsr4Module == nullptr)
|
||||
if (moduleAmdxcffx64 == nullptr)
|
||||
{
|
||||
auto storePath = GetDriverStore();
|
||||
|
||||
for (size_t i = 0; i < storePath.size(); i++)
|
||||
{
|
||||
if (fsr4Module == nullptr)
|
||||
if (moduleAmdxcffx64 == nullptr)
|
||||
{
|
||||
auto dllPath = storePath[i] / L"amdxcffx64.dll";
|
||||
LOG_DEBUG("Trying to load: {}", wstring_to_string(dllPath.c_str()));
|
||||
fsr4Module = NtdllProxy::LoadLibraryExW_Ldr(dllPath.c_str(), NULL, 0);
|
||||
moduleAmdxcffx64 = NtdllProxy::LoadLibraryExW_Ldr(dllPath.c_str(), NULL, 0);
|
||||
|
||||
if (fsr4Module != nullptr)
|
||||
if (moduleAmdxcffx64 != nullptr)
|
||||
{
|
||||
LOG_INFO(L"amdxcffx64 loaded from {}", dllPath.wstring());
|
||||
break;
|
||||
@@ -260,7 +260,7 @@ struct AmdExtFfxApi : public IAmdExtFfxApi
|
||||
LOG_INFO("amdxcffx64 loaded from game folder");
|
||||
}
|
||||
|
||||
if (fsr4Module == nullptr)
|
||||
if (moduleAmdxcffx64 == nullptr)
|
||||
{
|
||||
LOG_ERROR("Failed to load amdxcffx64.dll");
|
||||
return E_NOINTERFACE;
|
||||
@@ -269,15 +269,16 @@ struct AmdExtFfxApi : public IAmdExtFfxApi
|
||||
auto sdk2upscalingModule = KernelBaseProxy::GetModuleHandleA_()("amd_fidelityfx_upscaler_dx12.dll");
|
||||
constexpr bool unhookOld = false;
|
||||
|
||||
if (sdk2upscalingModule != nullptr)
|
||||
FSR4ModelSelection::Hook(sdk2upscalingModule, unhookOld);
|
||||
else
|
||||
FSR4ModelSelection::Hook(fsr4Module, unhookOld);
|
||||
if (sdk2upscalingModule)
|
||||
FSR4ModelSelection::Hook(sdk2upscalingModule, FSR4Source::SDK);
|
||||
|
||||
if (moduleAmdxcffx64)
|
||||
FSR4ModelSelection::Hook(moduleAmdxcffx64, FSR4Source::DriverDll);
|
||||
|
||||
o_UpdateFfxApiProvider =
|
||||
(PFN_UpdateFfxApiProvider) KernelBaseProxy::GetProcAddress_()(fsr4Module, "UpdateFfxApiProvider");
|
||||
o_UpdateFfxApiProviderEx =
|
||||
(PFN_UpdateFfxApiProviderEx) KernelBaseProxy::GetProcAddress_()(fsr4Module, "UpdateFfxApiProviderEx");
|
||||
(PFN_UpdateFfxApiProvider) KernelBaseProxy::GetProcAddress_()(moduleAmdxcffx64, "UpdateFfxApiProvider");
|
||||
o_UpdateFfxApiProviderEx = (PFN_UpdateFfxApiProviderEx) KernelBaseProxy::GetProcAddress_()(
|
||||
moduleAmdxcffx64, "UpdateFfxApiProviderEx");
|
||||
|
||||
if (o_UpdateFfxApiProvider == nullptr)
|
||||
{
|
||||
@@ -491,7 +492,7 @@ void InitFSR4Update()
|
||||
}
|
||||
}
|
||||
|
||||
HMODULE GetFSR4Module() { return fsr4Module; }
|
||||
HMODULE GetFSR4Module() { return moduleAmdxcffx64; }
|
||||
|
||||
HRESULT STDMETHODCALLTYPE hkAmdExtD3DCreateInterface(IUnknown* pOuter, REFIID riid, void** ppvObject)
|
||||
{
|
||||
|
||||
@@ -455,7 +455,7 @@ HMODULE LibraryLoadHooks::LoadLibraryCheckW(std::wstring libName, LPCWSTR lpLibF
|
||||
{
|
||||
auto module = NtdllProxy::LoadLibraryExW_Ldr(libName.c_str(), NULL, 0);
|
||||
|
||||
FSR4ModelSelection::Hook(module, true);
|
||||
FSR4ModelSelection::Hook(module, FSR4Source::SDK);
|
||||
|
||||
if (module != nullptr)
|
||||
FfxApiProxy::InitFfxDx12_SR(module);
|
||||
|
||||
@@ -321,7 +321,7 @@ class FfxApiProxy
|
||||
if (upscaling_dx12.dll != nullptr)
|
||||
{
|
||||
LOG_INFO("{} loaded from exe folder", wstring_to_string(dllNames[i]));
|
||||
FSR4ModelSelection::Hook(upscaling_dx12.dll);
|
||||
FSR4ModelSelection::Hook(upscaling_dx12.dll, FSR4Source::SDK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user