From fe62ac793addb7c2484111db58385b256b7b523f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Dec 2024 15:51:35 +0100 Subject: [PATCH 1/9] ImDebugger scheduler: Show userdata field --- UI/ImDebugger/ImDebugger.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index f8fd6b443c..64d8e93d3e 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -51,7 +51,7 @@ void DrawSchedulerView(ImConfig &cfg) { if (ImGui::BeginChild("event_list", ImVec2(300.0f, 0.0))) { const CoreTiming::Event *event = CoreTiming::GetFirstEvent(); while (event) { - ImGui::Text("%s (%lld)", CoreTiming::GetEventTypes()[event->type].name, event->time - ticks); + ImGui::Text("%s (%lld): %d", CoreTiming::GetEventTypes()[event->type].name, event->time - ticks, (int)event->userdata); event = event->next; } ImGui::EndChild(); @@ -195,6 +195,9 @@ void WaitIDToString(WaitType waitType, SceUID waitID, char *buffer, size_t bufSi case WAITTYPE_SLEEP: case WAITTYPE_HLEDELAY: case WAITTYPE_UMD: + case WAITTYPE_NONE: + case WAITTYPE_VBLANK: + case WAITTYPE_MICINPUT: truncate_cpy(buffer, bufSize, "-"); return; default: From 55217ddc11a3b12b5b1f5d0d13b4f5a37f23ecd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 6 Dec 2024 13:31:18 +0100 Subject: [PATCH 2/9] Minor UI tweaks --- UI/ImDebugger/ImDebugger.cpp | 5 +++++ UI/ImDebugger/ImGe.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 64d8e93d3e..3a97e41b68 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -1160,6 +1160,11 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, CoreStat disasmView_.setCurAddress(gotoAddr_); disasmView_.scrollAddressIntoView(); } + ImGui::SameLine(); + if (ImGui::Button("Go")) { + disasmView_.setCurAddress(gotoAddr_); + disasmView_.scrollAddressIntoView(); + } if (ImGui::BeginTable("main", 2)) { ImGui::TableSetupColumn("left", ImGuiTableColumnFlags_WidthFixed); diff --git a/UI/ImDebugger/ImGe.cpp b/UI/ImDebugger/ImGe.cpp index e79a583ddb..c5258f0554 100644 --- a/UI/ImDebugger/ImGe.cpp +++ b/UI/ImDebugger/ImGe.cpp @@ -242,9 +242,11 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, GPUDebugInterface *gpuDebug) { return; } + ImGui::BeginDisabled(coreState != CORE_STEPPING_GE); if (ImGui::Button("Run/Resume")) { Core_Resume(); } + ImGui::EndDisabled(); ImGui::SameLine(); ImGui::TextUnformatted("Break:"); ImGui::SameLine(); From a94431f4fa8f8a6fb435a4506cd2f90ba554586f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 6 Dec 2024 19:53:31 +0100 Subject: [PATCH 3/9] Remove an unnecessary wrapper function --- GPU/Debugger/Playback.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index 41a14dc43e..11f8a81684 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -293,7 +293,6 @@ public: private: void SyncStall(); - bool SubmitCmds(const void *p, u32 sz); void SubmitListEnd(); void Init(u32 ptr, u32 sz); @@ -331,6 +330,7 @@ private: void DumpExecute::SyncStall() { if (execListBuf == 0) { + VERBOSE_LOG(Log::G3D, "SyncStall: No active display list"); return; } @@ -347,12 +347,11 @@ void DumpExecute::SyncStall() { currentMIPS->downcount -= listTicks - nowTicks; } } - // Make sure downcount doesn't overflow. CoreTiming::ForceCheck(); } -bool DumpExecute::SubmitCmds(const void *p, u32 sz) { +void DumpExecute::Registers(u32 ptr, u32 sz) { if (execListBuf == 0) { u32 allocSize = LIST_BUF_SIZE; execListBuf = userMemory.Alloc(allocSize, true, "List buf"); @@ -361,7 +360,7 @@ bool DumpExecute::SubmitCmds(const void *p, u32 sz) { } if (execListBuf == 0) { ERROR_LOG(Log::System, "Unable to allocate for display list"); - return false; + return; } execListPos = execListBuf; @@ -389,13 +388,15 @@ bool DumpExecute::SubmitCmds(const void *p, u32 sz) { lastBase_ = execListBuf & 0xFF000000; // Don't continue until we've stalled. + // TODO: Is this really needed? It seems fine without it. SyncStall(); } Memory::MemcpyUnchecked(execListPos, execListQueue.data(), pendingSize); execListPos += pendingSize; u32 writePos = execListPos; - Memory::MemcpyUnchecked(execListPos, p, sz); + void *srcData = (void *)(pushbuf_.data() + ptr); + Memory::MemcpyUnchecked(execListPos, srcData, sz); execListPos += sz; // TODO: Unfortunate. Maybe Texture commands should contain the bufw instead. @@ -431,8 +432,6 @@ bool DumpExecute::SubmitCmds(const void *p, u32 sz) { } execListQueue.clear(); - - return true; } void DumpExecute::SubmitListEnd() { @@ -464,10 +463,6 @@ void DumpExecute::Init(u32 ptr, u32 sz) { lastBase_ = 0xFFFFFFFF; } -void DumpExecute::Registers(u32 ptr, u32 sz) { - SubmitCmds(pushbuf_.data() + ptr, sz); -} - void DumpExecute::Vertices(u32 ptr, u32 sz) { u32 psp = mapping_.Map(ptr, sz, std::bind(&DumpExecute::SyncStall, this)); if (psp == 0) { From de3617529f0c451b19b51aa60d897453af3571e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Dec 2024 16:21:08 +0100 Subject: [PATCH 4/9] const, rename a function --- Core/Core.h | 2 +- GPU/Debugger/Playback.cpp | 6 +++--- Windows/EmuThread.cpp | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Core/Core.h b/Core/Core.h index 0b20d2ac6a..d867e8b439 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -26,7 +26,7 @@ class GraphicsContext; -// For platforms that don't call Core_Run +// For platforms that don't call Run void Core_SetGraphicsContext(GraphicsContext *ctx); // Returns false when an UI exit state is detected. diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index 11f8a81684..8073440c0b 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -100,7 +100,7 @@ protected: u32 buf_pointer_ = 0; int last_used_ = 0; - bool Matches(u32 bufpos) { + bool Matches(u32 bufpos) const { // We check psp_pointer_ because bufpos = 0 is valid, and the initial value. return buf_pointer_ == bufpos && psp_pointer_ != 0; } @@ -130,12 +130,12 @@ protected: u32 buf_pointer_ = 0; u32 size_ = 0; - bool Matches(u32 bufpos, u32 sz) { + bool Matches(u32 bufpos, u32 sz) const { // We check psp_pointer_ because bufpos = 0 is valid, and the initial value. return buf_pointer_ == bufpos && psp_pointer_ != 0 && size_ >= sz; } - u32 Ptr() { + u32 Ptr() const { return psp_pointer_; } diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 4f0c1924c1..2e20d21b5b 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -75,7 +75,7 @@ bool MainThread_Ready() { return g_inLoop; } -static bool Core_Run(GraphicsContext *ctx) { +static bool Run(GraphicsContext *ctx) { System_Notify(SystemNotification::DISASSEMBLY); while (true) { if (GetUIState() != UISTATE_INGAME) { @@ -127,11 +127,11 @@ static void EmuThreadFunc(GraphicsContext *graphicsContext) { NativeInitGraphics(graphicsContext); while (emuThreadState != (int)EmuThreadState::QUIT_REQUESTED) { - // We're here again, so the game quit. Restart Core_Run() which controls the UI. + // We're here again, so the game quit. Restart Run() which controls the UI. // This way they can load a new game. if (!Core_IsActive()) UpdateUIState(UISTATE_MENU); - if (!Core_Run(g_graphicsContext)) { + if (!Run(g_graphicsContext)) { emuThreadState = (int)EmuThreadState::QUIT_REQUESTED; } } @@ -338,11 +338,11 @@ void MainThreadFunc() { } } else { while (GetUIState() != UISTATE_EXIT) { // && GetUIState() != UISTATE_EXCEPTION - // We're here again, so the game quit. Restart Core_Run() which controls the UI. + // We're here again, so the game quit. Restart Run() which controls the UI. // This way they can load a new game. if (!Core_IsActive()) UpdateUIState(UISTATE_MENU); - Core_Run(g_graphicsContext); + Run(g_graphicsContext); if (coreState == CORE_BOOT_ERROR) { break; } @@ -351,7 +351,7 @@ void MainThreadFunc() { Core_Stop(); if (!useEmuThread) { // Process the shutdown. Without this, non-GL delays 800ms on shutdown. - Core_Run(g_graphicsContext); + Run(g_graphicsContext); } Core_WaitInactive(); From 132fabff07c79300ccd03a95e8cf64c5778099e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 9 Dec 2024 10:54:55 +0100 Subject: [PATCH 5/9] ImDebugger: Add way to cancel pending step --- UI/ImDebugger/ImGe.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/UI/ImDebugger/ImGe.cpp b/UI/ImDebugger/ImGe.cpp index c5258f0554..ae697e9c77 100644 --- a/UI/ImDebugger/ImGe.cpp +++ b/UI/ImDebugger/ImGe.cpp @@ -304,6 +304,10 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, GPUDebugInterface *gpuDebug) { // Display any pending step event. if (GPUDebug::GetBreakNext() != GPUDebug::BreakNext::NONE) { ImGui::Text("Step pending (waiting for CPU): %s", GPUDebug::BreakNextToString(GPUDebug::GetBreakNext())); + ImGui::SameLine(); + if (ImGui::Button("Cancel step")) { + GPUDebug::SetBreakNext(GPUDebug::BreakNext::NONE); + } } // Let's display the current CLUT. From 10445c97d8eb28a152fde007ef07f53bbb82a847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Dec 2024 19:09:07 +0100 Subject: [PATCH 6/9] Warning fix --- GPU/Debugger/Playback.cpp | 2 ++ UI/ImDebugger/ImDebugger.cpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index 8073440c0b..1efe13da70 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -19,9 +19,11 @@ #include #include #include +#include #include #include #include + #include "Common/Profiler/Profiler.h" #include "Common/CommonTypes.h" #include "Common/Log.h" diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 3a97e41b68..b81e45c00b 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -314,7 +314,7 @@ static void DrawFilesystemBrowser(ImConfig &cfg) { std::string path; char desc[256]; fs.system->Describe(desc, sizeof(desc)); - char fsTitle[256]; + char fsTitle[512]; snprintf(fsTitle, sizeof(fsTitle), "%s - %s", fs.prefix.c_str(), desc); if (ImGui::TreeNode(fsTitle)) { auto system = fs.system; @@ -855,6 +855,8 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu Core_Break("Menu:Break"); } break; + default: + break; } ImGui::Separator(); ImGui::MenuItem("Ignore bad memory accesses", nullptr, &g_Config.bIgnoreBadMemAccess); From 43af3128e09e32ee4cdb532ce24d35f39c1f9915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 10 Dec 2024 00:56:49 +0100 Subject: [PATCH 7/9] Fix drag/drop crash --- Windows/MainWindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 72621a1f08..9cb88a34d6 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -1055,7 +1055,6 @@ namespace MainWindow if (DragQueryFile(hdrop, 0, filename, ARRAY_SIZE(filename)) != 0) { const std::string utf8_filename = ReplaceAll(ConvertWStringToUTF8(filename), "\\", "/"); System_PostUIMessage(UIMessage::REQUEST_GAME_BOOT, utf8_filename); - Core_Resume(); } } DragFinish(hdrop); From c842e3f137f0fe5df6c97f838ed9d30a48502277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 9 Dec 2024 12:00:15 +0100 Subject: [PATCH 8/9] Fix discrepancy between stepping and running across frame endings. Add some more menu options in the ImDebugger --- Core/Config.h | 4 +++- Core/Core.cpp | 7 +++++-- GPU/GPUCommon.cpp | 22 +++++++++++----------- GPU/GPUCommon.h | 4 ++-- UI/ImDebugger/ImDebugger.cpp | 5 +++++ 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Core/Config.h b/Core/Config.h index 8eff66237e..bf8f5b8634 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -70,11 +70,13 @@ public: bool bFirstRun; bool bGameSpecific = false; bool bUpdatedInstanceCounter = false; + bool bBrowse; // show a file browser on startup. TODO: Does anyone use this? int iRunCount; // To be used to for example check for updates every 10 runs and things like that. + // Debugger bool bAutoRun; // start immediately - bool bBrowse; // when opening the emulator, immediately show a file browser + bool bBreakOnFrameTimeout; // not saved // General bool bScreenshotsAsPNG; diff --git a/Core/Core.cpp b/Core/Core.cpp index cb6d9ca1e0..b92f94e3ce 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -430,12 +430,15 @@ void Core_Resume() { // Should be called from the EmuThread. bool Core_NextFrame() { + CoreState coreState = ::coreState; + _dbg_assert_(coreState != CORE_STEPPING_GE && coreState != CORE_RUNNING_GE); - if (coreState == CORE_RUNNING_CPU) { - coreState = CORE_NEXTFRAME; + if (coreState == CORE_RUNNING_CPU || coreState == CORE_STEPPING_CPU) { + ::coreState = CORE_NEXTFRAME; return true; } else { + ERROR_LOG(Log::System, "Core_NextFrame called with core state %s", CoreStateToString(coreState)); return false; } } diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index fa9a91f564..95c1c76830 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -97,7 +97,7 @@ void GPUCommon::Reinitialize() { memset(dls, 0, sizeof(dls)); for (int i = 0; i < DisplayListMaxCount; ++i) { dls[i].state = PSP_GE_DL_STATE_NONE; - dls[i].waitTicks = 0; + dls[i].waitUntilTicks = 0; } nextListID = 0; @@ -273,7 +273,7 @@ int GPUCommon::ListSync(int listid, int mode) { return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; } - if (dl.waitTicks > CoreTiming::GetTicks()) { + if (dl.waitUntilTicks > CoreTiming::GetTicks()) { __GeWaitCurrentThread(GPU_SYNC_LIST, listid, "GeListSync"); } return PSP_GE_LIST_COMPLETED; @@ -409,7 +409,7 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointerpendingInterrupt = true; } else { currentList->state = PSP_GE_DL_STATE_COMPLETED; - currentList->waitTicks = startingTicks + cyclesExecuted; - busyTicks = std::max(busyTicks, currentList->waitTicks); - __GeTriggerSync(GPU_SYNC_LIST, currentList->id, currentList->waitTicks); + currentList->waitUntilTicks = startingTicks + cyclesExecuted; + busyTicks = std::max(busyTicks, currentList->waitUntilTicks); + __GeTriggerSync(GPU_SYNC_LIST, currentList->id, currentList->waitUntilTicks); } break; } @@ -1419,7 +1419,7 @@ struct DisplayList_v1 { DisplayListStackEntry stack[32]; int stackptr; bool interrupted; - u64 waitTicks; + u64 waitUntilTicks; bool interruptsEnabled; bool pendingInterrupt; bool started; @@ -1440,7 +1440,7 @@ struct DisplayList_v2 { DisplayListStackEntry stack[32]; int stackptr; bool interrupted; - u64 waitTicks; + u64 waitUntilTicks; bool interruptsEnabled; bool pendingInterrupt; bool started; @@ -1547,7 +1547,7 @@ void GPUCommon::InterruptEnd(int listid) { gstate.Restore(dl.context); ReapplyGfxState(); } - dl.waitTicks = 0; + dl.waitUntilTicks = 0; __GeTriggerWait(GPU_SYNC_LIST, listid); // Make sure the list isn't still queued since it's now completed. diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index b14742bb0c..305a04d7da 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -125,7 +125,7 @@ struct DisplayList { DisplayListStackEntry stack[32]; int stackptr; bool interrupted; - u64 waitTicks; + u64 waitUntilTicks; bool interruptsEnabled; bool pendingInterrupt; bool started; @@ -371,7 +371,7 @@ public: s64 GetListTicks(int listid) const { if (listid >= 0 && listid < DisplayListMaxCount) { - return dls[listid].waitTicks; + return dls[listid].waitUntilTicks; } return -1; } diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index b81e45c00b..e115c6643e 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -860,7 +860,11 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu } ImGui::Separator(); ImGui::MenuItem("Ignore bad memory accesses", nullptr, &g_Config.bIgnoreBadMemAccess); + ImGui::MenuItem("Break on frame timeout", nullptr, &g_Config.bBreakOnFrameTimeout); + ImGui::MenuItem("Don't break on start", nullptr, &g_Config.bAutoRun); // should really invert this bool! + ImGui::MenuItem("Fast memory", nullptr, &g_Config.bFastMemory); ImGui::Separator(); + /* // Symbol stuff. Move to separate menu? // Doesn't quite seem to work yet. @@ -891,6 +895,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu if (ImGui::MenuItem("Take screenshot")) { g_TakeScreenshot = true; } + ImGui::MenuItem("Save screenshot as .png", nullptr, &g_Config.bScreenshotsAsPNG); if (ImGui::MenuItem("Restart graphics")) { System_PostUIMessage(UIMessage::RESTART_GRAPHICS); } From b2a8b4168bd506d95cb1c00ffc239552660c21b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 9 Dec 2024 23:49:37 +0100 Subject: [PATCH 9/9] Core: Minor changes to stepping (and some log changes) --- Common/GPU/Vulkan/VulkanRenderManager.cpp | 2 ++ Core/Core.cpp | 30 +++++++++++++++++------ Core/System.cpp | 1 + GPU/Common/FramebufferManagerCommon.cpp | 4 +-- GPU/GPUCommon.cpp | 2 +- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index 13b59510f8..57e4f199eb 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -129,6 +129,7 @@ bool VKRGraphicsPipeline::Create(VulkanContext *vulkan, VkRenderPass compatibleR double taken_ms_since_scheduling = (now - scheduleTime) * 1000.0; double taken_ms = (now - start) * 1000.0; +#ifndef _DEBUG if (taken_ms < 0.1) { DEBUG_LOG(Log::G3D, "Pipeline (x/%d) time on %s: %0.2f ms, %0.2f ms since scheduling (fast) rpType: %04x sampleBits: %d (%s)", countToCompile, GetCurrentThreadName(), taken_ms, taken_ms_since_scheduling, (u32)rpType, (u32)sampleCount, tag_.c_str()); @@ -136,6 +137,7 @@ bool VKRGraphicsPipeline::Create(VulkanContext *vulkan, VkRenderPass compatibleR INFO_LOG(Log::G3D, "Pipeline (x/%d) time on %s: %0.2f ms, %0.2f ms since scheduling rpType: %04x sampleBits: %d (%s)", countToCompile, GetCurrentThreadName(), taken_ms, taken_ms_since_scheduling, (u32)rpType, (u32)sampleCount, tag_.c_str()); } +#endif bool success = true; if (result == VK_INCOMPLETE) { diff --git a/Core/Core.cpp b/Core/Core.cpp index b92f94e3ce..109bb7551b 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -90,7 +90,7 @@ static bool g_breakAfterFrame = false; static MIPSExceptionInfo g_exceptionInfo; // This is called on EmuThread before RunLoop. -static void Core_ProcessStepping(MIPSDebugInterface *cpu); +static bool Core_ProcessStepping(MIPSDebugInterface *cpu); void Core_SetGraphicsContext(GraphicsContext *ctx) { PSP_CoreParameter().graphicsContext = ctx; @@ -173,8 +173,10 @@ void Core_RunLoopUntil(u64 globalticks) { return; case CORE_STEPPING_CPU: case CORE_STEPPING_GE: - Core_ProcessStepping(currentDebugMIPS); - return; + if (Core_ProcessStepping(currentDebugMIPS)) { + return; + } + break; case CORE_RUNNING_CPU: mipsr4k.RunLoopUntil(globalticks); if (g_breakAfterFrame && coreState == CORE_NEXTFRAME) { @@ -327,7 +329,7 @@ static void Core_PerformCPUStep(MIPSDebugInterface *cpu, CPUStepType stepType, i } } -static void Core_ProcessStepping(MIPSDebugInterface *cpu) { +static bool Core_ProcessStepping(MIPSDebugInterface *cpu) { Core_StateProcessed(); // Check if there's any pending save state actions. @@ -336,17 +338,23 @@ static void Core_ProcessStepping(MIPSDebugInterface *cpu) { switch (coreState) { case CORE_STEPPING_CPU: case CORE_STEPPING_GE: + case CORE_RUNNING_GE: // All good break; default: // Nothing to do. - return; + return true; } // Or any GPU actions. // Legacy stepping code. GPUStepping::ProcessStepping(); + if (coreState == CORE_RUNNING_GE) { + // Retry, to get it done this frame. + return false; + } + // We're not inside jit now, so it's safe to clear the breakpoints. static int lastSteppingCounter = -1; if (lastSteppingCounter != steppingCounter) { @@ -360,7 +368,7 @@ static void Core_ProcessStepping(MIPSDebugInterface *cpu) { std::lock_guard guard(g_stepMutex); if (coreState != CORE_STEPPING_CPU || g_cpuStepCommand.empty()) { - return; + return true; } Core_ResetException(); @@ -377,6 +385,7 @@ static void Core_ProcessStepping(MIPSDebugInterface *cpu) { // Update disasm dialog. System_Notify(SystemNotification::MEM_VIEW); + return true; } // Free-threaded (hm, possibly except tracing). @@ -434,11 +443,16 @@ bool Core_NextFrame() { _dbg_assert_(coreState != CORE_STEPPING_GE && coreState != CORE_RUNNING_GE); - if (coreState == CORE_RUNNING_CPU || coreState == CORE_STEPPING_CPU) { + if (coreState == CORE_RUNNING_CPU) { ::coreState = CORE_NEXTFRAME; return true; + } else if (coreState == CORE_STEPPING_CPU) { + // All good, just stepping through so no need to switch to the NextFrame coreState though, that'd + // just lose our stepping state. + INFO_LOG(Log::System, "Reached end-of-frame while stepping the CPU (this is ok)"); + return true; } else { - ERROR_LOG(Log::System, "Core_NextFrame called with core state %s", CoreStateToString(coreState)); + ERROR_LOG(Log::System, "Core_NextFrame called with wrong core state %s", CoreStateToString(coreState)); return false; } } diff --git a/Core/System.cpp b/Core/System.cpp index ef483c98d3..f2549495a1 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -596,6 +596,7 @@ void PSP_RunLoopWhileState() { int blockTicks = usToCycles(1000000 / 10); // Run until CORE_NEXTFRAME PSP_RunLoopFor(blockTicks); + // TODO: Check for frame timeout? } void PSP_RunLoopFor(int cycles) { diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index a37dd3a581..cacc866f8f 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1851,9 +1851,9 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, bool creating = old.bufferWidth == 0; if (creating) { - WARN_LOG(Log::FrameBuf, "Creating %s FBO at %08x/%08x stride=%d %dx%d (force=%d)", GeBufferFormatToString(vfb->fb_format), vfb->fb_address, vfb->z_address, vfb->fb_stride, vfb->bufferWidth, vfb->bufferHeight, (int)force); + INFO_LOG(Log::FrameBuf, "Creating %s FBO at %08x/%08x stride=%d %dx%d (force=%d)", GeBufferFormatToString(vfb->fb_format), vfb->fb_address, vfb->z_address, vfb->fb_stride, vfb->bufferWidth, vfb->bufferHeight, (int)force); } else { - WARN_LOG(Log::FrameBuf, "Resizing %s FBO at %08x/%08x stride=%d from %dx%d to %dx%d (force=%d, skipCopy=%d)", GeBufferFormatToString(vfb->fb_format), vfb->fb_address, vfb->z_address, vfb->fb_stride, old.bufferWidth, old.bufferHeight, vfb->bufferWidth, vfb->bufferHeight, (int)force, (int)skipCopy); + INFO_LOG(Log::FrameBuf, "Resizing %s FBO at %08x/%08x stride=%d from %dx%d to %dx%d (force=%d, skipCopy=%d)", GeBufferFormatToString(vfb->fb_format), vfb->fb_address, vfb->z_address, vfb->fb_stride, old.bufferWidth, old.bufferHeight, vfb->bufferWidth, vfb->bufferHeight, (int)force, (int)skipCopy); } // During hardware rendering, we always render at full color depth even if the game wouldn't on real hardware. diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 95c1c76830..5764f30a51 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -855,7 +855,7 @@ DLResult GPUCommon::ProcessDLQueue() { for (int listIndex = GetNextListIndex(); listIndex != -1; listIndex = GetNextListIndex()) { DisplayList &l = dls[listIndex]; - DEBUG_LOG(Log::G3D, "Starting DL execution at %08x - stall = %08x (startingTicks=%d)", l.pc, l.stall, startingTicks); + DEBUG_LOG(Log::G3D, "%s DL execution at %08x - stall = %08x (startingTicks=%d)", l.pc == l.startpc ? "Starting" : "Resuming", l.pc, l.stall, startingTicks); if (!InterpretList(l)) { switch (gpuState) { case GPURunState::GPUSTATE_STALL: