added a basic fps overlay

This commit is contained in:
cdozdil
2025-01-11 01:24:18 +03:00
parent 5a29532b88
commit c87718ff40
16 changed files with 450 additions and 187 deletions
+37
View File
@@ -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
+5
View File
@@ -74,6 +74,11 @@ public:
std::optional<int> ShortcutKey;
std::optional<bool> AdvancedSettings;
std::optional<bool> ExtendedLimits;
std::optional<bool> ShowFps;
std::optional<int> FpsOverlayPos; // 0 Top Left, 1 Top Right, 2 Bottom Left, 3 Bottom Right
std::optional<int> FpsOverlayType; // 0 Only FPS, 1 +Frame Time, 2 +Upscaler Time, 3 +Frame Time Graph, 4 +Upscaler Time Graph
std::optional<int> FpsShortcutKey;
std::optional<int> FpsCycleShortcutKey;
// hooks
std::optional<bool> HookOriginalNvngxOnly;
+1 -1
View File
@@ -82,7 +82,7 @@
<IncludePath>$(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)</IncludePath>
<LibraryPath>$(ProjectDir)fsr2\lib;$(ProjectDir)fsr2_212\lib;$(ProjectDir)fsr31\lib;$(ProjectDir)vulkan;$(ProjectDir)d3dx;$(ProjectDir)detours;$(SolutionDir)external\xess\lib;$(SolutionDir)external\freetype;$(LibraryPath)</LibraryPath>
<TargetName>dxgi</TargetName>
<OutDir>E:\Games\Deep Rock Galactic\FSD\Binaries\Win64\</OutDir>
<OutDir>E:\Games\Epic\Control\</OutDir>
<IntDir>.\x64\Debug</IntDir>
<TargetExt>.dll</TargetExt>
</PropertyGroup>
+2 -2
View File
@@ -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("");
+15 -6
View File
@@ -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<double>(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<double>(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;
}
+3 -3
View File
@@ -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);
+202 -29
View File
@@ -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<uint32_t>* 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<float> frameTimeArray(Config::Instance()->frameTimes.begin(), Config::Instance()->frameTimes.end());
std::vector<float> 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<int>(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<int>(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)
+1 -1
View File
@@ -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();
+2 -2
View File
@@ -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();
+3 -3
View File
@@ -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()
+1 -1
View File
@@ -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();
};
+62 -60
View File
@@ -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
{
+62 -61
View File
@@ -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<std::mutex> 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)
+30 -16
View File
@@ -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<NvApiTypes::PfnNvAPI_GPU_GetArchInfo>(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<NvApiTypes::PfnNvAPI_GPU_GetArchInfo>(functionPointer);
return &HookedNvAPI_GPU_GetArchInfo;
}
break;
}
}
LOG_DEBUG("counter: {} functionPointer: {:X}", qiCounter, (size_t)functionPointer);
return functionPointer;
}
+1 -1
View File
@@ -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
+23 -1
View File
@@ -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