Skip to content

Commit

Permalink
[WIP] Performance Overlay
Browse files Browse the repository at this point in the history
  • Loading branch information
VelocityRa committed May 20, 2018
1 parent e1c9d8c commit 67f662e
Show file tree
Hide file tree
Showing 13 changed files with 593 additions and 58 deletions.
135 changes: 135 additions & 0 deletions Utilities/CPUStats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#pragma once

#include <Utilities/types.h>

#ifdef _WIN32
#include "windows.h"
#include "tlhelp32.h"
#else
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "sys/times.h"
#include "sys/vtimes.h"
#endif

class CPUStats
{
#ifdef _WIN32
HANDLE m_self;
using time_type = ULARGE_INTEGER;
#else
using time_type = clock_t;
#endif

private:
s32 m_num_processors;
time_type m_last_cpu, m_sys_cpu, m_usr_cpu;

public:
CPUStats()
{
#ifdef _WIN32
SYSTEM_INFO sysInfo;
FILETIME ftime, fsys, fuser;

GetSystemInfo(&sysInfo);
m_num_processors = sysInfo.dwNumberOfProcessors;

GetSystemTimeAsFileTime(&ftime);
memcpy(&m_last_cpu, &ftime, sizeof(FILETIME));

m_self = GetCurrentProcess();
GetProcessTimes(m_self, &ftime, &ftime, &fsys, &fuser);
memcpy(&m_sys_cpu, &fsys, sizeof(FILETIME));
memcpy(&m_usr_cpu, &fuser, sizeof(FILETIME));
#else
FILE* file;
struct tms timeSample;
char line[128];

m_last_cpu = times(&timeSample);
m_sys_cpu = timeSample.tms_stime;
m_usr_cpu = timeSample.tms_utime;

file = fopen("/proc/cpuinfo", "r");
m_num_processors = 0;
while (fgets(line, 128, file) != NULL)
{
if (strncmp(line, "processor", 9) == 0) m_num_processors++;
}
fclose(file);
#endif
}

double get_usage()
{
#if _WIN32
FILETIME ftime, fsys, fusr;
ULARGE_INTEGER now, sys, usr;

GetSystemTimeAsFileTime(&ftime);
memcpy(&now, &ftime, sizeof(FILETIME));

GetProcessTimes(m_self, &ftime, &ftime, &fsys, &fusr);
memcpy(&sys, &fsys, sizeof(FILETIME));
memcpy(&usr, &fusr, sizeof(FILETIME));
double percent = (sys.QuadPart - m_sys_cpu.QuadPart) + (usr.QuadPart - m_usr_cpu.QuadPart);
percent /= (now.QuadPart - m_last_cpu.QuadPart);
percent /= m_num_processors;

m_last_cpu = now;
m_usr_cpu = usr;
m_sys_cpu = sys;

return std::clamp(percent * 100, 0.0, 100.0);
#else
struct tms timeSample;
clock_t now;
double percent;

now = times(&timeSample);
if (now <= m_last_cpu || timeSample.tms_stime < m_sys_cpu || timeSample.tms_utime < m_usr_cpu)
{
// Overflow detection. Just skip this value.
percent = -1.0;
}
else
{
percent = (timeSample.tms_stime - m_sys_cpu) + (timeSample.tms_utime - m_usr_cpu);
percent /= (now - m_last_cpu);
percent /= m_num_processors;
percent *= 100;
}
m_last_cpu = now;
m_sys_cpu = timeSample.tms_stime;
m_usr_cpu = timeSample.tms_utime;

return percent;
#endif
}

static u32 get_thread_count()
{
#ifdef _WIN32
// first determine the id of the current process
DWORD const id = GetCurrentProcessId();

// then get a process list snapshot.
HANDLE const snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);

// initialize the process entry structure.
PROCESSENTRY32 entry = {0};
entry.dwSize = sizeof(entry);

// get the first process info.
BOOL ret = true;
ret = Process32First(snapshot, &entry);
while (ret && entry.th32ProcessID != id) { ret = Process32Next(snapshot, &entry); }
CloseHandle(snapshot);
return ret ? entry.cntThreads : -1;
#else
// TODO
#endif
}
};
29 changes: 28 additions & 1 deletion Utilities/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#endif

