diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp index 0e073721..94538965 100644 --- a/OptiScaler/dllmain.cpp +++ b/OptiScaler/dllmain.cpp @@ -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(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(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) diff --git a/OptiScaler/dllmain.h b/OptiScaler/dllmain.h index 1e41a186..691dadd9 100644 --- a/OptiScaler/dllmain.h +++ b/OptiScaler/dllmain.h @@ -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() diff --git a/OptiScaler/nvapi/NvApiHooks.cpp b/OptiScaler/nvapi/NvApiHooks.cpp index 748ac871..bd12e027 100644 --- a/OptiScaler/nvapi/NvApiHooks.cpp +++ b/OptiScaler/nvapi/NvApiHooks.cpp @@ -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(functionPointer); + o_NvAPI_GPU_GetArchInfo = reinterpret_cast(functionPointer); return &hkNvAPI_GPU_GetArchInfo; } if (InterfaceId == GET_ID(NvAPI_DRS_GetSetting)) { - o_NvAPI_DRS_GetSetting = static_cast(functionPointer); + o_NvAPI_DRS_GetSetting = reinterpret_cast(functionPointer); return &hkNvAPI_DRS_GetSetting; } } diff --git a/OptiScaler/nvapi/NvApiTypes.h b/OptiScaler/nvapi/NvApiTypes.h index 73542e2d..8b3d05f9 100644 --- a/OptiScaler/nvapi/NvApiTypes.h +++ b/OptiScaler/nvapi/NvApiTypes.h @@ -6,6 +6,7 @@ #include #define GET_ID(name) NvApiTypes::Instance().getId(#name) +#define GET_INTERFACE(name, queryInterface) reinterpret_cast(queryInterface(GET_ID(name))) typedef void* (__stdcall* PFN_NvApi_QueryInterface)(unsigned int InterfaceId); typedef NvAPI_Status(__stdcall* PFN_Fake_InformFGState)(bool fg_state); diff --git a/OptiScaler/nvapi/ReflexHooks.cpp b/OptiScaler/nvapi/ReflexHooks.cpp index 306d4538..898207b6 100644 --- a/OptiScaler/nvapi/ReflexHooks.cpp +++ b/OptiScaler/nvapi/ReflexHooks.cpp @@ -91,11 +91,11 @@ void ReflexHooks::hookReflex(PFN_NvApi_QueryInterface& queryInterface) { #endif if (!_inited) { - o_NvAPI_D3D_SetSleepMode = static_cast(queryInterface(GET_ID(NvAPI_D3D_SetSleepMode))); - o_NvAPI_D3D_Sleep = static_cast(queryInterface(GET_ID(NvAPI_D3D_Sleep))); - o_NvAPI_D3D_GetLatency = static_cast(queryInterface(GET_ID(NvAPI_D3D_GetLatency))); - o_NvAPI_D3D_SetLatencyMarker = static_cast(queryInterface(GET_ID(NvAPI_D3D_SetLatencyMarker))); - o_NvAPI_D3D12_SetAsyncFrameMarker = static_cast(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;