From 1edc3044537d4772f72402ffec23b9ad9f6e467a Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Thu, 26 Mar 2026 20:08:42 +0000 Subject: [PATCH] OSD: Add option to show descriptor usage in D3D12 --- pcsx2-qt/Settings/OSDSettingsWidget.cpp | 11 +- pcsx2-qt/Settings/OSDSettingsWidget.ui | 153 +++++++++--------- pcsx2/Config.h | 1 + .../DX12/D3D12DescriptorHeapManager.cpp | 12 ++ .../DX12/D3D12DescriptorHeapManager.h | 3 + pcsx2/ImGui/FullscreenUI_Settings.cpp | 4 + pcsx2/ImGui/ImGuiOverlays.cpp | 28 ++++ pcsx2/Pcsx2Config.cpp | 2 + 8 files changed, 140 insertions(+), 74 deletions(-) diff --git a/pcsx2-qt/Settings/OSDSettingsWidget.cpp b/pcsx2-qt/Settings/OSDSettingsWidget.cpp index b9d16b5eeb..dd48f012b6 100644 --- a/pcsx2-qt/Settings/OSDSettingsWidget.cpp +++ b/pcsx2-qt/Settings/OSDSettingsWidget.cpp @@ -61,6 +61,7 @@ OSDSettingsWidget::OSDSettingsWidget(SettingsWindow* settings_dialog, QWidget* p SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showGSStats, "EmuCore/GS", "OsdShowGSStats", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showUsageCPU, "EmuCore/GS", "OsdShowCPU", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showUsageGPU, "EmuCore/GS", "OsdShowGPU", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showDebugGPU, "EmuCore/GS", "OsdShowGPUDebug", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showStatusIndicators, "EmuCore/GS", "OsdShowIndicators", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showFrameTimes, "EmuCore/GS", "OsdShowFrameTimes", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showHardwareInfo, "EmuCore/GS", "OsdShowHardwareInfo", false); @@ -74,6 +75,11 @@ OSDSettingsWidget::OSDSettingsWidget(SettingsWindow* settings_dialog, QWidget* p SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showTextureReplacements, "EmuCore/GS", "OsdShowTextureReplacements", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.warnAboutUnsafeSettings, "EmuCore", "OsdWarnAboutUnsafeSettings", true); +#ifndef _WIN32 + // Currently DX12 only + m_ui.showDebugGPU->deleteLater(); +#endif + connect(m_ui.showSettings, &QCheckBox::checkStateChanged, this, &OSDSettingsWidget::onOsdShowSettingsToggled); ////////////////////////////////////////////////////////////////////////// @@ -117,7 +123,10 @@ OSDSettingsWidget::OSDSettingsWidget(SettingsWindow* settings_dialog, QWidget* p dialog()->registerWidgetHelp(m_ui.showStatusIndicators, tr("Show Status Indicators"), tr("Checked"), tr("Shows icon indicators for emulation states such as Pausing, Turbo, Fast-Forward, and Slow-Motion.")); - +#ifdef _WIN32 + dialog()->registerWidgetHelp(m_ui.showDebugGPU, tr("Show GPU Debug Info"), + tr("Unchecked"), tr("Shows debug information about the renderer.")); +#endif dialog()->registerWidgetHelp(m_ui.showFrameTimes, tr("Show Frame Times"), tr("Unchecked"), tr("Displays a graph showing the average frametimes.")); diff --git a/pcsx2-qt/Settings/OSDSettingsWidget.ui b/pcsx2-qt/Settings/OSDSettingsWidget.ui index 61aab0d728..1fc86aacde 100644 --- a/pcsx2-qt/Settings/OSDSettingsWidget.ui +++ b/pcsx2-qt/Settings/OSDSettingsWidget.ui @@ -321,7 +321,7 @@ - + QLayout::SizeConstraint::SetDefaultConstraint @@ -331,34 +331,6 @@ 7 - - - - Show Frame Times - - - - - - - Show CPU Usage - - - - - - - Show Resolution - - - - - - - Show VPS - - - @@ -366,31 +338,17 @@ - - + + - Show Speed Percentages + Show Frame Times - - + + - Show GS Statistics - - - - - - - Show Status Indicators - - - - - - - Show FPS + Messages @@ -401,20 +359,6 @@ - - - - System Information - - - - - - - Settings & Inputs - - - @@ -429,13 +373,6 @@ - - - - Show Settings - - - @@ -443,6 +380,20 @@ + + + + Show Resolution + + + + + + + Show CPU Usage + + + @@ -471,10 +422,17 @@ - - + + - Messages + Show GS Statistics + + + + + + + Show Status Indicators @@ -485,6 +443,55 @@ + + + + Show FPS + + + + + + + System Information + + + + + + + Show Speed Percentages + + + + + + + Show Settings + + + + + + + Show VPS + + + + + + + Settings & Inputs + + + + + + + Show GPU Debug Info + + + diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 5e1f8bad00..c17cc9e4e4 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -772,6 +772,7 @@ struct Pcsx2Config OsdShowGSStats : 1, OsdShowCPU : 1, OsdShowGPU : 1, + OsdShowGPUDebug : 1, OsdShowIndicators : 1, OsdShowFrameTimes : 1, OsdShowHardwareInfo : 1, diff --git a/pcsx2/GS/Renderers/DX12/D3D12DescriptorHeapManager.cpp b/pcsx2/GS/Renderers/DX12/D3D12DescriptorHeapManager.cpp index fa26871b91..8950ea6511 100644 --- a/pcsx2/GS/Renderers/DX12/D3D12DescriptorHeapManager.cpp +++ b/pcsx2/GS/Renderers/DX12/D3D12DescriptorHeapManager.cpp @@ -102,6 +102,18 @@ void D3D12DescriptorHeapManager::Free(D3D12DescriptorHandle* handle) handle->Clear(); } +u32 D3D12DescriptorHeapManager::GetAllocatedDescriptors() +{ + u32 ret = 0; + + for (u32 group = 0; group < m_free_slots.size(); group++) + { + BitSetType& bs = m_free_slots[group]; + ret += BITSET_SIZE - bs.count(); + } + return ret; +} + D3D12DescriptorAllocator::D3D12DescriptorAllocator() = default; D3D12DescriptorAllocator::~D3D12DescriptorAllocator() = default; diff --git a/pcsx2/GS/Renderers/DX12/D3D12DescriptorHeapManager.h b/pcsx2/GS/Renderers/DX12/D3D12DescriptorHeapManager.h index 43bcd58631..59f4b8b5ad 100644 --- a/pcsx2/GS/Renderers/DX12/D3D12DescriptorHeapManager.h +++ b/pcsx2/GS/Renderers/DX12/D3D12DescriptorHeapManager.h @@ -62,6 +62,9 @@ public: void Free(D3D12DescriptorHandle* handle); void Free(u32 index); + u32 GetNumDescriptors() const { return m_num_descriptors; } + u32 GetAllocatedDescriptors(); + private: wil::com_ptr_nothrow m_descriptor_heap; u32 m_num_descriptors = 0; diff --git a/pcsx2/ImGui/FullscreenUI_Settings.cpp b/pcsx2/ImGui/FullscreenUI_Settings.cpp index 9b905b71b6..35ce77f1fd 100644 --- a/pcsx2/ImGui/FullscreenUI_Settings.cpp +++ b/pcsx2/ImGui/FullscreenUI_Settings.cpp @@ -3386,6 +3386,10 @@ void FullscreenUI::DrawOSDSettingsPage() DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_PLAY, "Show Status Indicators"), FSUI_CSTR("Shows indicators when fast forwarding, pausing, and other abnormal states are active."), "EmuCore/GS", "OsdShowIndicators", true); +#ifdef _WIN32 + DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_BUG, "Show GPU Debug Info"), + FSUI_CSTR("Shows debug information about the renderer."), "EmuCore/GS", "OsdShowGPUDebug", false); +#endif DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_PF_HEARTBEAT_ALT, "Show Frame Times"), FSUI_CSTR("Shows a visual history of frame times."), "EmuCore/GS", "OsdShowFrameTimes", false); DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_SLIDERS, "Show Settings"), diff --git a/pcsx2/ImGui/ImGuiOverlays.cpp b/pcsx2/ImGui/ImGuiOverlays.cpp index b1b5e20e97..597d5dfa48 100644 --- a/pcsx2/ImGui/ImGuiOverlays.cpp +++ b/pcsx2/ImGui/ImGuiOverlays.cpp @@ -8,6 +8,9 @@ #include "GS/GSCapture.h" #include "GS/GSVector.h" #include "GS/Renderers/Common/GSDevice.h" +#ifdef _WIN32 +#include "GS/Renderers/DX12/GSDevice12.h" +#endif #include "GS/Renderers/HW/GSTextureReplacements.h" #include "Host.h" #include "IconsFontAwesome.h" @@ -66,6 +69,7 @@ SmallString s_cpu_usage_vu_line; std::vector s_software_thread_lines; SmallString s_capture_line; SmallString s_gpu_usage_line; +SmallString s_gpu_debug_info_line; SmallString s_speed_icon; constexpr ImU32 white_color = IM_COL32(255, 255, 255, 255); @@ -482,6 +486,22 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f FormatProcessorStat(s_gpu_usage_line, PerformanceMetrics::GetGPUUsage(), PerformanceMetrics::GetGPUAverageTime()); DRAW_LINE(osd_font, font_size, s_gpu_usage_line.c_str(), white_color); } + + if (GSConfig.OsdShowGPUDebug) + { +#ifdef _WIN32 + if (g_gs_device->GetRenderAPI() == RenderAPI::D3D12) + { + GSDevice12* dev12 = static_cast(g_gs_device.get()); + + s_gpu_debug_info_line.format("D3D12 Descriptor Heaps | SRV/UAV: {}/{} | RTV: {}/{} | DSV {}/{}", + dev12->GetDescriptorHeapManager().GetAllocatedDescriptors(), dev12->GetDescriptorHeapManager().GetNumDescriptors(), + dev12->GetRTVHeapManager().GetAllocatedDescriptors(), dev12->GetRTVHeapManager().GetNumDescriptors(), + dev12->GetDSVHeapManager().GetAllocatedDescriptors(), dev12->GetDSVHeapManager().GetNumDescriptors()); + DRAW_LINE(osd_font, font_size, s_gpu_debug_info_line.c_str(), white_color); + } +#endif + } } // No refresh yet. Display cached lines. else @@ -526,6 +546,14 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f if (GSConfig.OsdShowGPU) DRAW_LINE(osd_font, font_size, s_gpu_usage_line.c_str(), white_color); + + if (GSConfig.OsdShowGPUDebug) + { +#ifdef _WIN32 + if (g_gs_device->GetRenderAPI() == RenderAPI::D3D12) + DRAW_LINE(osd_font, font_size, s_gpu_debug_info_line.c_str(), white_color); +#endif + } } // Check every OSD frame because this is an animation. diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index d3e61f7e12..6f8d48038e 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -732,6 +732,7 @@ Pcsx2Config::GSOptions::GSOptions() OsdShowGSStats = false; OsdShowCPU = false; OsdShowGPU = false; + OsdShowGPUDebug = false; OsdShowIndicators = true; OsdShowFrameTimes = false; OsdShowHardwareInfo = false; @@ -957,6 +958,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap) SettingsWrapBitBool(OsdShowVPS); SettingsWrapBitBool(OsdShowCPU); SettingsWrapBitBool(OsdShowGPU); + SettingsWrapBitBool(OsdShowGPUDebug); SettingsWrapBitBool(OsdShowResolution); SettingsWrapBitBool(OsdShowGSStats); SettingsWrapBitBool(OsdShowIndicators);