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_SPLINE, true);
}
if (GPUStepping::IsStepping()) {
GPUStepping::ResumeFromStepping();
}
lastStepTime = next == BreakNext::NONE ? -1.0 : time_now_d();
}

View file

@ -19,6 +19,7 @@
#include <condition_variable>
#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<std::mutex> guard(actionLock);
@ -80,12 +97,14 @@ static void SetPauseAction(PauseAction act, bool waitComplete = true) {
static void RunPauseAction() {
std::lock_guard<std::mutex> 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<std::mutex> 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;
}

View file

@ -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);

View file

@ -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:

View file

@ -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;