Files
HackerOoT/include/debug/profiler_inline.h
Yanis42 b4e82bc236 format
2024-07-18 02:32:31 +02:00

102 lines
3.4 KiB
C

#ifndef PROFILER_INLINE_H
#define PROFILER_INLINE_H
#include "profiler.h"
#include "../variables.h"
extern void Profiler_RecordEventWithTime(u8 type, OSTime time);
extern void Profiler_RecordEvent(u8 type);
// These are all inline functions because they're only called once. They would
// have just been directly included in the calling code, but this approach lets
// their functionality be separated visually, and lets this get ported to other
// projects more easily.
static inline void Profiler_RSPStart(u32 type, bool isFirstStartOfMainGfxTask){
OSTime t = osGetTime();
u8 eventType;
if(isFirstStartOfMainGfxTask){
activeProfilerState->traceEndTime = t;
{
u32 prevInt = __osDisableInt();
// Atomically swap last and active, and reset the important counter.
ProfilerState* temp = activeProfilerState;
activeProfilerState = lastProfilerState;
lastProfilerState = temp;
activeProfilerState->numEvents = 0;
__osRestoreInt(prevInt);
}
#if ENABLE_F3DEX3
activeProfilerState->f3dex3Version = gLoadedF3DEX3Version;
#endif
activeProfilerState->traceStartTime = t;
osDpSetStatus(DPC_CLR_CLOCK_CTR | DPC_CLR_CMD_CTR | DPC_CLR_PIPE_CTR | DPC_CLR_TMEM_CTR);
eventType = PROFILER_EVENT_TYPE_MAINGFXSTART;
}else if(type == M_AUDTASK){
eventType = PROFILER_EVENT_TYPE_RSPAUDIOSTART;
}else if(type == M_GFXTASK){
eventType = PROFILER_EVENT_TYPE_RSPGFXSTART;
}else{
eventType = PROFILER_EVENT_TYPE_RSPOTHERSTART;
}
activeProfilerState->lastRSPStartTime = t;
Profiler_RecordEventWithTime(eventType, t);
}
static inline void Profiler_RSPDone(u32 type){
u8 eventType;
if (type == M_AUDTASK) {
eventType = PROFILER_EVENT_TYPE_RSPAUDIOEND;
}else if(type == M_GFXTASK){
eventType = PROFILER_EVENT_TYPE_RSPGFXEND;
}else{
eventType = PROFILER_EVENT_TYPE_RSPOTHEREND;
}
Profiler_RecordEvent(eventType);
}
static inline void Profiler_RSPDoneNotYield(u32 flags){
if((flags & OS_SC_NEEDS_RDP)){
// This is the main graphics task, and it's done with the RSP
Profiler_RecordEvent(PROFILER_EVENT_TYPE_RSPGFXLASTEND);
#if ENABLE_F3DEX3
// Get F3DEX3 perf counters
F3DEX3YieldDataFooter* footer = (F3DEX3YieldDataFooter*)(
(u8*)gGfxSPTaskYieldBuffer +
OS_YIELD_DATA_SIZE - sizeof(F3DEX3YieldDataFooter));
osInvalDCache(footer, sizeof(F3DEX3YieldDataFooter));
bcopy(footer, &activeProfilerState->footer, sizeof(F3DEX3YieldDataFooter));
#endif
}
}
static inline void Profiler_RDPDone(){
activeProfilerState->rdpTmemCount = IO_READ(DPC_TMEM_REG);
activeProfilerState->rdpPipeCount = IO_READ(DPC_PIPEBUSY_REG);
activeProfilerState->rdpCmdCount = IO_READ(DPC_BUFBUSY_REG);
activeProfilerState->rdpClockCount = IO_READ(DPC_CLOCK_REG);
Profiler_RecordEvent(PROFILER_EVENT_TYPE_RDPEND);
}
static inline void Profiler_TaskAllDone(u32 flags){
if((flags & OS_SC_NEEDS_RDP)){
Profiler_RecordEvent(PROFILER_EVENT_TYPE_MAINGFXEND);
}
}
static inline bool Profiler_GfxIsHung(){
OSTime t = osGetTime();
return OS_CYCLES_TO_USEC(t - activeProfilerState->lastRSPStartTime) > 1000000
|| OS_CYCLES_TO_USEC(t - activeProfilerState->traceStartTime) > 1000000;
}
extern void Profiler_Init();
extern void Profiler_Draw(GraphicsContext* gfxCtx);
extern void Profiler_Destroy();
#endif