From dd314c83bdafab83b173257260e66952e84c1c8b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 8 Oct 2013 00:04:11 -0700 Subject: [PATCH] Add texture and frame break buttons. --- Windows/GEDebugger/GEDebugger.cpp | 77 +++++++++++++++++++++++-------- Windows/GEDebugger/GEDebugger.h | 10 ++++ Windows/ppsspp.rc | 4 +- Windows/resource.h | 4 +- 4 files changed, 73 insertions(+), 22 deletions(-) diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 556f733b80..be35b1e376 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -60,8 +60,8 @@ static std::vector breakCmds; static std::set breakPCs; static u32 tempBreakpoint = -1; static std::set breakTextures; -static bool breakNextOp = false; -static bool breakNextDraw = false; +static BreakNextType breakNext = BREAK_NONE; +static u32 lastTexture = -1; static bool bufferResult; static GPUDebugBuffer bufferFrame; @@ -93,10 +93,23 @@ bool CGEDebugger::IsOpBreakPoint(u32 op) { return breakCmds[cmd]; } +// Hmm, this is probably kinda slow now... bool CGEDebugger::IsTextureBreakPoint(u32 op) { u8 cmd = op >> 24; bool interesting = (cmd >= GE_CMD_TEXADDR0 && cmd <= GE_CMD_TEXADDR7); interesting = interesting || (cmd >= GE_CMD_TEXBUFWIDTH0 && cmd <= GE_CMD_TEXBUFWIDTH7); + + if (breakNext == BREAK_NEXT_NONTEX) { + // Okay, so we hit an interesting texture, but let's not break if this is a clut/etc. + // Otherwise we get garbage widths and colors. It's annoying. + bool textureCmd = interesting || cmd == GE_CMD_CLUTADDR || cmd == GE_CMD_CLUTADDRUPPER || cmd == GE_CMD_LOADCLUT || cmd == GE_CMD_CLUTFORMAT; + textureCmd = textureCmd || (cmd >= GE_CMD_TEXSIZE0 && cmd <= GE_CMD_TEXSIZE7); + textureCmd = textureCmd || cmd == GE_CMD_TEXFORMAT || cmd == GE_CMD_TEXMODE; + if (!textureCmd) { + return true; + } + } + if (!interesting || !gpuDebug) { return false; } @@ -104,8 +117,18 @@ bool CGEDebugger::IsTextureBreakPoint(u32 op) { // Okay, so we just set a texture of some sort, check if it was one we were waiting for. auto state = gpuDebug->GetGState(); int level = cmd <= GE_CMD_TEXADDR7 ? cmd - GE_CMD_TEXADDR0 : cmd - GE_CMD_TEXBUFWIDTH0; + + // Are we breaking on any texture? As long as it's level 0. + if (level == 0 && breakNext == BREAK_NEXT_TEX && lastTexture != state.getTextureAddress(level)) { + // Don't break right away, we'll get a garbage texture... + breakNext = BREAK_NEXT_NONTEX; + } + lock_guard guard(breaksLock); - return breakTextures.find(state.getTextureAddress(level)) != breakTextures.end(); + if (breakTextures.find(state.getTextureAddress(level)) != breakTextures.end()) { + breakNext = BREAK_NEXT_NONTEX; + } + return false; } bool CGEDebugger::IsOpOrTextureBreakPoint(u32 op) { @@ -310,6 +333,10 @@ void CGEDebugger::UpdatePreviews() { } _snwprintf(desc, ARRAY_SIZE(desc), L"Texture: 0x%08x (%dx%d)", state.getTextureAddress(0), state.getTextureWidth(0), state.getTextureHeight(0)); SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, desc); + + lastTexture = state.getTextureAddress(0); + } else { + lastTexture = -1; } } else { texWindow->Clear(); @@ -318,6 +345,7 @@ void CGEDebugger::UpdatePreviews() { } else { SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L"Texture: disabled"); } + lastTexture = -1; } DisplayList list; @@ -358,6 +386,14 @@ void CGEDebugger::SavePosition() } } +void CGEDebugger::SetBreakNext(BreakNextType type) { + attached = true; + SetupPreviews(); + + SetPauseAction(PAUSE_CONTINUE, false); + breakNext = type; +} + BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: @@ -413,16 +449,19 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_GEDBG_STEPDRAW: - attached = true; - SetupPreviews(); - - SetPauseAction(PAUSE_CONTINUE, false); - breakNextOp = false; - breakNextDraw = true; + SetBreakNext(BREAK_NEXT_DRAW); break; case IDC_GEDBG_STEP: - SendMessage(m_hDlg,WM_GEDBG_STEPDISPLAYLIST,0,0); + SetBreakNext(BREAK_NEXT_OP); + break; + + case IDC_GEDBG_STEPTEX: + SetBreakNext(BREAK_NEXT_TEX); + break; + + case IDC_GEDBG_STEPFRAME: + SetBreakNext(BREAK_NEXT_FRAME); break; case IDC_GEDBG_RESUME: @@ -433,8 +472,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: detach? Should probably have separate UI, or just on activate? SetPauseAction(PAUSE_CONTINUE, false); - breakNextOp = false; - breakNextDraw = false; + breakNext = BREAK_NONE; break; } break; @@ -457,12 +495,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { break; case WM_GEDBG_STEPDISPLAYLIST: - attached = true; - SetupPreviews(); - - SetPauseAction(PAUSE_CONTINUE, false); - breakNextOp = true; - breakNextDraw = false; + SetBreakNext(BREAK_NEXT_OP); break; case WM_GEDBG_TOGGLEPCBREAKPOINT: @@ -526,16 +559,20 @@ void WindowsHost::GPUNotifyCommand(u32 pc) { u32 op = Memory::ReadUnchecked_U32(pc); u8 cmd = op >> 24; - if (breakNextOp || CGEDebugger::IsOpOrTextureBreakPoint(op) || CGEDebugger::IsAddressBreakPoint(pc) || pc == tempBreakpoint) { + if (breakNext == BREAK_NEXT_OP || CGEDebugger::IsOpOrTextureBreakPoint(op) || CGEDebugger::IsAddressBreakPoint(pc) || pc == tempBreakpoint) { PauseWithMessage(WM_GEDBG_BREAK_CMD, (WPARAM) pc); } } void WindowsHost::GPUNotifyDisplay(u32 framebuf, u32 stride, int format) { + if (breakNext == BREAK_NEXT_FRAME) { + // This should work fine, start stepping at the first op of the new frame. + breakNext = BREAK_NEXT_OP; + } } void WindowsHost::GPUNotifyDraw() { - if (breakNextDraw) { + if (breakNext == BREAK_NEXT_DRAW) { PauseWithMessage(WM_GEDBG_BREAK_DRAW); } } diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index a5eff0736e..d1e4e3596e 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -33,6 +33,15 @@ enum { WM_GEDBG_SETCMDWPARAM, }; +enum BreakNextType { + BREAK_NONE, + BREAK_NEXT_OP, + BREAK_NEXT_DRAW, + BREAK_NEXT_TEX, + BREAK_NEXT_NONTEX, + BREAK_NEXT_FRAME, +}; + class CtrlDisplayListView; class TabDisplayLists; class TabStateFlags; @@ -61,6 +70,7 @@ private: void UpdatePreviews(); void UpdateSize(WORD width, WORD height); void SavePosition(); + void SetBreakNext(BreakNextType type); CtrlDisplayListView *displayList; TabDisplayLists *lists; diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 80c71402bb..7796ec440e 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -175,7 +175,9 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN PUSHBUTTON "Step Draw",IDC_GEDBG_STEPDRAW,0,0,48,14 PUSHBUTTON "Step Into",IDC_GEDBG_STEP,52,0,48,14 - PUSHBUTTON "Resume",IDC_GEDBG_RESUME,104,0,48,14 + PUSHBUTTON "Step Tex",IDC_GEDBG_STEPTEX,104,0,48,14 + PUSHBUTTON "Step Frame",IDC_GEDBG_STEPFRAME,156,0,48,14 + PUSHBUTTON "Resume",IDC_GEDBG_RESUME,208,0,48,14 CONTROL "",IDC_GEDBG_TEX,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,10,20,128,128 CONTROL "",IDC_GEDBG_FRAME,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,148,20,256,136 CONTROL "",IDC_GEDBG_MAINTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,10,216,480,180 diff --git a/Windows/resource.h b/Windows/resource.h index 4fc81fafa0..b7e0a975bd 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -290,6 +290,8 @@ #define ID_GEDBG_SETSTALLADDR 40130 #define ID_GEDBG_GOTOPC 40131 #define ID_GEDBG_GOTOADDR 40132 +#define IDC_GEDBG_STEPTEX 40133 +#define IDC_GEDBG_STEPFRAME 40134 // Dummy option to let the buffered rendering hotkey cycle through all the options. #define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500 @@ -302,7 +304,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 254 -#define _APS_NEXT_COMMAND_VALUE 40133 +#define _APS_NEXT_COMMAND_VALUE 40135 #define _APS_NEXT_CONTROL_VALUE 1193 #define _APS_NEXT_SYMED_VALUE 101 #endif