From bd9f396e1707f896a29e8ddfec450b733aff17ca Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Fri, 20 Mar 2026 17:12:00 +0100 Subject: [PATCH] Enforce more function signatures On the vulkan side I took the easy route and used Gemini, in case of issues please visit https://support.gemini.com/ --- OptiScaler/hooks/Advapi32_Hooks.h | 7 + OptiScaler/hooks/Crypt32_Hooks.h | 3 + OptiScaler/hooks/D3D11_Hooks.cpp | 23 +- OptiScaler/hooks/DxgiFactory_Hooks.cpp | 20 +- OptiScaler/hooks/DxgiFactory_Hooks.h | 34 +- OptiScaler/hooks/Dxgi_Hooks.cpp | 5 + OptiScaler/hooks/Gdi32_Hooks.h | 9 +- OptiScaler/hooks/Hook_Utils.h | 8 +- OptiScaler/hooks/Ntdll_Hooks.h | 5 + OptiScaler/hooks/VulkanwDx12_Hooks.cpp | 455 +++++++++++++------------ OptiScaler/hooks/VulkanwDx12_Hooks.h | 297 +++++++++++++++- OptiScaler/hooks/Wintrust_Hooks.h | 3 + OptiScaler/hooks/Xell_Hooks.h | 10 + 13 files changed, 623 insertions(+), 256 deletions(-) diff --git a/OptiScaler/hooks/Advapi32_Hooks.h b/OptiScaler/hooks/Advapi32_Hooks.h index c8ee5d1f..1832581b 100644 --- a/OptiScaler/hooks/Advapi32_Hooks.h +++ b/OptiScaler/hooks/Advapi32_Hooks.h @@ -3,6 +3,8 @@ #include "Config.h" #include "detours/detours.h" +#include "Hook_Utils.h" + const HKEY signatureMark = (HKEY) 0xFFFFFFFF13372137; typedef decltype(&RegOpenKeyExW) PFN_RegOpenKeyExW; @@ -17,6 +19,7 @@ static PFN_RegCloseKey o_RegCloseKey = nullptr; static PFN_RegQueryValueExW o_RegQueryValueExW = nullptr; static PFN_RegQueryValueExA o_RegQueryValueExA = nullptr; +VALIDATE_HOOK(hkRegOpenKeyExW, PFN_RegOpenKeyExW) static LSTATUS hkRegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) { if (lpSubKey != nullptr && (wcscmp(L"SOFTWARE\\NVIDIA Corporation\\Global", lpSubKey) == 0 || @@ -29,6 +32,7 @@ static LSTATUS hkRegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REG return o_RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult); } +VALIDATE_HOOK(hkRegEnumValueW, PFN_RegEnumValueW) static LSTATUS hkRegEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpValueName, LPDWORD lpcchValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) { @@ -75,6 +79,7 @@ static LSTATUS hkRegEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpValueName, LPD } } +VALIDATE_HOOK(hkRegCloseKey, PFN_RegCloseKey) static LSTATUS hkRegCloseKey(HKEY hKey) { if (hKey == signatureMark) @@ -341,6 +346,7 @@ static void SpoofMultiSzA(LPBYTE lpData, LPDWORD lpcbData, const std::string& sp // Original implementation: // https://github.com/artur-graniszewski/dlss-enabler-main/blob/1f8b24722f1b526ffb896ae62b6aa3ca766b0728/Utils/RegistryProxy.cpp#L137 +VALIDATE_HOOK(hkRegQueryValueExW, PFN_RegQueryValueExW) static LONG hkRegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) { @@ -488,6 +494,7 @@ static LONG hkRegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserve return result; } +VALIDATE_HOOK(hkRegQueryValueExA, PFN_RegQueryValueExA) LONG WINAPI hkRegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) { diff --git a/OptiScaler/hooks/Crypt32_Hooks.h b/OptiScaler/hooks/Crypt32_Hooks.h index 02e0d93f..42924b79 100644 --- a/OptiScaler/hooks/Crypt32_Hooks.h +++ b/OptiScaler/hooks/Crypt32_Hooks.h @@ -5,10 +5,13 @@ #include "detours/detours.h" #include +#include "Hook_Utils.h" + typedef decltype(&CryptQueryObject) PFN_CryptQueryObject; static PFN_CryptQueryObject o_CryptQueryObject = nullptr; +VALIDATE_HOOK(hkCryptQueryObject, PFN_CryptQueryObject) static BOOL hkCryptQueryObject(DWORD dwObjectType, const void* pvObject, DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags, DWORD dwFlags, DWORD* pdwMsgAndCertEncodingType, DWORD* pdwContentType, DWORD* pdwFormatType, HCERTSTORE* phCertStore, HCRYPTMSG* phMsg, diff --git a/OptiScaler/hooks/D3D11_Hooks.cpp b/OptiScaler/hooks/D3D11_Hooks.cpp index e754a01d..d1f65739 100644 --- a/OptiScaler/hooks/D3D11_Hooks.cpp +++ b/OptiScaler/hooks/D3D11_Hooks.cpp @@ -14,14 +14,16 @@ #include #include +#include "Hook_Utils.h" + #pragma intrinsic(_ReturnAddress) bool _skipDx11Create = false; // DirectX -typedef HRESULT (*PFN_CreateSamplerState)(ID3D11Device* This, const D3D11_SAMPLER_DESC* pSamplerDesc, - ID3D11SamplerState** ppSamplerState); -typedef ULONG (*PFN_Release)(IUnknown* This); +using PFN_CreateSamplerState = rewrite_signature::type; + +using PFN_Release = rewrite_signature::type; static PFN_D3D11_CREATE_DEVICE o_D3D11CreateDevice = nullptr; static PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN o_D3D11CreateDeviceAndSwapChain = nullptr; @@ -32,6 +34,7 @@ static PFN_Release o_D3D11DeviceRelease = nullptr; static HRESULT hkCreateSamplerState(ID3D11Device* This, const D3D11_SAMPLER_DESC* pSamplerDesc, ID3D11SamplerState** ppSamplerState); +VALIDATE_HOOK(hkD3D11DeviceRelease, PFN_Release) static ULONG hkD3D11DeviceRelease(IUnknown* device) { if (State::Instance().currentD3D11Device == device) @@ -112,9 +115,10 @@ static void HookToDeviceLocal(ID3D11Device* InDevice) } } +VALIDATE_HOOK(hkD3D11On12CreateDevice, PFN_D3D11ON12_CREATE_DEVICE) static HRESULT hkD3D11On12CreateDevice(IUnknown* pDevice, UINT Flags, const D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, IUnknown** ppCommandQueues, UINT NumQueues, UINT NodeMask, - ID3D11Device** ppDevice, ID3D11DeviceContext** ppImmediateContext, + UINT FeatureLevels, IUnknown* const* ppCommandQueues, UINT NumQueues, + UINT NodeMask, ID3D11Device** ppDevice, ID3D11DeviceContext** ppImmediateContext, D3D_FEATURE_LEVEL* pChosenFeatureLevel) { LOG_DEBUG("Caller: {}", Util::WhoIsTheCaller(_ReturnAddress())); @@ -125,6 +129,8 @@ static HRESULT hkD3D11On12CreateDevice(IUnknown* pDevice, UINT Flags, const D3D_ bool rtss = false; + IUnknown* copyCommandQueues = *ppCommandQueues; + // Assuming RTSS is creating a D3D11on12 device, not sure why but sometimes RTSS tries to create // it's D3D11on12 device with old CommandQueue which results crash // I am changing it's CommandQueue with current swapchain's command queue @@ -134,12 +140,12 @@ static HRESULT hkD3D11On12CreateDevice(IUnknown* pDevice, UINT Flags, const D3D_ LOG_INFO("Replaced RTSS CommandQueue with correct one {0:X} -> {1:X}", (UINT64) *ppCommandQueues, (UINT64) State::Instance().currentCommandQueue); - *ppCommandQueues = State::Instance().currentCommandQueue; + copyCommandQueues = State::Instance().currentCommandQueue; rtss = true; } - auto result = o_D3D11On12CreateDevice(pDevice, Flags, pFeatureLevels, FeatureLevels, ppCommandQueues, NumQueues, + auto result = o_D3D11On12CreateDevice(pDevice, Flags, pFeatureLevels, FeatureLevels, ©CommandQueues, NumQueues, NodeMask, ppDevice, ppImmediateContext, pChosenFeatureLevel); if (result == S_OK && *ppDevice != nullptr && !rtss && State::Instance().currentD3D12Device == nullptr) @@ -156,6 +162,7 @@ static HRESULT hkD3D11On12CreateDevice(IUnknown* pDevice, UINT Flags, const D3D_ return result; } +VALIDATE_HOOK(hkD3D11CreateDevice, PFN_D3D11_CREATE_DEVICE) static HRESULT hkD3D11CreateDevice(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, @@ -255,6 +262,7 @@ static HRESULT hkD3D11CreateDevice(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE Drive return result; } +VALIDATE_HOOK(hkD3D11CreateDeviceAndSwapChain, PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN) static HRESULT hkD3D11CreateDeviceAndSwapChain(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, @@ -430,6 +438,7 @@ static HRESULT hkD3D11CreateDeviceAndSwapChain(IDXGIAdapter* pAdapter, D3D_DRIVE return result; } +VALIDATE_HOOK(hkCreateSamplerState, PFN_CreateSamplerState) static HRESULT hkCreateSamplerState(ID3D11Device* This, const D3D11_SAMPLER_DESC* pSamplerDesc, ID3D11SamplerState** ppSamplerState) { diff --git a/OptiScaler/hooks/DxgiFactory_Hooks.cpp b/OptiScaler/hooks/DxgiFactory_Hooks.cpp index 0b34aa3e..c892eaf9 100644 --- a/OptiScaler/hooks/DxgiFactory_Hooks.cpp +++ b/OptiScaler/hooks/DxgiFactory_Hooks.cpp @@ -120,8 +120,8 @@ void DxgiFactoryHooks::HookToFactory(IDXGIFactory* pFactory) DetourTransactionCommit(); } -HRESULT DxgiFactoryHooks::CreateSwapChain(IDXGIFactory* realFactory, IUnknown* pDevice, - const DXGI_SWAP_CHAIN_DESC* pDesc, IDXGISwapChain** ppSwapChain) +HRESULT DxgiFactoryHooks::CreateSwapChain(IDXGIFactory* realFactory, IUnknown* pDevice, DXGI_SWAP_CHAIN_DESC* pDesc, + IDXGISwapChain** ppSwapChain) { *ppSwapChain = nullptr; @@ -841,7 +841,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters(IDXGIFactory* realFactory, UINT Adapter, HRESULT result = S_FALSE; if (State::Instance().skipDxgiLoadChecks) - return o_EnumAdapters(realFactory, Adapter, (IUnknown**) ppAdapter); + return o_EnumAdapters(realFactory, Adapter, ppAdapter); if (Config::Instance()->PreferFirstDedicatedGpu.value_or_default() && Adapter > 0) { @@ -860,7 +860,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters(IDXGIFactory* realFactory, UINT Adapter, auto gpuLuid = allGpus[Adapter].luid; ScopedSkipDxgiLoadChecks skipDxgiLoadChecks {}; - result = o_EnumAdapterByLuid(factory6, gpuLuid, __uuidof(IDXGIAdapter), (IUnknown**) ppAdapter); + result = o_EnumAdapterByLuid(factory6, gpuLuid, __uuidof(IDXGIAdapter), (void**) ppAdapter); } else result = DXGI_ERROR_NOT_FOUND; @@ -871,7 +871,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters(IDXGIFactory* realFactory, UINT Adapter, if (result != S_OK && result != DXGI_ERROR_NOT_FOUND) { ScopedSkipDxgiLoadChecks skipDxgiLoadChecks {}; - result = o_EnumAdapters(realFactory, Adapter, (IUnknown**) ppAdapter); + result = o_EnumAdapters(realFactory, Adapter, ppAdapter); } if (result == S_OK) @@ -889,7 +889,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters1(IDXGIFactory1* realFactory, UINT Adapter HRESULT result = S_FALSE; if (State::Instance().skipDxgiLoadChecks) - return o_EnumAdapters1(realFactory, Adapter, (IUnknown**) ppAdapter); + return o_EnumAdapters1(realFactory, Adapter, ppAdapter); if (Config::Instance()->PreferFirstDedicatedGpu.value_or_default() && Adapter > 0) { @@ -908,7 +908,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters1(IDXGIFactory1* realFactory, UINT Adapter auto gpuLuid = allGpus[Adapter].luid; ScopedSkipDxgiLoadChecks skipDxgiLoadChecks {}; - result = o_EnumAdapterByLuid(factory6, gpuLuid, __uuidof(IDXGIAdapter), (IUnknown**) ppAdapter); + result = o_EnumAdapterByLuid(factory6, gpuLuid, __uuidof(IDXGIAdapter), (void**) ppAdapter); } else result = DXGI_ERROR_NOT_FOUND; @@ -919,7 +919,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters1(IDXGIFactory1* realFactory, UINT Adapter if (result != S_OK && result != DXGI_ERROR_NOT_FOUND) { ScopedSkipDxgiLoadChecks skipDxgiLoadChecks {}; - result = o_EnumAdapters1(realFactory, Adapter, (IUnknown**) ppAdapter); + result = o_EnumAdapters1(realFactory, Adapter, ppAdapter); } if (result == S_OK) @@ -938,7 +938,7 @@ HRESULT DxgiFactoryHooks::EnumAdapterByLuid(IDXGIFactory4* realFactory, LUID Ada HRESULT result; { ScopedSkipDxgiLoadChecks skipDxgiLoadChecks {}; - result = o_EnumAdapterByLuid(realFactory, AdapterLuid, riid, (IUnknown**) ppvAdapter); + result = o_EnumAdapterByLuid(realFactory, AdapterLuid, riid, ppvAdapter); } if (result == S_OK) @@ -958,7 +958,7 @@ HRESULT DxgiFactoryHooks::EnumAdapterByGpuPreference(IDXGIFactory6* realFactory, { ScopedSkipDxgiLoadChecks skipDxgiLoadChecks {}; - result = o_EnumAdapterByGpuPreference(realFactory, Adapter, GpuPreference, riid, (IUnknown**) ppvAdapter); + result = o_EnumAdapterByGpuPreference(realFactory, Adapter, GpuPreference, riid, ppvAdapter); } // Log because that's not something we usually expect diff --git a/OptiScaler/hooks/DxgiFactory_Hooks.h b/OptiScaler/hooks/DxgiFactory_Hooks.h index 3f5e4480..d290902a 100644 --- a/OptiScaler/hooks/DxgiFactory_Hooks.h +++ b/OptiScaler/hooks/DxgiFactory_Hooks.h @@ -3,25 +3,23 @@ #include "FG_Hooks.h" #include +#include "Hook_Utils.h" + class DxgiFactoryHooks { public: static void HookToFactory(IDXGIFactory* pFactory); private: - typedef HRESULT (*PFN_EnumAdapterByGpuPreference)(IDXGIFactory6* This, UINT Adapter, - DXGI_GPU_PREFERENCE GpuPreference, REFIID riid, - IUnknown** ppvAdapter); - typedef HRESULT (*PFN_EnumAdapterByLuid)(IDXGIFactory4* This, LUID AdapterLuid, REFIID riid, IUnknown** ppvAdapter); - typedef HRESULT (*PFN_EnumAdapters1)(IDXGIFactory1* This, UINT Adapter, IUnknown** ppAdapter); - typedef HRESULT (*PFN_EnumAdapters)(IDXGIFactory* This, UINT Adapter, IUnknown** ppAdapter); - typedef HRESULT (*PFN_CreateSwapChain)(IDXGIFactory*, IUnknown*, const DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**); - typedef HRESULT (*PFN_CreateSwapChainForHwnd)(IDXGIFactory*, IUnknown*, HWND, const DXGI_SWAP_CHAIN_DESC1*, - const DXGI_SWAP_CHAIN_FULLSCREEN_DESC*, IDXGIOutput*, - IDXGISwapChain1**); - typedef HRESULT (*PFN_CreateSwapChainForCoreWindow)(IDXGIFactory2*, IUnknown* pDevice, IUnknown* pWindow, - const DXGI_SWAP_CHAIN_DESC1* pDesc, - IDXGIOutput* pRestrictToOutput, IDXGISwapChain1** ppSwapChain); + using PFN_EnumAdapterByGpuPreference = + rewrite_signature::type; + using PFN_EnumAdapterByLuid = rewrite_signature::type; + using PFN_EnumAdapters1 = rewrite_signature::type; + using PFN_EnumAdapters = rewrite_signature::type; + using PFN_CreateSwapChain = rewrite_signature::type; + using PFN_CreateSwapChainForHwnd = rewrite_signature::type; + using PFN_CreateSwapChainForCoreWindow = + rewrite_signature::type; inline static PFN_EnumAdapterByGpuPreference o_EnumAdapterByGpuPreference = nullptr; inline static PFN_EnumAdapterByLuid o_EnumAdapterByLuid = nullptr; @@ -31,7 +29,7 @@ class DxgiFactoryHooks inline static PFN_CreateSwapChainForHwnd o_CreateSwapChainForHwnd = nullptr; inline static PFN_CreateSwapChainForCoreWindow o_CreateSwapChainForCoreWindow = nullptr; - static HRESULT CreateSwapChain(IDXGIFactory* realFactory, IUnknown* pDevice, const DXGI_SWAP_CHAIN_DESC* pDesc, + static HRESULT CreateSwapChain(IDXGIFactory* realFactory, IUnknown* pDevice, DXGI_SWAP_CHAIN_DESC* pDesc, IDXGISwapChain** ppSwapChain); static HRESULT CreateSwapChainForHwnd(IDXGIFactory2* realFactory, IUnknown* pDevice, HWND hWnd, @@ -49,6 +47,14 @@ class DxgiFactoryHooks static HRESULT EnumAdapterByGpuPreference(IDXGIFactory6* realFactory, UINT Adapter, DXGI_GPU_PREFERENCE GpuPreference, REFIID riid, void** ppvAdapter); + VALIDATE_MEMBER_HOOK(CreateSwapChain, PFN_CreateSwapChain) + VALIDATE_MEMBER_HOOK(CreateSwapChainForHwnd, PFN_CreateSwapChainForHwnd) + VALIDATE_MEMBER_HOOK(CreateSwapChainForCoreWindow, PFN_CreateSwapChainForCoreWindow) + VALIDATE_MEMBER_HOOK(EnumAdapters, PFN_EnumAdapters) + VALIDATE_MEMBER_HOOK(EnumAdapters1, PFN_EnumAdapters1) + VALIDATE_MEMBER_HOOK(EnumAdapterByLuid, PFN_EnumAdapterByLuid) + VALIDATE_MEMBER_HOOK(EnumAdapterByGpuPreference, PFN_EnumAdapterByGpuPreference) + // To prevent recursive FG swapchain creation inline static bool _skipFGSwapChainCreation = false; diff --git a/OptiScaler/hooks/Dxgi_Hooks.cpp b/OptiScaler/hooks/Dxgi_Hooks.cpp index 319a7e0b..110fef82 100644 --- a/OptiScaler/hooks/Dxgi_Hooks.cpp +++ b/OptiScaler/hooks/Dxgi_Hooks.cpp @@ -10,6 +10,8 @@ #include #include +#include "Hook_Utils.h" + static DxgiProxy::PFN_CreateDxgiFactory o_CreateDXGIFactory = nullptr; static DxgiProxy::PFN_CreateDxgiFactory1 o_CreateDXGIFactory1 = nullptr; static DxgiProxy::PFN_CreateDxgiFactory2 o_CreateDXGIFactory2 = nullptr; @@ -82,6 +84,7 @@ static void CheckLumaAndReShade(IDXGIFactory* factory) } } +VALIDATE_HOOK(hkCreateDXGIFactory, DxgiProxy::PFN_CreateDxgiFactory) inline static HRESULT hkCreateDXGIFactory(REFIID riid, IDXGIFactory** ppFactory) { auto caller = Util::WhoIsTheCaller(_ReturnAddress()); @@ -133,6 +136,7 @@ inline static HRESULT hkCreateDXGIFactory(REFIID riid, IDXGIFactory** ppFactory) return result; } +VALIDATE_HOOK(hkCreateDXGIFactory1, DxgiProxy::PFN_CreateDxgiFactory1) inline static HRESULT hkCreateDXGIFactory1(REFIID riid, IDXGIFactory1** ppFactory) { auto caller = Util::WhoIsTheCaller(_ReturnAddress()); @@ -184,6 +188,7 @@ inline static HRESULT hkCreateDXGIFactory1(REFIID riid, IDXGIFactory1** ppFactor return result; } +VALIDATE_HOOK(hkCreateDXGIFactory2, DxgiProxy::PFN_CreateDxgiFactory2) inline static HRESULT hkCreateDXGIFactory2(UINT Flags, REFIID riid, IDXGIFactory2** ppFactory) { auto caller = Util::WhoIsTheCaller(_ReturnAddress()); diff --git a/OptiScaler/hooks/Gdi32_Hooks.h b/OptiScaler/hooks/Gdi32_Hooks.h index 9ab83191..8c4a173f 100644 --- a/OptiScaler/hooks/Gdi32_Hooks.h +++ b/OptiScaler/hooks/Gdi32_Hooks.h @@ -3,11 +3,15 @@ #include "Config.h" #include "detours/detours.h" +#include "Hook_Utils.h" + typedef decltype(&D3DKMTQueryAdapterInfo) PFN_D3DKMTQueryAdapterInfo; +typedef decltype(&D3DKMTEnumAdapters2) PFN_D3DKMTEnumAdapters2; static PFN_D3DKMTQueryAdapterInfo o_D3DKMTQueryAdapterInfo = nullptr; -static int hkD3DKMTQueryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* data) +VALIDATE_HOOK(hkD3DKMTQueryAdapterInfo, PFN_D3DKMTQueryAdapterInfo) +static NTSTATUS hkD3DKMTQueryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* data) { auto result = o_D3DKMTQueryAdapterInfo(data); @@ -49,7 +53,8 @@ static int hkD3DKMTQueryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* data) } // Only for Linux, Wine doesn't have this function -static int customD3DKMTEnumAdapters2(const D3DKMT_ENUMADAPTERS2* data) +VALIDATE_HOOK(customD3DKMTEnumAdapters2, PFN_D3DKMTEnumAdapters2) +static NTSTATUS customD3DKMTEnumAdapters2(const D3DKMT_ENUMADAPTERS2* data) { LOG_FUNC(); diff --git a/OptiScaler/hooks/Hook_Utils.h b/OptiScaler/hooks/Hook_Utils.h index f4414e73..e9e14d35 100644 --- a/OptiScaler/hooks/Hook_Utils.h +++ b/OptiScaler/hooks/Hook_Utils.h @@ -10,10 +10,14 @@ template struct rewrite_signatu using type = Ret(WINAPI*)(Class*, Args...); }; +// Same as VALIDATE_HOOK but for class members, put after function declaration +#define VALIDATE_MEMBER_HOOK(HookName, PfnType) \ + static_assert(std::is_same_v, \ + "Signature mismatch: " #HookName " does not match " #PfnType); + // For checking that the hooked function's signature matches the original // Place just above function definition, example of usage: // VALIDATE_HOOK(hkCheckFeatureSupport, PFN_CheckFeatureSupport) #define VALIDATE_HOOK(HookName, PfnType) \ extern std::remove_pointer_t HookName; \ - static_assert(std::is_same_v, \ - "Signature mismatch: " #HookName " does not match " #PfnType); \ No newline at end of file + VALIDATE_MEMBER_HOOK(HookName, PfnType) \ No newline at end of file diff --git a/OptiScaler/hooks/Ntdll_Hooks.h b/OptiScaler/hooks/Ntdll_Hooks.h index 4c189e53..a12097d4 100644 --- a/OptiScaler/hooks/Ntdll_Hooks.h +++ b/OptiScaler/hooks/Ntdll_Hooks.h @@ -6,6 +6,7 @@ #include #include "LibraryLoad_Hooks.h" +#include "Hook_Utils.h" #include @@ -158,6 +159,10 @@ class NtdllHooks return o_LdrUnloadDll(lpLibrary); } + VALIDATE_MEMBER_HOOK(hkNtLoadDll, NtdllProxy::PFN_NtLoadDll) + VALIDATE_MEMBER_HOOK(hkLdrLoadDll, NtdllProxy::PFN_LdrLoadDll) + VALIDATE_MEMBER_HOOK(hkLdrUnloadDll, NtdllProxy::PFN_LdrUnloadDll) + public: static void Hook() { diff --git a/OptiScaler/hooks/VulkanwDx12_Hooks.cpp b/OptiScaler/hooks/VulkanwDx12_Hooks.cpp index 23e3900a..852a88c7 100644 --- a/OptiScaler/hooks/VulkanwDx12_Hooks.cpp +++ b/OptiScaler/hooks/VulkanwDx12_Hooks.cpp @@ -12,18 +12,15 @@ #include #include -typedef VkResult (*PFN_vkQueueSubmitL)(VkQueue queue, uint32_t submitCount, VkSubmitInfo* pSubmits, VkFence fence); -typedef VkResult (*PFN_vkQueueSubmit2L)(VkQueue queue, uint32_t submitCount, VkSubmitInfo2* pSubmits, VkFence fence); - typedef struct VkDummyProps { VkStructureType sType; void* pNext; } VkDummyProps; -static PFN_vkQueueSubmitL o_vkQueueSubmit = nullptr; -static PFN_vkQueueSubmit2L o_vkQueueSubmit2 = nullptr; -static PFN_vkQueueSubmit2L o_vkQueueSubmit2KHR = nullptr; +static PFN_vkQueueSubmit o_vkQueueSubmit = nullptr; +static PFN_vkQueueSubmit2 o_vkQueueSubmit2 = nullptr; +static PFN_vkQueueSubmit2KHR o_vkQueueSubmit2KHR = nullptr; static PFN_vkBeginCommandBuffer o_vkBeginCommandBuffer = nullptr; static PFN_vkEndCommandBuffer o_vkEndCommandBuffer = nullptr; static PFN_vkResetCommandBuffer o_vkResetCommandBuffer = nullptr; @@ -6050,8 +6047,8 @@ void Vulkan_wDx12::hk_vkCmdDrawMeshTasksIndirectCountEXT(VkCommandBuffer command #pragma endregion -VkResult hk_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool) +VkResult Vulkan_wDx12::hk_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool) { VkResult result = o_vkCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool); @@ -6468,7 +6465,8 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkS return result; } #else -VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkSubmitInfo* pSubmits, VkFence fence) +VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, + VkFence fence) { if (pSubmits == nullptr || o_vkQueueSubmit == nullptr) { @@ -6480,8 +6478,13 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkS LOG_DEBUG("queue: {:X}, submitCount: {}, fence: {:X}", (size_t) queue, submitCount, (size_t) fence); #endif + // Copy to freely modify + std::vector submitInfos(pSubmits, pSubmits + submitCount); + + // Modified submits sent to the original call + std::vector finalSubmits; + std::vector semaphores; - std::vector submitInfos; std::vector signalValues; std::vector cmdBuffers; bool injected = false; @@ -6518,22 +6521,22 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkS if (addSemaphore) { // Original signals in submit - auto signalCount = pSubmits[submitIndex].signalSemaphoreCount; - auto signals = pSubmits[submitIndex].pSignalSemaphores; - bool allFound = false; - VkDummyProps* lastNode = nullptr; + auto signalCount = submitInfos[submitIndex].signalSemaphoreCount; + auto signals = submitInfos[submitIndex].pSignalSemaphores; - VkDummyProps* next = (VkDummyProps*) &pSubmits[submitIndex]; + // Use the standard Vulkan struct to traverse the pNext chain safely + VkBaseOutStructure* lastNode = nullptr; + VkBaseOutStructure* next = reinterpret_cast(&submitInfos[submitIndex]); lastNode = next; // collect all signal semaphore submit infos while (next->pNext != nullptr) { - next = (VkDummyProps*) next->pNext; + next = reinterpret_cast(next->pNext); if (next->sType == VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO) { - auto tlSemaphoreInfo = (VkTimelineSemaphoreSubmitInfo*) next; + auto tlSemaphoreInfo = reinterpret_cast(next); if (tlSemaphoreInfo->signalSemaphoreValueCount > 0) { @@ -6550,11 +6553,16 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkS tlSemaphoreInfo->signalSemaphoreValueCount = 0; tlSemaphoreInfo->pSignalSemaphoreValues = nullptr; } - else if (lastNode != nullptr && lastNode->pNext == next) + else if (lastNode != nullptr && + lastNode->pNext == reinterpret_cast(next)) { // removing this signal info so update previous nodes pNext LOG_DEBUG("Remove timeline semaphore submit info"); lastNode->pNext = next->pNext; + + // FIX: Back up 'next' so the loop iterates correctly after removal + next = lastNode; + continue; } } } @@ -6564,39 +6572,40 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkS } } - // insert out signal info structure after lastNode + // insert our signal info structure after lastNode if (lastNode != nullptr) - lastNode->pNext = &timelineInfoResourceCopy; + lastNode->pNext = reinterpret_cast( + const_cast(&timelineInfoResourceCopy)); - LOG_DEBUG("Original submit command buffer count: {}", pSubmits[submitIndex].commandBufferCount); + LOG_DEBUG("Original submit command buffer count: {}", submitInfos[submitIndex].commandBufferCount); // Find upscaler command buffer and move all after it to dummy submit cmdBuffers.push_back(syncSubmitInfo.pCommandBuffers[0]); // Barrier command buffer bool bufferFound = false; - uint32_t newCommandCount = pSubmits[submitIndex].commandBufferCount; - for (uint32_t b = 0; b < pSubmits[submitIndex].commandBufferCount; b++) + uint32_t newCommandCount = submitInfos[submitIndex].commandBufferCount; + for (uint32_t b = 0; b < submitInfos[submitIndex].commandBufferCount; b++) { if (bufferFound) - cmdBuffers.push_back(pSubmits[submitIndex].pCommandBuffers[b]); + cmdBuffers.push_back(submitInfos[submitIndex].pCommandBuffers[b]); - if (!bufferFound && pSubmits[submitIndex].pCommandBuffers[b] == lastCmdBuffer) + if (!bufferFound && submitInfos[submitIndex].pCommandBuffers[b] == lastCmdBuffer) { newCommandCount = b + 1; bufferFound = true; } } - // Remove moved command buffers from original submit - pSubmits[submitIndex].commandBufferCount = newCommandCount; + // Remove moved command buffers from our local submit + submitInfos[submitIndex].commandBufferCount = newCommandCount; LOG_DEBUG("Moved {} command buffers to new submit", cmdBuffers.size() - 1); - LOG_DEBUG("Original submit command buffer count: {}", pSubmits[submitIndex].commandBufferCount); + LOG_DEBUG("Original submit command buffer count: {}", submitInfos[submitIndex].commandBufferCount); // now inserting our signal to it - pSubmits[submitIndex].signalSemaphoreCount = resourceCopySubmitInfo.signalSemaphoreCount; - pSubmits[submitIndex].pSignalSemaphores = resourceCopySubmitInfo.pSignalSemaphores; - timelineInfoResourceCopy.waitSemaphoreValueCount = pSubmits[submitIndex].waitSemaphoreCount; + submitInfos[submitIndex].signalSemaphoreCount = resourceCopySubmitInfo.signalSemaphoreCount; + submitInfos[submitIndex].pSignalSemaphores = resourceCopySubmitInfo.pSignalSemaphores; + timelineInfoResourceCopy.waitSemaphoreValueCount = submitInfos[submitIndex].waitSemaphoreCount; // Inject signal semaphore info to out submit info syncSubmitInfo.commandBufferCount = static_cast(cmdBuffers.size()); @@ -6620,24 +6629,28 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkS } // prepare new submit infos list - submitInfos.reserve(submitCount + 2); + finalSubmits.reserve(submitCount + 2); - // copyback old submit infos + // copyback old submit infos using our mutated local copy for (uint32_t n = 0; n < submitCount; n++) { - submitInfos.push_back(pSubmits[n]); + finalSubmits.push_back(submitInfos[n]); // add our submit info if (n == submitIndex) { - submitInfos.push_back(copyBackSubmitInfo); - submitInfos.push_back(syncSubmitInfo); + finalSubmits.push_back(copyBackSubmitInfo); + finalSubmits.push_back(syncSubmitInfo); } } // update submit infos - submitCount = static_cast(submitInfos.size()); - pSubmits = submitInfos.data(); + submitCount = static_cast(finalSubmits.size()); + + // Reassign the pointer to our local managed vector. + // This is completely valid since we are just moving what the pointer is looking at, + // and finalSubmits lives until the end of this function scope. + pSubmits = finalSubmits.data(); LOG_DEBUG("Injected w/Dx12 submits"); lastCmdBuffer = VK_NULL_HANDLE; @@ -6722,7 +6735,8 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkS } #endif -VkResult Vulkan_wDx12::hk_vkQueueSubmit2(VkQueue queue, uint32_t submitCount, VkSubmitInfo2* pSubmits, VkFence fence) +VkResult Vulkan_wDx12::hk_vkQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, + VkFence fence) { if (pSubmits == nullptr || o_vkQueueSubmit2 == nullptr) { @@ -6734,11 +6748,20 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit2(VkQueue queue, uint32_t submitCount, Vk LOG_DEBUG("queue: {:X}, submitCount: {}, fence: {:X}", (size_t) queue, submitCount, (size_t) fence); #endif - std::vector waitSemaphores; - std::vector signalSemaphores; - std::vector submitInfos; - std::vector cmdBufferInfos; - std::vector signalValues; + // Elevate the scope of all structs so they survive until o_vkQueueSubmit2 is called + std::vector finalSubmits; + VkSubmitInfo2 modifiedOriginalSubmit = {}; + VkSubmitInfo2 copyBackSubmit = {}; + VkSubmitInfo2 syncSubmit = {}; + + std::vector modifiedOriginalCmdBuffers; + std::vector syncCmdBuffers; + std::vector syncSignalSemaphores; + + VkSemaphoreSubmitInfo resourceCopyWaitInfo = {}; + VkSemaphoreSubmitInfo resourceCopySignalInfo = {}; + VkCommandBufferSubmitInfo copyBackCmdInfo = {}; + bool injected = false; if (commandBufferFoundCount < 1 && lastCmdBuffer != VK_NULL_HANDLE && submitCount > 0) @@ -6756,7 +6779,6 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit2(VkQueue queue, uint32_t submitCount, Vk { LOG_DEBUG("Found upscaling command buffer: {:X}, submit: {}, queue: {:X}", (size_t) lastCmdBuffer, i, (size_t) queue); - // Upscaling command buffer found, inject timeline semaphore commandBufferFoundCount++; submitIndex = i; @@ -6771,101 +6793,93 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit2(VkQueue queue, uint32_t submitCount, Vk if (addSemaphore) { - // Collect original signal semaphores - auto signalCount = pSubmits[submitIndex].signalSemaphoreInfoCount; - auto signals = pSubmits[submitIndex].pSignalSemaphoreInfos; - LOG_DEBUG("Original submit command buffer count: {}", pSubmits[submitIndex].commandBufferInfoCount); - // Find upscaler command buffer and move all after it to new submit - VkCommandBufferSubmitInfo barrierCmdInfo = {}; - barrierCmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO; - barrierCmdInfo.commandBuffer = syncSubmitInfo.pCommandBuffers[0]; // Barrier command buffer - cmdBufferInfos.push_back(barrierCmdInfo); - + // 1. Split command buffers into 'original' and 'sync' phases bool bufferFound = false; - uint32_t newCommandCount = pSubmits[submitIndex].commandBufferInfoCount; for (uint32_t b = 0; b < pSubmits[submitIndex].commandBufferInfoCount; b++) { if (bufferFound) - cmdBufferInfos.push_back(pSubmits[submitIndex].pCommandBufferInfos[b]); - - if (!bufferFound && pSubmits[submitIndex].pCommandBufferInfos[b].commandBuffer == lastCmdBuffer) { - newCommandCount = b + 1; - bufferFound = true; + syncCmdBuffers.push_back(pSubmits[submitIndex].pCommandBufferInfos[b]); + } + else + { + modifiedOriginalCmdBuffers.push_back(pSubmits[submitIndex].pCommandBufferInfos[b]); + if (pSubmits[submitIndex].pCommandBufferInfos[b].commandBuffer == lastCmdBuffer) + { + bufferFound = true; + } } } - // Remove moved command buffers from original submit - pSubmits[submitIndex].commandBufferInfoCount = newCommandCount; + LOG_DEBUG("Moved {} command buffers to new submit", syncCmdBuffers.size()); - LOG_DEBUG("Moved {} command buffers to new submit", cmdBufferInfos.size() - 1); - LOG_DEBUG("Original submit command buffer count: {}", pSubmits[submitIndex].commandBufferInfoCount); - - // Create wait semaphore info for resource copy - VkSemaphoreSubmitInfo resourceCopyWaitInfo = {}; - resourceCopyWaitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO; - resourceCopyWaitInfo.semaphore = resourceCopySubmitInfo.pSignalSemaphores[0]; - resourceCopyWaitInfo.value = timelineInfoResourceCopy.pSignalSemaphoreValues[0]; - resourceCopyWaitInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - waitSemaphores.push_back(resourceCopyWaitInfo); - - // Create signal semaphore info for original submit - VkSemaphoreSubmitInfo resourceCopySignalInfo = {}; + // 2. Setup the signal info that ties Original -> CopyBack resourceCopySignalInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO; resourceCopySignalInfo.semaphore = resourceCopySubmitInfo.pSignalSemaphores[0]; resourceCopySignalInfo.value = timelineInfoResourceCopy.pSignalSemaphoreValues[0]; resourceCopySignalInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - // Update original submit to signal our semaphore - pSubmits[submitIndex].signalSemaphoreInfoCount = 1; - pSubmits[submitIndex].pSignalSemaphoreInfos = &resourceCopySignalInfo; + // 3. Assemble the Modified Original Submit (copying base properties, overriding cmd/signals) + modifiedOriginalSubmit = pSubmits[submitIndex]; + modifiedOriginalSubmit.commandBufferInfoCount = + static_cast(modifiedOriginalCmdBuffers.size()); + modifiedOriginalSubmit.pCommandBufferInfos = modifiedOriginalCmdBuffers.data(); + modifiedOriginalSubmit.signalSemaphoreInfoCount = 1; + modifiedOriginalSubmit.pSignalSemaphoreInfos = &resourceCopySignalInfo; - // Create copyBack submit (Dx12 -> Vulkan) - VkSubmitInfo2 copyBackSubmit2 = {}; - copyBackSubmit2.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; - copyBackSubmit2.waitSemaphoreInfoCount = 1; - copyBackSubmit2.pWaitSemaphoreInfos = waitSemaphores.data(); - copyBackSubmit2.commandBufferInfoCount = 1; + // 4. Setup the CopyBack Submit + resourceCopyWaitInfo = resourceCopySignalInfo; // Wait is identical to the signal above - VkCommandBufferSubmitInfo copyBackCmdInfo = {}; copyBackCmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO; copyBackCmdInfo.commandBuffer = copyBackSubmitInfo.pCommandBuffers[0]; - copyBackSubmit2.pCommandBufferInfos = ©BackCmdInfo; - // Move original signal semaphores to final submit - for (uint32_t s = 0; s < signalCount; s++) + copyBackSubmit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; + copyBackSubmit.waitSemaphoreInfoCount = 1; + copyBackSubmit.pWaitSemaphoreInfos = &resourceCopyWaitInfo; + copyBackSubmit.commandBufferInfoCount = 1; + copyBackSubmit.pCommandBufferInfos = ©BackCmdInfo; + + // 5. Setup the final Sync Submit + VkCommandBufferSubmitInfo barrierCmdInfo = {}; + barrierCmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO; + barrierCmdInfo.commandBuffer = syncSubmitInfo.pCommandBuffers[0]; + + // Prepend barrier command buffer to the remaining sync command buffers + syncCmdBuffers.insert(syncCmdBuffers.begin(), barrierCmdInfo); + + // Carry over the original signal semaphores + for (uint32_t s = 0; s < pSubmits[submitIndex].signalSemaphoreInfoCount; s++) { - signalSemaphores.push_back(signals[s]); + syncSignalSemaphores.push_back(pSubmits[submitIndex].pSignalSemaphoreInfos[s]); } - // Create final sync submit with moved command buffers - VkSubmitInfo2 syncSubmit2 = {}; - syncSubmit2.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; - syncSubmit2.commandBufferInfoCount = static_cast(cmdBufferInfos.size()); - syncSubmit2.pCommandBufferInfos = cmdBufferInfos.data(); - syncSubmit2.signalSemaphoreInfoCount = static_cast(signalSemaphores.size()); - syncSubmit2.pSignalSemaphoreInfos = signalSemaphores.data(); + syncSubmit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; + syncSubmit.commandBufferInfoCount = static_cast(syncCmdBuffers.size()); + syncSubmit.pCommandBufferInfos = syncCmdBuffers.data(); + syncSubmit.signalSemaphoreInfoCount = static_cast(syncSignalSemaphores.size()); + syncSubmit.pSignalSemaphoreInfos = syncSignalSemaphores.data(); - // Prepare new submit infos list - submitInfos.reserve(submitCount + 2); - - // Copy old submit infos and insert our submits + // 6. Build the final submit array + finalSubmits.reserve(submitCount + 2); for (uint32_t n = 0; n < submitCount; n++) { - submitInfos.push_back(pSubmits[n]); - if (n == submitIndex) { - submitInfos.push_back(copyBackSubmit2); - submitInfos.push_back(syncSubmit2); + finalSubmits.push_back(modifiedOriginalSubmit); + finalSubmits.push_back(copyBackSubmit); + finalSubmits.push_back(syncSubmit); + } + else + { + finalSubmits.push_back(pSubmits[n]); } } - // Update submit infos - submitCount = static_cast(submitInfos.size()); - pSubmits = submitInfos.data(); + // Redirect the pointers to our persistent vector + submitCount = static_cast(finalSubmits.size()); + pSubmits = finalSubmits.data(); LOG_DEBUG("Injected w/Dx12 submits"); lastCmdBuffer = VK_NULL_HANDLE; @@ -6917,7 +6931,8 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit2(VkQueue queue, uint32_t submitCount, Vk return result; } -VkResult Vulkan_wDx12::hk_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, VkSubmitInfo2* pSubmits, VkFence fence) +VkResult Vulkan_wDx12::hk_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, + VkFence fence) { if (pSubmits == nullptr || o_vkQueueSubmit2KHR == nullptr) { @@ -6929,11 +6944,21 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, LOG_DEBUG("queue: {:X}, submitCount: {}, fence: {:X}", (size_t) queue, submitCount, (size_t) fence); #endif - std::vector waitSemaphores; - std::vector signalSemaphores; - std::vector submitInfos; - std::vector cmdBufferInfos; - std::vector signalValues; + // Elevate the scope of all structs so they survive until o_vkQueueSubmit2KHR is called + std::vector finalSubmits; + VkSubmitInfo2 modifiedOriginalSubmit = {}; + VkSubmitInfo2 copyBackSubmit = {}; + VkSubmitInfo2 syncSubmit = {}; + + std::vector modifiedOriginalCmdBuffers; + std::vector syncCmdBuffers; + std::vector syncSignalSemaphores; + + VkSemaphoreSubmitInfo resourceCopyWaitInfo = {}; + VkSemaphoreSubmitInfo resourceCopySignalInfo = {}; + VkCommandBufferSubmitInfo copyBackCmdInfo = {}; + + bool injected = false; if (commandBufferFoundCount < 1 && lastCmdBuffer != VK_NULL_HANDLE && submitCount > 0) { @@ -6950,7 +6975,6 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, { LOG_DEBUG("Found upscaling command buffer: {:X}, submit: {}, queue: {:X}", (size_t) lastCmdBuffer, i, (size_t) queue); - // Upscaling command buffer found, inject timeline semaphore commandBufferFoundCount++; submitIndex = i; @@ -6965,134 +6989,97 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, if (addSemaphore) { - // Collect original signal semaphores - auto signalCount = pSubmits[submitIndex].signalSemaphoreInfoCount; - auto signals = pSubmits[submitIndex].pSignalSemaphoreInfos; - LOG_DEBUG("Original submit command buffer count: {}", pSubmits[submitIndex].commandBufferInfoCount); - // Find upscaler command buffer and move all after it to new submit - VkCommandBufferSubmitInfo barrierCmdInfo = {}; - barrierCmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO; - barrierCmdInfo.commandBuffer = syncSubmitInfo.pCommandBuffers[0]; // Barrier command buffer - cmdBufferInfos.push_back(barrierCmdInfo); - + // 1. Split command buffers into 'original' and 'sync' phases bool bufferFound = false; - uint32_t newCommandCount = pSubmits[submitIndex].commandBufferInfoCount; for (uint32_t b = 0; b < pSubmits[submitIndex].commandBufferInfoCount; b++) { if (bufferFound) - cmdBufferInfos.push_back(pSubmits[submitIndex].pCommandBufferInfos[b]); - - if (!bufferFound && pSubmits[submitIndex].pCommandBufferInfos[b].commandBuffer == lastCmdBuffer) { - newCommandCount = b + 1; - bufferFound = true; + syncCmdBuffers.push_back(pSubmits[submitIndex].pCommandBufferInfos[b]); + } + else + { + modifiedOriginalCmdBuffers.push_back(pSubmits[submitIndex].pCommandBufferInfos[b]); + if (pSubmits[submitIndex].pCommandBufferInfos[b].commandBuffer == lastCmdBuffer) + { + bufferFound = true; + } } } - // Remove moved command buffers from original submit - pSubmits[submitIndex].commandBufferInfoCount = newCommandCount; + LOG_DEBUG("Moved {} command buffers to new submit", syncCmdBuffers.size()); - LOG_DEBUG("Moved {} command buffers to new submit", cmdBufferInfos.size() - 1); - LOG_DEBUG("Original submit command buffer count: {}", pSubmits[submitIndex].commandBufferInfoCount); - - // Create wait semaphore info for resource copy - VkSemaphoreSubmitInfo resourceCopyWaitInfo = {}; - resourceCopyWaitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO; - resourceCopyWaitInfo.semaphore = resourceCopySubmitInfo.pSignalSemaphores[0]; - resourceCopyWaitInfo.value = timelineInfoResourceCopy.pSignalSemaphoreValues[0]; - resourceCopyWaitInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - waitSemaphores.push_back(resourceCopyWaitInfo); - - // Create signal semaphore info for original submit - VkSemaphoreSubmitInfo resourceCopySignalInfo = {}; + // 2. Setup the signal info that ties Original -> CopyBack resourceCopySignalInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO; resourceCopySignalInfo.semaphore = resourceCopySubmitInfo.pSignalSemaphores[0]; resourceCopySignalInfo.value = timelineInfoResourceCopy.pSignalSemaphoreValues[0]; resourceCopySignalInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - // Update original submit to signal our semaphore - pSubmits[submitIndex].signalSemaphoreInfoCount = 1; - pSubmits[submitIndex].pSignalSemaphoreInfos = &resourceCopySignalInfo; + // 3. Assemble the Modified Original Submit (copying base properties, overriding cmd/signals) + modifiedOriginalSubmit = pSubmits[submitIndex]; + modifiedOriginalSubmit.commandBufferInfoCount = + static_cast(modifiedOriginalCmdBuffers.size()); + modifiedOriginalSubmit.pCommandBufferInfos = modifiedOriginalCmdBuffers.data(); + modifiedOriginalSubmit.signalSemaphoreInfoCount = 1; + modifiedOriginalSubmit.pSignalSemaphoreInfos = &resourceCopySignalInfo; - // Create copyBack submit (Dx12 -> Vulkan) - VkSubmitInfo2 copyBackSubmit2 = {}; - copyBackSubmit2.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; - copyBackSubmit2.waitSemaphoreInfoCount = 1; - copyBackSubmit2.pWaitSemaphoreInfos = waitSemaphores.data(); - copyBackSubmit2.commandBufferInfoCount = 1; + // 4. Setup the CopyBack Submit + resourceCopyWaitInfo = resourceCopySignalInfo; // Wait is identical to the signal above - VkCommandBufferSubmitInfo copyBackCmdInfo = {}; copyBackCmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO; copyBackCmdInfo.commandBuffer = copyBackSubmitInfo.pCommandBuffers[0]; - copyBackSubmit2.pCommandBufferInfos = ©BackCmdInfo; - // Move original signal semaphores to final submit - for (uint32_t s = 0; s < signalCount; s++) + copyBackSubmit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; + copyBackSubmit.waitSemaphoreInfoCount = 1; + copyBackSubmit.pWaitSemaphoreInfos = &resourceCopyWaitInfo; + copyBackSubmit.commandBufferInfoCount = 1; + copyBackSubmit.pCommandBufferInfos = ©BackCmdInfo; + + // 5. Setup the final Sync Submit + VkCommandBufferSubmitInfo barrierCmdInfo = {}; + barrierCmdInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO; + barrierCmdInfo.commandBuffer = syncSubmitInfo.pCommandBuffers[0]; + + // Prepend barrier command buffer to the remaining sync command buffers + syncCmdBuffers.insert(syncCmdBuffers.begin(), barrierCmdInfo); + + // Carry over the original signal semaphores + for (uint32_t s = 0; s < pSubmits[submitIndex].signalSemaphoreInfoCount; s++) { - signalSemaphores.push_back(signals[s]); + syncSignalSemaphores.push_back(pSubmits[submitIndex].pSignalSemaphoreInfos[s]); } - // Create final sync submit with moved command buffers - VkSubmitInfo2 syncSubmit2 = {}; - syncSubmit2.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; - syncSubmit2.commandBufferInfoCount = static_cast(cmdBufferInfos.size()); - syncSubmit2.pCommandBufferInfos = cmdBufferInfos.data(); - syncSubmit2.signalSemaphoreInfoCount = static_cast(signalSemaphores.size()); - syncSubmit2.pSignalSemaphoreInfos = signalSemaphores.data(); + syncSubmit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; + syncSubmit.commandBufferInfoCount = static_cast(syncCmdBuffers.size()); + syncSubmit.pCommandBufferInfos = syncCmdBuffers.data(); + syncSubmit.signalSemaphoreInfoCount = static_cast(syncSignalSemaphores.size()); + syncSubmit.pSignalSemaphoreInfos = syncSignalSemaphores.data(); - // Prepare new submit infos list - submitInfos.reserve(submitCount + 2); - - // Copy old submit infos and insert our submits + // 6. Build the final submit array + finalSubmits.reserve(submitCount + 2); for (uint32_t n = 0; n < submitCount; n++) { - submitInfos.push_back(pSubmits[n]); - if (n == submitIndex) { - submitInfos.push_back(copyBackSubmit2); - submitInfos.push_back(syncSubmit2); + finalSubmits.push_back(modifiedOriginalSubmit); + finalSubmits.push_back(copyBackSubmit); + finalSubmits.push_back(syncSubmit); + } + else + { + finalSubmits.push_back(pSubmits[n]); } } - // Update submit infos - submitCount = static_cast(submitInfos.size()); - pSubmits = submitInfos.data(); + // Redirect the pointers to our persistent vector + submitCount = static_cast(finalSubmits.size()); + pSubmits = finalSubmits.data(); - LOG_DEBUG("Injected w/Dx12 submits (VkSubmitInfo2)"); -#ifdef LOG_ALL_RECORDS - LOG_DEBUG("=================================================="); - - for (size_t a = 0; a < submitCount; a++) - { - LOG_DEBUG(" Submit[{}]: cmdBufferInfoCount: {}", a, pSubmits[a].commandBufferInfoCount); - - for (size_t b = 0; b < pSubmits[a].commandBufferInfoCount; b++) - { - LOG_DEBUG(" CmdBuffer[{}]: {:X}", b, - (size_t) pSubmits[a].pCommandBufferInfos[b].commandBuffer); - } - - LOG_DEBUG(" waitSemaphoreInfoCount: {}", pSubmits[a].waitSemaphoreInfoCount); - for (size_t c = 0; c < pSubmits[a].waitSemaphoreInfoCount; c++) - { - LOG_DEBUG(" WaitSemaphore[{}]: {:X}, value: {}", c, - (size_t) pSubmits[a].pWaitSemaphoreInfos[c].semaphore, - pSubmits[a].pWaitSemaphoreInfos[c].value); - } - - LOG_DEBUG(" signalSemaphoreInfoCount: {}", pSubmits[a].signalSemaphoreInfoCount); - for (size_t d = 0; d < pSubmits[a].signalSemaphoreInfoCount; d++) - { - LOG_DEBUG(" SignalSemaphore[{}]: {:X}, value: {}", d, - (size_t) pSubmits[a].pSignalSemaphoreInfos[d].semaphore, - pSubmits[a].pSignalSemaphoreInfos[d].value); - } - } -#endif + LOG_DEBUG("Injected w/Dx12 submits"); lastCmdBuffer = VK_NULL_HANDLE; + injected = true; break; } } @@ -7101,9 +7088,41 @@ VkResult Vulkan_wDx12::hk_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, // Call original function auto result = o_vkQueueSubmit2KHR(queue, submitCount, pSubmits, fence); -#ifdef LOG_ALL_RECORDS - LOG_DEBUG("o_vkQueueSubmit2KHR result: {}", magic_enum::enum_name(result)); -#endif + if (result != VK_SUCCESS) + { + LOG_ERROR("o_vkQueueSubmit2 result: {}", magic_enum::enum_name(result)); + + if (injected) + { + LOG_DEBUG("=================================================="); + + for (size_t a = 0; a < submitCount; a++) + { + LOG_DEBUG(" Submit[{}]: cmdBufferInfoCount: {}", a, pSubmits[a].commandBufferInfoCount); + + for (size_t b = 0; b < pSubmits[a].commandBufferInfoCount; b++) + { + LOG_DEBUG(" CmdBuffer[{}]: {:X}", b, (size_t) pSubmits[a].pCommandBufferInfos[b].commandBuffer); + } + + LOG_DEBUG(" waitSemaphoreInfoCount: {}", pSubmits[a].waitSemaphoreInfoCount); + for (size_t c = 0; c < pSubmits[a].waitSemaphoreInfoCount; c++) + { + LOG_DEBUG(" WaitSemaphore[{}]: {:X}, value: {}", c, + (size_t) pSubmits[a].pWaitSemaphoreInfos[c].semaphore, + pSubmits[a].pWaitSemaphoreInfos[c].value); + } + + LOG_DEBUG(" signalSemaphoreInfoCount: {}", pSubmits[a].signalSemaphoreInfoCount); + for (size_t d = 0; d < pSubmits[a].signalSemaphoreInfoCount; d++) + { + LOG_DEBUG(" SignalSemaphore[{}]: {:X}, value: {}", d, + (size_t) pSubmits[a].pSignalSemaphoreInfos[d].semaphore, + pSubmits[a].pSignalSemaphoreInfos[d].value); + } + } + } + } return result; } @@ -7242,7 +7261,7 @@ PFN_vkVoidFunction Vulkan_wDx12::GetAddress(const PFN_vkVoidFunction original, c // LOG_DEBUG("vkQueueSubmit"); if (o_vkQueueSubmit == nullptr) - o_vkQueueSubmit = (PFN_vkQueueSubmitL) original; + o_vkQueueSubmit = (PFN_vkQueueSubmit) original; return (PFN_vkVoidFunction) hk_vkQueueSubmit; } @@ -7251,7 +7270,7 @@ PFN_vkVoidFunction Vulkan_wDx12::GetAddress(const PFN_vkVoidFunction original, c // LOG_DEBUG("vkQueueSubmit2"); if (o_vkQueueSubmit2 == nullptr) - o_vkQueueSubmit2 = (PFN_vkQueueSubmit2L) original; + o_vkQueueSubmit2 = (PFN_vkQueueSubmit2) original; return (PFN_vkVoidFunction) hk_vkQueueSubmit2; } @@ -7260,7 +7279,7 @@ PFN_vkVoidFunction Vulkan_wDx12::GetAddress(const PFN_vkVoidFunction original, c // LOG_DEBUG("vkQueueSubmit2KHR"); if (o_vkQueueSubmit2KHR == nullptr) - o_vkQueueSubmit2KHR = (PFN_vkQueueSubmit2L) original; + o_vkQueueSubmit2KHR = (PFN_vkQueueSubmit2KHR) original; return (PFN_vkVoidFunction) hk_vkQueueSubmit2KHR; } @@ -9774,9 +9793,9 @@ void Vulkan_wDx12::Hook(HMODULE vulkanModule) if (o_vkQueueSubmit != nullptr) return; - o_vkQueueSubmit = (PFN_vkQueueSubmitL) GetProcAddress(vulkanModule, "vkQueueSubmit"); - o_vkQueueSubmit2 = (PFN_vkQueueSubmit2L) GetProcAddress(vulkanModule, "vkQueueSubmit2"); - o_vkQueueSubmit2KHR = (PFN_vkQueueSubmit2L) GetProcAddress(vulkanModule, "vkQueueSubmit2KHR"); + o_vkQueueSubmit = (PFN_vkQueueSubmit) GetProcAddress(vulkanModule, "vkQueueSubmit"); + o_vkQueueSubmit2 = (PFN_vkQueueSubmit2) GetProcAddress(vulkanModule, "vkQueueSubmit2"); + o_vkQueueSubmit2KHR = (PFN_vkQueueSubmit2KHR) GetProcAddress(vulkanModule, "vkQueueSubmit2KHR"); o_vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) GetProcAddress(vulkanModule, "vkBeginCommandBuffer"); o_vkEndCommandBuffer = (PFN_vkEndCommandBuffer) GetProcAddress(vulkanModule, "vkEndCommandBuffer"); o_vkResetCommandBuffer = (PFN_vkResetCommandBuffer) GetProcAddress(vulkanModule, "vkResetCommandBuffer"); diff --git a/OptiScaler/hooks/VulkanwDx12_Hooks.h b/OptiScaler/hooks/VulkanwDx12_Hooks.h index 08e07d32..c966413c 100644 --- a/OptiScaler/hooks/VulkanwDx12_Hooks.h +++ b/OptiScaler/hooks/VulkanwDx12_Hooks.h @@ -10,12 +10,16 @@ #include #endif +#include "Hook_Utils.h" + class Vulkan_wDx12 { private: - static VkResult hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, VkSubmitInfo* pSubmits, VkFence fence); - static VkResult hk_vkQueueSubmit2(VkQueue queue, uint32_t submitCount, VkSubmitInfo2* pSubmits, VkFence fence); - static VkResult hk_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, VkSubmitInfo2* pSubmits, VkFence fence); + static VkResult hk_vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence); + static VkResult hk_vkQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, + VkFence fence); + static VkResult hk_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, + VkFence fence); static VkResult hk_vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo); static VkResult hk_vkEndCommandBuffer(VkCommandBuffer commandBuffer); static VkResult hk_vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); @@ -29,6 +33,8 @@ class Vulkan_wDx12 static void hk_vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); + static VkResult hk_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool); static PFN_vkVoidFunction GetAddress(const PFN_vkVoidFunction original, const char* pName); static void InitializeStateTrackerFunctionTable(); @@ -569,6 +575,291 @@ class Vulkan_wDx12 VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); + VALIDATE_MEMBER_HOOK(hk_vkQueueSubmit, PFN_vkQueueSubmit) + VALIDATE_MEMBER_HOOK(hk_vkQueueSubmit2, PFN_vkQueueSubmit2) + VALIDATE_MEMBER_HOOK(hk_vkQueueSubmit2KHR, PFN_vkQueueSubmit2) + VALIDATE_MEMBER_HOOK(hk_vkBeginCommandBuffer, PFN_vkBeginCommandBuffer) + VALIDATE_MEMBER_HOOK(hk_vkEndCommandBuffer, PFN_vkEndCommandBuffer) + VALIDATE_MEMBER_HOOK(hk_vkResetCommandBuffer, PFN_vkResetCommandBuffer) + VALIDATE_MEMBER_HOOK(hk_vkCmdExecuteCommands, PFN_vkCmdExecuteCommands) + VALIDATE_MEMBER_HOOK(hk_vkFreeCommandBuffers, PFN_vkFreeCommandBuffers) + VALIDATE_MEMBER_HOOK(hk_vkResetCommandPool, PFN_vkResetCommandPool) + VALIDATE_MEMBER_HOOK(hk_vkAllocateCommandBuffers, PFN_vkAllocateCommandBuffers) + VALIDATE_MEMBER_HOOK(hk_vkDestroyCommandPool, PFN_vkDestroyCommandPool) + VALIDATE_MEMBER_HOOK(hk_vkCreateCommandPool, PFN_vkCreateCommandPool) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindPipeline, PFN_vkCmdBindPipeline) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetViewport, PFN_vkCmdSetViewport) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetScissor, PFN_vkCmdSetScissor) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetLineWidth, PFN_vkCmdSetLineWidth) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthBias, PFN_vkCmdSetDepthBias) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetBlendConstants, PFN_vkCmdSetBlendConstants) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthBounds, PFN_vkCmdSetDepthBounds) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetStencilCompareMask, PFN_vkCmdSetStencilCompareMask) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetStencilWriteMask, PFN_vkCmdSetStencilWriteMask) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetStencilReference, PFN_vkCmdSetStencilReference) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindDescriptorSets, PFN_vkCmdBindDescriptorSets) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindIndexBuffer, PFN_vkCmdBindIndexBuffer) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindVertexBuffers, PFN_vkCmdBindVertexBuffers) + VALIDATE_MEMBER_HOOK(hk_vkCmdDraw, PFN_vkCmdDraw) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndexed, PFN_vkCmdDrawIndexed) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndirect, PFN_vkCmdDrawIndirect) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndexedIndirect, PFN_vkCmdDrawIndexedIndirect) + VALIDATE_MEMBER_HOOK(hk_vkCmdDispatch, PFN_vkCmdDispatch) + VALIDATE_MEMBER_HOOK(hk_vkCmdDispatchIndirect, PFN_vkCmdDispatchIndirect) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyBuffer, PFN_vkCmdCopyBuffer) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyImage, PFN_vkCmdCopyImage) + VALIDATE_MEMBER_HOOK(hk_vkCmdBlitImage, PFN_vkCmdBlitImage) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyBufferToImage, PFN_vkCmdCopyBufferToImage) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyImageToBuffer, PFN_vkCmdCopyImageToBuffer) + VALIDATE_MEMBER_HOOK(hk_vkCmdUpdateBuffer, PFN_vkCmdUpdateBuffer) + VALIDATE_MEMBER_HOOK(hk_vkCmdFillBuffer, PFN_vkCmdFillBuffer) + VALIDATE_MEMBER_HOOK(hk_vkCmdClearColorImage, PFN_vkCmdClearColorImage) + VALIDATE_MEMBER_HOOK(hk_vkCmdClearDepthStencilImage, PFN_vkCmdClearDepthStencilImage) + VALIDATE_MEMBER_HOOK(hk_vkCmdClearAttachments, PFN_vkCmdClearAttachments) + VALIDATE_MEMBER_HOOK(hk_vkCmdResolveImage, PFN_vkCmdResolveImage) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetEvent, PFN_vkCmdSetEvent) + VALIDATE_MEMBER_HOOK(hk_vkCmdResetEvent, PFN_vkCmdResetEvent) + VALIDATE_MEMBER_HOOK(hk_vkCmdWaitEvents, PFN_vkCmdWaitEvents) + VALIDATE_MEMBER_HOOK(hk_vkCmdPipelineBarrier, PFN_vkCmdPipelineBarrier) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginQuery, PFN_vkCmdBeginQuery) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndQuery, PFN_vkCmdEndQuery) + VALIDATE_MEMBER_HOOK(hk_vkCmdResetQueryPool, PFN_vkCmdResetQueryPool) + VALIDATE_MEMBER_HOOK(hk_vkCmdWriteTimestamp, PFN_vkCmdWriteTimestamp) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyQueryPoolResults, PFN_vkCmdCopyQueryPoolResults) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushConstants, PFN_vkCmdPushConstants) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginRenderPass, PFN_vkCmdBeginRenderPass) + VALIDATE_MEMBER_HOOK(hk_vkCmdNextSubpass, PFN_vkCmdNextSubpass) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndRenderPass, PFN_vkCmdEndRenderPass) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDeviceMask, PFN_vkCmdSetDeviceMask) + VALIDATE_MEMBER_HOOK(hk_vkCmdDispatchBase, PFN_vkCmdDispatchBase) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndirectCount, PFN_vkCmdDrawIndirectCount) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndexedIndirectCount, PFN_vkCmdDrawIndexedIndirectCount) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginRenderPass2, PFN_vkCmdBeginRenderPass2) + VALIDATE_MEMBER_HOOK(hk_vkCmdNextSubpass2, PFN_vkCmdNextSubpass2) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndRenderPass2, PFN_vkCmdEndRenderPass2) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetEvent2, PFN_vkCmdSetEvent2) + VALIDATE_MEMBER_HOOK(hk_vkCmdResetEvent2, PFN_vkCmdResetEvent2) + VALIDATE_MEMBER_HOOK(hk_vkCmdWaitEvents2, PFN_vkCmdWaitEvents2) + VALIDATE_MEMBER_HOOK(hk_vkCmdPipelineBarrier2, PFN_vkCmdPipelineBarrier2) + VALIDATE_MEMBER_HOOK(hk_vkCmdWriteTimestamp2, PFN_vkCmdWriteTimestamp2) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyBuffer2, PFN_vkCmdCopyBuffer2) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyImage2, PFN_vkCmdCopyImage2) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyBufferToImage2, PFN_vkCmdCopyBufferToImage2) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyImageToBuffer2, PFN_vkCmdCopyImageToBuffer2) + VALIDATE_MEMBER_HOOK(hk_vkCmdBlitImage2, PFN_vkCmdBlitImage2) + VALIDATE_MEMBER_HOOK(hk_vkCmdResolveImage2, PFN_vkCmdResolveImage2) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginRendering, PFN_vkCmdBeginRendering) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndRendering, PFN_vkCmdEndRendering) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCullMode, PFN_vkCmdSetCullMode) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetFrontFace, PFN_vkCmdSetFrontFace) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPrimitiveTopology, PFN_vkCmdSetPrimitiveTopology) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetViewportWithCount, PFN_vkCmdSetViewportWithCount) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetScissorWithCount, PFN_vkCmdSetScissorWithCount) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindVertexBuffers2, PFN_vkCmdBindVertexBuffers2) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthTestEnable, PFN_vkCmdSetDepthTestEnable) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthWriteEnable, PFN_vkCmdSetDepthWriteEnable) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthCompareOp, PFN_vkCmdSetDepthCompareOp) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthBoundsTestEnable, PFN_vkCmdSetDepthBoundsTestEnable) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetStencilTestEnable, PFN_vkCmdSetStencilTestEnable) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetStencilOp, PFN_vkCmdSetStencilOp) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRasterizerDiscardEnable, PFN_vkCmdSetRasterizerDiscardEnable) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthBiasEnable, PFN_vkCmdSetDepthBiasEnable) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPrimitiveRestartEnable, PFN_vkCmdSetPrimitiveRestartEnable) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetLineStipple, PFN_vkCmdSetLineStipple) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindIndexBuffer2, PFN_vkCmdBindIndexBuffer2) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushDescriptorSet, PFN_vkCmdPushDescriptorSet) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushDescriptorSetWithTemplate, PFN_vkCmdPushDescriptorSetWithTemplate) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRenderingAttachmentLocations, PFN_vkCmdSetRenderingAttachmentLocations) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRenderingInputAttachmentIndices, PFN_vkCmdSetRenderingInputAttachmentIndices) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindDescriptorSets2, PFN_vkCmdBindDescriptorSets2) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushConstants2, PFN_vkCmdPushConstants2) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushDescriptorSet2, PFN_vkCmdPushDescriptorSet2) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushDescriptorSetWithTemplate2, PFN_vkCmdPushDescriptorSetWithTemplate2) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginVideoCodingKHR, PFN_vkCmdBeginVideoCodingKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndVideoCodingKHR, PFN_vkCmdEndVideoCodingKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdControlVideoCodingKHR, PFN_vkCmdControlVideoCodingKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdDecodeVideoKHR, PFN_vkCmdDecodeVideoKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginRenderingKHR, PFN_vkCmdBeginRenderingKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndRenderingKHR, PFN_vkCmdEndRenderingKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDeviceMaskKHR, PFN_vkCmdSetDeviceMaskKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdDispatchBaseKHR, PFN_vkCmdDispatchBaseKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushDescriptorSetKHR, PFN_vkCmdPushDescriptorSetKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushDescriptorSetWithTemplateKHR, PFN_vkCmdPushDescriptorSetWithTemplateKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginRenderPass2KHR, PFN_vkCmdBeginRenderPass2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdNextSubpass2KHR, PFN_vkCmdNextSubpass2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndRenderPass2KHR, PFN_vkCmdEndRenderPass2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndirectCountKHR, PFN_vkCmdDrawIndirectCountKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndexedIndirectCountKHR, PFN_vkCmdDrawIndexedIndirectCountKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetFragmentShadingRateKHR, PFN_vkCmdSetFragmentShadingRateKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRenderingAttachmentLocationsKHR, PFN_vkCmdSetRenderingAttachmentLocationsKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRenderingInputAttachmentIndicesKHR, PFN_vkCmdSetRenderingInputAttachmentIndicesKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdEncodeVideoKHR, PFN_vkCmdEncodeVideoKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetEvent2KHR, PFN_vkCmdSetEvent2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdResetEvent2KHR, PFN_vkCmdResetEvent2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdWaitEvents2KHR, PFN_vkCmdWaitEvents2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdPipelineBarrier2KHR, PFN_vkCmdPipelineBarrier2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdWriteTimestamp2KHR, PFN_vkCmdWriteTimestamp2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyBuffer2KHR, PFN_vkCmdCopyBuffer2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyImage2KHR, PFN_vkCmdCopyImage2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyBufferToImage2KHR, PFN_vkCmdCopyBufferToImage2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyImageToBuffer2KHR, PFN_vkCmdCopyImageToBuffer2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdBlitImage2KHR, PFN_vkCmdBlitImage2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdResolveImage2KHR, PFN_vkCmdResolveImage2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdTraceRaysIndirect2KHR, PFN_vkCmdTraceRaysIndirect2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindIndexBuffer2KHR, PFN_vkCmdBindIndexBuffer2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetLineStippleKHR, PFN_vkCmdSetLineStippleKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindDescriptorSets2KHR, PFN_vkCmdBindDescriptorSets2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushConstants2KHR, PFN_vkCmdPushConstants2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushDescriptorSet2KHR, PFN_vkCmdPushDescriptorSet2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdPushDescriptorSetWithTemplate2KHR, PFN_vkCmdPushDescriptorSetWithTemplate2KHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDescriptorBufferOffsets2EXT, PFN_vkCmdSetDescriptorBufferOffsets2EXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT, + PFN_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDebugMarkerBeginEXT, PFN_vkCmdDebugMarkerBeginEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDebugMarkerEndEXT, PFN_vkCmdDebugMarkerEndEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDebugMarkerInsertEXT, PFN_vkCmdDebugMarkerInsertEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindTransformFeedbackBuffersEXT, PFN_vkCmdBindTransformFeedbackBuffersEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginTransformFeedbackEXT, PFN_vkCmdBeginTransformFeedbackEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndTransformFeedbackEXT, PFN_vkCmdEndTransformFeedbackEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginQueryIndexedEXT, PFN_vkCmdBeginQueryIndexedEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndQueryIndexedEXT, PFN_vkCmdEndQueryIndexedEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndirectByteCountEXT, PFN_vkCmdDrawIndirectByteCountEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdCuLaunchKernelNVX, PFN_vkCmdCuLaunchKernelNVX) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndirectCountAMD, PFN_vkCmdDrawIndirectCountAMD) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawIndexedIndirectCountAMD, PFN_vkCmdDrawIndexedIndirectCountAMD) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginConditionalRenderingEXT, PFN_vkCmdBeginConditionalRenderingEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndConditionalRenderingEXT, PFN_vkCmdEndConditionalRenderingEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetViewportWScalingNV, PFN_vkCmdSetViewportWScalingNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDiscardRectangleEXT, PFN_vkCmdSetDiscardRectangleEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDiscardRectangleEnableEXT, PFN_vkCmdSetDiscardRectangleEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDiscardRectangleModeEXT, PFN_vkCmdSetDiscardRectangleModeEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBeginDebugUtilsLabelEXT, PFN_vkCmdBeginDebugUtilsLabelEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdEndDebugUtilsLabelEXT, PFN_vkCmdEndDebugUtilsLabelEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdInsertDebugUtilsLabelEXT, PFN_vkCmdInsertDebugUtilsLabelEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetSampleLocationsEXT, PFN_vkCmdSetSampleLocationsEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindShadingRateImageNV, PFN_vkCmdBindShadingRateImageNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetViewportShadingRatePaletteNV, PFN_vkCmdSetViewportShadingRatePaletteNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCoarseSampleOrderNV, PFN_vkCmdSetCoarseSampleOrderNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdBuildAccelerationStructureNV, PFN_vkCmdBuildAccelerationStructureNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyAccelerationStructureNV, PFN_vkCmdCopyAccelerationStructureNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdTraceRaysNV, PFN_vkCmdTraceRaysNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdWriteAccelerationStructuresPropertiesNV, + PFN_vkCmdWriteAccelerationStructuresPropertiesNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdWriteBufferMarkerAMD, PFN_vkCmdWriteBufferMarkerAMD) + VALIDATE_MEMBER_HOOK(hk_vkCmdWriteBufferMarker2AMD, PFN_vkCmdWriteBufferMarker2AMD) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawMeshTasksNV, PFN_vkCmdDrawMeshTasksNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawMeshTasksIndirectNV, PFN_vkCmdDrawMeshTasksIndirectNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawMeshTasksIndirectCountNV, PFN_vkCmdDrawMeshTasksIndirectCountNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetExclusiveScissorEnableNV, PFN_vkCmdSetExclusiveScissorEnableNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetExclusiveScissorNV, PFN_vkCmdSetExclusiveScissorNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCheckpointNV, PFN_vkCmdSetCheckpointNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPerformanceMarkerINTEL, PFN_vkCmdSetPerformanceMarkerINTEL) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPerformanceStreamMarkerINTEL, PFN_vkCmdSetPerformanceStreamMarkerINTEL) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPerformanceOverrideINTEL, PFN_vkCmdSetPerformanceOverrideINTEL) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetLineStippleEXT, PFN_vkCmdSetLineStippleEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCullModeEXT, PFN_vkCmdSetCullModeEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetFrontFaceEXT, PFN_vkCmdSetFrontFaceEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPrimitiveTopologyEXT, PFN_vkCmdSetPrimitiveTopologyEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetViewportWithCountEXT, PFN_vkCmdSetViewportWithCountEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetScissorWithCountEXT, PFN_vkCmdSetScissorWithCountEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindVertexBuffers2EXT, PFN_vkCmdBindVertexBuffers2EXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthTestEnableEXT, PFN_vkCmdSetDepthTestEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthWriteEnableEXT, PFN_vkCmdSetDepthWriteEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthCompareOpEXT, PFN_vkCmdSetDepthCompareOpEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthBoundsTestEnableEXT, PFN_vkCmdSetDepthBoundsTestEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetStencilTestEnableEXT, PFN_vkCmdSetStencilTestEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetStencilOpEXT, PFN_vkCmdSetStencilOpEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdPreprocessGeneratedCommandsNV, PFN_vkCmdPreprocessGeneratedCommandsNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdExecuteGeneratedCommandsNV, PFN_vkCmdExecuteGeneratedCommandsNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindPipelineShaderGroupNV, PFN_vkCmdBindPipelineShaderGroupNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthBias2EXT, PFN_vkCmdSetDepthBias2EXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdCudaLaunchKernelNV, PFN_vkCmdCudaLaunchKernelNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindDescriptorBuffersEXT, PFN_vkCmdBindDescriptorBuffersEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDescriptorBufferOffsetsEXT, PFN_vkCmdSetDescriptorBufferOffsetsEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindDescriptorBufferEmbeddedSamplersEXT, + PFN_vkCmdBindDescriptorBufferEmbeddedSamplersEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetFragmentShadingRateEnumNV, PFN_vkCmdSetFragmentShadingRateEnumNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetVertexInputEXT, PFN_vkCmdSetVertexInputEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSubpassShadingHUAWEI, PFN_vkCmdSubpassShadingHUAWEI) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindInvocationMaskHUAWEI, PFN_vkCmdBindInvocationMaskHUAWEI) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPatchControlPointsEXT, PFN_vkCmdSetPatchControlPointsEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRasterizerDiscardEnableEXT, PFN_vkCmdSetRasterizerDiscardEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthBiasEnableEXT, PFN_vkCmdSetDepthBiasEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetLogicOpEXT, PFN_vkCmdSetLogicOpEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPrimitiveRestartEnableEXT, PFN_vkCmdSetPrimitiveRestartEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetColorWriteEnableEXT, PFN_vkCmdSetColorWriteEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawMultiEXT, PFN_vkCmdDrawMultiEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawMultiIndexedEXT, PFN_vkCmdDrawMultiIndexedEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBuildMicromapsEXT, PFN_vkCmdBuildMicromapsEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyMicromapEXT, PFN_vkCmdCopyMicromapEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyMicromapToMemoryEXT, PFN_vkCmdCopyMicromapToMemoryEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyMemoryToMicromapEXT, PFN_vkCmdCopyMemoryToMicromapEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdWriteMicromapsPropertiesEXT, PFN_vkCmdWriteMicromapsPropertiesEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawClusterHUAWEI, PFN_vkCmdDrawClusterHUAWEI) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawClusterIndirectHUAWEI, PFN_vkCmdDrawClusterIndirectHUAWEI) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyMemoryIndirectNV, PFN_vkCmdCopyMemoryIndirectNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyMemoryToImageIndirectNV, PFN_vkCmdCopyMemoryToImageIndirectNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdDecompressMemoryNV, PFN_vkCmdDecompressMemoryNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdDecompressMemoryIndirectCountNV, PFN_vkCmdDecompressMemoryIndirectCountNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdUpdatePipelineIndirectBufferNV, PFN_vkCmdUpdatePipelineIndirectBufferNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthClampEnableEXT, PFN_vkCmdSetDepthClampEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetPolygonModeEXT, PFN_vkCmdSetPolygonModeEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRasterizationSamplesEXT, PFN_vkCmdSetRasterizationSamplesEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetSampleMaskEXT, PFN_vkCmdSetSampleMaskEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetAlphaToCoverageEnableEXT, PFN_vkCmdSetAlphaToCoverageEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetAlphaToOneEnableEXT, PFN_vkCmdSetAlphaToOneEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetLogicOpEnableEXT, PFN_vkCmdSetLogicOpEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetColorBlendEnableEXT, PFN_vkCmdSetColorBlendEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetColorBlendEquationEXT, PFN_vkCmdSetColorBlendEquationEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetColorWriteMaskEXT, PFN_vkCmdSetColorWriteMaskEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetTessellationDomainOriginEXT, PFN_vkCmdSetTessellationDomainOriginEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRasterizationStreamEXT, PFN_vkCmdSetRasterizationStreamEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetConservativeRasterizationModeEXT, PFN_vkCmdSetConservativeRasterizationModeEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetExtraPrimitiveOverestimationSizeEXT, + PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthClipEnableEXT, PFN_vkCmdSetDepthClipEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetSampleLocationsEnableEXT, PFN_vkCmdSetSampleLocationsEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetColorBlendAdvancedEXT, PFN_vkCmdSetColorBlendAdvancedEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetProvokingVertexModeEXT, PFN_vkCmdSetProvokingVertexModeEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetLineRasterizationModeEXT, PFN_vkCmdSetLineRasterizationModeEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetLineStippleEnableEXT, PFN_vkCmdSetLineStippleEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthClipNegativeOneToOneEXT, PFN_vkCmdSetDepthClipNegativeOneToOneEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetViewportWScalingEnableNV, PFN_vkCmdSetViewportWScalingEnableNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetViewportSwizzleNV, PFN_vkCmdSetViewportSwizzleNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCoverageToColorEnableNV, PFN_vkCmdSetCoverageToColorEnableNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCoverageToColorLocationNV, PFN_vkCmdSetCoverageToColorLocationNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCoverageModulationModeNV, PFN_vkCmdSetCoverageModulationModeNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCoverageModulationTableEnableNV, PFN_vkCmdSetCoverageModulationTableEnableNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCoverageModulationTableNV, PFN_vkCmdSetCoverageModulationTableNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetShadingRateImageEnableNV, PFN_vkCmdSetShadingRateImageEnableNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRepresentativeFragmentTestEnableNV, PFN_vkCmdSetRepresentativeFragmentTestEnableNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetCoverageReductionModeNV, PFN_vkCmdSetCoverageReductionModeNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdOpticalFlowExecuteNV, PFN_vkCmdOpticalFlowExecuteNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdBindShadersEXT, PFN_vkCmdBindShadersEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetDepthClampRangeEXT, PFN_vkCmdSetDepthClampRangeEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdConvertCooperativeVectorMatrixNV, PFN_vkCmdConvertCooperativeVectorMatrixNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetAttachmentFeedbackLoopEnableEXT, PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBuildClusterAccelerationStructureIndirectNV, + PFN_vkCmdBuildClusterAccelerationStructureIndirectNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdBuildPartitionedAccelerationStructuresNV, + PFN_vkCmdBuildPartitionedAccelerationStructuresNV) + VALIDATE_MEMBER_HOOK(hk_vkCmdPreprocessGeneratedCommandsEXT, PFN_vkCmdPreprocessGeneratedCommandsEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdExecuteGeneratedCommandsEXT, PFN_vkCmdExecuteGeneratedCommandsEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdBuildAccelerationStructuresKHR, PFN_vkCmdBuildAccelerationStructuresKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdBuildAccelerationStructuresIndirectKHR, + PFN_vkCmdBuildAccelerationStructuresIndirectKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyAccelerationStructureKHR, PFN_vkCmdCopyAccelerationStructureKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyAccelerationStructureToMemoryKHR, PFN_vkCmdCopyAccelerationStructureToMemoryKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdCopyMemoryToAccelerationStructureKHR, PFN_vkCmdCopyMemoryToAccelerationStructureKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdWriteAccelerationStructuresPropertiesKHR, + PFN_vkCmdWriteAccelerationStructuresPropertiesKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdTraceRaysKHR, PFN_vkCmdTraceRaysKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdTraceRaysIndirectKHR, PFN_vkCmdTraceRaysIndirectKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdSetRayTracingPipelineStackSizeKHR, PFN_vkCmdSetRayTracingPipelineStackSizeKHR) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawMeshTasksEXT, PFN_vkCmdDrawMeshTasksEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawMeshTasksIndirectEXT, PFN_vkCmdDrawMeshTasksIndirectEXT) + VALIDATE_MEMBER_HOOK(hk_vkCmdDrawMeshTasksIndirectCountEXT, PFN_vkCmdDrawMeshTasksIndirectCountEXT) + #pragma endregion public: diff --git a/OptiScaler/hooks/Wintrust_Hooks.h b/OptiScaler/hooks/Wintrust_Hooks.h index d92a9370..c8603cb2 100644 --- a/OptiScaler/hooks/Wintrust_Hooks.h +++ b/OptiScaler/hooks/Wintrust_Hooks.h @@ -6,9 +6,12 @@ #include #include +#include "Hook_Utils.h" + typedef decltype(&WinVerifyTrust) PFN_WinVerifyTrust; static PFN_WinVerifyTrust o_WinVerifyTrust = nullptr; +VALIDATE_HOOK(hkWinVerifyTrust, PFN_WinVerifyTrust) static LONG hkWinVerifyTrust(HWND hwnd, GUID* pgActionID, LPVOID pWVTData) { if (!pWVTData || !IsEqualGUID(*pgActionID, WINTRUST_ACTION_GENERIC_VERIFY_V2)) diff --git a/OptiScaler/hooks/Xell_Hooks.h b/OptiScaler/hooks/Xell_Hooks.h index 52d3d235..166832bc 100644 --- a/OptiScaler/hooks/Xell_Hooks.h +++ b/OptiScaler/hooks/Xell_Hooks.h @@ -6,6 +6,8 @@ #include #include +#include "Hook_Utils.h" + typedef decltype(&xellDestroyContext) PFN_xellDestroyContext; typedef decltype(&xellSetSleepMode) PFN_xellSetSleepMode; typedef decltype(&xellGetSleepMode) PFN_xellGetSleepMode; @@ -47,4 +49,12 @@ class XellHooks static xell_result_t hkxellSetLoggingCallback(xell_context_handle_t hContext, xell_logging_level_t loggingLevel, xell_app_log_callback_t loggingCallback); static xell_result_t hkxellD3D12CreateContext(ID3D12Device* device, xell_context_handle_t* out_context); + + VALIDATE_MEMBER_HOOK(hkxellDestroyContext, PFN_xellDestroyContext) + VALIDATE_MEMBER_HOOK(hkxellSetSleepMode, PFN_xellSetSleepMode) + VALIDATE_MEMBER_HOOK(hkxellSleep, PFN_xellSleep) + VALIDATE_MEMBER_HOOK(hkxellAddMarkerData, PFN_xellAddMarkerData) + VALIDATE_MEMBER_HOOK(hkxellGetVersion, PFN_xellGetVersion) + VALIDATE_MEMBER_HOOK(hkxellSetLoggingCallback, PFN_xellSetLoggingCallback) + VALIDATE_MEMBER_HOOK(hkxellD3D12CreateContext, PFN_xellD3D12CreateContext) };