From 11819e87cfe6e1461d10a385030e185433bd85d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 3 Dec 2024 10:52:48 +0100 Subject: [PATCH] PauseAction readbacks now work again --- GPU/Debugger/Debugger.cpp | 4 ++- GPU/Debugger/Stepping.cpp | 41 +++++++++++++++++++++++---- GPU/Debugger/Stepping.h | 2 ++ Windows/GEDebugger/GEDebugger.cpp | 33 +++++++++++---------- Windows/GEDebugger/SimpleGLWindow.cpp | 2 +- 5 files changed, 60 insertions(+), 22 deletions(-) diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 84e5606bb7..8ed4917552 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -83,7 +83,9 @@ void SetBreakNext(BreakNext next) { GPUBreakpoints::AddCmdBreakpoint(GE_CMD_BEZIER, true); GPUBreakpoints::AddCmdBreakpoint(GE_CMD_SPLINE, true); } - GPUStepping::ResumeFromStepping(); + if (GPUStepping::IsStepping()) { + GPUStepping::ResumeFromStepping(); + } lastStepTime = next == BreakNext::NONE ? -1.0 : time_now_d(); } diff --git a/GPU/Debugger/Stepping.cpp b/GPU/Debugger/Stepping.cpp index 9e2296f91f..d952a23a0b 100644 --- a/GPU/Debugger/Stepping.cpp +++ b/GPU/Debugger/Stepping.cpp @@ -19,6 +19,7 @@ #include #include "Common/Log.h" +#include "Common/Thread/ThreadUtil.h" #include "Core/Core.h" #include "GPU/Common/GPUDebugInterface.h" #include "GPU/Debugger/Stepping.h" @@ -67,6 +68,22 @@ static u32 pauseSetCmdValue; static GPUgstate lastGState; +const char *PauseActionToString(PauseAction action) { + switch (action) { + case PAUSE_CONTINUE: return "CONTINUE"; + case PAUSE_BREAK: return "BREAK"; + case PAUSE_GETOUTPUTBUF: return "GETOUTPUTBUF"; + case PAUSE_GETFRAMEBUF: return "GETFRAMEBUF"; + case PAUSE_GETDEPTHBUF: return "GETDEPTHBUF"; + case PAUSE_GETSTENCILBUF: return "GETSTENCILBUF"; + case PAUSE_GETTEX: return "GETTEX"; + case PAUSE_GETCLUT: return "GETCLUT"; + case PAUSE_SETCMDVALUE: return "SETCMDVALUE"; + case PAUSE_FLUSHDRAW: return "FLUSHDRAW"; + default: return "N/A"; + } +} + static void SetPauseAction(PauseAction act, bool waitComplete = true) { pauseLock.lock(); std::unique_lock guard(actionLock); @@ -80,12 +97,14 @@ static void SetPauseAction(PauseAction act, bool waitComplete = true) { static void RunPauseAction() { std::lock_guard guard(actionLock); - - switch (pauseAction) { - case PAUSE_CONTINUE: + if (pauseAction == PAUSE_BREAK) { // Don't notify, just go back, woke up by accident. return; + } + INFO_LOG(Log::G3D, "RunPauseAction: %s", PauseActionToString(pauseAction)); + + switch (pauseAction) { case PAUSE_BREAK: break; @@ -127,9 +146,15 @@ static void RunPauseAction() { actionComplete = true; actionWait.notify_all(); + pauseAction = PAUSE_BREAK; } +void WaitForPauseAction() { + std::unique_lock guard(actionLock); + actionWait.wait(guard); +} + static void StartStepping() { if (lastGState.cmdmem[1] == 0) { lastGState = gstate; @@ -138,6 +163,7 @@ static void StartStepping() { } gpuDebug->NotifySteppingEnter(); isStepping = true; + stepCounter++; } static void StopStepping() { @@ -166,9 +192,7 @@ bool ProcessStepping() { return false; } - StartStepping(); RunPauseAction(); - StopStepping(); return true; } @@ -187,6 +211,8 @@ bool EnterStepping() { return false; } + StartStepping(); + // Just to be sure. if (pauseAction == PAUSE_CONTINUE) { pauseAction = PAUSE_BREAK; @@ -197,6 +223,7 @@ bool EnterStepping() { } void ResumeFromStepping() { + StopStepping(); SetPauseAction(PAUSE_CONTINUE, false); } @@ -208,12 +235,16 @@ int GetSteppingCounter() { return stepCounter; } +// NOTE: This can't be called on the EmuThread! static bool GetBuffer(const GPUDebugBuffer *&buffer, PauseAction type, const GPUDebugBuffer &resultBuffer) { if (!isStepping && coreState != CORE_STEPPING_CPU) { return false; } + _dbg_assert_(strcmp(GetCurrentThreadName(), "EmuThread") != 0); + SetPauseAction(type); + WaitForPauseAction(); buffer = &resultBuffer; return bufferResult; } diff --git a/GPU/Debugger/Stepping.h b/GPU/Debugger/Stepping.h index 2d50ee7f4f..38c192b8f3 100644 --- a/GPU/Debugger/Stepping.h +++ b/GPU/Debugger/Stepping.h @@ -30,12 +30,14 @@ namespace GPUStepping { bool EnterStepping(); bool IsStepping(); void ResumeFromStepping(); + void WaitForAction(); int GetSteppingCounter(); // Called from the emu thread. bool ProcessStepping(); + // NOTE: These are only usable from non-EmuThread threads. bool GPU_GetOutputFramebuffer(const GPUDebugBuffer *&buffer); bool GPU_GetCurrentFramebuffer(const GPUDebugBuffer *&buffer, GPUDebugFramebufferType type); bool GPU_GetCurrentDepthbuffer(const GPUDebugBuffer *&buffer); diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 0d141b55e1..7004ed80b7 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -56,7 +56,6 @@ #include "GPU/Debugger/Stepping.h" using namespace GPUBreakpoints; -using namespace GPUDebug; using namespace GPUStepping; enum PrimaryDisplayType { @@ -136,8 +135,8 @@ StepCountDlg::~StepCountDlg() { void StepCountDlg::Jump(int count, bool relative) { if (relative && count == 0) return; - SetBreakNext(BreakNext::COUNT); - SetBreakCount(count, relative); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::COUNT); + GPUDebug::SetBreakCount(count, relative); }; BOOL StepCountDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { @@ -575,7 +574,7 @@ void CGEDebugger::UpdatePreviews() { } wchar_t primCounter[1024]{}; - swprintf(primCounter, ARRAY_SIZE(primCounter), L"%d/%d", PrimsThisFrame(), PrimsLastFrame()); + swprintf(primCounter, ARRAY_SIZE(primCounter), L"%d/%d", GPUDebug::PrimsThisFrame(), GPUDebug::PrimsLastFrame()); SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, primCounter); for (GEDebuggerTab &tabState : tabStates_) { @@ -698,7 +697,9 @@ void CGEDebugger::UpdatePrimaryPreview(const GPUgstate &state) { } if (bufferResult && primaryBuffer_ != nullptr) { - auto fmt = SimpleGLWindow::Format(primaryBuffer_->GetFormat()); + const GPUDebugBufferFormat bufFmt = primaryBuffer_->GetFormat(); + _dbg_assert_(bufFmt != GPUDebugBufferFormat::GPU_DBG_FORMAT_INVALID); + const SimpleGLWindow::Format fmt = (SimpleGLWindow::Format)bufFmt; primaryWindow->SetFlags(flags); primaryWindow->Draw(primaryBuffer_->GetData(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight(), primaryBuffer_->GetFlipped(), fmt); @@ -735,7 +736,9 @@ void CGEDebugger::UpdateSecondPreview(const GPUgstate &state) { } if (bufferResult) { - auto fmt = SimpleGLWindow::Format(secondBuffer_->GetFormat()); + const GPUDebugBufferFormat bufFmt = secondBuffer_->GetFormat(); + _dbg_assert_(bufFmt != GPUDebugBufferFormat::GPU_DBG_FORMAT_INVALID); + const SimpleGLWindow::Format fmt = (SimpleGLWindow::Format)bufFmt; secondWindow->SetFlags(TexturePreviewFlags(state)); if (showClut_) { // Reduce the stride so it's easier to see. @@ -1127,31 +1130,31 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_GEDBG_STEPDRAW: - SetBreakNext(BreakNext::DRAW); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::DRAW); break; case IDC_GEDBG_STEP: - SetBreakNext(BreakNext::OP); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::OP); break; case IDC_GEDBG_STEPTEX: - SetBreakNext(BreakNext::TEX); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::TEX); break; case IDC_GEDBG_STEPFRAME: - SetBreakNext(BreakNext::FRAME); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::FRAME); break; case IDC_GEDBG_STEPVSYNC: - SetBreakNext(BreakNext::VSYNC); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::VSYNC); break; case IDC_GEDBG_STEPPRIM: - SetBreakNext(BreakNext::PRIM); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::PRIM); break; case IDC_GEDBG_STEPCURVE: - SetBreakNext(BreakNext::CURVE); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::CURVE); break; case IDC_GEDBG_STEPCOUNT: @@ -1218,7 +1221,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L""); SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, L""); - SetBreakNext(BreakNext::NONE); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::NONE); break; case IDC_GEDBG_RECORD: @@ -1266,7 +1269,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { break; case WM_GEDBG_STEPDISPLAYLIST: - SetBreakNext(BreakNext::OP); + GPUDebug::SetBreakNext(GPUDebug::BreakNext::OP); break; case WM_GEDBG_TOGGLEPCBREAKPOINT: diff --git a/Windows/GEDebugger/SimpleGLWindow.cpp b/Windows/GEDebugger/SimpleGLWindow.cpp index eb21c5512b..08060967ce 100644 --- a/Windows/GEDebugger/SimpleGLWindow.cpp +++ b/Windows/GEDebugger/SimpleGLWindow.cpp @@ -253,7 +253,7 @@ void SimpleGLWindow::DrawChecker() { glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, vao_ ? 0 : indices); } -void SimpleGLWindow::Draw(const u8 *data, int w, int h, bool flipped, Format fmt) { +void SimpleGLWindow::Draw(const u8 *data, int w, int h, bool flipped, const Format fmt) { wglMakeCurrent(hDC_, hGLRC_); GLint components = GL_RGBA;