PauseAction readbacks now work again

This commit is contained in:
Henrik Rydgård 2024-12-03 10:52:48 +01:00
parent f8af4906f5
commit 11819e87cf
5 changed files with 60 additions and 22 deletions

View file

@ -83,7 +83,9 @@ void SetBreakNext(BreakNext next) {
GPUBreakpoints::AddCmdBreakpoint(GE_CMD_BEZIER, true); GPUBreakpoints::AddCmdBreakpoint(GE_CMD_BEZIER, true);
GPUBreakpoints::AddCmdBreakpoint(GE_CMD_SPLINE, true); GPUBreakpoints::AddCmdBreakpoint(GE_CMD_SPLINE, true);
} }
GPUStepping::ResumeFromStepping(); if (GPUStepping::IsStepping()) {
GPUStepping::ResumeFromStepping();
}
lastStepTime = next == BreakNext::NONE ? -1.0 : time_now_d(); lastStepTime = next == BreakNext::NONE ? -1.0 : time_now_d();
} }

View file

@ -19,6 +19,7 @@
#include <condition_variable> #include <condition_variable>
#include "Common/Log.h" #include "Common/Log.h"
#include "Common/Thread/ThreadUtil.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "GPU/Common/GPUDebugInterface.h" #include "GPU/Common/GPUDebugInterface.h"
#include "GPU/Debugger/Stepping.h" #include "GPU/Debugger/Stepping.h"
@ -67,6 +68,22 @@ static u32 pauseSetCmdValue;
static GPUgstate lastGState; 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) { static void SetPauseAction(PauseAction act, bool waitComplete = true) {
pauseLock.lock(); pauseLock.lock();
std::unique_lock<std::mutex> guard(actionLock); std::unique_lock<std::mutex> guard(actionLock);
@ -80,12 +97,14 @@ static void SetPauseAction(PauseAction act, bool waitComplete = true) {
static void RunPauseAction() { static void RunPauseAction() {
std::lock_guard<std::mutex> guard(actionLock); std::lock_guard<std::mutex> guard(actionLock);
if (pauseAction == PAUSE_BREAK) {
switch (pauseAction) {
case PAUSE_CONTINUE:
// Don't notify, just go back, woke up by accident. // Don't notify, just go back, woke up by accident.
return; return;
}
INFO_LOG(Log::G3D, "RunPauseAction: %s", PauseActionToString(pauseAction));
switch (pauseAction) {
case PAUSE_BREAK: case PAUSE_BREAK:
break; break;
@ -127,9 +146,15 @@ static void RunPauseAction() {
actionComplete = true; actionComplete = true;
actionWait.notify_all(); actionWait.notify_all();
pauseAction = PAUSE_BREAK; pauseAction = PAUSE_BREAK;
} }
void WaitForPauseAction() {
std::unique_lock<std::mutex> guard(actionLock);
actionWait.wait(guard);
}
static void StartStepping() { static void StartStepping() {
if (lastGState.cmdmem[1] == 0) { if (lastGState.cmdmem[1] == 0) {
lastGState = gstate; lastGState = gstate;
@ -138,6 +163,7 @@ static void StartStepping() {
} }
gpuDebug->NotifySteppingEnter(); gpuDebug->NotifySteppingEnter();
isStepping = true; isStepping = true;
stepCounter++;
} }
static void StopStepping() { static void StopStepping() {
@ -166,9 +192,7 @@ bool ProcessStepping() {
return false; return false;
} }
StartStepping();
RunPauseAction(); RunPauseAction();
StopStepping();
return true; return true;
} }
@ -187,6 +211,8 @@ bool EnterStepping() {
return false; return false;
} }
StartStepping();
// Just to be sure. // Just to be sure.
if (pauseAction == PAUSE_CONTINUE) { if (pauseAction == PAUSE_CONTINUE) {
pauseAction = PAUSE_BREAK; pauseAction = PAUSE_BREAK;
@ -197,6 +223,7 @@ bool EnterStepping() {
} }
void ResumeFromStepping() { void ResumeFromStepping() {
StopStepping();
SetPauseAction(PAUSE_CONTINUE, false); SetPauseAction(PAUSE_CONTINUE, false);
} }
@ -208,12 +235,16 @@ int GetSteppingCounter() {
return stepCounter; return stepCounter;
} }
// NOTE: This can't be called on the EmuThread!
static bool GetBuffer(const GPUDebugBuffer *&buffer, PauseAction type, const GPUDebugBuffer &resultBuffer) { static bool GetBuffer(const GPUDebugBuffer *&buffer, PauseAction type, const GPUDebugBuffer &resultBuffer) {
if (!isStepping && coreState != CORE_STEPPING_CPU) { if (!isStepping && coreState != CORE_STEPPING_CPU) {
return false; return false;
} }
_dbg_assert_(strcmp(GetCurrentThreadName(), "EmuThread") != 0);
SetPauseAction(type); SetPauseAction(type);
WaitForPauseAction();
buffer = &resultBuffer; buffer = &resultBuffer;
return bufferResult; return bufferResult;
} }

View file

@ -30,12 +30,14 @@ namespace GPUStepping {
bool EnterStepping(); bool EnterStepping();
bool IsStepping(); bool IsStepping();
void ResumeFromStepping(); void ResumeFromStepping();
void WaitForAction();
int GetSteppingCounter(); int GetSteppingCounter();
// Called from the emu thread. // Called from the emu thread.
bool ProcessStepping(); bool ProcessStepping();
// NOTE: These are only usable from non-EmuThread threads.
bool GPU_GetOutputFramebuffer(const GPUDebugBuffer *&buffer); bool GPU_GetOutputFramebuffer(const GPUDebugBuffer *&buffer);
bool GPU_GetCurrentFramebuffer(const GPUDebugBuffer *&buffer, GPUDebugFramebufferType type); bool GPU_GetCurrentFramebuffer(const GPUDebugBuffer *&buffer, GPUDebugFramebufferType type);
bool GPU_GetCurrentDepthbuffer(const GPUDebugBuffer *&buffer); bool GPU_GetCurrentDepthbuffer(const GPUDebugBuffer *&buffer);

View file

@ -56,7 +56,6 @@
#include "GPU/Debugger/Stepping.h" #include "GPU/Debugger/Stepping.h"
using namespace GPUBreakpoints; using namespace GPUBreakpoints;
using namespace GPUDebug;
using namespace GPUStepping; using namespace GPUStepping;
enum PrimaryDisplayType { enum PrimaryDisplayType {
@ -136,8 +135,8 @@ StepCountDlg::~StepCountDlg() {
void StepCountDlg::Jump(int count, bool relative) { void StepCountDlg::Jump(int count, bool relative) {
if (relative && count == 0) if (relative && count == 0)
return; return;
SetBreakNext(BreakNext::COUNT); GPUDebug::SetBreakNext(GPUDebug::BreakNext::COUNT);
SetBreakCount(count, relative); GPUDebug::SetBreakCount(count, relative);
}; };
BOOL StepCountDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { BOOL StepCountDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
@ -575,7 +574,7 @@ void CGEDebugger::UpdatePreviews() {
} }
wchar_t primCounter[1024]{}; 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); SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, primCounter);
for (GEDebuggerTab &tabState : tabStates_) { for (GEDebuggerTab &tabState : tabStates_) {
@ -698,7 +697,9 @@ void CGEDebugger::UpdatePrimaryPreview(const GPUgstate &state) {
} }
if (bufferResult && primaryBuffer_ != nullptr) { 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->SetFlags(flags);
primaryWindow->Draw(primaryBuffer_->GetData(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight(), primaryBuffer_->GetFlipped(), fmt); primaryWindow->Draw(primaryBuffer_->GetData(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight(), primaryBuffer_->GetFlipped(), fmt);
@ -735,7 +736,9 @@ void CGEDebugger::UpdateSecondPreview(const GPUgstate &state) {
} }
if (bufferResult) { 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)); secondWindow->SetFlags(TexturePreviewFlags(state));
if (showClut_) { if (showClut_) {
// Reduce the stride so it's easier to see. // 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: case WM_COMMAND:
switch (LOWORD(wParam)) { switch (LOWORD(wParam)) {
case IDC_GEDBG_STEPDRAW: case IDC_GEDBG_STEPDRAW:
SetBreakNext(BreakNext::DRAW); GPUDebug::SetBreakNext(GPUDebug::BreakNext::DRAW);
break; break;
case IDC_GEDBG_STEP: case IDC_GEDBG_STEP:
SetBreakNext(BreakNext::OP); GPUDebug::SetBreakNext(GPUDebug::BreakNext::OP);
break; break;
case IDC_GEDBG_STEPTEX: case IDC_GEDBG_STEPTEX:
SetBreakNext(BreakNext::TEX); GPUDebug::SetBreakNext(GPUDebug::BreakNext::TEX);
break; break;
case IDC_GEDBG_STEPFRAME: case IDC_GEDBG_STEPFRAME:
SetBreakNext(BreakNext::FRAME); GPUDebug::SetBreakNext(GPUDebug::BreakNext::FRAME);
break; break;
case IDC_GEDBG_STEPVSYNC: case IDC_GEDBG_STEPVSYNC:
SetBreakNext(BreakNext::VSYNC); GPUDebug::SetBreakNext(GPUDebug::BreakNext::VSYNC);
break; break;
case IDC_GEDBG_STEPPRIM: case IDC_GEDBG_STEPPRIM:
SetBreakNext(BreakNext::PRIM); GPUDebug::SetBreakNext(GPUDebug::BreakNext::PRIM);
break; break;
case IDC_GEDBG_STEPCURVE: case IDC_GEDBG_STEPCURVE:
SetBreakNext(BreakNext::CURVE); GPUDebug::SetBreakNext(GPUDebug::BreakNext::CURVE);
break; break;
case IDC_GEDBG_STEPCOUNT: 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_TEXADDR, L"");
SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, L""); SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, L"");
SetBreakNext(BreakNext::NONE); GPUDebug::SetBreakNext(GPUDebug::BreakNext::NONE);
break; break;
case IDC_GEDBG_RECORD: case IDC_GEDBG_RECORD:
@ -1266,7 +1269,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
break; break;
case WM_GEDBG_STEPDISPLAYLIST: case WM_GEDBG_STEPDISPLAYLIST:
SetBreakNext(BreakNext::OP); GPUDebug::SetBreakNext(GPUDebug::BreakNext::OP);
break; break;
case WM_GEDBG_TOGGLEPCBREAKPOINT: case WM_GEDBG_TOGGLEPCBREAKPOINT:

View file

@ -253,7 +253,7 @@ void SimpleGLWindow::DrawChecker() {
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, vao_ ? 0 : indices); 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_); wglMakeCurrent(hDC_, hGLRC_);
GLint components = GL_RGBA; GLint components = GL_RGBA;