Skip debug stepping time in list/func time.

Just makes the debug stats actually useful while stepping.  A bit of
overengineering, but it makes it easy to go frame-by-frame looking for
perf issues.
This commit is contained in:
Unknown W. Brackets 2014-06-14 08:42:18 -07:00
parent 5f6c083a3e
commit 03f86f364f
6 changed files with 78 additions and 37 deletions

View File

@ -510,6 +510,12 @@ void *GetQuickSyscallFunc(MIPSOpcode op)
return (void *)&CallSyscallWithoutFlags;
}
static double hleSteppingTime = 0.0;
void hleSetSteppingTime(double t)
{
hleSteppingTime += t;
}
void CallSyscall(MIPSOpcode op)
{
double start = 0.0; // need to initialize to fix the race condition where g_Config.bShowDebugStats is enabled in the middle of this func.
@ -540,6 +546,8 @@ void CallSyscall(MIPSOpcode op)
u32 callno = (op >> 6) & 0xFFFFF; //20 bits
int funcnum = callno & 0xFFF;
int modulenum = (callno & 0xFF000) >> 12;
updateSyscallStats(modulenum, funcnum, time_now_d() - start);
double total = time_now_d() - start - hleSteppingTime;
hleSteppingTime = 0.0;
updateSyscallStats(modulenum, funcnum, total);
}
}

View File

@ -91,6 +91,8 @@ void hleRunInterrupts();
void hleDebugBreak();
// Don't set temp regs to 0xDEADBEEF.
void hleSkipDeadbeef();
// Set time spent in debugger (for more useful debug stats while debugging.)
void hleSetSteppingTime(double t);
// Delays the result for usec microseconds, allowing other threads to run during this time.
u32 hleDelayResult(u32 result, const char *reason, int usec);

View File

@ -200,6 +200,10 @@ public:
virtual GPUDebugOp DissassembleOp(u32 pc, u32 op) = 0;
virtual std::vector<GPUDebugOp> DissassembleOpRange(u32 startpc, u32 endpc) = 0;
// Enter/exit stepping mode. Mainly for better debug stats on time taken.
virtual void NotifySteppingEnter() = 0;
virtual void NotifySteppingExit() = 0;
virtual u32 GetRelativeAddress(u32 data) = 0;
virtual u32 GetVertexAddress() = 0;
virtual u32 GetIndexAddress() = 0;

View File

@ -118,6 +118,8 @@ bool EnterStepping(std::function<void()> callback) {
return false;
}
gpuDebug->NotifySteppingEnter();
// Just to be sure.
if (pauseAction == PAUSE_CONTINUE) {
pauseAction = PAUSE_BREAK;
@ -131,6 +133,7 @@ bool EnterStepping(std::function<void()> callback) {
pauseWait.wait(pauseLock);
} while (pauseAction != PAUSE_CONTINUE);
gpuDebug->NotifySteppingExit();
isStepping = false;
return true;
}

View File

@ -10,6 +10,7 @@
#include "Core/MemMap.h"
#include "Core/Host.h"
#include "Core/Reporting.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/HLE/sceKernelThread.h"
@ -36,6 +37,7 @@ void GPUCommon::Reinitialize() {
isbreak = false;
drawCompleteTicks = 0;
busyTicks = 0;
timeSpentStepping_ = 0.0;
interruptsEnabled_ = true;
UpdateTickEstimate(0);
}
@ -446,6 +448,23 @@ u32 GPUCommon::Break(int mode) {
return currentList->id;
}
void GPUCommon::NotifySteppingEnter() {
if (g_Config.bShowDebugStats) {
time_update();
timeSteppingStarted_ = time_now_d();
}
}
void GPUCommon::NotifySteppingExit() {
if (g_Config.bShowDebugStats) {
if (timeSteppingStarted_ <= 0.0) {
ERROR_LOG(G3D, "Mismatched stepping enter/exit.");
}
time_update();
timeSpentStepping_ += time_now_d() - timeSteppingStarted_;
timeSteppingStarted_ = 0.0;
}
}
bool GPUCommon::InterpretList(DisplayList &list) {
// Initialized to avoid a race condition with bShowDebugStats changing.
double start = 0.0;
@ -518,7 +537,10 @@ bool GPUCommon::InterpretList(DisplayList &list) {
if (g_Config.bShowDebugStats) {
time_update();
gpuStats.msProcessingDisplayLists += time_now_d() - start;
double total = time_now_d() - start - timeSpentStepping_;
hleSetSteppingTime(timeSpentStepping_);
timeSpentStepping_ = 0.0;
gpuStats.msProcessingDisplayLists += total;
}
return gpuState == GPUSTATE_DONE || gpuState == GPUSTATE_ERROR;
}

View File

@ -85,6 +85,40 @@ public:
return false;
}
// From GPUDebugInterface.
virtual bool GetCurrentDisplayList(DisplayList &list);
virtual std::vector<DisplayList> ActiveDisplayLists();
virtual void ResetListPC(int listID, u32 pc);
virtual void ResetListStall(int listID, u32 stall);
virtual void ResetListState(int listID, DisplayListState state);
virtual GPUDebugOp DissassembleOp(u32 pc, u32 op);
virtual std::vector<GPUDebugOp> DissassembleOpRange(u32 startpc, u32 endpc);
virtual void NotifySteppingEnter();
virtual void NotifySteppingExit();
virtual u32 GetRelativeAddress(u32 data);
virtual u32 GetVertexAddress();
virtual u32 GetIndexAddress();
virtual GPUgstate GetGState();
virtual void SetCmdValue(u32 op);
virtual DisplayList* getList(int listid) {
return &dls[listid];
}
const std::list<int>& GetDisplayLists() {
return dlQueue;
}
virtual bool DecodeTexture(u8* dest, GPUgstate state) {
return false;
}
std::vector<FramebufferInfo> GetFramebufferList() {
return std::vector<FramebufferInfo>();
}
virtual void ClearShaderCache() {}
protected:
// To avoid virtual calls to PreExecuteOp().
virtual void FastRunLoop(DisplayList &list) = 0;
@ -162,39 +196,7 @@ private:
#endif
}
public:
// From GPUDebugInterface.
virtual bool GetCurrentDisplayList(DisplayList &list);
virtual std::vector<DisplayList> ActiveDisplayLists();
virtual void ResetListPC(int listID, u32 pc);
virtual void ResetListStall(int listID, u32 stall);
virtual void ResetListState(int listID, DisplayListState state);
virtual GPUDebugOp DissassembleOp(u32 pc, u32 op);
virtual std::vector<GPUDebugOp> DissassembleOpRange(u32 startpc, u32 endpc);
virtual u32 GetRelativeAddress(u32 data);
virtual u32 GetVertexAddress();
virtual u32 GetIndexAddress();
virtual GPUgstate GetGState();
virtual void SetCmdValue(u32 op);
virtual DisplayList* getList(int listid)
{
return &dls[listid];
}
const std::list<int>& GetDisplayLists()
{
return dlQueue;
}
virtual bool DecodeTexture(u8* dest, GPUgstate state)
{
return false;
}
std::vector<FramebufferInfo> GetFramebufferList()
{
return std::vector<FramebufferInfo>();
}
virtual void ClearShaderCache() {}
// Debug stats.
double timeSteppingStarted_;
double timeSpentStepping_;
};