diff --git a/OptiScaler/Config.cpp b/OptiScaler/Config.cpp index e4bb262b..ab188c9e 100644 --- a/OptiScaler/Config.cpp +++ b/OptiScaler/Config.cpp @@ -300,6 +300,40 @@ bool Config::Reload(std::filesystem::path iniPath) if (!ExtendedLimits.has_value()) ExtendedLimits = readBool("Menu", "ExtendedLimits"); + + if (!ShowFps.has_value()) + ShowFps = readBool("Menu", "ShowFps"); + + if (!FpsOverlayPos.has_value()) + FpsOverlayPos = readInt("Menu", "FpsOverlayPos"); + + if (FpsOverlayPos.has_value()) + { + if (Config::Instance()->FpsOverlayPos.value_or(0) < 0) + Config::Instance()->FpsOverlayPos = 0; + + if (Config::Instance()->FpsOverlayPos.value_or(0) > 3) + Config::Instance()->FpsOverlayPos = 3; + } + + if (!FpsOverlayType.has_value()) + FpsOverlayType = readInt("Menu", "FpsOverlayType"); + + if (FpsOverlayType.has_value()) + { + if (Config::Instance()->FpsOverlayType.value_or(0) < 0) + Config::Instance()->FpsOverlayType = 0; + + if (Config::Instance()->FpsOverlayType.value_or(0) > 4) + Config::Instance()->FpsOverlayType = 4; + } + + if (!FpsShortcutKey.has_value()) + FpsShortcutKey = readInt("Menu", "FpsShortcutKey"); + + if (!FpsCycleShortcutKey.has_value()) + FpsCycleShortcutKey = readInt("Menu", "FpsCycleShortcutKey"); + } // Hooks @@ -842,6 +876,9 @@ bool Config::SaveIni() ini.SetValue("Menu", "ShortcutKey", GetIntValue(Instance()->ShortcutKey).c_str()); ini.SetValue("Menu", "AdvancedSettings", GetBoolValue(Instance()->AdvancedSettings).c_str()); ini.SetValue("Menu", "ExtendedLimits", GetBoolValue(Instance()->ExtendedLimits).c_str()); + ini.SetValue("Menu", "ShowFps", GetBoolValue(Instance()->ShowFps).c_str()); + ini.SetValue("Menu", "FpsOverlayPos", GetIntValue(Instance()->FpsOverlayPos).c_str()); + ini.SetValue("Menu", "FpsOverlayType", GetIntValue(Instance()->FpsOverlayType).c_str()); } // Hooks diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index 08ad950c..5f3b7696 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -74,6 +74,11 @@ public: std::optional ShortcutKey; std::optional AdvancedSettings; std::optional ExtendedLimits; + std::optional ShowFps; + std::optional FpsOverlayPos; // 0 Top Left, 1 Top Right, 2 Bottom Left, 3 Bottom Right + std::optional FpsOverlayType; // 0 Only FPS, 1 +Frame Time, 2 +Upscaler Time, 3 +Frame Time Graph, 4 +Upscaler Time Graph + std::optional FpsShortcutKey; + std::optional FpsCycleShortcutKey; // hooks std::optional HookOriginalNvngxOnly; diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj index 3f55642d..9b1cc767 100644 --- a/OptiScaler/OptiScaler.vcxproj +++ b/OptiScaler/OptiScaler.vcxproj @@ -82,7 +82,7 @@ $(SolutionDir)external\vulkan\include;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\FidelityFX-SDK\ffx-api\include\ffx_api;$(SolutionDir)external\simpleini;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)external\freetype;$(IncludePath) $(ProjectDir)fsr2\lib;$(ProjectDir)fsr2_212\lib;$(ProjectDir)fsr31\lib;$(ProjectDir)vulkan;$(ProjectDir)d3dx;$(ProjectDir)detours;$(SolutionDir)external\xess\lib;$(SolutionDir)external\freetype;$(LibraryPath) dxgi - E:\Games\Deep Rock Galactic\FSD\Binaries\Win64\ + E:\Games\Epic\Control\ .\x64\Debug .dll diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp index bf018b5d..4fb7cc2d 100644 --- a/OptiScaler/dllmain.cpp +++ b/OptiScaler/dllmain.cpp @@ -2178,8 +2178,8 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv for (size_t i = 0; i < 300; i++) { - Config::Instance()->frameTimes.push_back(0.0); - Config::Instance()->upscaleTimes.push_back(0.0); + Config::Instance()->frameTimes.push_back(0.0f); + Config::Instance()->upscaleTimes.push_back(0.0f); } spdlog::info(""); diff --git a/OptiScaler/hooks/HooksDx.cpp b/OptiScaler/hooks/HooksDx.cpp index 67e07aaa..ac469ceb 100644 --- a/OptiScaler/hooks/HooksDx.cpp +++ b/OptiScaler/hooks/HooksDx.cpp @@ -2100,9 +2100,13 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags UINT64 startTime = timestampData[0]; UINT64 endTime = timestampData[1]; double elapsedTimeMs = (endTime - startTime) / static_cast(gpuFrequency) * 1000.0; - - Config::Instance()->upscaleTimes.push_back(elapsedTimeMs); - Config::Instance()->upscaleTimes.pop_front(); + + // filter out posibly wrong measured high values + if (elapsedTimeMs < 100.0) + { + Config::Instance()->upscaleTimes.push_back(elapsedTimeMs); + Config::Instance()->upscaleTimes.pop_front(); + } } else { @@ -2131,8 +2135,13 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags g_pd3dDeviceContext->GetData(HooksDx::endQueries[HooksDx::previousFrameIndex], &endTime, sizeof(UINT64), 0) == S_OK) { double elapsedTimeMs = (endTime - startTime) / static_cast(disjointData.Frequency) * 1000.0; - Config::Instance()->upscaleTimes.push_back(elapsedTimeMs); - Config::Instance()->upscaleTimes.pop_front(); + + // filter out posibly wrong measured high values + if (elapsedTimeMs < 100.0) + { + Config::Instance()->upscaleTimes.push_back(elapsedTimeMs); + Config::Instance()->upscaleTimes.pop_front(); + } } } } @@ -3515,7 +3524,7 @@ static HRESULT hkD3D12CreateDevice(IDXGIAdapter* pAdapter, D3D_FEATURE_LEVEL Min #endif } - LOG_FUNC_RESULT(result); + LOG_DEBUG("result: {:X}", (UINT)result); return result; } diff --git a/OptiScaler/imgui/Imgui_Dx11.cpp b/OptiScaler/imgui/Imgui_Dx11.cpp index 3fe1d6d7..3102a792 100644 --- a/OptiScaler/imgui/Imgui_Dx11.cpp +++ b/OptiScaler/imgui/Imgui_Dx11.cpp @@ -76,10 +76,10 @@ bool Imgui_Dx11::Render(ID3D11DeviceContext* pCmdList, ID3D11Resource* outTextur frameCounter++; - if (!IsVisible()) - return true; + //if (!IsVisible()) + // return true; - LOG_FUNC(); + //LOG_FUNC(); CreateRenderTarget(outTexture); diff --git a/OptiScaler/imgui/imgui_common.cpp b/OptiScaler/imgui/imgui_common.cpp index 575d55a3..77b92593 100644 --- a/OptiScaler/imgui/imgui_common.cpp +++ b/OptiScaler/imgui/imgui_common.cpp @@ -3,6 +3,8 @@ #include "../font/Hack_Compressed.h" #include "../nvapi/fakenvapi.h" +static ImVec2 overlayPosition(-1000.0f, -1000.0f); + void ImGuiCommon::ShowTooltip(const char* tip) { if (ImGui::IsItemHovered()) { @@ -320,6 +322,8 @@ LRESULT ImGuiCommon::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) bool rawRead = false; bool inputMenu = false; + bool inputFps = false; + bool inputFpsCycle = false; ImGuiKey imguiKey; RAWINPUT rawData{}; @@ -329,13 +333,25 @@ LRESULT ImGuiCommon::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) auto rawCode = GET_RAWINPUT_CODE_WPARAM(wParam); rawRead = true; if (rawData.header.dwType == RIM_TYPEKEYBOARD && rawData.data.keyboard.VKey != 0) + { inputMenu = rawData.data.keyboard.VKey == Config::Instance()->ShortcutKey.value_or(VK_INSERT); + inputFps = rawData.data.keyboard.VKey == Config::Instance()->FpsShortcutKey.value_or(VK_PRIOR); + inputFpsCycle = rawData.data.keyboard.VKey == Config::Instance()->FpsCycleShortcutKey.value_or(VK_NEXT); + } } else { inputMenu = msg == WM_KEYDOWN && wParam == Config::Instance()->ShortcutKey.value_or(VK_INSERT); + inputFps = msg == WM_KEYDOWN && wParam == Config::Instance()->FpsShortcutKey.value_or(VK_PRIOR); + inputFpsCycle = msg == WM_KEYDOWN && wParam == Config::Instance()->FpsCycleShortcutKey.value_or(VK_NEXT); } + if (inputFps) + Config::Instance()->ShowFps = !Config::Instance()->ShowFps.value_or(false); + + if (inputFpsCycle && Config::Instance()->ShowFps.value_or(false)) + Config::Instance()->FpsOverlayType = (Config::Instance()->FpsOverlayType.value_or(0) + 1) % 5; + // INSERT - OPEN MENU if (inputMenu) { @@ -744,13 +760,152 @@ void ImGuiCommon::PopulateCombo(std::string name, std::optional* value } } -void ImGuiCommon::RenderMenu() +bool ImGuiCommon::RenderMenu() { - if (!_isInited || !_isVisible) - return; + if (!_isInited) + return false; ImGuiIO const& io = ImGui::GetIO(); (void)io; + if (!Config::Instance()->MenuScale.has_value()) + { + // 900p is minimum for 1.0 menu ratio + Config::Instance()->MenuScale = (float)((int)((float)io.DisplaySize.y / 90.0f)) / 10.0f; + + if (Config::Instance()->MenuScale.value() > 1.0f) + Config::Instance()->MenuScale.value() = 1.0f; + + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(Config::Instance()->MenuScale.value()); + + if (Config::Instance()->MenuScale.value() < 1.0f) + style.MouseCursorScale = 1.0f; + } + + if (Config::Instance()->MenuScale.value() < 0.5f) + Config::Instance()->MenuScale = 0.5f; + + if (Config::Instance()->MenuScale.value() > 2.0f) + Config::Instance()->MenuScale = 2.0f; + + if (Config::Instance()->ShowFps.value_or(false)) + { + ImGui::NewFrame(); + + if (Config::Instance()->FpsOverlayType.value_or(0) == 0) + ImGui::PushFont(_scaledOptiFont); + else + ImGui::PushFont(_optiFont); + + Config::Instance()->frameTimes.pop_front(); + Config::Instance()->frameTimes.push_back(1000.0 / io.Framerate); + + std::vector frameTimeArray(Config::Instance()->frameTimes.begin(), Config::Instance()->frameTimes.end()); + std::vector upscalerFrameTimeArray(Config::Instance()->upscaleTimes.begin(), Config::Instance()->upscaleTimes.end()); + float averageFrameTime = 0.0f; + float averageUpscalerFT = 0.0f; + + for (size_t i = 0; i < frameTimeArray.size(); i++) + { + averageFrameTime += frameTimeArray[i]; + averageUpscalerFT += upscalerFrameTimeArray[i]; + } + averageFrameTime /= frameTimeArray.size(); + averageUpscalerFT /= frameTimeArray.size(); + + // Set overlay position + ImGui::SetNextWindowPos(overlayPosition, ImGuiCond_Always); + + // Set overlay window properties + ImGui::SetNextWindowBgAlpha(0.3f); // Transparent background + ImGui::PushStyleColor(ImGuiCol_Border, IM_COL32(0, 0, 0, 0)); // Transparent border + ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(0, 0, 0, 0)); // Transparent frame background + ImGui::PushStyleColor(ImGuiCol_PlotLines, IM_COL32(0, 255, 0, 255)); // Set plot line color (green in this case) + + auto size = ImVec2{ 0.0f, 0.0f }; + ImGui::SetNextWindowSize(size); + + if (ImGui::Begin("Performance Overlay", nullptr, ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav)) + { + ImGui::SetWindowFontScale(Config::Instance()->MenuScale.value()); + + if (Config::Instance()->FpsOverlayType.value_or(0) == 0) + ImGui::Text("%.1f fps %.2f ms", io.Framerate, 1000.0f / io.Framerate); + else + ImGui::Text("FPS: %.1f, Avg: %.1f", io.Framerate, 1000.0f / averageFrameTime); + + + if (Config::Instance()->FpsOverlayType.value_or(0) > 0) + { + ImGui::Spacing(); + ImGui::Text("Frame Time: %.2f ms, Avg: %.2f ms", Config::Instance()->frameTimes.back(), averageFrameTime); + } + + if (Config::Instance()->FpsOverlayType.value_or(0) > 1) + { + // Graph of frame times + ImGui::PlotLines( + "##FrameTimeGraph", // Graph label (hidden by "##") + frameTimeArray.data(), // Data source + static_cast(frameTimeArray.size()),// Data count + 0, // Offset (usually 0 unless circular buffer) + nullptr, // Overlay text + *std::min_element(frameTimeArray.begin(), frameTimeArray.end()) * 0.9f, // Maximum scale + *std::max_element(frameTimeArray.begin(), frameTimeArray.end()) * 1.1f, // Maximum scale + ImVec2(Config::Instance()->MenuScale.value() * 300, Config::Instance()->MenuScale.value() * 40)); // Graph size (width, height) + } + + if (Config::Instance()->FpsOverlayType.value_or(0) > 2) + { + ImGui::Spacing(); + ImGui::Text("Upscaler Time: %.2f ms, Avg: %.2f ms", Config::Instance()->upscaleTimes.back(), averageUpscalerFT); + } + + if (Config::Instance()->FpsOverlayType.value_or(0) > 3) + { + ImGui::Spacing(); + // Graph of upscaler frame times + + auto uftMin = *std::min_element(upscalerFrameTimeArray.begin(), upscalerFrameTimeArray.end()); + auto uftMax = *std::max_element(upscalerFrameTimeArray.begin(), upscalerFrameTimeArray.end()); + + ImGui::PlotLines( + "##UpscalerFrameTimeGraph", // Graph label (hidden by "##") + upscalerFrameTimeArray.data(), // Data source + static_cast(upscalerFrameTimeArray.size()),// Data count + 0, // Offset (usually 0 unless circular buffer) + nullptr, // Overlay text + uftMin * 0.9f, // Minimum scale + uftMax * 1.1f, // Maximum scale + ImVec2(Config::Instance()->MenuScale.value() * 300, Config::Instance()->MenuScale.value() * 40)); // Graph size (width, height) + } + + ImGui::PopStyleColor(3); // Restore the style + } + + ImGui::PopFont(); + + auto winSize = ImGui::GetWindowSize(); + + ImGui::End(); + + if (Config::Instance()->FpsOverlayPos.value_or(0) == 0 || Config::Instance()->FpsOverlayPos.value_or(0) == 2) + overlayPosition.x = 0; + else + overlayPosition.x = io.DisplaySize.x - winSize.x; + + if (Config::Instance()->FpsOverlayPos.value_or(0) < 2) + overlayPosition.y = 0; + else + overlayPosition.y = io.DisplaySize.y - winSize.y; + + if (!_isVisible) + return true; + } + + if (!_isVisible) + return false; + { ImGuiWindowFlags flags = 0; flags |= ImGuiWindowFlags_NoSavedSettings; @@ -781,7 +936,8 @@ void ImGuiCommon::RenderMenu() CopyMemory(style.Colors, styleold.Colors, sizeof(style.Colors)); // Restore colors } - ImGui::NewFrame(); + if (!Config::Instance()->ShowFps.value_or(false)) + ImGui::NewFrame(); if (Config::Instance()->MenuScale.value_or(1.0) <= 1.0) ImGui::PushFont(_optiFont); @@ -800,27 +956,6 @@ void ImGuiCommon::RenderMenu() if (!_showMipmapCalcWindow && !ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow)) ImGui::SetWindowFocus(); - if (!Config::Instance()->MenuScale.has_value()) - { - // 900p is minimum for 1.0 menu ratio - Config::Instance()->MenuScale = (float)((int)((float)Config::Instance()->ScreenHeight / 90.0f)) / 10.0f; - - if (Config::Instance()->MenuScale.value() > 1.0f) - Config::Instance()->MenuScale.value() = 1.0f; - - ImGuiStyle& style = ImGui::GetStyle(); - style.ScaleAllSizes(Config::Instance()->MenuScale.value()); - - if (Config::Instance()->MenuScale.value() < 1.0f) - style.MouseCursorScale = 1.0f; - } - - if (Config::Instance()->MenuScale.value() < 0.5f) - Config::Instance()->MenuScale = 0.5f; - - if (Config::Instance()->MenuScale.value() > 2.0f) - Config::Instance()->MenuScale = 2.0f; - _selectedScale = ((int)(Config::Instance()->MenuScale.value() * 10.0f)) - 5; ImGui::SetWindowFontScale(Config::Instance()->MenuScale.value()); @@ -850,14 +985,15 @@ void ImGuiCommon::RenderMenu() ImGui::SetWindowFontScale(Config::Instance()->MenuScale.value()); ImGui::Spacing(); - ImGui::Text("nvngx.dll: %sExist", Config::Instance()->nvngxExist ? "" : "Not "); + ImGui::Text("nvngx.dll: %sExist", Config::Instance()->nvngxExist || Config::Instance()->IsRunningOnNvidia ? "" : "Not "); ImGui::Text("libxess.dll: %sExist", Config::Instance()->libxessExist ? "" : "Not "); + ImGui::Text("fsr: %sExist", Config::Instance()->fsrHooks ? "" : "Not "); ImGui::Spacing(); } else { ImGui::Spacing(); - ImGui::Text("Can't find nvngx.dll and libxess.dll\nUpscaling support will NOT work."); + ImGui::Text("Can't find nvngx.dll and libxess.dll and FSR inputs\nUpscaling support will NOT work."); ImGui::Spacing(); ImGui::PopFont(); @@ -1370,8 +1506,8 @@ void ImGuiCommon::RenderMenu() } ImGui::SameLine(0.0f, 6.0f); - ImGui::Text("Near: %.1f Far: %.1f", - Config::Instance()->LastFsrCameraNear < 500000.0f ? Config::Instance()->LastFsrCameraNear : 500000.0f, + ImGui::Text("Near: %.1f Far: %.1f", + Config::Instance()->LastFsrCameraNear < 500000.0f ? Config::Instance()->LastFsrCameraNear : 500000.0f, Config::Instance()->LastFsrCameraFar < 500000.0f ? Config::Instance()->LastFsrCameraFar : 500000.0f); } @@ -2202,6 +2338,41 @@ void ImGuiCommon::RenderMenu() ImGui::EndCombo(); } + // LOGGING ----------------------------- + ImGui::SeparatorText("FPS Overlay"); + + bool fpsEnabled = Config::Instance()->ShowFps.value_or(false); + if (ImGui::Checkbox("FPS Overlay Enabled", &fpsEnabled)) + Config::Instance()->ShowFps = fpsEnabled; + + const char* fpsPosition[] = { "Top Left", "Top Right", "Bottom Left", "Bottom Right" }; + const char* selectedPosition = fpsPosition[Config::Instance()->FpsOverlayPos.value_or(0)]; + + if (ImGui::BeginCombo("Overlay Position", selectedPosition)) + { + for (int n = 0; n < 4; n++) + { + if (ImGui::Selectable(fpsPosition[n], (Config::Instance()->FpsOverlayPos.value_or(0) == n))) + Config::Instance()->FpsOverlayPos = n; + } + + ImGui::EndCombo(); + } + + const char* fpsType[] = { "Simple", "Detailed", "Detailed + Graph", "Full", "Full + Graph" }; + const char* selectedType = fpsType[Config::Instance()->FpsOverlayType.value_or(0)]; + + if (ImGui::BeginCombo("Overlay Type", selectedType)) + { + for (int n = 0; n < 5; n++) + { + if (ImGui::Selectable(fpsType[n], (Config::Instance()->FpsOverlayType.value_or(0) == n))) + Config::Instance()->FpsOverlayType = n; + } + + ImGui::EndCombo(); + } + if (cf != nullptr) { // ADVANCED SETTINGS ----------------------------- @@ -2513,6 +2684,8 @@ void ImGuiCommon::RenderMenu() ImGui::PopFont(); } + + return true; } void ImGuiCommon::Init(HWND InHwnd) diff --git a/OptiScaler/imgui/imgui_common.h b/OptiScaler/imgui/imgui_common.h index 2b70f754..b5da5699 100644 --- a/OptiScaler/imgui/imgui_common.h +++ b/OptiScaler/imgui/imgui_common.h @@ -138,7 +138,7 @@ public: static bool IsVisible() { return _isVisible; } static HWND Handle() { return _handle; } - static void RenderMenu(); + static bool RenderMenu(); static void Init(HWND InHwnd); static void Shutdown(); static void HideMenu(); diff --git a/OptiScaler/imgui/imgui_dx12.cpp b/OptiScaler/imgui/imgui_dx12.cpp index c46cbc86..95086475 100644 --- a/OptiScaler/imgui/imgui_dx12.cpp +++ b/OptiScaler/imgui/imgui_dx12.cpp @@ -17,8 +17,8 @@ bool Imgui_Dx12::Render(ID3D12GraphicsCommandList* pCmdList, ID3D12Resource* out frameCounter++; - if (!IsVisible()) - return true; + //if (!IsVisible()) + // return true; auto outDesc = outTexture->GetDesc(); diff --git a/OptiScaler/imgui/imgui_overlay_base.cpp b/OptiScaler/imgui/imgui_overlay_base.cpp index b1893e67..67e7d215 100644 --- a/OptiScaler/imgui/imgui_overlay_base.cpp +++ b/OptiScaler/imgui/imgui_overlay_base.cpp @@ -49,12 +49,12 @@ void ImGuiOverlayBase::Init(HWND InHandle) ImGuiCommon::Init(InHandle); } -void ImGuiOverlayBase::RenderMenu() +bool ImGuiOverlayBase::RenderMenu() { if (!Config::Instance()->OverlayMenu.value_or(true)) - return; + return false; - ImGuiCommon::RenderMenu(); + return ImGuiCommon::RenderMenu(); } void ImGuiOverlayBase::Shutdown() diff --git a/OptiScaler/imgui/imgui_overlay_base.h b/OptiScaler/imgui/imgui_overlay_base.h index f689fe6c..d503438d 100644 --- a/OptiScaler/imgui/imgui_overlay_base.h +++ b/OptiScaler/imgui/imgui_overlay_base.h @@ -18,7 +18,7 @@ public: static bool IsVisible(); static void Init(HWND InHandle); - static void RenderMenu(); + static bool RenderMenu(); static void Shutdown(); static void HideMenu(); }; diff --git a/OptiScaler/imgui/imgui_overlay_dx.cpp b/OptiScaler/imgui/imgui_overlay_dx.cpp index 61674495..13c9ec03 100644 --- a/OptiScaler/imgui/imgui_overlay_dx.cpp +++ b/OptiScaler/imgui/imgui_overlay_dx.cpp @@ -243,8 +243,8 @@ static void RenderImGui_DX11(IDXGISwapChain* pSwapChain) break; // Draw only when menu activated - if (!ImGuiOverlayBase::IsVisible()) - break; + //if (!ImGuiOverlayBase::IsVisible()) + // break; if (!_dx11Device || g_pd3dDevice == nullptr) break; @@ -280,12 +280,13 @@ static void RenderImGui_DX11(IDXGISwapChain* pSwapChain) ImGui_ImplDX11_NewFrame(); ImGui_ImplWin32_NewFrame(); - ImGuiOverlayBase::RenderMenu(); + if (ImGuiOverlayBase::RenderMenu()) + { + ImGui::Render(); - ImGui::Render(); - - g_pd3dDeviceContext->OMSetRenderTargets(1, &g_pd3dRenderTarget, NULL); - ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + g_pd3dDeviceContext->OMSetRenderTargets(1, &g_pd3dRenderTarget, NULL); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + } } } } @@ -304,8 +305,8 @@ static void RenderImGui_DX12(IDXGISwapChain* pSwapChainPlain) break; // Draw only when menu activated - if (!ImGuiOverlayBase::IsVisible()) - break; + //if (!ImGuiOverlayBase::IsVisible()) + // break; if (!_dx12Device || currentSCCommandQueue == nullptr || g_pd3dDeviceParam == nullptr) break; @@ -440,59 +441,60 @@ static void RenderImGui_DX12(IDXGISwapChain* pSwapChainPlain) ImGui_ImplDX12_NewFrame(); ImGui_ImplWin32_NewFrame(); - ImGuiOverlayBase::RenderMenu(); - - ImGui::Render(); - - UINT backBufferIdx = pSwapChain->GetCurrentBackBufferIndex(); - ID3D12CommandAllocator* commandAllocator = g_commandAllocators[backBufferIdx]; - - auto result = commandAllocator->Reset(); - if (result != S_OK) + if (ImGuiOverlayBase::RenderMenu()) { - LOG_ERROR("commandAllocator->Reset: {0:X}", (unsigned long)result); - CleanupRenderTargetDx12(false); - pSwapChain->Release(); - return; + ImGui::Render(); + + UINT backBufferIdx = pSwapChain->GetCurrentBackBufferIndex(); + ID3D12CommandAllocator* commandAllocator = g_commandAllocators[backBufferIdx]; + + auto result = commandAllocator->Reset(); + if (result != S_OK) + { + LOG_ERROR("commandAllocator->Reset: {0:X}", (unsigned long)result); + CleanupRenderTargetDx12(false); + pSwapChain->Release(); + return; + } + + D3D12_RESOURCE_BARRIER barrier = { }; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = g_mainRenderTargetResource[backBufferIdx]; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + + result = g_pd3dCommandList->Reset(commandAllocator, nullptr); + if (result != S_OK) + { + LOG_ERROR("g_pd3dCommandList->Reset: {0:X}", (unsigned long)result); + pSwapChain->Release(); + return; + } + + g_pd3dCommandList->ResourceBarrier(1, &barrier); + g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL); + g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap); + + ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList); + + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + g_pd3dCommandList->ResourceBarrier(1, &barrier); + + result = g_pd3dCommandList->Close(); + if (result != S_OK) + { + LOG_ERROR("g_pd3dCommandList->Close: {0:X}", (unsigned long)result); + CleanupRenderTargetDx12(true); + pSwapChain->Release(); + return; + } + + ID3D12CommandList* ppCommandLists[] = { g_pd3dCommandList }; + ((ID3D12CommandQueue*)currentSCCommandQueue)->ExecuteCommandLists(1, ppCommandLists); } - - D3D12_RESOURCE_BARRIER barrier = { }; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = g_mainRenderTargetResource[backBufferIdx]; - barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; - - result = g_pd3dCommandList->Reset(commandAllocator, nullptr); - if (result != S_OK) - { - LOG_ERROR("g_pd3dCommandList->Reset: {0:X}", (unsigned long)result); - pSwapChain->Release(); - return; - } - - g_pd3dCommandList->ResourceBarrier(1, &barrier); - g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL); - g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap); - - ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList); - - barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; - g_pd3dCommandList->ResourceBarrier(1, &barrier); - - result = g_pd3dCommandList->Close(); - if (result != S_OK) - { - LOG_ERROR("g_pd3dCommandList->Close: {0:X}", (unsigned long)result); - CleanupRenderTargetDx12(true); - pSwapChain->Release(); - return; - } - - ID3D12CommandList* ppCommandLists[] = { g_pd3dCommandList }; - ((ID3D12CommandQueue*)currentSCCommandQueue)->ExecuteCommandLists(1, ppCommandLists); } else { diff --git a/OptiScaler/imgui/imgui_overlay_vk.cpp b/OptiScaler/imgui/imgui_overlay_vk.cpp index 143d4ad0..cc4fca72 100644 --- a/OptiScaler/imgui/imgui_overlay_vk.cpp +++ b/OptiScaler/imgui/imgui_overlay_vk.cpp @@ -452,7 +452,7 @@ bool ImGuiOverlayVk::QueuePresent(VkQueue queue, VkPresentInfoKHR* pPresentInfo) if (!_vulkanObjectsCreated) return true; - if (!ImGuiOverlayBase::IsInited() || !ImGuiOverlayBase::IsVisible() || _ImVulkan_Info.Device == VK_NULL_HANDLE) + if (!ImGuiOverlayBase::IsInited() || _ImVulkan_Info.Device == VK_NULL_HANDLE) return true; std::lock_guard lock(_vkPresentMutex); @@ -467,68 +467,69 @@ bool ImGuiOverlayVk::QueuePresent(VkQueue queue, VkPresentInfoKHR* pPresentInfo) ImGui_ImplVulkan_NewFrame(); ImGui_ImplWin32_NewFrame(); - ImGuiOverlayBase::RenderMenu(); - - uint32_t idx = pPresentInfo->pImageIndices[scIndex]; - ImGui_ImplVulkanH_Frame* fd = &_ImVulkan_Frames[idx]; - - vkWaitForFences(_ImVulkan_Info.Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); - vkResetFences(_ImVulkan_Info.Device, 1, &fd->Fence); - + if (ImGuiOverlayBase::RenderMenu()) { - vkResetCommandPool(_ImVulkan_Info.Device, fd->CommandPool, 0); - VkCommandBufferBeginInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - vkBeginCommandBuffer(fd->CommandBuffer, &info); + uint32_t idx = pPresentInfo->pImageIndices[scIndex]; + ImGui_ImplVulkanH_Frame* fd = &_ImVulkan_Frames[idx]; + + vkWaitForFences(_ImVulkan_Info.Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); + vkResetFences(_ImVulkan_Info.Device, 1, &fd->Fence); + + { + vkResetCommandPool(_ImVulkan_Info.Device, fd->CommandPool, 0); + VkCommandBufferBeginInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer(fd->CommandBuffer, &info); + } + + { + VkRenderPassBeginInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + info.renderPass = _vkRenderPass; + info.framebuffer = fd->Framebuffer; + info.renderArea.extent.width = ImGui::GetIO().DisplaySize.x; + info.renderArea.extent.height = ImGui::GetIO().DisplaySize.y; + vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + } + + ImGui::Render(); + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); + + // Submit command buffer + vkCmdEndRenderPass(fd->CommandBuffer); + auto ecbResult = vkEndCommandBuffer(fd->CommandBuffer); + if (ecbResult != VK_SUCCESS) + { + LOG_ERROR("vkQueueSubmit error: {0:X}", (UINT)ecbResult); + break; + } + + // Submit queue and semaphores + LOG_DEBUG("waitSemaphoreCount: {0}", pPresentInfo->waitSemaphoreCount); + VkPipelineStageFlags waitStages[8] = { VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT }; + + VkSubmitInfo submit_info = { }; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &fd->CommandBuffer; + submit_info.pWaitDstStageMask = waitStages; + + submit_info.waitSemaphoreCount = pPresentInfo->waitSemaphoreCount; + submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores; + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = &_ImVulkan_Semaphores[idx]; + + auto qResult = vkQueueSubmit(_ImVulkan_Info.Queue, 1, &submit_info, fd->Fence); + if (qResult != VK_SUCCESS) + { + LOG_ERROR("vkQueueSubmit error: {0:X}", (UINT)qResult); + break; + } + + signalSemaphores[scIndex] = _ImVulkan_Semaphores[idx]; + errorWhenRenderingMenu = false; } - - { - VkRenderPassBeginInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - info.renderPass = _vkRenderPass; - info.framebuffer = fd->Framebuffer; - info.renderArea.extent.width = ImGui::GetIO().DisplaySize.x; - info.renderArea.extent.height = ImGui::GetIO().DisplaySize.y; - vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); - } - - ImGui::Render(); - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); - - // Submit command buffer - vkCmdEndRenderPass(fd->CommandBuffer); - auto ecbResult = vkEndCommandBuffer(fd->CommandBuffer); - if (ecbResult != VK_SUCCESS) - { - LOG_ERROR("vkQueueSubmit error: {0:X}", (UINT)ecbResult); - break; - } - - // Submit queue and semaphores - LOG_DEBUG("waitSemaphoreCount: {0}", pPresentInfo->waitSemaphoreCount); - VkPipelineStageFlags waitStages[8] = { VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT }; - - VkSubmitInfo submit_info = { }; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &fd->CommandBuffer; - submit_info.pWaitDstStageMask = waitStages; - - submit_info.waitSemaphoreCount = pPresentInfo->waitSemaphoreCount; - submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = &_ImVulkan_Semaphores[idx]; - - auto qResult = vkQueueSubmit(_ImVulkan_Info.Queue, 1, &submit_info, fd->Fence); - if (qResult != VK_SUCCESS) - { - LOG_ERROR("vkQueueSubmit error: {0:X}", (UINT)qResult); - break; - } - - signalSemaphores[scIndex] = _ImVulkan_Semaphores[idx]; - errorWhenRenderingMenu = false; } if (!errorWhenRenderingMenu) diff --git a/OptiScaler/nvapi/NvApiHooks.h b/OptiScaler/nvapi/NvApiHooks.h index ba410861..41bcaa0c 100644 --- a/OptiScaler/nvapi/NvApiHooks.h +++ b/OptiScaler/nvapi/NvApiHooks.h @@ -47,36 +47,50 @@ public: return status; } + LOG_DEBUG("return 0xFFFFFFFF"); return 0xFFFFFFFF; } + inline static UINT64 qiCounter = 0; + inline static void* __stdcall HookedNvAPI_QueryInterface(NvApiTypes::NV_INTERFACE InterfaceId) { - switch (InterfaceId) { - case NvApiTypes::NV_INTERFACE::D3D_SetSleepMode: - case NvApiTypes::NV_INTERFACE::D3D_Sleep: - case NvApiTypes::NV_INTERFACE::D3D_GetLatency: - case NvApiTypes::NV_INTERFACE::D3D_SetLatencyMarker: - case NvApiTypes::NV_INTERFACE::D3D12_SetAsyncFrameMarker: - return ReflexHooks::hookReflex(OriginalNvAPI_QueryInterface, InterfaceId); - default: - ReflexHooks::hookReflex(OriginalNvAPI_QueryInterface, InterfaceId); + //LOG_DEBUG("counter: {} InterfaceId: {:X}", ++qiCounter, (uint32_t)InterfaceId); + + switch (InterfaceId) + { + case NvApiTypes::NV_INTERFACE::D3D_SetSleepMode: + case NvApiTypes::NV_INTERFACE::D3D_Sleep: + case NvApiTypes::NV_INTERFACE::D3D_GetLatency: + case NvApiTypes::NV_INTERFACE::D3D_SetLatencyMarker: + case NvApiTypes::NV_INTERFACE::D3D12_SetAsyncFrameMarker: + //LOG_DEBUG("counter: {}, hookReflex()", qiCounter); + return ReflexHooks::hookReflex(OriginalNvAPI_QueryInterface, InterfaceId); + + default: + ReflexHooks::hookReflex(OriginalNvAPI_QueryInterface, InterfaceId); } const auto functionPointer = OriginalNvAPI_QueryInterface(InterfaceId); if (functionPointer) { - switch (InterfaceId) { - case NvApiTypes::NV_INTERFACE::GPU_GetArchInfo: - if (!Config::Instance()->DE_Available) { - OriginalNvAPI_GPU_GetArchInfo = static_cast(functionPointer); - return &HookedNvAPI_GPU_GetArchInfo; - } - break; + switch (InterfaceId) + { + case NvApiTypes::NV_INTERFACE::GPU_GetArchInfo: + //LOG_DEBUG("GPU_GetArchInfo"); + + if (!Config::Instance()->DE_Available) { + OriginalNvAPI_GPU_GetArchInfo = static_cast(functionPointer); + return &HookedNvAPI_GPU_GetArchInfo; + } + + break; } } + LOG_DEBUG("counter: {} functionPointer: {:X}", qiCounter, (size_t)functionPointer); + return functionPointer; } diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index b382c298..a6abd9a9 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -21,7 +21,7 @@ #define VER_MAJOR_VERSION 0 #define VER_MINOR_VERSION 7 #define VER_HOTFIX_VERSION 0 -#define VER_BUILD_NUMBER 90 +#define VER_BUILD_NUMBER 91 #define VER_PRE_RELEASE diff --git a/nvngx.ini b/nvngx.ini index ba77563b..8ca4ed10 100644 --- a/nvngx.ini +++ b/nvngx.ini @@ -167,7 +167,7 @@ DontUseNTShared=auto BuildPipelines=auto ; Creating heap objects for XeSS before init -; true or false - Default (auto) is true +; true or false - Default (auto) is false CreateHeaps=auto ;Select XeSS network model @@ -292,6 +292,28 @@ AdvancedSettings=auto ; true or false - Default (auto) is false ExtendedLimits=auto +; Enables Fps overlay +; true or false - Default (auto) is false +ShowFps=auto + +; Fps overlay position +; 0 = Top Left | 1 = Top Right | 2 = Bottom Left | 3 Bottom Right +; 0 to 3 - Default (auto) is 0 +FpsOverlayPos=auto + +; Fps overlay type +; 0 = Simple | 1 = Detailed | 2 = Detailed + Graph | 3 Full | 4 Full + Graph +; 0 to 4 - Default (auto) is 0 +FpsOverlayType=auto + +; Shortcut key for fps overlay +; Integer value - Default (auto) is 33 -> VK_PRIOR (0x21) +FpsShortcutKey=auto + +; Shortcut key for fps overlay type cycle +; Integer value - Default (auto) is 34 -> VK_NEXT (0x22) +FpsCycleShortcutKey=auto +