From 4d5c8fcff4e5dbbc6a99ee42f8eaa66af0a915ff Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Dec 2018 06:26:35 -0800 Subject: [PATCH 1/3] GE Debugger: Track a counter of prims. --- GPU/Debugger/Debugger.cpp | 22 ++++++++++++++++++++++ GPU/Debugger/Debugger.h | 3 +++ GPU/Debugger/Stepping.cpp | 1 + Windows/GEDebugger/GEDebugger.cpp | 5 +++++ Windows/ppsspp.rc | 17 +++++++++-------- Windows/resource.h | 3 ++- 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 088836c2ff44..27083674b094 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -26,6 +26,10 @@ static bool active = false; static bool inited = false; static BreakNext breakNext = BreakNext::NONE; +static int primsLastFrame = 0; +static int primsThisFrame = 0; +static int thisFlipNum = 0; + static void Init() { if (!inited) { GPUBreakpoints::Init(); @@ -68,6 +72,16 @@ void NotifyCommand(u32 pc) { if (!active) return; u32 op = Memory::ReadUnchecked_U32(pc); + u32 cmd = op >> 24; + if (thisFlipNum != gpuStats.numFlips) { + primsLastFrame = primsThisFrame; + primsThisFrame = 0; + thisFlipNum = gpuStats.numFlips; + } + if (cmd == GE_CMD_PRIM || cmd == GE_CMD_BEZIER || cmd == GE_CMD_SPLINE) { + primsThisFrame++; + } + if (breakNext == BreakNext::OP || GPUBreakpoints::IsBreakpoint(pc, op)) { GPUBreakpoints::ClearTempBreakpoints(); @@ -100,4 +114,12 @@ void NotifyTextureAttachment(u32 texaddr) { return; } +int PrimsThisFrame() { + return primsThisFrame; +} + +int PrimsLastFrame() { + return primsLastFrame; +} + } diff --git a/GPU/Debugger/Debugger.h b/GPU/Debugger/Debugger.h index 2a45f93ba0b8..193b4630ec93 100644 --- a/GPU/Debugger/Debugger.h +++ b/GPU/Debugger/Debugger.h @@ -43,4 +43,7 @@ void NotifyDraw(); void NotifyDisplay(u32 framebuf, u32 stride, int format); void NotifyTextureAttachment(u32 texaddr); +int PrimsThisFrame(); +int PrimsLastFrame(); + } diff --git a/GPU/Debugger/Stepping.cpp b/GPU/Debugger/Stepping.cpp index b27749655640..bf5ddb483479 100644 --- a/GPU/Debugger/Stepping.cpp +++ b/GPU/Debugger/Stepping.cpp @@ -38,6 +38,7 @@ enum PauseAction { }; static bool isStepping; +// Number of times we've entered stepping, to detect a resume asynchronously. static int stepCounter = 0; static std::mutex pauseLock; diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index e36fe84a52cb..5d4f978357c3 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -291,6 +291,10 @@ void CGEDebugger::UpdatePreviews() { displayList->setDisplayList(list); } + wchar_t primCounter[1024]{}; + swprintf(primCounter, ARRAY_SIZE(primCounter), L"%d/%d", PrimsThisFrame(), PrimsLastFrame()); + SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, primCounter); + flags->Update(); lighting->Update(); textureState->Update(); @@ -778,6 +782,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { secondWindow->Clear(); SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, L""); SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L""); + SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, L""); SetBreakNext(BreakNext::NONE); break; diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 4d3ae58dcf59..3aa2993ec68f 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -210,14 +210,15 @@ EXSTYLE WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW CAPTION "GE" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - PUSHBUTTON "Step &Frame",IDC_GEDBG_STEPFRAME,10,2,48,14 - PUSHBUTTON "Step &Tex",IDC_GEDBG_STEPTEX,62,2,48,14 - PUSHBUTTON "Step &Draw",IDC_GEDBG_STEPDRAW,114,2,48,14 - PUSHBUTTON "Step &Prim",IDC_GEDBG_STEPPRIM,166,2,48,14 - PUSHBUTTON "Step &Curve",IDC_GEDBG_STEPCURVE,218,2,48,14 - PUSHBUTTON "Step &Into",IDC_GEDBG_STEP,270,2,48,14 - PUSHBUTTON "&Resume",IDC_GEDBG_RESUME,322,2,48,14 - PUSHBUTTON "Rec&ord",IDC_GEDBG_RECORD,440,2,48,14 + PUSHBUTTON "Step &Frame",IDC_GEDBG_STEPFRAME,10,2,44,14 + PUSHBUTTON "Step &Tex",IDC_GEDBG_STEPTEX,55,2,44,14 + PUSHBUTTON "Step &Draw",IDC_GEDBG_STEPDRAW,100,2,44,14 + PUSHBUTTON "Step &Prim",IDC_GEDBG_STEPPRIM,145,2,44,14 + PUSHBUTTON "Step &Curve",IDC_GEDBG_STEPCURVE,190,2,44,14 + PUSHBUTTON "Step &Into",IDC_GEDBG_STEP,235,2,44,14 + EDITTEXT IDC_GEDBG_PRIMCOUNTER,340,4,44,12,ES_READONLY | NOT WS_BORDER + PUSHBUTTON "&Resume",IDC_GEDBG_RESUME,396,2,44,14 + PUSHBUTTON "Rec&ord",IDC_GEDBG_RECORD,444,2,44,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 7ae3fc5b4534..1d56567dcd29 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -165,6 +165,7 @@ #define IDC_GEDBG_SHOWCLUT 1198 #define IDC_BREAKPOINT_LOG_FORMAT 1199 #define IDC_SHOWOFFSETS 1200 +#define IDC_GEDBG_PRIMCOUNTER 1201 #define ID_SHADERS_BASE 5000 @@ -375,7 +376,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 #define _APS_NEXT_COMMAND_VALUE 40199 -#define _APS_NEXT_CONTROL_VALUE 1200 +#define _APS_NEXT_CONTROL_VALUE 1202 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif From e029168be2fc0a92975f99a8e6381446e11adebc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Dec 2018 06:40:27 -0800 Subject: [PATCH 2/3] GE Debugger: Allow jumping to a specific prim. This will make the most sense when frames are relatively stable, and works great for GE dumps. --- GPU/Debugger/Debugger.cpp | 21 +++++++++++++++++++-- GPU/Debugger/Debugger.h | 2 ++ Windows/GEDebugger/GEDebugger.cpp | 14 ++++++++++++++ Windows/ppsspp.rc | 3 ++- Windows/resource.h | 3 ++- 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 27083674b094..9591cec8c14d 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -25,6 +25,7 @@ namespace GPUDebug { static bool active = false; static bool inited = false; static BreakNext breakNext = BreakNext::NONE; +static int breakAtCount = -1; static int primsLastFrame = 0; static int primsThisFrame = 0; @@ -44,6 +45,7 @@ void SetActive(bool flag) { active = flag; if (!active) { breakNext = BreakNext::NONE; + breakAtCount = -1; GPUStepping::ResumeFromStepping(); } } @@ -55,9 +57,10 @@ bool IsActive() { void SetBreakNext(BreakNext next) { SetActive(true); breakNext = next; + breakAtCount = -1; if (next == BreakNext::TEX) { GPUBreakpoints::AddTextureChangeTempBreakpoint(); - } else if (next == BreakNext::PRIM) { + } else if (next == BreakNext::PRIM || next == BreakNext::COUNT) { GPUBreakpoints::AddCmdBreakpoint(GE_CMD_PRIM, true); GPUBreakpoints::AddCmdBreakpoint(GE_CMD_BEZIER, true); GPUBreakpoints::AddCmdBreakpoint(GE_CMD_SPLINE, true); @@ -68,6 +71,20 @@ void SetBreakNext(BreakNext next) { GPUStepping::ResumeFromStepping(); } +void SetBreakCount(int c) { + breakAtCount = c; +} + +static bool IsBreakpoint(u32 pc, u32 op) { + if (breakNext == BreakNext::OP) { + return true; + } else if (breakNext == BreakNext::COUNT) { + return primsThisFrame == breakAtCount; + } else { + return GPUBreakpoints::IsBreakpoint(pc, op); + } +} + void NotifyCommand(u32 pc) { if (!active) return; @@ -82,7 +99,7 @@ void NotifyCommand(u32 pc) { primsThisFrame++; } - if (breakNext == BreakNext::OP || GPUBreakpoints::IsBreakpoint(pc, op)) { + if (IsBreakpoint(pc, op)) { GPUBreakpoints::ClearTempBreakpoints(); auto info = gpuDebug->DissassembleOp(pc); diff --git a/GPU/Debugger/Debugger.h b/GPU/Debugger/Debugger.h index 193b4630ec93..b459f5a859ee 100644 --- a/GPU/Debugger/Debugger.h +++ b/GPU/Debugger/Debugger.h @@ -30,12 +30,14 @@ enum class BreakNext { FRAME, PRIM, CURVE, + COUNT, }; void SetActive(bool flag); bool IsActive(); void SetBreakNext(BreakNext next); +void SetBreakCount(int c); // While debugging is active, these may block. void NotifyCommand(u32 pc); diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 5d4f978357c3..8ff0223ecd94 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -20,6 +20,7 @@ #include #include +#include "base/stringutil.h" #include "Common/ColorConv.h" #include "Core/Config.h" #include "Core/Screenshot.h" @@ -724,6 +725,19 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { SetBreakNext(BreakNext::CURVE); break; + case IDC_GEDBG_STEPCOUNT: + { + std::string value; + int count; + if (InputBox_GetString(GetModuleHandle(NULL), m_hDlg, L"Prim count", "", value)) { + if (TryParse(value, &count)) { + SetBreakNext(BreakNext::COUNT); + SetBreakCount(count); + } + } + } + break; + case IDC_GEDBG_BREAKTEX: { GPUDebug::SetActive(true); diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 3aa2993ec68f..195f92eb05cb 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -216,7 +216,8 @@ BEGIN PUSHBUTTON "Step &Prim",IDC_GEDBG_STEPPRIM,145,2,44,14 PUSHBUTTON "Step &Curve",IDC_GEDBG_STEPCURVE,190,2,44,14 PUSHBUTTON "Step &Into",IDC_GEDBG_STEP,235,2,44,14 - EDITTEXT IDC_GEDBG_PRIMCOUNTER,340,4,44,12,ES_READONLY | NOT WS_BORDER + PUSHBUTTON "Step Cou&nt",IDC_GEDBG_STEPCOUNT,280,2,44,14 + EDITTEXT IDC_GEDBG_PRIMCOUNTER,325,4,50,12,ES_READONLY | NOT WS_BORDER PUSHBUTTON "&Resume",IDC_GEDBG_RESUME,396,2,44,14 PUSHBUTTON "Rec&ord",IDC_GEDBG_RECORD,444,2,44,14 CONTROL "",IDC_GEDBG_TEX,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,10,20,128,128 diff --git a/Windows/resource.h b/Windows/resource.h index 1d56567dcd29..ee64c5759f60 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -363,6 +363,7 @@ #define ID_OPTIONS_TEXTUREFILTERING_MENU 40196 #define ID_OPTIONS_SCREENFILTER_MENU 40197 #define ID_OPTIONS_TEXTURESCALING_MENU 40198 +#define IDC_GEDBG_STEPCOUNT 40199 // Dummy option to let the buffered rendering hotkey cycle through all the options. #define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500 @@ -375,7 +376,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 -#define _APS_NEXT_COMMAND_VALUE 40199 +#define _APS_NEXT_COMMAND_VALUE 40200 #define _APS_NEXT_CONTROL_VALUE 1202 #define _APS_NEXT_SYMED_VALUE 101 #endif From f88dc9e821b24ed179e9693ba3385806eb188748 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Dec 2018 15:50:20 -0800 Subject: [PATCH 3/3] GE Debugger: Allow relative prim counts. --- GPU/Debugger/Debugger.cpp | 8 ++++++-- GPU/Debugger/Debugger.h | 2 +- Windows/GEDebugger/GEDebugger.cpp | 8 +++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 9591cec8c14d..2d5da1af3aed 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -71,8 +71,12 @@ void SetBreakNext(BreakNext next) { GPUStepping::ResumeFromStepping(); } -void SetBreakCount(int c) { - breakAtCount = c; +void SetBreakCount(int c, bool relative) { + if (relative) { + breakAtCount = primsThisFrame + c; + } else { + breakAtCount = c; + } } static bool IsBreakpoint(u32 pc, u32 op) { diff --git a/GPU/Debugger/Debugger.h b/GPU/Debugger/Debugger.h index b459f5a859ee..15be467cdacc 100644 --- a/GPU/Debugger/Debugger.h +++ b/GPU/Debugger/Debugger.h @@ -37,7 +37,7 @@ void SetActive(bool flag); bool IsActive(); void SetBreakNext(BreakNext next); -void SetBreakCount(int c); +void SetBreakCount(int c, bool relative = false); // While debugging is active, these may block. void NotifyCommand(u32 pc); diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 8ff0223ecd94..57f122694ed1 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -730,7 +730,13 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { std::string value; int count; if (InputBox_GetString(GetModuleHandle(NULL), m_hDlg, L"Prim count", "", value)) { - if (TryParse(value, &count)) { + if (value.length() > 1 && value[0] == '+' && TryParse(value.substr(1), &count)) { + SetBreakNext(BreakNext::COUNT); + SetBreakCount(count, true); + } else if (value.length() > 1 && value[0] == '-' && TryParse(value.substr(1), &count)) { + SetBreakNext(BreakNext::COUNT); + SetBreakCount(-count, true); + } else if (TryParse(value, &count)) { SetBreakNext(BreakNext::COUNT); SetBreakCount(count); }