ImGeDebugger: Highlight changes, show old value on hover

This commit is contained in:
Henrik Rydgård 2024-12-14 11:03:18 +01:00
parent 0b4ca639a4
commit 68f61c2add
5 changed files with 38 additions and 28 deletions

View file

@ -167,6 +167,9 @@ void TextDrawer::MeasureStringRect(std::string_view str, const Bounds &bounds, f
}
void TextDrawer::DrawStringRect(DrawBuffer &target, std::string_view str, const Bounds &bounds, uint32_t color, int align) {
if (bounds.w < 0.0f || bounds.h < 0.0f) {
return;
}
float x = bounds.x;
float y = bounds.y;
if (align & ALIGN_HCENTER) {

View file

@ -12,6 +12,9 @@
#include "Core/System.h"
void FormatStateRow(GPUDebugInterface *gpudebug, char *dest, size_t destSize, CmdFormatType fmt, u32 value, bool enabled, u32 otherValue, u32 otherValue2) {
value &= 0xFFFFFF;
otherValue &= 0xFFFFFF;
otherValue2 &= 0xFFFFFF;
switch (fmt) {
case CMD_FMT_HEX:
snprintf(dest, destSize, "%06x", value);

View file

@ -71,6 +71,7 @@ static int bufferLevel;
static bool lastWasFramebuffer;
static u32 pauseSetCmdValue;
// This is used only to highlight differences. Should really be owned by the debugger.
static GPUgstate lastGState;
const char *PauseActionToString(PauseAction action) {
@ -161,21 +162,6 @@ void WaitForPauseAction() {
actionWait.wait(guard);
}
static void StartStepping() {
if (lastGState.cmdmem[1] == 0) {
lastGState = gstate;
// Play it safe so we don't keep resetting.
lastGState.cmdmem[1] |= 0x01000000;
}
isStepping = true;
stepCounter++;
}
static void StopStepping() {
lastGState = gstate;
isStepping = false;
}
bool ProcessStepping() {
_dbg_assert_(gpuDebug);
@ -215,7 +201,15 @@ bool EnterStepping() {
return false;
}
StartStepping();
// StartStepping
if (lastGState.cmdmem[1] == 0) {
lastGState = gstate;
// Play it safe so we don't keep resetting.
lastGState.cmdmem[1] |= 0x01000000;
}
isStepping = true;
stepCounter++;
// Just to be sure.
if (pauseAction == PAUSE_CONTINUE) {
@ -227,7 +221,8 @@ bool EnterStepping() {
}
void ResumeFromStepping() {
StopStepping();
lastGState = gstate;
isStepping = false;
SetPauseAction(PAUSE_CONTINUE, false);
}
@ -300,7 +295,7 @@ bool GPU_FlushDrawing() {
return true;
}
GPUgstate LastState() {
const GPUgstate &LastState() {
return lastGState;
}

View file

@ -46,5 +46,6 @@ namespace GPUStepping {
bool GPU_SetCmdValue(u32 op);
bool GPU_FlushDrawing();
GPUgstate LastState();
// Can be used to highlight differences in a debugger.
const GPUgstate &LastState();
};

View file

@ -746,7 +746,7 @@ static const StateItem g_vertexState[] = {
};
void ImGeStateWindow::Snapshot() {
// Not needed for now, we have GPUStepping::LastState()
}
// TODO: Separate window or merge into Ge debugger?
@ -769,6 +769,8 @@ void ImGeStateWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterface
bool sectionOpen = false;
for (size_t i = 0; i < numRows; i++) {
const GECmdInfo &info = GECmdInfoByCmd(rows[i].cmd);
const GPUgstate &lastState = GPUStepping::LastState();
bool diff = lastState.cmdmem[rows[i].cmd] != gstate.cmdmem[rows[i].cmd];
if (rows[i].header) {
anySection = true;
@ -788,31 +790,37 @@ void ImGeStateWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterface
}
const bool enabled = info.enableCmd == 0 || (gstate.cmdmem[info.enableCmd] & 1) == 1;
if (!enabled)
if (diff) {
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 96, 32, enabled ? 255 : 128));
} else if (!enabled) {
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 128));
}
if (!rows[i].header) {
ImGui::TextUnformatted(info.uiName);
ImGui::TableNextColumn();
}
if (rows[i].cmd != GE_CMD_NOP) {
char temp[256];
char temp[128], temp2[128];
const u32 value = gstate.cmdmem[info.cmd] & 0xFFFFFF;
const u32 otherValue = gstate.cmdmem[info.otherCmd] & 0xFFFFFF;
const u32 otherValue2 = gstate.cmdmem[info.otherCmd2] & 0xFFFFFF;
const u32 value = gstate.cmdmem[info.cmd];
const u32 otherValue = gstate.cmdmem[info.otherCmd];
// Special handling for pointer and pointer/width entries
// Special handling for pointer and pointer/width entries - create an address control
if (info.fmt == CMD_FMT_PTRWIDTH) {
const u32 val = value | (otherValue & 0x00FF0000) << 8;
ImClickableAddress(val, control, ImCmd::NONE);
ImGui::SameLine();
ImGui::Text("w=%d", otherValue & 0xFFFF);
} else {
FormatStateRow(gpuDebug, temp, sizeof(temp), info.fmt, value, true, otherValue, otherValue2);
FormatStateRow(gpuDebug, temp, sizeof(temp), info.fmt, value, true, otherValue, gstate.cmdmem[info.otherCmd2]);
ImGui::TextUnformatted(temp);
}
if (diff && ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) {
FormatStateRow(gpuDebug, temp2, sizeof(temp2), info.fmt, lastState.cmdmem[info.cmd], true, lastState.cmdmem[info.otherCmd], lastState.cmdmem[info.otherCmd2]);
ImGui::SetTooltip("Previous: %s", temp2);
}
}
if (!enabled)
if (diff || !enabled)
ImGui::PopStyleColor();
}
if (sectionOpen) {