#include "sync.h"
#include "CPUStats.h"

thread_local u64 g_tls_fault_all = 0;
thread_local u64 g_tls_fault_rsx = 0;
Expand Down Expand Up @@ -1271,7 +1272,8 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
be_t<u64> data3 = vm::check_addr(addr, a_size, vm::page_readable) ? SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY : SYS_MEMORY_PAGE_FAULT_CAUSE_NON_MAPPED;

LOG_ERROR(MEMORY, "Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
addr, data3 == SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY ? "writing read-only" : "using unmapped");
addr, data3 == SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY ? "writing read-only" : "using unmapped")
;

error_code sending_error = sys_event_port_send(entry.port_id, data1, data2, data3);

Expand Down Expand Up @@ -1851,6 +1853,31 @@ void thread_ctrl::notify()
}
}

u64 thread_ctrl::get_cycles()
{
#ifdef _WIN32
u64 cycles;
if (QueryThreadCycleTime((HANDLE)m_thread.load(), &cycles)) {
// Report 0 the first time this function is called
if (m_cycles == 0)
{
m_cycles = cycles;
return 0;
}

const auto diff_cycles = cycles - m_cycles;
m_cycles = cycles;
return diff_cycles;
}
else
{
return m_cycles;
}
#else
// TODO:
#endif
}

void thread_ctrl::test()
{
const auto _this = g_tls_this_thread;
Expand Down
12 changes: 12 additions & 0 deletions Utilities/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ class thread_ctrl final
// Fixed name
std::string m_name;

// CPU cycles thread has run for
u64 m_cycles;

// Start thread
static void start(const std::shared_ptr<thread_ctrl>&, task_stack);

Expand Down Expand Up @@ -172,6 +175,15 @@ class thread_ctrl final
return m_name;
}

// Get CPU cycles since last time this function was called. First call returns 0.
u64 get_cycles();

// Get platform-specific thread handle
std::uintptr_t get_native_handle() const
{
return m_thread.load();
}

// Get exception
std::exception_ptr get_exception() const;

Expand Down
21 changes: 21 additions & 0 deletions rpcs3/Emu/RSX/GL/GLGSRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#include "../rsx_methods.h"
#include "../Common/BufferUtils.h"
#include "../rsx_utils.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/RawSPUThread.h"

#define DUMP_VERTEX_DATA 0

Expand Down Expand Up @@ -877,6 +880,15 @@ void GLGSRender::on_init_thread()

m_frame->enable_wm_event_queue();
m_shaders_cache->load(&helper);

if (g_cfg.video.perf_overlay.perf_overlay_enabled)
{
m_perf_overlay = std::make_unique<rsx::overlays::perf_metrics_overlay>(false);
m_perf_overlay->set_detail_level(g_cfg.video.perf_overlay.level);
m_perf_overlay->set_update_interval(g_cfg.video.perf_overlay.update_interval);
m_perf_overlay->set_font_size(g_cfg.video.perf_overlay.font_size);
m_perf_overlay->init();
}
}
}

Expand Down Expand Up @@ -1461,6 +1473,15 @@ void GLGSRender::flip(int buffer)
}
}

if (m_perf_overlay)
{
m_perf_overlay->update();

gl::screen.bind();
glViewport(0, 0, m_frame->client_width(), m_frame->client_height());
m_ui_renderer.run(m_frame->client_width(), m_frame->client_height(), 0, *m_perf_overlay.get());
}

if (m_custom_ui)
{
gl::screen.bind();
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/GL/GLOverlays.h
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ namespace gl
}
}

