Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImDebugger: Add a window to inspect upcoming CoreTiming events #19705

Merged
merged 1 commit into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Common/Common.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@
<ClInclude Include="Data\Collections\CharQueue.h" />
<ClInclude Include="Data\Collections\FixedSizeQueue.h" />
<ClInclude Include="Data\Collections\Hashmaps.h" />
<ClInclude Include="Data\Collections\LinkedList.h" />
<ClInclude Include="Data\Collections\Slice.h" />
<ClInclude Include="Data\Collections\ThreadSafeList.h" />
<ClInclude Include="Data\Collections\TinySet.h" />
Expand Down
3 changes: 3 additions & 0 deletions Common/Common.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,9 @@
<ClInclude Include="Data\Collections\CharQueue.h">
<Filter>Data\Collections</Filter>
</ClInclude>
<ClInclude Include="Data\Collections\LinkedList.h">
<Filter>Data\Collections</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ABI.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions Common/Data/Collections/LinkedList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

template <class T>
struct LinkedListItem : public T {
LinkedListItem<T> *next;
};
7 changes: 1 addition & 6 deletions Common/Serialize/Serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,12 @@
#include "Common/CommonTypes.h"
#include "Common/Log.h"
#include "Common/File/Path.h"
#include "Common/Data/Collections/LinkedList.h"

namespace File {
class IOFile;
};

template <class T>
struct LinkedListItem : public T
{
LinkedListItem<T> *next;
};

class PointerWrap;

class PointerWrapSection
Expand Down
24 changes: 9 additions & 15 deletions Core/CoreTiming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,14 @@ int CPU_HZ = 222000000;
#define INITIAL_SLICE_LENGTH 20000
#define MAX_SLICE_LENGTH 100000000

