mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 20:15:27 +00:00
rsx: Basic performance counters
This commit is contained in:
parent
2855869530
commit
84b8a08d26
5 changed files with 80 additions and 21 deletions
|
@ -1370,20 +1370,21 @@ void GLGSRender::flip(int buffer)
|
|||
gl::screen.bind();
|
||||
glViewport(0, 0, m_frame->client_width(), m_frame->client_height());
|
||||
|
||||
m_text_printer.print_text(0, 0, m_frame->client_width(), m_frame->client_height(), "draw calls: " + std::to_string(m_draw_calls));
|
||||
m_text_printer.print_text(0, 18, m_frame->client_width(), m_frame->client_height(), "draw call setup: " + std::to_string(m_begin_time) + "us");
|
||||
m_text_printer.print_text(0, 36, m_frame->client_width(), m_frame->client_height(), "vertex upload time: " + std::to_string(m_vertex_upload_time) + "us");
|
||||
m_text_printer.print_text(0, 54, m_frame->client_width(), m_frame->client_height(), "textures upload time: " + std::to_string(m_textures_upload_time) + "us");
|
||||
m_text_printer.print_text(0, 72, m_frame->client_width(), m_frame->client_height(), "draw call execution: " + std::to_string(m_draw_time) + "us");
|
||||
m_text_printer.print_text(0, 0, m_frame->client_width(), m_frame->client_height(), "RSX Load: " + std::to_string(get_load()) + "%");
|
||||
m_text_printer.print_text(0, 18, m_frame->client_width(), m_frame->client_height(), "draw calls: " + std::to_string(m_draw_calls));
|
||||
m_text_printer.print_text(0, 36, m_frame->client_width(), m_frame->client_height(), "draw call setup: " + std::to_string(m_begin_time) + "us");
|
||||
m_text_printer.print_text(0, 54, m_frame->client_width(), m_frame->client_height(), "vertex upload time: " + std::to_string(m_vertex_upload_time) + "us");
|
||||
m_text_printer.print_text(0, 72, m_frame->client_width(), m_frame->client_height(), "textures upload time: " + std::to_string(m_textures_upload_time) + "us");
|
||||
m_text_printer.print_text(0, 90, m_frame->client_width(), m_frame->client_height(), "draw call execution: " + std::to_string(m_draw_time) + "us");
|
||||
|
||||
const auto num_dirty_textures = m_gl_texture_cache.get_unreleased_textures_count();
|
||||
const auto texture_memory_size = m_gl_texture_cache.get_texture_memory_in_use() / (1024 * 1024);
|
||||
const auto num_flushes = m_gl_texture_cache.get_num_flush_requests();
|
||||
const auto num_mispredict = m_gl_texture_cache.get_num_cache_mispredictions();
|
||||
const auto cache_miss_ratio = (u32)ceil(m_gl_texture_cache.get_cache_miss_ratio() * 100);
|
||||
m_text_printer.print_text(0, 108, m_frame->client_width(), m_frame->client_height(), "Unreleased textures: " + std::to_string(num_dirty_textures));
|
||||
m_text_printer.print_text(0, 126, m_frame->client_width(), m_frame->client_height(), "Texture memory: " + std::to_string(texture_memory_size) + "M");
|
||||
m_text_printer.print_text(0, 144, m_frame->client_width(), m_frame->client_height(), fmt::format("Flush requests: %d (%d%% hard faults, %d mispedictions)", num_flushes, cache_miss_ratio, num_mispredict));
|
||||
m_text_printer.print_text(0, 126, m_frame->client_width(), m_frame->client_height(), "Unreleased textures: " + std::to_string(num_dirty_textures));
|
||||
m_text_printer.print_text(0, 144, m_frame->client_width(), m_frame->client_height(), "Texture memory: " + std::to_string(texture_memory_size) + "M");
|
||||
m_text_printer.print_text(0, 162, m_frame->client_width(), m_frame->client_height(), fmt::format("Flush requests: %d (%d%% hard faults, %d mispedictions)", num_flushes, cache_miss_ratio, num_mispredict));
|
||||
}
|
||||
|
||||
m_frame->flip(m_context);
|
||||
|
|
|
@ -527,12 +527,26 @@ namespace rsx
|
|||
if (put == internal_get || !Emu.IsRunning())
|
||||
{
|
||||
if (has_deferred_call)
|
||||
{
|
||||
flush_command_queue();
|
||||
}
|
||||
else if (!performance_counters.FIFO_is_idle)
|
||||
{
|
||||
performance_counters.FIFO_idle_timestamp = get_system_time();
|
||||
performance_counters.FIFO_is_idle = true;
|
||||
}
|
||||
|
||||
do_internal_task();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (performance_counters.FIFO_is_idle)
|
||||
{
|
||||
//Update performance counters with time spent in idle mode
|
||||
performance_counters.FIFO_is_idle = false;
|
||||
performance_counters.idle_time += (get_system_time() - performance_counters.FIFO_idle_timestamp);
|
||||
}
|
||||
|
||||
//Validate put and get registers
|
||||
//TODO: Who should handle graphics exceptions??
|
||||
const u32 get_address = RSXIOMem.RealAddr(internal_get);
|
||||
|
@ -2027,6 +2041,8 @@ namespace rsx
|
|||
|
||||
skip_frame = (m_skip_frame_ctr < 0);
|
||||
}
|
||||
|
||||
performance_counters.sampled_frames++;
|
||||
}
|
||||
|
||||
void thread::check_zcull_status(bool framebuffer_swap, bool force_read)
|
||||
|
@ -2223,6 +2239,28 @@ namespace rsx
|
|||
external_interrupt_lock.store(false);
|
||||
}
|
||||
|
||||
u32 thread::get_load()
|
||||
{
|
||||
//Average load over around 30 frames
|
||||
if (!performance_counters.last_update_timestamp || performance_counters.sampled_frames > 30)
|
||||
{
|
||||
const auto timestamp = get_system_time();
|
||||
const auto idle = performance_counters.idle_time.load();
|
||||
const auto elapsed = timestamp - performance_counters.last_update_timestamp;
|
||||
|
||||
if (elapsed > idle)
|
||||
performance_counters.approximate_load = (elapsed - idle) * 100 / elapsed;
|
||||
else
|
||||
performance_counters.approximate_load = 0;
|
||||
|
||||
performance_counters.idle_time = 0;
|
||||
performance_counters.sampled_frames = 0;
|
||||
performance_counters.last_update_timestamp = timestamp;
|
||||
}
|
||||
|
||||
return performance_counters.approximate_load;
|
||||
}
|
||||
|
||||
//TODO: Move these helpers into a better class dedicated to shell interface handling (use idm?)
|
||||
//They are not dependent on rsx at all
|
||||
rsx::overlays::save_dialog* thread::shell_open_save_dialog()
|
||||
|
|
|
@ -257,6 +257,18 @@ namespace rsx
|
|||
atomic_t<bool> external_interrupt_lock{ false };
|
||||
atomic_t<bool> external_interrupt_ack{ false };
|
||||
|
||||
//performance approximation counters
|
||||
struct
|
||||
{
|
||||
atomic_t<u64> idle_time{ 0 }; //Time spent idling in microseconds
|
||||
u64 last_update_timestamp = 0; //Timestamp of last load update
|
||||
u64 FIFO_idle_timestamp = 0; //Timestamp of when FIFO queue becomes idle
|
||||
bool FIFO_is_idle = false; //True if FIFO is in idle state
|
||||
u32 approximate_load = 0;
|
||||
u32 sampled_frames = 0;
|
||||
}
|
||||
performance_counters;
|
||||
|
||||
//native UI interrupts
|
||||
atomic_t<bool> native_ui_flip_request{ false };
|
||||
|
||||
|
@ -510,6 +522,9 @@ namespace rsx
|
|||
void pause();
|
||||
void unpause();
|
||||
|
||||
//Get RSX approximate load in %
|
||||
u32 get_load();
|
||||
|
||||
//HLE vsh stuff
|
||||
//TODO: Move into a separate helper
|
||||
virtual rsx::overlays::save_dialog* shell_open_save_dialog();
|
||||
|
|
|
@ -3106,12 +3106,13 @@ void VKGSRender::flip(int buffer)
|
|||
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 0, direct_fbo->width(), direct_fbo->height(), "draw calls: " + std::to_string(m_draw_calls));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 18, direct_fbo->width(), direct_fbo->height(), "draw call setup: " + std::to_string(m_setup_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 36, direct_fbo->width(), direct_fbo->height(), "vertex upload time: " + std::to_string(m_vertex_upload_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 54, direct_fbo->width(), direct_fbo->height(), "texture upload time: " + std::to_string(m_textures_upload_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 72, direct_fbo->width(), direct_fbo->height(), "draw call execution: " + std::to_string(m_draw_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 90, direct_fbo->width(), direct_fbo->height(), "submit and flip: " + std::to_string(m_flip_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 0, direct_fbo->width(), direct_fbo->height(), "RSX Load: " + std::to_string(get_load()) + "%");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 18, direct_fbo->width(), direct_fbo->height(), "draw calls: " + std::to_string(m_draw_calls));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 36, direct_fbo->width(), direct_fbo->height(), "draw call setup: " + std::to_string(m_setup_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 54, direct_fbo->width(), direct_fbo->height(), "vertex upload time: " + std::to_string(m_vertex_upload_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 72, direct_fbo->width(), direct_fbo->height(), "texture upload time: " + std::to_string(m_textures_upload_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 90, direct_fbo->width(), direct_fbo->height(), "draw call execution: " + std::to_string(m_draw_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 108, direct_fbo->width(), direct_fbo->height(), "submit and flip: " + std::to_string(m_flip_time) + "us");
|
||||
|
||||
const auto num_dirty_textures = m_texture_cache.get_unreleased_textures_count();
|
||||
const auto texture_memory_size = m_texture_cache.get_texture_memory_in_use() / (1024 * 1024);
|
||||
|
@ -3119,10 +3120,10 @@ void VKGSRender::flip(int buffer)
|
|||
const auto num_flushes = m_texture_cache.get_num_flush_requests();
|
||||
const auto num_mispredict = m_texture_cache.get_num_cache_mispredictions();
|
||||
const auto cache_miss_ratio = (u32)ceil(m_texture_cache.get_cache_miss_ratio() * 100);
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 126, direct_fbo->width(), direct_fbo->height(), "Unreleased textures: " + std::to_string(num_dirty_textures));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 144, direct_fbo->width(), direct_fbo->height(), "Texture cache memory: " + std::to_string(texture_memory_size) + "M");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 162, direct_fbo->width(), direct_fbo->height(), "Temporary texture memory: " + std::to_string(tmp_texture_memory_size) + "M");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 180, direct_fbo->width(), direct_fbo->height(), fmt::format("Flush requests: %d (%d%% hard faults, %d mispedictions)", num_flushes, cache_miss_ratio, num_mispredict));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 144, direct_fbo->width(), direct_fbo->height(), "Unreleased textures: " + std::to_string(num_dirty_textures));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 162, direct_fbo->width(), direct_fbo->height(), "Texture cache memory: " + std::to_string(texture_memory_size) + "M");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 180, direct_fbo->width(), direct_fbo->height(), "Temporary texture memory: " + std::to_string(tmp_texture_memory_size) + "M");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 198, direct_fbo->width(), direct_fbo->height(), fmt::format("Flush requests: %d (%d%% hard faults, %d mispedictions)", num_flushes, cache_miss_ratio, num_mispredict));
|
||||
}
|
||||
|
||||
vk::change_image_layout(*m_current_command_buffer, target_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, present_layout, subres);
|
||||
|
|
|
@ -71,10 +71,10 @@ namespace rsx
|
|||
{
|
||||
// todo: LLE: why does this one keep hanging? is it vsh system semaphore? whats actually pushing this to the command buffer?!
|
||||
if (addr == 0x40000030)
|
||||
break;
|
||||
return;
|
||||
|
||||
if (Emu.IsStopped())
|
||||
break;
|
||||
return;
|
||||
|
||||
const auto tdr = (s64)g_cfg.video.driver_recovery_timeout;
|
||||
if (tdr == 0)
|
||||
|
@ -106,6 +106,8 @@ namespace rsx
|
|||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
rsx->performance_counters.idle_time += (get_system_time() - start);
|
||||
}
|
||||
|
||||
void semaphore_release(thread* rsx, u32 _reg, u32 arg)
|
||||
|
@ -1024,7 +1026,9 @@ namespace rsx
|
|||
|
||||
if (expected > time + 1000)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{static_cast<s64>(expected - time) / 1000});
|
||||
const auto delay_us = static_cast<s64>(expected - time);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{delay_us / 1000});
|
||||
rsx->performance_counters.idle_time += delay_us;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue