From 2d4a808f3950cd93c8a092a43604bccddd3a366f Mon Sep 17 00:00:00 2001
From: FakeMichau <49685661+FakeMichau@users.noreply.github.com>
Date: Mon, 15 Sep 2025 14:04:31 +0200
Subject: [PATCH] Clean up FSR 4 upgrade
---
OptiScaler/OptiScaler.vcxproj | 1 +
OptiScaler/OptiScaler.vcxproj.filters | 3 +
OptiScaler/fsr4/FSR4Upgrade.cpp | 490 ++++++++++++++++++++++++++
OptiScaler/fsr4/FSR4Upgrade.h | 104 +-----
OptiScaler/hooks/Crypt32_Hooks.h | 4 +-
OptiScaler/hooks/Kernel_Hooks.h | 2 +
6 files changed, 514 insertions(+), 90 deletions(-)
create mode 100644 OptiScaler/fsr4/FSR4Upgrade.cpp
diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj
index c5a18ad0..76689f79 100644
--- a/OptiScaler/OptiScaler.vcxproj
+++ b/OptiScaler/OptiScaler.vcxproj
@@ -478,6 +478,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
+
diff --git a/OptiScaler/OptiScaler.vcxproj.filters b/OptiScaler/OptiScaler.vcxproj.filters
index fda4730c..1be84760 100644
--- a/OptiScaler/OptiScaler.vcxproj.filters
+++ b/OptiScaler/OptiScaler.vcxproj.filters
@@ -890,6 +890,9 @@
Source Files
+
+ Source Files
+
diff --git a/OptiScaler/fsr4/FSR4Upgrade.cpp b/OptiScaler/fsr4/FSR4Upgrade.cpp
new file mode 100644
index 00000000..3e438fe0
--- /dev/null
+++ b/OptiScaler/fsr4/FSR4Upgrade.cpp
@@ -0,0 +1,490 @@
+#include "FSR4Upgrade.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "FSR4ModelSelection.h"
+
+static HMODULE moduleAmdxc64 = nullptr;
+static HMODULE fsr4Module = nullptr;
+
+static AmdExtFfxCapability* amdExtFfxThird = nullptr;
+static AmdExtFfxCapability2* amdExtFfxSecond = nullptr;
+static AmdExtFfxQuery* amdExtFfxQuery = nullptr;
+static AmdExtFfxQuery* o_amdExtFfxQuery = nullptr;
+static AmdExtFfxApi* amdExtFfxApi = nullptr;
+
+static PFN_AmdExtD3DCreateInterface o_AmdExtD3DCreateInterface = nullptr;
+
+#pragma region GDI32
+
+// Manually define structures
+typedef struct _D3DKMT_UMDFILENAMEINFO_L
+{
+ UINT Version;
+ WCHAR UmdFileName[MAX_PATH];
+} D3DKMT_UMDFILENAMEINFO_L;
+
+typedef struct _D3DKMT_ADAPTERINFO_L
+{
+ UINT hAdapter;
+ LUID AdapterLuid;
+ ULONG NumOfSources;
+ BOOL bPrecisePresentRegionsPreferred;
+} D3DKMT_ADAPTERINFO_L;
+
+typedef struct _D3DKMT_QUERYADAPTERINFO_L
+{
+ UINT hAdapter;
+ UINT Type;
+ VOID* pPrivateDriverData;
+ UINT PrivateDriverDataSize;
+} D3DKMT_QUERYADAPTERINFO_L;
+
+typedef struct _D3DKMT_ENUMADAPTERS_L
+{
+ ULONG NumAdapters;
+ D3DKMT_ADAPTERINFO_L Adapters[16];
+} D3DKMT_ENUMADAPTERS_L;
+
+typedef struct _D3DKMT_CLOSEADAPTER_L
+{
+ UINT hAdapter; // in: adapter handle
+} D3DKMT_CLOSEADAPTER_L;
+
+// Function pointers
+typedef UINT (*PFN_D3DKMTQueryAdapterInfo_L)(D3DKMT_QUERYADAPTERINFO_L*);
+typedef UINT (*PFN_D3DKMTEnumAdapters_L)(D3DKMT_ENUMADAPTERS_L*);
+typedef UINT (*PFN_D3DKMTCloseAdapter)(D3DKMT_CLOSEADAPTER_L*);
+
+std::vector GetDriverStore()
+{
+ std::vector result;
+
+ // Load D3DKMT functions dynamically
+ bool libraryLoaded = false;
+ HMODULE hGdi32 = KernelBaseProxy::GetModuleHandleW_()(L"Gdi32.dll");
+
+ if (hGdi32 == nullptr)
+ {
+ hGdi32 = NtdllProxy::LoadLibraryExW_Ldr(L"Gdi32.dll", NULL, 0);
+ libraryLoaded = hGdi32 != nullptr;
+ }
+
+ if (hGdi32 == nullptr)
+ {
+ LOG_ERROR("Failed to load Gdi32.dll");
+ return result;
+ }
+
+ do
+ {
+ auto o_D3DKMTEnumAdapters =
+ (PFN_D3DKMTEnumAdapters_L) KernelBaseProxy::GetProcAddress_()(hGdi32, "D3DKMTEnumAdapters");
+ auto o_D3DKMTQueryAdapterInfo =
+ (PFN_D3DKMTQueryAdapterInfo_L) KernelBaseProxy::GetProcAddress_()(hGdi32, "D3DKMTQueryAdapterInfo");
+ auto o_D3DKMTCloseAdapter =
+ (PFN_D3DKMTCloseAdapter) KernelBaseProxy::GetProcAddress_()(hGdi32, "D3DKMTCloseAdapter");
+
+ if (o_D3DKMTEnumAdapters == nullptr || o_D3DKMTQueryAdapterInfo == nullptr || o_D3DKMTCloseAdapter == nullptr)
+ {
+ LOG_ERROR("Failed to resolve D3DKMT functions");
+ break;
+ }
+
+ D3DKMT_UMDFILENAMEINFO_L umdFileInfo = {};
+ D3DKMT_QUERYADAPTERINFO_L queryAdapterInfo = {};
+
+ queryAdapterInfo.Type = 1; // KMTQAITYPE_UMDRIVERNAME
+ queryAdapterInfo.pPrivateDriverData = &umdFileInfo;
+ queryAdapterInfo.PrivateDriverDataSize = sizeof(umdFileInfo);
+
+ D3DKMT_ENUMADAPTERS_L enumAdapters = {};
+
+ // Query the number of adapters first
+ if (o_D3DKMTEnumAdapters(&enumAdapters) != 0)
+ {
+ LOG_ERROR("Failed to enumerate adapters.");
+ break;
+ }
+
+ // If there are any adapters, the first one should be in the list
+ if (enumAdapters.NumAdapters > 0)
+ {
+ for (size_t i = 0; i < enumAdapters.NumAdapters; i++)
+ {
+ D3DKMT_ADAPTERINFO_L adapter = enumAdapters.Adapters[i];
+ queryAdapterInfo.hAdapter = adapter.hAdapter;
+
+ auto hr = o_D3DKMTQueryAdapterInfo(&queryAdapterInfo);
+
+ if (hr != 0)
+ LOG_ERROR("Failed to query adapter info {:X}", hr);
+ else
+ result.push_back(std::filesystem::path(umdFileInfo.UmdFileName).parent_path());
+
+ D3DKMT_CLOSEADAPTER_L closeAdapter = {};
+ closeAdapter.hAdapter = adapter.hAdapter;
+ auto closeResult = o_D3DKMTCloseAdapter(&closeAdapter);
+ if (closeResult != 0)
+ LOG_ERROR("D3DKMTCloseAdapter error: {:X}", closeResult);
+ }
+ }
+ else
+ {
+ LOG_ERROR("No adapters found.");
+ break;
+ }
+
+ } while (false);
+
+ if (libraryLoaded)
+ NtdllProxy::FreeLibrary_Ldr(hGdi32);
+
+ return result;
+}
+
+#pragma endregion
+
+void CheckForGPU()
+{
+ if (Config::Instance()->Fsr4Update.has_value())
+ return;
+
+ // Call init for any case
+ DxgiProxy::Init();
+
+ IDXGIFactory* factory = nullptr;
+ HRESULT result = DxgiProxy::CreateDxgiFactory_()(__uuidof(factory), &factory);
+
+ if (result != S_OK || factory == nullptr)
+ return;
+
+ UINT adapterIndex = 0;
+ DXGI_ADAPTER_DESC adapterDesc {};
+ IDXGIAdapter* adapter;
+
+ while (factory->EnumAdapters(adapterIndex, &adapter) == S_OK)
+ {
+ if (adapter == nullptr)
+ {
+ adapterIndex++;
+ continue;
+ }
+
+ State::Instance().skipSpoofing = true;
+ result = adapter->GetDesc(&adapterDesc);
+ State::Instance().skipSpoofing = false;
+
+ if (result == S_OK && adapterDesc.VendorId != VendorId::Microsoft)
+ {
+ std::wstring szName(adapterDesc.Description);
+ std::string descStr = std::format("Adapter: {}, VRAM: {} MB", wstring_to_string(szName),
+ adapterDesc.DedicatedVideoMemory / (1024 * 1024));
+ LOG_INFO("{}", descStr);
+
+ // If GPU is AMD
+ if (adapterDesc.VendorId == VendorId::AMD)
+ {
+ // If GPU Name contains 90XX or GFX12 (Linux) always set it to true
+ if (szName.find(L" 90") != std::wstring::npos || szName.find(L" GFX12") != std::wstring::npos)
+ Config::Instance()->Fsr4Update.set_volatile_value(true);
+ }
+ }
+ else
+ {
+ LOG_DEBUG("Can't get description of adapter: {}", adapterIndex);
+ }
+
+ adapter->Release();
+ adapter = nullptr;
+ adapterIndex++;
+ }
+
+ factory->Release();
+ factory = nullptr;
+
+ LOG_INFO("Fsr4Update: {}", Config::Instance()->Fsr4Update.value_or_default());
+}
+
+struct AmdExtFfxApi : public IAmdExtFfxApi
+{
+ PFN_UpdateFfxApiProvider o_UpdateFfxApiProvider = nullptr;
+
+ HRESULT STDMETHODCALLTYPE UpdateFfxApiProvider(void* pData, uint32_t dataSizeInBytes) override
+ {
+ LOG_INFO("UpdateFfxApiProvider called");
+
+ if (o_UpdateFfxApiProvider == nullptr)
+ {
+ fsr4Module = NtdllProxy::LoadLibraryExW_Ldr(L"amdxcffx64.dll", NULL, 0);
+
+ if (fsr4Module == nullptr)
+ {
+ auto storePath = GetDriverStore();
+
+ for (size_t i = 0; i < storePath.size(); i++)
+ {
+ if (fsr4Module == 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);
+
+ if (fsr4Module != nullptr)
+ {
+ LOG_INFO("amdxcffx64 loaded from {}", dllPath.string());
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ LOG_INFO("amdxcffx64 loaded from game folder");
+ }
+
+ if (fsr4Module == nullptr)
+ {
+ LOG_ERROR("Failed to load amdxcffx64.dll");
+ return E_NOINTERFACE;
+ }
+
+ 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);
+
+ o_UpdateFfxApiProvider =
+ (PFN_UpdateFfxApiProvider) KernelBaseProxy::GetProcAddress_()(fsr4Module, "UpdateFfxApiProvider");
+
+ if (o_UpdateFfxApiProvider == nullptr)
+ {
+ LOG_ERROR("Failed to get UpdateFfxApiProvider");
+ return E_NOINTERFACE;
+ }
+ }
+
+ if (o_UpdateFfxApiProvider != nullptr)
+ {
+ State::DisableChecks(1);
+ auto result = o_UpdateFfxApiProvider(pData, dataSizeInBytes);
+ LOG_INFO("UpdateFfxApiProvider called, result: {} ({:X})", result == S_OK ? "Ok" : "Error", (UINT) result);
+ State::EnableChecks(1);
+ return result;
+ }
+
+ return E_NOINTERFACE;
+ }
+
+ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override { return E_NOTIMPL; }
+
+ ULONG __stdcall AddRef(void) override { return 0; }
+
+ ULONG __stdcall Release(void) override { return 0; }
+};
+
+#define STUB(number) \
+ HRESULT STDMETHODCALLTYPE unknown##number() \
+ { \
+ LOG_FUNC(); \
+ return S_OK; \
+ }
+
+struct AmdExtFfxCapability2 : public IAmdExtFfxCapability2
+{
+ STUB(1)
+ HRESULT STDMETHODCALLTYPE IsSupported(uint64_t a)
+ {
+ LOG_TRACE(": {}", a);
+ return S_OK;
+ }
+ STUB(3)
+
+ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override { return E_NOTIMPL; }
+ ULONG __stdcall AddRef(void) override { return 0; }
+ ULONG __stdcall Release(void) override { return 0; }
+};
+
+struct AmdExtFfxCapability : public IAmdExtFfxCapability
+{
+ STUB(1)
+ STUB(2)
+ STUB(3)
+ STUB(4)
+ STUB(5)
+ STUB(6)
+ STUB(7)
+ STUB(8)
+ STUB(9)
+ STUB(10)
+ STUB(11)
+ STUB(12)
+ STUB(13)
+ HRESULT STDMETHODCALLTYPE CheckWMMASupport(uint64_t* a, uint8_t* data)
+ {
+ LOG_TRACE(": {}", *a);
+
+ *reinterpret_cast(&data[0x00]) = 16;
+ *reinterpret_cast(&data[0x08]) = 16;
+ *reinterpret_cast(&data[0x10]) = 16;
+
+ *reinterpret_cast(&data[0x18]) = 11;
+ *reinterpret_cast(&data[0x1C]) = 11;
+
+ *reinterpret_cast(&data[0x20]) = 1;
+ *reinterpret_cast(&data[0x24]) = 1;
+
+ data[0x28] = 0;
+
+ return S_OK;
+ }
+
+ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override { return E_NOTIMPL; }
+ ULONG __stdcall AddRef(void) override { return 0; }
+ ULONG __stdcall Release(void) override { return 0; }
+};
+
+struct AmdExtFfxQuery : public IAmdExtFfxQuery
+{
+ HRESULT STDMETHODCALLTYPE queryInternal(IUnknown* pOuter, REFIID riid, void** ppvObject) override
+ {
+ if (riid == __uuidof(IAmdExtFfxCapability2))
+ {
+ if (amdExtFfxSecond == nullptr)
+ amdExtFfxSecond = new AmdExtFfxCapability2();
+
+ *ppvObject = amdExtFfxSecond;
+
+ LOG_INFO("Custom IAmdExtFfxCapability2 queried, returning custom AmdExtFfxCapability2");
+
+ return S_OK;
+ }
+ else if (riid == __uuidof(IAmdExtFfxCapability))
+ {
+ if (amdExtFfxThird == nullptr)
+ amdExtFfxThird = new AmdExtFfxCapability();
+
+ *ppvObject = amdExtFfxThird;
+
+ LOG_INFO("Custom IAmdExtFfxCapability queried, returning custom AmdExtFfxCapability");
+
+ return S_OK;
+ }
+ else if (o_amdExtFfxQuery)
+ {
+ return o_amdExtFfxQuery->queryInternal(pOuter, riid, ppvObject);
+ }
+
+ return E_NOINTERFACE;
+ }
+
+ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override
+ {
+ if (o_amdExtFfxQuery)
+ return o_amdExtFfxQuery->QueryInterface(riid, ppvObject);
+
+ return E_NOTIMPL;
+ }
+ ULONG __stdcall AddRef(void) override
+ {
+ if (o_amdExtFfxQuery)
+ return o_amdExtFfxQuery->AddRef();
+
+ return 0;
+ }
+ ULONG __stdcall Release(void) override
+ {
+ if (o_amdExtFfxQuery)
+ return o_amdExtFfxQuery->Release();
+
+ return 0;
+ }
+};
+
+void InitFSR4Update()
+{
+ if (Config::Instance()->Fsr4Update.has_value() && !Config::Instance()->Fsr4Update.value())
+ return;
+
+ if (o_AmdExtD3DCreateInterface != nullptr)
+ return;
+
+ LOG_DEBUG("");
+
+ // For FSR4 Upgrade
+ moduleAmdxc64 = KernelBaseProxy::GetModuleHandleW_()(L"amdxc64.dll");
+ if (moduleAmdxc64 == nullptr)
+ moduleAmdxc64 = NtdllProxy::LoadLibraryExW_Ldr(L"amdxc64.dll", NULL, 0);
+
+ if (moduleAmdxc64 != nullptr)
+ {
+ LOG_INFO("amdxc64.dll loaded");
+ o_AmdExtD3DCreateInterface = (PFN_AmdExtD3DCreateInterface) KernelBaseProxy::GetProcAddress_()(
+ moduleAmdxc64, "AmdExtD3DCreateInterface");
+
+ if (o_AmdExtD3DCreateInterface != nullptr)
+ {
+ LOG_DEBUG("Hooking AmdExtD3DCreateInterface");
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourAttach(&(PVOID&) o_AmdExtD3DCreateInterface, hkAmdExtD3DCreateInterface);
+ DetourTransactionCommit();
+ }
+ }
+ else
+ {
+ LOG_INFO("Failed to load amdxc64.dll");
+ }
+}
+
+HMODULE GetFSR4Module() { return fsr4Module; }
+
+HRESULT STDMETHODCALLTYPE hkAmdExtD3DCreateInterface(IUnknown* pOuter, REFIID riid, void** ppvObject)
+{
+ CheckForGPU();
+
+ if (!Config::Instance()->Fsr4Update.value_or_default() && o_AmdExtD3DCreateInterface != nullptr)
+ return o_AmdExtD3DCreateInterface(pOuter, riid, ppvObject);
+
+ // Proton bleeding edge ships amdxc64 that is missing some required functions
+ else if (riid == __uuidof(IAmdExtFfxQuery) && State::Instance().isRunningOnLinux)
+ {
+ // Required for the custom AmdExtFfxApi, lack of it triggers visual glitches
+ if (amdExtFfxQuery == nullptr)
+ amdExtFfxQuery = new AmdExtFfxQuery();
+
+ *ppvObject = amdExtFfxQuery;
+
+ LOG_INFO("IAmdExtFfxQuery queried, returning custom AmdExtFfxQuery");
+
+ if (o_AmdExtD3DCreateInterface != nullptr && o_amdExtFfxQuery == nullptr)
+ o_AmdExtD3DCreateInterface(pOuter, riid, (void**) &o_amdExtFfxQuery);
+
+ return S_OK;
+ }
+
+ else if (riid == __uuidof(IAmdExtFfxApi))
+ {
+ if (amdExtFfxApi == nullptr)
+ amdExtFfxApi = new AmdExtFfxApi();
+
+ // Return custom one
+ *ppvObject = amdExtFfxApi;
+
+ LOG_INFO("IAmdExtFfxApi queried, returning custom AmdExtFfxApi");
+
+ return S_OK;
+ }
+
+ else if (o_AmdExtD3DCreateInterface != nullptr)
+ return o_AmdExtD3DCreateInterface(pOuter, riid, ppvObject);
+
+ return E_NOINTERFACE;
+}
\ No newline at end of file
diff --git a/OptiScaler/fsr4/FSR4Upgrade.h b/OptiScaler/fsr4/FSR4Upgrade.h
index be818cdf..3490934d 100644
--- a/OptiScaler/fsr4/FSR4Upgrade.h
+++ b/OptiScaler/fsr4/FSR4Upgrade.h
@@ -3,14 +3,18 @@
#include
#include
-#include
+#include
#include
#include
-#include
-#include
-#include "FSR4ModelSelection.h"
+#include
+
+// Forward declarations
+struct AmdExtFfxApi;
+struct AmdExtFfxQuery;
+struct AmdExtFfxCapability2;
+struct AmdExtFfxCapability;
typedef HRESULT(__cdecl* PFN_AmdExtD3DCreateInterface)(IUnknown* pOuter, REFIID riid, void** ppvObject);
@@ -68,7 +72,7 @@ inline static std::vector GetDriverStore()
if (hGdi32 == nullptr)
{
- hGdi32 = NtdllProxy::LoadLibraryExW_Ldr(L"Gdi32.dll", NULL, 0);
+ hGdi32 = KernelBaseProxy::LoadLibraryExW_()(L"Gdi32.dll", NULL, 0);
libraryLoaded = hGdi32 != nullptr;
}
@@ -140,7 +144,7 @@ inline static std::vector GetDriverStore()
} while (false);
if (libraryLoaded)
- NtdllProxy::FreeLibrary_Ldr(hGdi32);
+ KernelBaseProxy::FreeLibrary_()(hGdi32);
return result;
}
@@ -155,7 +159,7 @@ inline static std::vector GetDriverStore()
}
MIDL_INTERFACE("F714E11A-B54E-4E0F-ABC5-DF58B18133D1")
-IAmdExtFfxThird : public IUnknown
+IAmdExtFfxCapability : public IUnknown
{
virtual HRESULT unknown1() = 0; // not used
virtual HRESULT unknown2() = 0; // not used
@@ -170,87 +174,11 @@ IAmdExtFfxThird : public IUnknown
virtual HRESULT unknown11() = 0; // not used
virtual HRESULT unknown12() = 0; // not used
virtual HRESULT unknown13() = 0; // not used
- virtual HRESULT unknown14(uint64_t* a, uint8_t* data) = 0;
+ virtual HRESULT CheckWMMASupport(uint64_t* a, uint8_t* data) = 0;
};
-struct AmdExtFfxThird : public IAmdExtFfxThird
-{
- STUB(1)
- STUB(2)
- STUB(3)
- STUB(4)
- STUB(5)
- STUB(6)
- STUB(7)
- STUB(8)
- STUB(9)
- STUB(10)
- STUB(11)
- STUB(12)
- STUB(13)
- HRESULT STDMETHODCALLTYPE unknown14(uint64_t* a, uint8_t* data)
- {
- LOG_TRACE(": {}", *a);
-
- *reinterpret_cast(&data[0x00]) = 16;
- *reinterpret_cast(&data[0x08]) = 16;
- *reinterpret_cast(&data[0x10]) = 16;
-
- *reinterpret_cast(&data[0x18]) = 11;
- *reinterpret_cast(&data[0x1C]) = 11;
-
- *reinterpret_cast(&data[0x20]) = 1;
- *reinterpret_cast(&data[0x24]) = 1;
-
- data[0x28] = 0;
-
- return S_OK;
- }
-
- HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override { return E_NOTIMPL; }
- ULONG __stdcall AddRef(void) override { return 0; }
- ULONG __stdcall Release(void) override { return 0; }
-};
-
-static AmdExtFfxThird* _amdExtFfxThird = nullptr;
-
-// Internal interfaces needed for custom the IAmdExtFfxApi
-MIDL_INTERFACE("BA019D53-CCAB-4CBD-B56A-7230ED4330AD")
-IAmdExtFfxSecond : public IUnknown
-{
- public:
- virtual HRESULT unknown1() = 0; // not used
- virtual HRESULT unknown2(uint64_t a) = 0;
- virtual HRESULT unknown3() = 0;
-};
-
-struct AmdExtFfxSecond : public IAmdExtFfxSecond
-{
- HRESULT STDMETHODCALLTYPE unknown1()
- {
- LOG_FUNC();
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE unknown2(uint64_t a)
- {
- LOG_TRACE(": {}", a);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE unknown3()
- {
- LOG_FUNC();
- return S_OK;
- }
-
- HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override { return E_NOTIMPL; }
- ULONG __stdcall AddRef(void) override { return 0; }
- ULONG __stdcall Release(void) override { return 0; }
-};
-
-static AmdExtFfxSecond* _amdExtFfxSecond = nullptr;
-
MIDL_INTERFACE("014937EC-9288-446F-A9AC-D75A8E3A984F")
-IAmdExtFfxFirst : public IUnknown
+IAmdExtFfxQuery : public IUnknown
{
public:
virtual HRESULT queryInternal(IUnknown * pOuter, REFIID riid, void** ppvObject) = 0;
@@ -315,7 +243,7 @@ struct AmdExtFfxApi : public IAmdExtFfxApi
if (o_UpdateFfxApiProvider == nullptr)
{
- fsr4Module = NtdllProxy::LoadLibraryExW_Ldr(L"amdxcffx64.dll", NULL, 0);
+ fsr4Module = KernelBaseProxy::LoadLibraryExW_()(L"amdxcffx64.dll", NULL, 0);
if (fsr4Module == nullptr)
{
@@ -327,7 +255,7 @@ struct AmdExtFfxApi : public IAmdExtFfxApi
{
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);
+ fsr4Module = KernelBaseProxy::LoadLibraryExW_()(dllPath.c_str(), NULL, 0);
if (fsr4Module != nullptr)
{
@@ -507,7 +435,7 @@ inline void InitFSR4Update()
// For FSR4 Upgrade
moduleAmdxc64 = KernelBaseProxy::GetModuleHandleW_()(L"amdxc64.dll");
if (moduleAmdxc64 == nullptr)
- moduleAmdxc64 = NtdllProxy::LoadLibraryExW_Ldr(L"amdxc64.dll", NULL, 0);
+ moduleAmdxc64 = KernelBaseProxy::LoadLibraryExW_()(L"amdxc64.dll", NULL, 0);
if (moduleAmdxc64 != nullptr)
{
diff --git a/OptiScaler/hooks/Crypt32_Hooks.h b/OptiScaler/hooks/Crypt32_Hooks.h
index 78dd89cb..465f521e 100644
--- a/OptiScaler/hooks/Crypt32_Hooks.h
+++ b/OptiScaler/hooks/Crypt32_Hooks.h
@@ -26,11 +26,11 @@ static BOOL hkCryptQueryObject(DWORD dwObjectType, const void* pvObject, DWORD d
// It's applied even if ffx is already signed, could be improved
if (pathString.contains("amd_fidelityfx_dx12.dll") ||
- pathString.contains("amd_fidelityfx_vk.dll") && fsr4Module)
+ pathString.contains("amd_fidelityfx_vk.dll") && GetFSR4Module())
{
LOG_DEBUG("Replacing FFX with a signed dll");
WCHAR signedDll[256] {};
- GetModuleFileNameW(fsr4Module, signedDll, 256);
+ GetModuleFileNameW(GetFSR4Module(), signedDll, 256);
return o_CryptQueryObject(dwObjectType, signedDll, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
dwFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore,
diff --git a/OptiScaler/hooks/Kernel_Hooks.h b/OptiScaler/hooks/Kernel_Hooks.h
index a583bc6c..1a94278a 100644
--- a/OptiScaler/hooks/Kernel_Hooks.h
+++ b/OptiScaler/hooks/Kernel_Hooks.h
@@ -28,6 +28,8 @@
#include
#include
+#include
+
#include
#pragma intrinsic(_ReturnAddress)