namespace CoreTiming
{

struct EventType {
TimedCallback callback;
const char *name;
};
namespace CoreTiming {

static std::vector<EventType> event_types;
// Only used during restore.
static std::set<int> usedEventTypes;
static std::set<int> restoredEventTypes;
static int nextEventTypeRestoreId = -1;

struct BaseEvent {
s64 time;
u64 userdata;
int type;
};

typedef LinkedListItem<BaseEvent> Event;

Event *first;
Event *eventPool = 0;

Expand Down Expand Up @@ -120,6 +106,14 @@ u64 GetGlobalTimeUs() {
return lastGlobalTimeUs + usSinceLast;
}

const Event *GetFirstEvent() {
return first;
}

const std::vector<EventType> &GetEventTypes() {
return event_types;
}

Event* GetNewEvent()
{
if(!eventPool)
Expand Down
28 changes: 23 additions & 5 deletions Core/CoreTiming.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#pragma once

#include <string>
#include <vector>
#include "Common/CommonTypes.h"
#include "Common/Data/Collections/LinkedList.h"

// This is a system to schedule events into the emulated machine's future. Time is measured
// in main CPU clock cycles.
Expand Down Expand Up @@ -70,21 +72,33 @@ inline s64 cyclesToUs(s64 cycles) {
return (cycles * 1000000) / CPU_HZ;
}

namespace CoreTiming
{
void Init();
void Shutdown();

namespace CoreTiming {
typedef void (*MHzChangeCallback)();
typedef void (*TimedCallback)(u64 userdata, int cyclesLate);

struct EventType {
TimedCallback callback;
const char *name;
};

struct BaseEvent {
s64 time;
u64 userdata;
int type;
};
typedef LinkedListItem<BaseEvent> Event;

void Init();
void Shutdown();

u64 GetTicks();
u64 GetIdleTicks();
u64 GetGlobalTimeUs();
u64 GetGlobalTimeUsScaled();

// Returns the event_type identifier.
int RegisterEvent(const char *name, TimedCallback callback);

// For save states.
void RestoreRegisterEvent(int &event_type, const char *name, TimedCallback callback);
void UnregisterAllEvents();
Expand All @@ -94,6 +108,8 @@ namespace CoreTiming
void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata=0);
s64 UnscheduleEvent(int event_type, u64 userdata);

const std::vector<EventType> &GetEventTypes();
const Event *GetFirstEvent();
void RemoveEvent(int event_type);
bool IsScheduled(int event_type);
void Advance();
Expand All @@ -116,6 +132,8 @@ namespace CoreTiming

void SetClockFrequencyHz(int cpuHz);
int GetClockFrequencyHz();

// TODO: Add accessors?
extern int slicelength;

}; // end of namespace
15 changes: 15 additions & 0 deletions Core/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,3 +779,18 @@ bool CreateSysDirectories() {
}
return true;
}

const char *CoreStateToString(CoreState state) {
switch (state) {
case CORE_RUNNING_CPU: return "RUNNING_CPU";
case CORE_NEXTFRAME: return "NEXTFRAME";
case CORE_STEPPING_CPU: return "STEPPING_CPU";
case CORE_POWERUP: return "POWERUP";
case CORE_POWERDOWN: return "POWERDOWN";
case CORE_BOOT_ERROR: return "BOOT_ERROR";
case CORE_RUNTIME_ERROR: return "RUNTIME_ERROR";
case CORE_STEPPING_GE: return "STEPPING_GE";
case CORE_RUNNING_GE: return "RUNNING_GE";
default: return "N/A";
}
}
2 changes: 2 additions & 0 deletions Core/System.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ enum CoreState {
CORE_RUNNING_GE,
};

const char *CoreStateToString(CoreState state);

extern bool coreCollectDebugStats;

extern volatile CoreState coreState;
Expand Down
21 changes: 21 additions & 0 deletions GPU/Debugger/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ static uint32_t g_skipPcOnce = 0;
static std::vector<std::pair<int, int>> restrictPrimRanges;
static std::string restrictPrimRule;

const char *BreakNextToString(BreakNext next) {
switch (next) {
case BreakNext::NONE: return "NONE,";
case BreakNext::OP: return "OP";
case BreakNext::DRAW: return "DRAW";
case BreakNext::TEX: return "TEX";
case BreakNext::NONTEX: return "NONTEX";
case BreakNext::FRAME: return "FRAME";
case BreakNext::VSYNC: return "VSYNC";
case BreakNext::PRIM: return "PRIM";
case BreakNext::CURVE: return "CURVE";
case BreakNext::COUNT: return "COUNT";
default: return "N/A";
}
}

static void Init() {
if (!inited) {
GPUBreakpoints::Init([](bool flag) {
Expand All @@ -69,6 +85,10 @@ bool IsActive() {
return active;
}

BreakNext GetBreakNext() {
return breakNext;
}

void SetBreakNext(BreakNext next) {
SetActive(true);
breakNext = next;
Expand Down Expand Up @@ -166,6 +186,7 @@ NotifyResult NotifyCommand(u32 pc) {
}

g_skipPcOnce = pc;
breakNext = BreakNext::NONE;
return NotifyResult::Break; // new. caller will call GPUStepping::EnterStepping().
}

Expand Down
2 changes: 2 additions & 0 deletions GPU/Debugger/Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ bool IsActive();

void SetBreakNext(BreakNext next);
void SetBreakCount(int c, bool relative = false);
BreakNext GetBreakNext();
const char *BreakNextToString(BreakNext next);

enum class NotifyResult {
Execute,
Expand Down
37 changes: 36 additions & 1 deletion UI/ImDebugger/ImDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "Core/HLE/sceAudiocodec.h"
#include "Core/HLE/sceMp3.h"
#include "Core/HLE/AtracCtx.h"

#include "Core/CoreTiming.h"
// Threads window
#include "Core/HLE/sceKernelThread.h"

Expand All @@ -41,7 +41,36 @@

extern bool g_TakeScreenshot;

void DrawSchedulerView(ImConfig &cfg) {
ImGui::SetNextWindowSize(ImVec2(420, 300), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("Event Scheduler", &cfg.schedulerOpen)) {
ImGui::End();
return;
}
s64 ticks = CoreTiming::GetTicks();
if (ImGui::BeginChild("event_list", ImVec2(300.0f, 0.0))) {
const CoreTiming::Event *event = CoreTiming::GetFirstEvent();
while (event) {
ImGui::Text("%s (%lld)", CoreTiming::GetEventTypes()[event->type].name, event->time - ticks);
event = event->next;
}
ImGui::EndChild();
}
ImGui::SameLine();
if (ImGui::BeginChild("general")) {
ImGui::Text("CoreState: %s", CoreStateToString(coreState));
ImGui::Text("downcount: %d", currentMIPS->downcount);
ImGui::Text("slicelength: %d", CoreTiming::slicelength);
ImGui::Text("Ticks: %lld", ticks);
ImGui::Text("Clock (MHz): %0.1f", (float)CoreTiming::GetClockFrequencyHz() / 1000000.0f);
ImGui::Text("Global time (us): %lld", CoreTiming::GetGlobalTimeUs());
ImGui::EndChild();
}
ImGui::End();
}

void DrawRegisterView(MIPSDebugInterface *mipsDebug, bool *open) {
ImGui::SetNextWindowSize(ImVec2(320, 600), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("Registers", open)) {
ImGui::End();
return;
Expand Down Expand Up @@ -814,6 +843,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
ImGui::MenuItem("Registers", nullptr, &cfg_.regsOpen);
ImGui::MenuItem("Callstacks", nullptr, &cfg_.callstackOpen);
ImGui::MenuItem("Breakpoints", nullptr, &cfg_.breakpointsOpen);
ImGui::MenuItem("Scheduler", nullptr, &cfg_.schedulerOpen);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("HLE")) {
Expand Down Expand Up @@ -932,6 +962,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
if (cfg_.geStateOpen) {
DrawGeStateWindow(cfg_, gpuDebug);
}

if (cfg_.schedulerOpen) {
DrawSchedulerView(cfg_);
}
}

void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, CoreState coreState) {
Expand Down Expand Up @@ -1155,6 +1189,7 @@ void ImConfig::SyncConfig(IniFile *ini, bool save) {
sync.Sync("debugStatsOpen", &debugStatsOpen, false);
sync.Sync("geDebuggerOpen", &geDebuggerOpen, false);
sync.Sync("geStateOpen", &geStateOpen, false);
sync.Sync("schedulerOpen", &schedulerOpen, false);

sync.SetSection(ini->GetOrCreateSection("Settings"));
sync.Sync("displayLatched", &displayLatched, false);
Expand Down
1 change: 1 addition & 0 deletions UI/ImDebugger/ImDebugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct ImConfig {
bool debugStatsOpen;
bool geDebuggerOpen;
bool geStateOpen;
bool schedulerOpen;

// HLE explorer settings
// bool filterByUsed = true;
Expand Down
14 changes: 14 additions & 0 deletions UI/ImDebugger/ImGe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, GPUDebugInterface *gpuDebug) {
// TODO: This doesn't work correctly.
// GPUDebug::SetBreakNext(GPUDebug::BreakNext::FRAME);
//}

bool disableStepButtons = GPUDebug::GetBreakNext() != GPUDebug::BreakNext::NONE;

if (disableStepButtons) {
ImGui::BeginDisabled();
}
ImGui::SameLine();
if (ImGui::Button("Tex")) {
GPUDebug::SetBreakNext(GPUDebug::BreakNext::TEX);
Expand All @@ -276,6 +282,9 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, GPUDebugInterface *gpuDebug) {
if (ImGui::Button("Single step")) {
GPUDebug::SetBreakNext(GPUDebug::BreakNext::OP);
}
if (disableStepButtons) {
ImGui::EndDisabled();
}

// Line break
if (ImGui::Button("Goto PC")) {
Expand All @@ -290,6 +299,11 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, GPUDebugInterface *gpuDebug) {
ImGui::EndPopup();
}

// Display any pending step event.
if (GPUDebug::GetBreakNext() != GPUDebug::BreakNext::NONE) {
ImGui::Text("Step pending (waiting for CPU): %s", GPUDebug::BreakNextToString(GPUDebug::GetBreakNext()));
}

// Let's display the current CLUT.

// First, let's list any active display lists in the left column.
Expand Down
Loading