diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index f941e4d170..e1cfacdc90 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -485,7 +485,7 @@ void DrawEngineD3D11::DoFlush() { ResetAfterDrawInline(); framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); - GPUDebug::NotifyDraw(); + GPUDebug::NotifyFlush(); } TessellationDataTransferD3D11::TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device) diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 740f47e612..e7dee230e7 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -26,7 +26,6 @@ namespace GPUDebug { -static bool active = false; static BreakNext breakNext = BreakNext::NONE; static int breakAtCount = -1; @@ -58,26 +57,15 @@ const char *BreakNextToString(BreakNext next) { } } -void SetActive(bool flag) { - active = flag; - if (!active) { - breakNext = BreakNext::NONE; - breakAtCount = -1; - GPUStepping::ResumeFromStepping(); - lastStepTime = -1.0; - } - /* - active = false; - breakAtCount = -1; - thisFlipNum = 0; - g_primAfterDraw = false; - lastStepTime = -1.0f; - g_skipPcOnce = false; - */ +bool NeedsSlowInterpreter() { + return breakNext != BreakNext::NONE || GPUBreakpoints::g_hasBreakpoints; } -bool IsActive() { - return active; +void ClearBreak() { + breakNext = BreakNext::NONE; + breakAtCount = -1; + GPUStepping::ResumeFromStepping(); + lastStepTime = -1.0; } BreakNext GetBreakNext() { @@ -85,7 +73,6 @@ BreakNext GetBreakNext() { } void SetBreakNext(BreakNext next) { - SetActive(true); breakNext = next; breakAtCount = -1; if (next == BreakNext::TEX) { @@ -119,11 +106,6 @@ void SetBreakCount(int c, bool relative) { } NotifyResult NotifyCommand(u32 pc) { - if (!active) { - _dbg_assert_(false); - return NotifyResult::Skip; // return false - } - u32 op = Memory::ReadUnchecked_U32(pc); u32 cmd = op >> 24; if (thisFlipNum != gpuStats.numFlips) { @@ -187,12 +169,9 @@ NotifyResult NotifyCommand(u32 pc) { return process ? NotifyResult::Execute : NotifyResult::Skip; } -// TODO: This mechanism is a bit hacky. -void NotifyDraw() { - if (!active) - return; +void NotifyFlush() { if (breakNext == BreakNext::DRAW && !GPUStepping::IsStepping()) { - // Hack to handle draw notifications, that don't come in via NotifyCommand. + // Break on the first PRIM after a flush. if (g_primAfterDraw) { NOTICE_LOG(Log::GeDebugger, "Flush detected, breaking at next PRIM"); g_primAfterDraw = false; @@ -203,17 +182,13 @@ void NotifyDraw() { } void NotifyDisplay(u32 framebuf, u32 stride, int format) { - if (!active) - return; if (breakNext == BreakNext::FRAME) { - // This should work fine, start stepping at the first op of the new frame. + // Start stepping at the first op of the new frame. breakNext = BreakNext::OP; } } void NotifyBeginFrame() { - if (!active) - return; if (breakNext == BreakNext::VSYNC) { // Just start stepping as soon as we can once the vblank finishes. breakNext = BreakNext::OP; @@ -238,7 +213,6 @@ static bool ParseRange(const std::string &s, std::pair &range) { } bool SetRestrictPrims(const char *rule) { - SetActive(true); if (rule == nullptr || rule[0] == 0 || (rule[0] == '*' && rule[1] == 0)) { restrictPrimRanges.clear(); restrictPrimRule.clear(); diff --git a/GPU/Debugger/Debugger.h b/GPU/Debugger/Debugger.h index d7cfb7a7bf..1c19b9b885 100644 --- a/GPU/Debugger/Debugger.h +++ b/GPU/Debugger/Debugger.h @@ -34,8 +34,7 @@ enum class BreakNext { COUNT, }; -void SetActive(bool flag); -bool IsActive(); +bool NeedsSlowInterpreter(); void SetBreakNext(BreakNext next); void SetBreakCount(int c, bool relative = false); @@ -50,7 +49,7 @@ enum class NotifyResult { // While debugging is active, these may block. NotifyResult NotifyCommand(u32 pc); -void NotifyDraw(); +void NotifyFlush(); void NotifyDisplay(u32 framebuf, u32 stride, int format); void NotifyBeginFrame(); diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 6b8e8bdca0..50f830b385 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -421,7 +421,7 @@ void DrawEngineDX9::DoFlush() { ResetAfterDrawInline(); framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); - GPUDebug::NotifyDraw(); + GPUDebug::NotifyFlush(); } void TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) { diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 0e3090752b..08df5d630b 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -451,7 +451,7 @@ void DrawEngineGLES::DoFlush() { bail: ResetAfterDrawInline(); framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); - GPUDebug::NotifyDraw(); + GPUDebug::NotifyFlush(); } // TODO: Refactor this to a single USE flag. diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index ec29fbad32..2a3b5d7d47 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -791,7 +791,8 @@ DLResult GPUCommon::ProcessDLQueue() { gpuState = list.pc == list.stall ? GPUSTATE_STALL : GPUSTATE_RUNNING; // To enable breakpoints, we don't do fast matrix loads while debugger active. - debugRecording_ = GPUDebug::IsActive() || GPURecord::IsActive(); + debugRecording_ = GPURecord::IsActive(); + useFastRunLoop_ = !(dumpThisFrame_ || debugRecording_ || GPUDebug::NeedsSlowInterpreter()); } else { resumingFromDebugBreak_ = false; // The bottom part of the gpuState loop below, that wasn't executed @@ -804,7 +805,7 @@ DLResult GPUCommon::ProcessDLQueue() { // Proceed... } - const bool useFastRunLoop = !dumpThisFrame_ && !debugRecording_; + const bool useFastRunLoop = useFastRunLoop_; while (gpuState == GPUSTATE_RUNNING) { if (list.pc == list.stall) { @@ -880,9 +881,9 @@ DLResult GPUCommon::ProcessDLQueue() { } bool GPUCommon::ShouldSplitOverGe() const { - // Check for debugger active, etc. + // Check for debugger active. // We only need to do this if we want to be able to step through Ge display lists using the Ge debuggers. - return GPUDebug::IsActive() || g_Config.bShowImDebugger; + return GPUDebug::NeedsSlowInterpreter(); } void GPUCommon::Execute_OffsetAddr(u32 op, u32 diff) { @@ -948,8 +949,8 @@ void GPUCommon::DoExecuteCall(u32 target) { DisplayList *currentList = this->currentList; // Bone matrix optimization - many games will CALL a bone matrix (!). - // We don't optimize during recording - so the matrix data gets recorded. - if (!debugRecording_ && Memory::IsValidRange(target, 13 * 4) && (Memory::ReadUnchecked_U32(target) >> 24) == GE_CMD_BONEMATRIXDATA) { + // We don't optimize during recording or debugging - so the matrix data gets recorded. + if (useFastRunLoop_ && Memory::IsValidRange(target, 13 * 4) && (Memory::ReadUnchecked_U32(target) >> 24) == GE_CMD_BONEMATRIXDATA) { // Check for the end if ((Memory::ReadUnchecked_U32(target + 11 * 4) >> 24) == GE_CMD_BONEMATRIXDATA && (Memory::ReadUnchecked_U32(target + 12 * 4) >> 24) == GE_CMD_RET && diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index cf442ed61c..4bdfcaf7a0 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -447,7 +447,7 @@ protected: bool interruptRunning = false; GPURunState gpuState = GPUSTATE_RUNNING; - bool isbreak; + bool isbreak; // This doesn't mean debugger breakpoints. u64 drawCompleteTicks; u64 busyTicks; @@ -459,8 +459,9 @@ protected: bool resumingFromDebugBreak_ = false; bool dumpNextFrame_ = false; bool dumpThisFrame_ = false; - bool debugRecording_; - bool interruptsEnabled_; + bool useFastRunLoop_ = false; + bool debugRecording_ = false; + bool interruptsEnabled_ = false; bool displayResized_ = false; bool renderResized_ = false; bool configChanged_ = false; diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index b92cb7c1be..2a8e4c72ed 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -896,7 +896,7 @@ void TransformUnit::Flush(const char *reason) { return; binner_->Flush(reason); - GPUDebug::NotifyDraw(); + GPUDebug::NotifyFlush(); hasDraws_ = false; } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 3285ef13d5..47b466fc11 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -569,7 +569,7 @@ void DrawEngineVulkan::DoFlush() { framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); - GPUDebug::NotifyDraw(); + GPUDebug::NotifyFlush(); } void DrawEngineVulkan::ResetAfterDraw() { diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 2878ad1867..4bcf4de7e4 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -925,8 +925,6 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { return TRUE; case WM_CLOSE: - GPUDebug::SetActive(false); - stepCountDlg.Show(false); Show(false); return TRUE; @@ -978,7 +976,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { break; case IDC_GEDBG_FBTABS: fbTabs->HandleNotify(lParam); - if (GPUDebug::IsActive() && gpuDebug != nullptr) { + if (gpuDebug != nullptr) { UpdatePreviews(); } break; @@ -1025,7 +1023,6 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case IDC_GEDBG_BREAKTEX: { - GPUDebug::SetActive(true); if (!gpuDebug) { break; } @@ -1044,7 +1041,6 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case IDC_GEDBG_BREAKTARGET: { - GPUDebug::SetActive(true); if (!gpuDebug) { break; } @@ -1062,15 +1058,15 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { break; case IDC_GEDBG_TEXLEVELDOWN: - UpdateTextureLevel(textureLevel_ - 1); - if (GPUDebug::IsActive() && gpuDebug != nullptr) { + if (gpuDebug != nullptr) { + UpdateTextureLevel(textureLevel_ - 1); UpdatePreviews(); } break; case IDC_GEDBG_TEXLEVELUP: - UpdateTextureLevel(textureLevel_ + 1); - if (GPUDebug::IsActive() && gpuDebug != nullptr) { + if (gpuDebug != nullptr) { + UpdateTextureLevel(textureLevel_ + 1); UpdatePreviews(); } break; @@ -1094,7 +1090,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { break; case IDC_GEDBG_FLUSH: - if (GPUDebug::IsActive() && gpuDebug != nullptr) { + if (gpuDebug != nullptr) { if (!autoFlush_) GPU_FlushDrawing(); UpdatePreviews(); @@ -1106,14 +1102,14 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { break; case IDC_GEDBG_FORCEOPAQUE: - if (GPUDebug::IsActive() && gpuDebug != nullptr) { + if (gpuDebug != nullptr) { forceOpaque_ = SendMessage(GetDlgItem(m_hDlg, IDC_GEDBG_FORCEOPAQUE), BM_GETCHECK, 0, 0) != 0; UpdatePreviews(); } break; case IDC_GEDBG_SHOWCLUT: - if (GPUDebug::IsActive() && gpuDebug != nullptr) { + if (gpuDebug != nullptr) { showClut_ = SendMessage(GetDlgItem(m_hDlg, IDC_GEDBG_SHOWCLUT), BM_GETCHECK, 0, 0) != 0; UpdatePreviews(); } @@ -1136,7 +1132,6 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case WM_GEDBG_TOGGLEPCBREAKPOINT: { - GPUDebug::SetActive(true); u32 pc = (u32)wParam; bool temp; bool isBreak = IsAddressBreakpoint(pc, temp); @@ -1156,7 +1151,6 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case WM_GEDBG_RUNTOWPARAM: { - GPUDebug::SetActive(true); u32 pc = (u32)wParam; AddAddressBreakpoint(pc, true); SendMessage(m_hDlg,WM_COMMAND,IDC_GEDBG_RESUME,0);