diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 28383ac2bd..d643bff0f1 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -500,7 +500,7 @@ namespace rsx } //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 zcull_ctrl->update(this); @@ -520,6 +520,18 @@ namespace rsx 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 ctrl->get.store(internal_get.load()); @@ -527,30 +539,15 @@ namespace rsx if (put == internal_get || !Emu.IsRunning()) { - if (has_deferred_call) - { - flush_command_queue(); - } - else if (!performance_counters.FIFO_is_idle) + if (!performance_counters.FIFO_is_idle) { performance_counters.FIFO_idle_timestamp = get_system_time(); performance_counters.FIFO_is_idle = true; } - else - { - 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); @@ -580,6 +577,16 @@ namespace rsx if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD) { 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); internal_get = offs; continue; @@ -587,6 +594,16 @@ namespace rsx if ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD) { 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); internal_get = offs; continue; @@ -616,6 +633,12 @@ namespace rsx } 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; continue; } @@ -662,6 +685,13 @@ namespace rsx if (internal_get < put && ((internal_get + (count + 1) * 4) > put)) 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++) { u32 reg = ((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? first_cmd : first_cmd + i;