rsx: Fix performance counters

- Detect jump-to-self type idling
This commit is contained in:
kd-11 2018-04-16 02:00:18 +03:00 committed by kd-11
parent 91a6091d26
commit c5d1f30e82

View File

@ -500,7 +500,7 @@ namespace rsx
} }
//Execute backend-local tasks first //Execute backend-local tasks first
do_local_task(ctrl->put.load() == internal_get.load()); do_local_task(performance_counters.FIFO_is_idle);
//Update sub-units //Update sub-units
zcull_ctrl->update(this); zcull_ctrl->update(this);
@ -520,6 +520,18 @@ namespace rsx
sync_point_request = false; sync_point_request = false;
} }
else if (performance_counters.FIFO_is_idle)
{
//Registers not updated, do housekeeping since queue is idle
if (has_deferred_call)
{
flush_command_queue();
}
else
{
do_internal_task();
}
}
//Now load the FIFO ctrl registers //Now load the FIFO ctrl registers
ctrl->get.store(internal_get.load()); ctrl->get.store(internal_get.load());
@ -527,30 +539,15 @@ namespace rsx
if (put == internal_get || !Emu.IsRunning()) if (put == internal_get || !Emu.IsRunning())
{ {
if (has_deferred_call) if (!performance_counters.FIFO_is_idle)
{
flush_command_queue();
}
else if (!performance_counters.FIFO_is_idle)
{ {
performance_counters.FIFO_idle_timestamp = get_system_time(); performance_counters.FIFO_idle_timestamp = get_system_time();
performance_counters.FIFO_is_idle = true; performance_counters.FIFO_is_idle = true;
} }
else
{
do_internal_task();
}
continue; 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 //Validate put and get registers
//TODO: Who should handle graphics exceptions?? //TODO: Who should handle graphics exceptions??
const u32 get_address = RSXIOMem.RealAddr(internal_get); const u32 get_address = RSXIOMem.RealAddr(internal_get);
@ -580,6 +577,16 @@ namespace rsx
if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD) if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD)
{ {
u32 offs = cmd & 0x1ffffffc; u32 offs = cmd & 0x1ffffffc;
if (offs == internal_get.load())
{
//Jump to self
if (!performance_counters.FIFO_is_idle)
{
performance_counters.FIFO_idle_timestamp = get_system_time();
performance_counters.FIFO_is_idle = true;
}
}
//LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put);
internal_get = offs; internal_get = offs;
continue; continue;
@ -587,6 +594,16 @@ namespace rsx
if ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD) if ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD)
{ {
u32 offs = cmd & 0xfffffffc; u32 offs = cmd & 0xfffffffc;
if (offs == internal_get.load())
{
//Jump to self
if (!performance_counters.FIFO_is_idle)
{
performance_counters.FIFO_idle_timestamp = get_system_time();
performance_counters.FIFO_is_idle = true;
}
}
//LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put);
internal_get = offs; internal_get = offs;
continue; continue;
@ -616,6 +633,12 @@ namespace rsx
} }
if (cmd == 0) //nop if (cmd == 0) //nop
{ {
if (!performance_counters.FIFO_is_idle)
{
performance_counters.FIFO_idle_timestamp = get_system_time();
performance_counters.FIFO_is_idle = true;
}
internal_get += 4; internal_get += 4;
continue; continue;
} }
@ -662,6 +685,13 @@ namespace rsx
if (internal_get < put && ((internal_get + (count + 1) * 4) > put)) if (internal_get < put && ((internal_get + (count + 1) * 4) > put))
LOG_ERROR(RSX, "Get pointer jumping over put pointer! This is bad!"); LOG_ERROR(RSX, "Get pointer jumping over put pointer! This is bad!");
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);
}
for (u32 i = 0; i < count; i++) for (u32 i = 0; i < count; i++)
{ {
u32 reg = ((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? first_cmd : first_cmd + i; u32 reg = ((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? first_cmd : first_cmd + i;