HostDisplay: Add GPU usage statistics
This commit is contained in:
@ -22,7 +22,11 @@ const GPU::GP0CommandHandlerTable GPU::s_GP0_command_handler_table = GPU::Genera
|
||||
|
||||
GPU::GPU() = default;
|
||||
|
||||
GPU::~GPU() = default;
|
||||
GPU::~GPU()
|
||||
{
|
||||
if (g_host_display)
|
||||
g_host_display->SetGPUTimingEnabled(false);
|
||||
}
|
||||
|
||||
bool GPU::Initialize()
|
||||
{
|
||||
@ -41,15 +45,14 @@ bool GPU::Initialize()
|
||||
m_console_is_pal = System::IsPALRegion();
|
||||
UpdateCRTCConfig();
|
||||
|
||||
g_host_display->SetDisplayLinearFiltering(g_settings.display_linear_filtering);
|
||||
g_host_display->SetDisplayIntegerScaling(g_settings.display_integer_scaling);
|
||||
g_host_display->SetDisplayStretch(g_settings.display_stretch);
|
||||
if (g_settings.display_post_processing && !g_settings.display_post_process_chain.empty() &&
|
||||
!g_host_display->SetPostProcessingChain(g_settings.display_post_process_chain))
|
||||
{
|
||||
Host::AddOSDMessage(Host::TranslateStdString("OSDMessage", "Failed to load post processing shader chain."), 20.0f);
|
||||
}
|
||||
|
||||
g_host_display->SetGPUTimingEnabled(g_settings.display_show_gpu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -69,9 +72,7 @@ void GPU::UpdateSettings()
|
||||
// Crop mode calls this, so recalculate the display area
|
||||
UpdateCRTCDisplayParameters();
|
||||
|
||||
g_host_display->SetDisplayLinearFiltering(g_settings.display_linear_filtering);
|
||||
g_host_display->SetDisplayIntegerScaling(g_settings.display_integer_scaling);
|
||||
g_host_display->SetDisplayStretch(g_settings.display_stretch);
|
||||
g_host_display->SetGPUTimingEnabled(g_settings.display_show_gpu);
|
||||
}
|
||||
|
||||
bool GPU::IsHardwareRenderer()
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/timer.h"
|
||||
#include "settings.h"
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_resize.h"
|
||||
#include "stb_image_write.h"
|
||||
@ -164,6 +165,16 @@ bool HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
||||
return WindowInfo::QueryRefreshRateForWindow(m_window_info, refresh_rate);
|
||||
}
|
||||
|
||||
bool HostDisplay::SetGPUTimingEnabled(bool enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float HostDisplay::GetAndResetAccumulatedGPUTime()
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void HostDisplay::SetSoftwareCursor(std::unique_ptr<HostDisplayTexture> texture, float scale /*= 1.0f*/)
|
||||
{
|
||||
m_cursor_texture = std::move(texture);
|
||||
@ -216,13 +227,18 @@ void HostDisplay::ClearSoftwareCursor()
|
||||
m_cursor_texture_scale = 1.0f;
|
||||
}
|
||||
|
||||
bool HostDisplay::IsUsingLinearFiltering() const
|
||||
{
|
||||
return g_settings.display_linear_filtering;
|
||||
}
|
||||
|
||||
void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, float* out_left, float* out_top,
|
||||
float* out_width, float* out_height, float* out_left_padding,
|
||||
float* out_top_padding, float* out_scale, float* out_x_scale,
|
||||
bool apply_aspect_ratio /* = true */) const
|
||||
{
|
||||
const float window_ratio = static_cast<float>(window_width) / static_cast<float>(window_height);
|
||||
const float display_aspect_ratio = m_display_stretch ? window_ratio : m_display_aspect_ratio;
|
||||
const float display_aspect_ratio = g_settings.display_stretch ? window_ratio : m_display_aspect_ratio;
|
||||
const float x_scale =
|
||||
apply_aspect_ratio ?
|
||||
(display_aspect_ratio / (static_cast<float>(m_display_width) / static_cast<float>(m_display_height))) :
|
||||
@ -242,12 +258,12 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, float*
|
||||
{
|
||||
// align in middle vertically
|
||||
scale = static_cast<float>(window_width) / display_width;
|
||||
if (m_display_integer_scaling)
|
||||
if (g_settings.display_integer_scaling)
|
||||
scale = std::max(std::floor(scale), 1.0f);
|
||||
|
||||
if (out_left_padding)
|
||||
{
|
||||
if (m_display_integer_scaling)
|
||||
if (g_settings.display_integer_scaling)
|
||||
*out_left_padding = std::max<float>((static_cast<float>(window_width) - display_width * scale) / 2.0f, 0.0f);
|
||||
else
|
||||
*out_left_padding = 0.0f;
|
||||
@ -276,7 +292,7 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, float*
|
||||
{
|
||||
// align in middle horizontally
|
||||
scale = static_cast<float>(window_height) / display_height;
|
||||
if (m_display_integer_scaling)
|
||||
if (g_settings.display_integer_scaling)
|
||||
scale = std::max(std::floor(scale), 1.0f);
|
||||
|
||||
if (out_left_padding)
|
||||
@ -301,7 +317,7 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, float*
|
||||
|
||||
if (out_top_padding)
|
||||
{
|
||||
if (m_display_integer_scaling)
|
||||
if (g_settings.display_integer_scaling)
|
||||
*out_top_padding = std::max<float>((static_cast<float>(window_height) - (display_height * scale)) / 2.0f, 0.0f);
|
||||
else
|
||||
*out_top_padding = 0.0f;
|
||||
|
||||
@ -85,6 +85,13 @@ public:
|
||||
m_mouse_position_y = y;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE const void* GetDisplayTextureHandle() const { return m_display_texture_handle; }
|
||||
ALWAYS_INLINE s32 GetDisplayTopMargin() const { return m_display_top_margin; }
|
||||
ALWAYS_INLINE s32 GetDisplayWidth() const { return m_display_width; }
|
||||
ALWAYS_INLINE s32 GetDisplayHeight() const { return m_display_height; }
|
||||
ALWAYS_INLINE float GetDisplayAspectRatio() const { return m_display_aspect_ratio; }
|
||||
ALWAYS_INLINE bool IsGPUTimingEnabled() const { return m_gpu_timing_enabled; }
|
||||
|
||||
virtual RenderAPI GetRenderAPI() const = 0;
|
||||
virtual void* GetRenderDevice() const = 0;
|
||||
virtual void* GetRenderContext() const = 0;
|
||||
@ -137,12 +144,6 @@ public:
|
||||
virtual void DestroyImGuiContext() = 0;
|
||||
virtual bool UpdateImGuiFontTexture() = 0;
|
||||
|
||||
const void* GetDisplayTextureHandle() const { return m_display_texture_handle; }
|
||||
s32 GetDisplayTopMargin() const { return m_display_top_margin; }
|
||||
s32 GetDisplayWidth() const { return m_display_width; }
|
||||
s32 GetDisplayHeight() const { return m_display_height; }
|
||||
float GetDisplayAspectRatio() const { return m_display_aspect_ratio; }
|
||||
|
||||
bool UsesLowerLeftOrigin() const;
|
||||
void SetDisplayMaxFPS(float max_fps);
|
||||
bool ShouldSkipDisplayingFrame();
|
||||
@ -209,11 +210,14 @@ public:
|
||||
|
||||
virtual bool GetHostRefreshRate(float* refresh_rate);
|
||||
|
||||
void SetDisplayLinearFiltering(bool enabled) { m_display_linear_filtering = enabled; }
|
||||
/// Enables/disables GPU frame timing.
|
||||
virtual bool SetGPUTimingEnabled(bool enabled);
|
||||
|
||||
/// Returns the amount of GPU time utilized since the last time this method was called.
|
||||
virtual float GetAndResetAccumulatedGPUTime();
|
||||
|
||||
void SetDisplayTopMargin(s32 height) { m_display_top_margin = height; }
|
||||
void SetDisplayIntegerScaling(bool enabled) { m_display_integer_scaling = enabled; }
|
||||
void SetDisplayAlignment(Alignment alignment) { m_display_alignment = alignment; }
|
||||
void SetDisplayStretch(bool stretch) { m_display_stretch = stretch; }
|
||||
|
||||
/// Sets the software cursor to the specified texture. Ownership of the texture is transferred.
|
||||
void SetSoftwareCursor(std::unique_ptr<HostDisplayTexture> texture, float scale = 1.0f);
|
||||
@ -256,6 +260,8 @@ protected:
|
||||
ALWAYS_INLINE bool HasSoftwareCursor() const { return static_cast<bool>(m_cursor_texture); }
|
||||
ALWAYS_INLINE bool HasDisplayTexture() const { return (m_display_texture_handle != nullptr); }
|
||||
|
||||
bool IsUsingLinearFiltering() const;
|
||||
|
||||
void CalculateDrawRect(s32 window_width, s32 window_height, float* out_left, float* out_top, float* out_width,
|
||||
float* out_height, float* out_left_padding, float* out_top_padding, float* out_scale,
|
||||
float* out_x_scale, bool apply_aspect_ratio = true) const;
|
||||
@ -294,10 +300,8 @@ protected:
|
||||
std::unique_ptr<HostDisplayTexture> m_cursor_texture;
|
||||
float m_cursor_texture_scale = 1.0f;
|
||||
|
||||
bool m_display_linear_filtering = false;
|
||||
bool m_display_changed = false;
|
||||
bool m_display_integer_scaling = false;
|
||||
bool m_display_stretch = false;
|
||||
bool m_gpu_timing_enabled = false;
|
||||
};
|
||||
|
||||
/// Returns a pointer to the current host display abstraction. Assumes AcquireHostDisplay() has been caled.
|
||||
|
||||
@ -255,6 +255,7 @@ void Settings::Load(SettingsInterface& si)
|
||||
display_show_speed = si.GetBoolValue("Display", "ShowSpeed", false);
|
||||
display_show_resolution = si.GetBoolValue("Display", "ShowResolution", false);
|
||||
display_show_cpu = si.GetBoolValue("Display", "ShowCPU", false);
|
||||
display_show_gpu = si.GetBoolValue("Display", "ShowGPU", false);
|
||||
display_show_status_indicators = si.GetBoolValue("Display", "ShowStatusIndicators", true);
|
||||
display_show_inputs = si.GetBoolValue("Display", "ShowInputs", false);
|
||||
display_show_enhancements = si.GetBoolValue("Display", "ShowEnhancements", false);
|
||||
@ -459,6 +460,7 @@ void Settings::Save(SettingsInterface& si) const
|
||||
si.SetBoolValue("Display", "ShowSpeed", display_show_speed);
|
||||
si.SetBoolValue("Display", "ShowResolution", display_show_resolution);
|
||||
si.SetBoolValue("Display", "ShowCPU", display_show_cpu);
|
||||
si.SetBoolValue("Display", "ShowGPU", display_show_gpu);
|
||||
si.SetBoolValue("Display", "ShowStatusIndicators", display_show_status_indicators);
|
||||
si.SetBoolValue("Display", "ShowInputs", display_show_inputs);
|
||||
si.SetBoolValue("Display", "ShowEnhancements", display_show_enhancements);
|
||||
|
||||
@ -129,6 +129,7 @@ struct Settings
|
||||
bool display_show_speed = false;
|
||||
bool display_show_resolution = false;
|
||||
bool display_show_cpu = false;
|
||||
bool display_show_gpu = false;
|
||||
bool display_show_status_indicators = true;
|
||||
bool display_show_inputs = false;
|
||||
bool display_show_enhancements = false;
|
||||
|
||||
@ -162,11 +162,15 @@ static float s_cpu_thread_usage = 0.0f;
|
||||
static float s_cpu_thread_time = 0.0f;
|
||||
static float s_sw_thread_usage = 0.0f;
|
||||
static float s_sw_thread_time = 0.0f;
|
||||
static float s_average_gpu_time = 0.0f;
|
||||
static float s_accumulated_gpu_time = 0.0f;
|
||||
static float s_gpu_usage = 0.0f;
|
||||
static u32 s_last_frame_number = 0;
|
||||
static u32 s_last_internal_frame_number = 0;
|
||||
static u32 s_last_global_tick_counter = 0;
|
||||
static u64 s_last_cpu_time = 0;
|
||||
static u64 s_last_sw_time = 0;
|
||||
static u32 s_presents_since_last_update = 0;
|
||||
static Common::Timer s_fps_timer;
|
||||
static Common::Timer s_frame_timer;
|
||||
static Threading::ThreadHandle s_cpu_thread_handle;
|
||||
@ -350,6 +354,14 @@ float System::GetSWThreadAverageTime()
|
||||
{
|
||||
return s_sw_thread_time;
|
||||
}
|
||||
float System::GetGPUUsage()
|
||||
{
|
||||
return s_gpu_usage;
|
||||
}
|
||||
float System::GetGPUAverageTime()
|
||||
{
|
||||
return s_average_gpu_time;
|
||||
}
|
||||
|
||||
bool System::IsExeFileName(const std::string_view& path)
|
||||
{
|
||||
@ -1257,9 +1269,13 @@ bool System::Initialize(bool force_software_renderer)
|
||||
s_cpu_thread_time = 0.0f;
|
||||
s_sw_thread_usage = 0.0f;
|
||||
s_sw_thread_time = 0.0f;
|
||||
s_average_gpu_time = 0.0f;
|
||||
s_accumulated_gpu_time = 0.0f;
|
||||
s_gpu_usage = 0.0f;
|
||||
s_last_frame_number = 0;
|
||||
s_last_internal_frame_number = 0;
|
||||
s_last_global_tick_counter = 0;
|
||||
s_presents_since_last_update = 0;
|
||||
s_last_cpu_time = 0;
|
||||
s_fps_timer.Reset();
|
||||
s_frame_timer.Reset();
|
||||
@ -1427,7 +1443,13 @@ void System::Execute()
|
||||
PauseSystem(true);
|
||||
}
|
||||
|
||||
Host::RenderDisplay(g_host_display->ShouldSkipDisplayingFrame());
|
||||
const bool skip_present = g_host_display->ShouldSkipDisplayingFrame();
|
||||
Host::RenderDisplay(skip_present);
|
||||
if (!skip_present && g_host_display->IsGPUTimingEnabled())
|
||||
{
|
||||
s_accumulated_gpu_time += g_host_display->GetAndResetAccumulatedGPUTime();
|
||||
s_presents_since_last_update++;
|
||||
}
|
||||
|
||||
System::UpdatePerformanceCounters();
|
||||
|
||||
@ -2125,7 +2147,7 @@ void System::UpdatePerformanceCounters()
|
||||
if (time < 1.0f)
|
||||
return;
|
||||
|
||||
const float frames_presented = static_cast<float>(s_frame_number - s_last_frame_number);
|
||||
const float frames_run = static_cast<float>(s_frame_number - s_last_frame_number);
|
||||
const u32 global_tick_counter = TimingEvents::GetGlobalTickCounter();
|
||||
|
||||
// TODO: Make the math here less rubbish
|
||||
@ -2133,13 +2155,13 @@ void System::UpdatePerformanceCounters()
|
||||
100.0 * (1.0 / ((static_cast<double>(ticks_diff) * static_cast<double>(Threading::GetThreadTicksPerSecond())) /
|
||||
Common::Timer::GetFrequency() / 1000000000.0));
|
||||
const double time_divider = 1000.0 * (1.0 / static_cast<double>(Threading::GetThreadTicksPerSecond())) *
|
||||
(1.0 / static_cast<double>(frames_presented));
|
||||
(1.0 / static_cast<double>(frames_run));
|
||||
|
||||
s_worst_frame_time = s_worst_frame_time_accumulator;
|
||||
s_worst_frame_time_accumulator = 0.0f;
|
||||
s_average_frame_time = s_average_frame_time_accumulator / frames_presented;
|
||||
s_average_frame_time = s_average_frame_time_accumulator / frames_run;
|
||||
s_average_frame_time_accumulator = 0.0f;
|
||||
s_vps = static_cast<float>(frames_presented / time);
|
||||
s_vps = static_cast<float>(frames_run / time);
|
||||
s_last_frame_number = s_frame_number;
|
||||
s_fps = static_cast<float>(s_internal_frame_number - s_last_internal_frame_number) / time;
|
||||
s_last_internal_frame_number = s_internal_frame_number;
|
||||
@ -2163,8 +2185,16 @@ void System::UpdatePerformanceCounters()
|
||||
|
||||
s_fps_timer.ResetTo(now_ticks);
|
||||
|
||||
Log_VerbosePrintf("FPS: %.2f VPS: %.2f CPU: %.2f Average: %.2fms Worst: %.2fms", s_fps, s_vps, s_cpu_thread_usage,
|
||||
s_average_frame_time, s_worst_frame_time);
|
||||
if (g_host_display->IsGPUTimingEnabled())
|
||||
{
|
||||
s_average_gpu_time = s_accumulated_gpu_time / static_cast<float>(std::max(s_presents_since_last_update, 1u));
|
||||
s_gpu_usage = s_accumulated_gpu_time / (time * 10.0f);
|
||||
}
|
||||
s_accumulated_gpu_time = 0.0f;
|
||||
s_presents_since_last_update = 0;
|
||||
|
||||
Log_VerbosePrintf("FPS: %.2f VPS: %.2f CPU: %.2f GPU: %.2f Average: %.2fms Worst: %.2fms", s_fps, s_vps,
|
||||
s_cpu_thread_usage, s_gpu_usage, s_average_frame_time, s_worst_frame_time);
|
||||
|
||||
Host::OnPerformanceCountersUpdated();
|
||||
}
|
||||
@ -3123,10 +3153,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
||||
g_settings.display_line_start_offset != old_settings.display_line_start_offset ||
|
||||
g_settings.display_line_end_offset != old_settings.display_line_end_offset ||
|
||||
g_settings.rewind_enable != old_settings.rewind_enable ||
|
||||
g_settings.runahead_frames != old_settings.runahead_frames ||
|
||||
g_settings.display_linear_filtering != old_settings.display_linear_filtering ||
|
||||
g_settings.display_integer_scaling != old_settings.display_integer_scaling ||
|
||||
g_settings.display_stretch != old_settings.display_stretch)
|
||||
g_settings.runahead_frames != old_settings.runahead_frames)
|
||||
{
|
||||
g_gpu->UpdateSettings();
|
||||
Host::InvalidateDisplay();
|
||||
|
||||
@ -181,6 +181,8 @@ float GetCPUThreadUsage();
|
||||
float GetCPUThreadAverageTime();
|
||||
float GetSWThreadUsage();
|
||||
float GetSWThreadAverageTime();
|
||||
float GetGPUUsage();
|
||||
float GetGPUAverageTime();
|
||||
|
||||
/// Loads global settings (i.e. EmuConfig).
|
||||
void LoadSettings(bool display_osd_messages);
|
||||
|
||||
Reference in New Issue
Block a user