mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-05-06 09:40:54 +00:00
Better deal with dxvk-nvapi (#230)
This commit is contained in:
committed by
GitHub
parent
db86103b44
commit
d7845abcbb
+43
-14
@@ -2292,40 +2292,69 @@ static void CheckQuirks() {
|
||||
|
||||
bool isNvidia()
|
||||
{
|
||||
bool nvidiaDetected = false;
|
||||
bool loadedHere = false;
|
||||
auto nvapiModule = GetModuleHandleW(L"nvapi64.dll");
|
||||
|
||||
bool loadedHere = false;
|
||||
if (!nvapiModule) {
|
||||
nvapiModule = LoadLibraryExW(L"nvapi64.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
loadedHere = true;
|
||||
}
|
||||
|
||||
// No nvapi, should not be nvidia
|
||||
if (!nvapiModule)
|
||||
return false;
|
||||
|
||||
NvAPI_Status result = NVAPI_NVIDIA_DEVICE_NOT_FOUND;
|
||||
if (!nvapiModule) {
|
||||
LOG_DEBUG("Detected: {}", nvidiaDetected);
|
||||
return nvidiaDetected;
|
||||
}
|
||||
|
||||
if (auto o_NvAPI_QueryInterface = (PFN_NvApi_QueryInterface)GetProcAddress(nvapiModule, "nvapi_QueryInterface"))
|
||||
{
|
||||
auto init = static_cast<decltype(&NvAPI_Initialize)>(o_NvAPI_QueryInterface(GET_ID(NvAPI_Initialize)));
|
||||
result = init();
|
||||
|
||||
if (result == NVAPI_OK)
|
||||
// dxvk-nvapi calls CreateDxgiFactory which we can't do because we are inside DLL_PROCESS_ATTACH
|
||||
NvAPI_ShortString desc;
|
||||
auto* getVersion = GET_INTERFACE(NvAPI_GetInterfaceVersionString, o_NvAPI_QueryInterface);
|
||||
if (getVersion
|
||||
&& getVersion(desc) == NVAPI_OK
|
||||
&& (std::string_view(desc) == std::string_view("NVAPI Open Source Interface (DXVK-NVAPI)") || std::string_view(desc) == std::string_view("DXVK_NVAPI")))
|
||||
{
|
||||
if (auto unload = static_cast<decltype(&NvAPI_Unload)>(o_NvAPI_QueryInterface(GET_ID(NvAPI_Unload))))
|
||||
unload();
|
||||
LOG_DEBUG("Using dxvk-nvapi");
|
||||
DISPLAY_DEVICEA dd;
|
||||
dd.cb = sizeof(dd);
|
||||
int deviceIndex = 0;
|
||||
|
||||
while (EnumDisplayDevicesA(nullptr, deviceIndex, &dd, 0)) {
|
||||
if (dd.StateFlags & DISPLAY_DEVICE_ACTIVE && std::string_view(dd.DeviceID).contains("VEN_10DE")) {
|
||||
// Having any Nvidia GPU active will take precedence
|
||||
nvidiaDetected = true;
|
||||
}
|
||||
deviceIndex++;
|
||||
}
|
||||
}
|
||||
else if (o_NvAPI_QueryInterface(GET_ID(Fake_InformFGState)))
|
||||
{
|
||||
// Check for fakenvapi in system32, assume it's not nvidia if found
|
||||
if (o_NvAPI_QueryInterface(GET_ID(Fake_InformFGState)) != nullptr)
|
||||
return false;
|
||||
LOG_DEBUG("Using fakenvapi");
|
||||
nvidiaDetected = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("Using Nvidia's nvapi");
|
||||
auto init = GET_INTERFACE(NvAPI_Initialize, o_NvAPI_QueryInterface);
|
||||
if (init && init() == NVAPI_OK)
|
||||
{
|
||||
nvidiaDetected = true;
|
||||
|
||||
if (auto unload = GET_INTERFACE(NvAPI_Unload, o_NvAPI_QueryInterface))
|
||||
unload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (loadedHere)
|
||||
FreeLibrary(nvapiModule);
|
||||
|
||||
return result != NVAPI_NVIDIA_DEVICE_NOT_FOUND;
|
||||
LOG_DEBUG("Detected: {}", nvidiaDetected);
|
||||
|
||||
return nvidiaDetected;
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
|
||||
+39
-15
@@ -2248,37 +2248,61 @@ HRESULT WINAPI detEnumAdapters(IDXGIFactory* This, UINT Adapter, IDXGIAdapter**
|
||||
HRESULT _CreateDXGIFactory(REFIID riid, IDXGIFactory** ppFactory)
|
||||
{
|
||||
State::Instance().skipDxgiLoadChecks = true;
|
||||
HRESULT result = dxgi.CreateDxgiFactory(riid, ppFactory);
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
if (dxgi.CreateDxgiFactory) {
|
||||
HRESULT result = dxgi.CreateDxgiFactory(riid, ppFactory);
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
|
||||
if (result == S_OK)
|
||||
AttachToFactory(*ppFactory);
|
||||
if (result == S_OK)
|
||||
AttachToFactory(*ppFactory);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("CreateDxgiFactory is NULL");
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT _CreateDXGIFactory1(REFIID riid, IDXGIFactory1** ppFactory)
|
||||
{
|
||||
State::Instance().skipDxgiLoadChecks = true;
|
||||
HRESULT result = dxgi.CreateDxgiFactory1(riid, ppFactory);
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
if (dxgi.CreateDxgiFactory1) {
|
||||
HRESULT result = dxgi.CreateDxgiFactory1(riid, ppFactory);
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
|
||||
if (result == S_OK)
|
||||
AttachToFactory(*ppFactory);
|
||||
if (result == S_OK)
|
||||
AttachToFactory(*ppFactory);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("CreateDxgiFactory1 is NULL");
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT _CreateDXGIFactory2(UINT Flags, REFIID riid, IDXGIFactory2** ppFactory)
|
||||
{
|
||||
State::Instance().skipDxgiLoadChecks = true;
|
||||
HRESULT result = dxgi.CreateDxgiFactory2(Flags, riid, ppFactory);
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
if (dxgi.CreateDxgiFactory2) {
|
||||
HRESULT result = dxgi.CreateDxgiFactory2(Flags, riid, ppFactory);
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
|
||||
if (result == S_OK)
|
||||
AttachToFactory(*ppFactory);
|
||||
if (result == S_OK)
|
||||
AttachToFactory(*ppFactory);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("CreateDxgiFactory2 is NULL");
|
||||
State::Instance().skipDxgiLoadChecks = false;
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT _DXGIDeclareAdapterRemovalSupport()
|
||||
|
||||
@@ -84,12 +84,12 @@ void* __stdcall NvApiHooks::hkNvAPI_QueryInterface(unsigned int InterfaceId)
|
||||
{
|
||||
if (InterfaceId == GET_ID(NvAPI_GPU_GetArchInfo) && !State::Instance().enablerAvailable)
|
||||
{
|
||||
o_NvAPI_GPU_GetArchInfo = static_cast<decltype(&NvAPI_GPU_GetArchInfo)>(functionPointer);
|
||||
o_NvAPI_GPU_GetArchInfo = reinterpret_cast<decltype(&NvAPI_GPU_GetArchInfo)>(functionPointer);
|
||||
return &hkNvAPI_GPU_GetArchInfo;
|
||||
}
|
||||
if (InterfaceId == GET_ID(NvAPI_DRS_GetSetting))
|
||||
{
|
||||
o_NvAPI_DRS_GetSetting = static_cast<decltype(&NvAPI_DRS_GetSetting)>(functionPointer);
|
||||
o_NvAPI_DRS_GetSetting = reinterpret_cast<decltype(&NvAPI_DRS_GetSetting)>(functionPointer);
|
||||
return &hkNvAPI_DRS_GetSetting;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <nvapi.h>
|
||||
|
||||
#define GET_ID(name) NvApiTypes::Instance().getId(#name)
|
||||
#define GET_INTERFACE(name, queryInterface) reinterpret_cast<decltype(&name)>(queryInterface(GET_ID(name)))
|
||||
|
||||
typedef void* (__stdcall* PFN_NvApi_QueryInterface)(unsigned int InterfaceId);
|
||||
typedef NvAPI_Status(__stdcall* PFN_Fake_InformFGState)(bool fg_state);
|
||||
|
||||
@@ -91,11 +91,11 @@ void ReflexHooks::hookReflex(PFN_NvApi_QueryInterface& queryInterface) {
|
||||
#endif
|
||||
|
||||
if (!_inited) {
|
||||
o_NvAPI_D3D_SetSleepMode = static_cast<decltype(&NvAPI_D3D_SetSleepMode)>(queryInterface(GET_ID(NvAPI_D3D_SetSleepMode)));
|
||||
o_NvAPI_D3D_Sleep = static_cast<decltype(&NvAPI_D3D_Sleep)>(queryInterface(GET_ID(NvAPI_D3D_Sleep)));
|
||||
o_NvAPI_D3D_GetLatency = static_cast<decltype(&NvAPI_D3D_GetLatency)>(queryInterface(GET_ID(NvAPI_D3D_GetLatency)));
|
||||
o_NvAPI_D3D_SetLatencyMarker = static_cast<decltype(&NvAPI_D3D_SetLatencyMarker)>(queryInterface(GET_ID(NvAPI_D3D_SetLatencyMarker)));
|
||||
o_NvAPI_D3D12_SetAsyncFrameMarker = static_cast<decltype(&NvAPI_D3D12_SetAsyncFrameMarker)>(queryInterface(GET_ID(NvAPI_D3D12_SetAsyncFrameMarker)));
|
||||
o_NvAPI_D3D_SetSleepMode = GET_INTERFACE(NvAPI_D3D_SetSleepMode, queryInterface);
|
||||
o_NvAPI_D3D_Sleep = GET_INTERFACE(NvAPI_D3D_Sleep, queryInterface);
|
||||
o_NvAPI_D3D_GetLatency = GET_INTERFACE(NvAPI_D3D_GetLatency, queryInterface);
|
||||
o_NvAPI_D3D_SetLatencyMarker = GET_INTERFACE(NvAPI_D3D_SetLatencyMarker, queryInterface);
|
||||
o_NvAPI_D3D12_SetAsyncFrameMarker = GET_INTERFACE(NvAPI_D3D12_SetAsyncFrameMarker, queryInterface);
|
||||
|
||||
_inited = o_NvAPI_D3D_SetSleepMode && o_NvAPI_D3D_Sleep && o_NvAPI_D3D_GetLatency && o_NvAPI_D3D_SetLatencyMarker && o_NvAPI_D3D12_SetAsyncFrameMarker;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user