diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt index 1a03eac3f4..68c859082c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt @@ -700,6 +700,18 @@ enum class BooleanSetting( false ), GFX_OVERLAY_STATS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "OverlayStats", false), + GFX_OVERLAY_PROJ_STATS( + Settings.FILE_GFX, + Settings.SECTION_GFX_SETTINGS, + "OverlayProjStats", + false + ), + GFX_SHOW_INTERNAL_RESOLUTION( + Settings.FILE_GFX, + Settings.SECTION_GFX_SETTINGS, + "ShowInternalResolution", + false + ), GFX_DUMP_TEXTURES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpTextures", false), GFX_DUMP_MIP_TEXTURES( Settings.FILE_GFX, diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt index 85c909d5a5..a9ca9c3c3d 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt @@ -2169,6 +2169,22 @@ class SettingsFragmentPresenter( R.string.leave_this_unchecked ) ) + sl.add( + SwitchSetting( + context, + BooleanSetting.GFX_OVERLAY_PROJ_STATS, + R.string.show_proj_stats, + R.string.leave_this_unchecked + ) + ) + sl.add( + SwitchSetting( + context, + BooleanSetting.GFX_SHOW_INTERNAL_RESOLUTION, + R.string.show_internal_resolution, + R.string.leave_this_unchecked + ) + ) sl.add( SwitchSetting( context, diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 21a42e5939..07c5e7ebc0 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -374,6 +374,8 @@ Debugging Enable Wireframe Show Statistics + Show Projection Statistics + Show XFB Resolution Texture Format Overlay Enable API Validation Layers Dump EFB Target diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index fb7f6a872b..f91b87e490 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -43,8 +43,6 @@ const Info GFX_CROP_CUSTOM_BOTTOM{{System::GFX, "Settings", "CropCustomBott const Info GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES{ {System::GFX, "Settings", "SafeTextureCacheColorSamples"}, 128}; const Info GFX_SHOW_FPS{{System::GFX, "Settings", "ShowFPS"}, false}; -const Info GFX_SHOW_INTERNAL_RESOLUTION{{System::GFX, "Settings", "ShowInternalResolution"}, - false}; const Info GFX_SHOW_FTIMES{{System::GFX, "Settings", "ShowFTimes"}, false}; const Info GFX_SHOW_VPS{{System::GFX, "Settings", "ShowVPS"}, false}; const Info GFX_SHOW_VTIMES{{System::GFX, "Settings", "ShowVTimes"}, false}; @@ -61,6 +59,8 @@ const Info GFX_LOG_RENDER_TIME_TO_FILE{{System::GFX, "Settings", "LogRende const Info GFX_OVERLAY_STATS{{System::GFX, "Settings", "OverlayStats"}, false}; const Info GFX_OVERLAY_PROJ_STATS{{System::GFX, "Settings", "OverlayProjStats"}, false}; const Info GFX_OVERLAY_SCISSOR_STATS{{System::GFX, "Settings", "OverlayScissorStats"}, false}; +const Info GFX_SHOW_INTERNAL_RESOLUTION{{System::GFX, "Settings", "ShowInternalResolution"}, + false}; const Info GFX_DUMP_TEXTURES{{System::GFX, "Settings", "DumpTextures"}, false}; const Info GFX_DUMP_MIP_TEXTURES{{System::GFX, "Settings", "DumpMipTextures"}, true}; const Info GFX_DUMP_BASE_TEXTURES{{System::GFX, "Settings", "DumpBaseTextures"}, true}; diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index 831e04422b..502d2f0764 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -47,7 +47,6 @@ extern const Info GFX_CROP_CUSTOM_RIGHT; extern const Info GFX_CROP_CUSTOM_BOTTOM; extern const Info GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES; extern const Info GFX_SHOW_FPS; -extern const Info GFX_SHOW_INTERNAL_RESOLUTION; extern const Info GFX_SHOW_FTIMES; extern const Info GFX_SHOW_VPS; extern const Info GFX_SHOW_VTIMES; @@ -62,6 +61,7 @@ extern const Info GFX_LOG_RENDER_TIME_TO_FILE; extern const Info GFX_OVERLAY_STATS; extern const Info GFX_OVERLAY_PROJ_STATS; extern const Info GFX_OVERLAY_SCISSOR_STATS; +extern const Info GFX_SHOW_INTERNAL_RESOLUTION; extern const Info GFX_DUMP_TEXTURES; extern const Info GFX_DUMP_MIP_TEXTURES; extern const Info GFX_DUMP_BASE_TEXTURES; diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index cebcc748ec..1b50796e34 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -863,6 +863,9 @@ void Callback_FramePresented(const PresentInfo& present_info) present_info.actual_present_time - present_info.intended_present_time; perf_metrics.SetLatestFramePresentationOffset(presentation_offset); + perf_metrics.SetLatestFrameBufferSize(present_info.frame_buffer_width, + present_info.frame_buffer_height); + if (present_info.reason == PresentInfo::PresentReason::VideoInterfaceDuplicate) return; diff --git a/Source/Core/DolphinQt/Settings/OnScreenDisplayPane.cpp b/Source/Core/DolphinQt/Settings/OnScreenDisplayPane.cpp index 37239b9c74..2c8b55b899 100644 --- a/Source/Core/DolphinQt/Settings/OnScreenDisplayPane.cpp +++ b/Source/Core/DolphinQt/Settings/OnScreenDisplayPane.cpp @@ -43,8 +43,6 @@ void OnScreenDisplayPane::CreateLayout() performance_box->setLayout(performance_layout); m_show_fps = new ConfigBool(tr("Show FPS"), Config::GFX_SHOW_FPS); - m_show_internal_resolution = - new ConfigBool(tr("Show Internal Resolution"), Config::GFX_SHOW_INTERNAL_RESOLUTION); m_show_ftimes = new ConfigBool(tr("Show Frame Times"), Config::GFX_SHOW_FTIMES); m_show_vps = new ConfigBool(tr("Show VPS"), Config::GFX_SHOW_VPS); m_show_vtimes = new ConfigBool(tr("Show VBlank Times"), Config::GFX_SHOW_VTIMES); @@ -103,6 +101,8 @@ void OnScreenDisplayPane::CreateLayout() m_show_statistics = new ConfigBool(tr("Show Statistics"), Config::GFX_OVERLAY_STATS); m_show_proj_statistics = new ConfigBool(tr("Show Projection Statistics"), Config::GFX_OVERLAY_PROJ_STATS); + m_show_internal_resolution = + new ConfigBool(tr("Show XFB Resolution"), Config::GFX_SHOW_INTERNAL_RESOLUTION); debug_layout->addWidget(m_show_statistics, 0, 0); debug_layout->addWidget(m_show_proj_statistics, 0, 1); @@ -153,11 +153,6 @@ void OnScreenDisplayPane::AddDescriptions() QT_TR_NOOP("Shows the number of distinct frames rendered per second as a measure of " "visual smoothness.

If unsure, leave this " "unchecked."); - - static const char TR_SHOW_INTERNAL_RESOLUTION_DESCRIPTION[] = - QT_TR_NOOP("Shows the internal resolution in pixels, as a product of " - "width and height.

If unsure, leave this " - "unchecked."); static const char TR_SHOW_FTIMES_DESCRIPTION[] = QT_TR_NOOP("Shows the average time in ms between each distinct rendered frame alongside " "the standard deviation.

If unsure, leave this " @@ -225,12 +220,15 @@ void OnScreenDisplayPane::AddDescriptions() static const char TR_SHOW_PROJ_STATS_DESCRIPTION[] = QT_TR_NOOP("Shows various projection statistics.

If unsure, " "leave this unchecked."); + static const char TR_SHOW_INTERNAL_RESOLUTION_DESCRIPTION[] = + QT_TR_NOOP("Shows the size of the emulated external frame buffer (XFB) in pixels, as a " + "product of width and height.

If unsure, leave this " + "unchecked."); m_enable_osd->SetDescription(tr(TR_ENABLE_OSD_DESCRIPTION)); m_font_size->SetDescription(tr(TR_OSD_FONT_SIZE_DESCRIPTION)); m_show_fps->SetDescription(tr(TR_SHOW_FPS_DESCRIPTION)); - m_show_internal_resolution->SetDescription(tr(TR_SHOW_INTERNAL_RESOLUTION_DESCRIPTION)); m_show_ftimes->SetDescription(tr(TR_SHOW_FTIMES_DESCRIPTION)); m_show_vps->SetDescription(tr(TR_SHOW_VPS_DESCRIPTION)); m_show_vtimes->SetDescription(tr(TR_SHOW_VTIMES_DESCRIPTION)); @@ -251,4 +249,5 @@ void OnScreenDisplayPane::AddDescriptions() m_show_statistics->SetDescription(tr(TR_SHOW_STATS_DESCRIPTION)); m_show_proj_statistics->SetDescription(tr(TR_SHOW_PROJ_STATS_DESCRIPTION)); + m_show_internal_resolution->SetDescription(tr(TR_SHOW_INTERNAL_RESOLUTION_DESCRIPTION)); } diff --git a/Source/Core/DolphinQt/Settings/OnScreenDisplayPane.h b/Source/Core/DolphinQt/Settings/OnScreenDisplayPane.h index 27653d009c..8ae4e9bc76 100644 --- a/Source/Core/DolphinQt/Settings/OnScreenDisplayPane.h +++ b/Source/Core/DolphinQt/Settings/OnScreenDisplayPane.h @@ -25,7 +25,6 @@ private: // Performance ConfigBool* m_show_fps; - ConfigBool* m_show_internal_resolution; ConfigBool* m_show_ftimes; ConfigBool* m_show_vps; ConfigBool* m_show_vtimes; @@ -49,4 +48,5 @@ private: // Debug ConfigBool* m_show_statistics; ConfigBool* m_show_proj_statistics; + ConfigBool* m_show_internal_resolution; }; diff --git a/Source/Core/VideoCommon/PerformanceMetrics.cpp b/Source/Core/VideoCommon/PerformanceMetrics.cpp index fccc8ae38e..98efa64108 100644 --- a/Source/Core/VideoCommon/PerformanceMetrics.cpp +++ b/Source/Core/VideoCommon/PerformanceMetrics.cpp @@ -11,7 +11,6 @@ #include "Common/HookableEvent.h" #include "Core/Config/GraphicsSettings.h" #include "Core/Core.h" -#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/VideoConfig.h" PerformanceMetrics::PerformanceMetrics() @@ -89,20 +88,6 @@ double PerformanceMetrics::GetFPS() const return m_fps_counter.GetHzAvg(); } -u32 PerformanceMetrics::GetEFBWidth() const -{ - if (g_framebuffer_manager) - return g_framebuffer_manager->GetEFBWidth(); - return 0; -} - -u32 PerformanceMetrics::GetEFBHeight() const -{ - if (g_framebuffer_manager) - return g_framebuffer_manager->GetEFBHeight(); - return 0; -} - double PerformanceMetrics::GetVPS() const { return m_vps_counter.GetHzAvg(); @@ -123,6 +108,11 @@ void PerformanceMetrics::SetLatestFramePresentationOffset(DT offset) m_frame_presentation_offset.store(offset, std::memory_order_relaxed); } +void PerformanceMetrics::SetLatestFrameBufferSize(u32 width, u32 height) +{ + m_frame_buffer_size.store(FrameBufferSize{width, height}, std::memory_order_relaxed); +} + void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) { m_vps_counter.UpdateStats(); @@ -139,8 +129,6 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const double fps = GetFPS(); const double vps = GetVPS(); const double speed = GetSpeed(); - const u32 width = GetEFBWidth(); - const u32 height = GetEFBHeight(); static ImVec2 last_display_size(-1.0f, -1.0f); @@ -335,26 +323,6 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) ImGui::End(); } - if (g_ActiveConfig.bShowInternalResolution) - { - ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition, - ImVec2(1.0f, 0.0f)); - ImGui::SetNextWindowBgAlpha(bg_alpha); - - if (ImGui::Begin("ResolutionStats", nullptr, imgui_flags)) - { - if (stack_vertically) - window_y += ImGui::GetWindowHeight() + window_padding; - else - window_x -= ImGui::GetWindowWidth() + window_padding; - - clamp_window_position(); - - ImGui::TextColored(ImVec4(r, g, b, 1.0f), "Res: %ux%u", width, height); - } - ImGui::End(); - } - if (g_ActiveConfig.bShowVPS || g_ActiveConfig.bShowVTimes) { // Position in the top-right corner of the screen. @@ -382,5 +350,26 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) ImGui::End(); } + if (g_ActiveConfig.bShowInternalResolution) + { + ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition, + ImVec2(1.0f, 0.0f)); + ImGui::SetNextWindowBgAlpha(bg_alpha); + + if (ImGui::Begin("ResolutionStats", nullptr, imgui_flags)) + { + if (stack_vertically) + window_y += ImGui::GetWindowHeight() + window_padding; + else + window_x -= ImGui::GetWindowWidth() + window_padding; + + clamp_window_position(); + + const FrameBufferSize size = m_frame_buffer_size.load(std::memory_order_relaxed); + ImGui::TextColored(ImVec4(r, g, b, 1.0f), "XFB res: %ux%u", size.width, size.height); + } + ImGui::End(); + } + ImGui::PopStyleVar(2); } diff --git a/Source/Core/VideoCommon/PerformanceMetrics.h b/Source/Core/VideoCommon/PerformanceMetrics.h index 538360a05b..b24c6f6659 100644 --- a/Source/Core/VideoCommon/PerformanceMetrics.h +++ b/Source/Core/VideoCommon/PerformanceMetrics.h @@ -41,15 +41,20 @@ public: double GetVPS() const; double GetSpeed() const; double GetMaxSpeed() const; - u32 GetEFBWidth() const; - u32 GetEFBHeight() const; // Call from any thread. void SetLatestFramePresentationOffset(DT offset); + void SetLatestFrameBufferSize(u32 width, u32 height); // ImGui Functions void DrawImGuiStats(const float backbuffer_scale); private: + struct FrameBufferSize + { + u32 width = 0; + u32 height = 0; + }; + PerformanceTracker m_fps_counter{"render_times.txt"}; PerformanceTracker m_vps_counter{"vblank_times.txt"}; @@ -59,6 +64,7 @@ private: std::atomic m_max_speed{}; std::atomic
m_frame_presentation_offset{}; + std::atomic m_frame_buffer_size{}; struct PerfSample { diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp index 7c62730667..41d05f3652 100644 --- a/Source/Core/VideoCommon/Present.cpp +++ b/Source/Core/VideoCommon/Present.cpp @@ -174,6 +174,8 @@ void Presenter::ViSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, .present_count = m_present_count++, .emulated_timestamp = ticks, .intended_present_time = presentation_time, + .frame_buffer_width = fb_width, + .frame_buffer_height = fb_height, }; if (is_duplicate) @@ -234,9 +236,11 @@ void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_ PresentInfo present_info{ .frame_count = m_frame_count++, .present_count = m_present_count++, - .reason = PresentInfo::PresentReason::Immediate, .emulated_timestamp = ticks, .intended_present_time = m_next_swap_estimated_time, + .reason = PresentInfo::PresentReason::Immediate, + .frame_buffer_width = fb_width, + .frame_buffer_height = fb_height, }; auto& video_events = GetVideoEvents(); diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 448f447741..c56f32c00c 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -106,7 +106,6 @@ void VideoConfig::Refresh() iCropCustomBottom = Config::Get(Config::GFX_CROP_CUSTOM_BOTTOM); iSafeTextureCache_ColorSamples = Config::Get(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES); bShowFPS = Config::Get(Config::GFX_SHOW_FPS); - bShowInternalResolution = Config::Get(Config::GFX_SHOW_INTERNAL_RESOLUTION); bShowFTimes = Config::Get(Config::GFX_SHOW_FTIMES); bShowVPS = Config::Get(Config::GFX_SHOW_VPS); bShowVTimes = Config::Get(Config::GFX_SHOW_VTIMES); @@ -118,6 +117,7 @@ void VideoConfig::Refresh() bOverlayStats = Config::Get(Config::GFX_OVERLAY_STATS); bOverlayProjStats = Config::Get(Config::GFX_OVERLAY_PROJ_STATS); bOverlayScissorStats = Config::Get(Config::GFX_OVERLAY_SCISSOR_STATS); + bShowInternalResolution = Config::Get(Config::GFX_SHOW_INTERNAL_RESOLUTION); bDumpTextures = Config::Get(Config::GFX_DUMP_TEXTURES); bDumpMipmapTextures = Config::Get(Config::GFX_DUMP_MIP_TEXTURES); bDumpBaseTextures = Config::Get(Config::GFX_DUMP_BASE_TEXTURES); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index ec06f4a606..e16015491b 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -250,7 +250,6 @@ struct VideoConfig final // Information bool bShowFPS = false; - bool bShowInternalResolution = false; bool bShowFTimes = false; bool bShowVPS = false; bool bShowVTimes = false; @@ -261,6 +260,7 @@ struct VideoConfig final bool bOverlayStats = false; bool bOverlayProjStats = false; bool bOverlayScissorStats = false; + bool bShowInternalResolution = false; bool bTexFmtOverlayEnable = false; bool bTexFmtOverlayCenter = false; bool bLogRenderTimeToFile = false; diff --git a/Source/Core/VideoCommon/VideoEvents.h b/Source/Core/VideoCommon/VideoEvents.h index fe30aa251b..f037dc266d 100644 --- a/Source/Core/VideoCommon/VideoEvents.h +++ b/Source/Core/VideoCommon/VideoEvents.h @@ -16,31 +16,6 @@ class System; struct PresentInfo { - enum class PresentReason - { - Immediate, // FIFO is Presenting the XFB immediately, straight after the XFB copy - VideoInterface, // VideoInterface has triggered a present with a new frame - VideoInterfaceDuplicate, // VideoInterface has triggered a present with a duplicate frame - }; - - // The number of (unique) frames since the emulated console booted - u64 frame_count = 0; - - // The number of presents since the video backend was initialized. - // never goes backwards. - u64 present_count = 0; - - // The frame is identical to the previous frame - PresentReason reason = PresentReason::Immediate; - - // The exact emulated time of the when real hardware would have presented this frame - u64 emulated_timestamp = 0; - - TimePoint intended_present_time{}; - - // AfterPresent only: The actual time the frame was presented - TimePoint actual_present_time{}; - enum class PresentTimeAccuracy { // The Driver/OS has given us an exact timestamp of when the first line of the frame started @@ -58,9 +33,37 @@ struct PresentInfo Unimplemented, }; + enum class PresentReason + { + Immediate, // FIFO is Presenting the XFB immediately, straight after the XFB copy + VideoInterface, // VideoInterface has triggered a present with a new frame + VideoInterfaceDuplicate, // VideoInterface has triggered a present with a duplicate frame + }; + + // The number of (unique) frames since the emulated console booted + u64 frame_count = 0; + + // The number of presents since the video backend was initialized. + // never goes backwards. + u64 present_count = 0; + + // The exact emulated time of the when real hardware would have presented this frame + u64 emulated_timestamp = 0; + + TimePoint intended_present_time{}; + + // AfterPresent only: The actual time the frame was presented + TimePoint actual_present_time{}; + // Accuracy of actual_present_time PresentTimeAccuracy present_time_accuracy = PresentTimeAccuracy::Unimplemented; + // Where the presentation of the frame was triggered from + PresentReason reason = PresentReason::Immediate; + + u32 frame_buffer_width; + u32 frame_buffer_height; + std::vector xfb_copy_hashes; };