void run(u16 w, u16 h, GLuint target, rsx::overlays::user_interface& ui)
void run(u16 w, u16 h, GLuint target, rsx::overlays::overlay& ui)
{
program_handle.uniforms["ui_scale"] = color4f((f32)ui.virtual_width, (f32)ui.virtual_height, 1.f, 1.f);
program_handle.uniforms["time"] = (f32)(get_system_time() / 1000) * 0.005f;
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/RSXThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2391,7 +2391,7 @@ namespace rsx
rsx::overlays::user_interface* thread::shell_get_current_dialog()
{
//TODO: Only get dialog type interfaces
return m_custom_ui.get();
return static_cast<rsx::overlays::user_interface*>(m_custom_ui.get());
}

bool thread::shell_close_dialog()
Expand Down
6 changes: 4 additions & 2 deletions rpcs3/Emu/RSX/RSXThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,10 @@ namespace rsx
rsx::gcm_framebuffer_info m_depth_surface_info;
bool framebuffer_status_valid = false;

std::unique_ptr<rsx::overlays::user_interface> m_custom_ui;
std::unique_ptr<rsx::overlays::user_interface> m_invalidated_ui;
std::unique_ptr<rsx::overlays::perf_metrics_overlay> m_perf_overlay;

std::unique_ptr<rsx::overlays::overlay> m_custom_ui;
std::unique_ptr<rsx::overlays::overlay> m_invalidated_ui;

public:
RsxDmaControl* ctrl = nullptr;
Expand Down
18 changes: 17 additions & 1 deletion rpcs3/Emu/RSX/VK/VKGSRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,15 @@ void VKGSRender::on_init_thread()
m_frame->disable_wm_event_queue();
m_shaders_cache->load(&helper, *m_device, pipeline_layout);
m_frame->enable_wm_event_queue();

if (g_cfg.video.perf_overlay.perf_overlay_enabled)
{
m_perf_overlay = std::make_unique<rsx::overlays::perf_metrics_overlay>(false);
m_perf_overlay->set_detail_level(g_cfg.video.perf_overlay.level);
m_perf_overlay->set_update_interval(g_cfg.video.perf_overlay.update_interval);
m_perf_overlay->set_font_size(g_cfg.video.perf_overlay.font_size);
m_perf_overlay->init();
}
}
}

Expand Down Expand Up @@ -3174,7 +3183,7 @@ void VKGSRender::flip(int buffer)

std::unique_ptr<vk::framebuffer_holder> direct_fbo;
std::vector<std::unique_ptr<vk::image_view>> swap_image_view;
if (g_cfg.video.overlay || m_custom_ui)
if (m_perf_overlay || m_custom_ui || g_cfg.video.overlay)
{
//Change the image layout whilst setting up a dependency on waiting for the blit op to finish before we start writing
VkImageSubresourceRange subres = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
Expand Down Expand Up @@ -3212,6 +3221,13 @@ void VKGSRender::flip(int buffer)
direct_fbo.reset(new vk::framebuffer_holder(*m_device, single_target_pass, m_client_width, m_client_height, std::move(swap_image_view)));
}

if (m_perf_overlay)
{
m_perf_overlay->update();

m_ui_renderer->run(*m_current_command_buffer, direct_fbo->width(), direct_fbo->height(), direct_fbo.get(), single_target_pass, m_texture_upload_buffer_ring_info, *m_perf_overlay);
}

if (m_custom_ui)
{
m_ui_renderer->run(*m_current_command_buffer, direct_fbo->width(), direct_fbo->height(), direct_fbo.get(), single_target_pass, m_texture_upload_buffer_ring_info, *m_custom_ui);
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/VK/VKOverlays.h
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ namespace vk
}

void run(vk::command_buffer &cmd, u16 w, u16 h, vk::framebuffer* target, VkRenderPass render_pass,
vk::vk_data_heap &upload_heap, rsx::overlays::user_interface &ui)
vk::vk_data_heap &upload_heap, rsx::overlays::overlay &ui)
{
m_scale_offset = color4f((f32)ui.virtual_width, (f32)ui.virtual_height, 1.f, 1.f);
m_time = (f32)(get_system_time() / 1000) * 0.005f;
Expand Down
Loading

0 comments on commit 67f662e

Please sign in to comment.