diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index 4e90b13b88..13b59510f8 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -1875,7 +1875,7 @@ void VulkanRenderManager::SanityCheckPassesOnAdd() { // Check that we don't have any previous passes that write to the backbuffer, that must ALWAYS be the last one. for (int i = 0; i < steps_.size(); i++) { if (steps_[i]->stepType == VKRStepType::RENDER) { - _dbg_assert_(steps_[i]->render.framebuffer != nullptr); + _dbg_assert_msg_(steps_[i]->render.framebuffer != nullptr, "Adding second backbuffer pass? Not good!"); } } #endif diff --git a/Core/Core.cpp b/Core/Core.cpp index 1450d2aed7..f7e6978853 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -335,12 +335,22 @@ static void Core_PerformStep(MIPSDebugInterface *cpu, CPUStepType stepType, int } } +void Core_SwitchToGe() { + coreState = CORE_RUNNING_GE; +} + void Core_ProcessStepping(MIPSDebugInterface *cpu) { Core_StateProcessed(); // Check if there's any pending save state actions. SaveState::Process(); - if (coreState != CORE_STEPPING_CPU) { + + switch (coreState) { + case CORE_STEPPING_CPU: + // All good + break; + default: + // Nothing to do. return; } diff --git a/Core/Core.h b/Core/Core.h index 3ae8385434..586f3bd165 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -59,6 +59,7 @@ bool Core_ShouldRunBehind(); bool Core_MustRunBehind(); bool Core_NextFrame(); +void Core_SwitchToGe(); // Switches from CPU emulation to GE display list execution. // Changes every time we enter stepping. int Core_GetSteppingCounter(); diff --git a/Core/System.cpp b/Core/System.cpp index 83fc4f514f..3e0a0dba40 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -620,27 +620,32 @@ void PSP_RunLoopWhileState() { // We just run the CPU until we get to vblank. This will quickly sync up pretty nicely. // The actual number of cycles doesn't matter so much here as we will break due to CORE_NEXTFRAME, most of the time hopefully... int blockTicks = usToCycles(1000000 / 10); - // Run until CORE_NEXTFRAME - while (coreState == CORE_RUNNING_CPU || coreState == CORE_STEPPING_CPU) { - PSP_RunLoopFor(blockTicks); - if (coreState == CORE_STEPPING_CPU) { - // Keep the UI responsive. - break; - } - } + PSP_RunLoopFor(blockTicks); } void PSP_RunLoopUntil(u64 globalticks) { - if (coreState == CORE_POWERDOWN || coreState == CORE_BOOT_ERROR || coreState == CORE_RUNTIME_ERROR) { - return; - } else if (coreState == CORE_STEPPING_CPU) { - Core_ProcessStepping(currentDebugMIPS); - return; - } - - if (coreState != CORE_NEXTFRAME) { // Can be set by SaveState as well as by sceDisplay - mipsr4k.RunLoopUntil(globalticks); + while (true) { + switch (coreState) { + case CORE_POWERDOWN: + case CORE_BOOT_ERROR: + case CORE_RUNTIME_ERROR: + case CORE_NEXTFRAME: + return; + case CORE_STEPPING_CPU: + Core_ProcessStepping(currentDebugMIPS); + return; + case CORE_RUNNING_CPU: + mipsr4k.RunLoopUntil(globalticks); + break; // Will loop around to go to RUNNING_GE or NEXTFRAME, which will exit. + case CORE_STEPPING_GE: + _dbg_assert_(false); + break; + case CORE_RUNNING_GE: + gpu->ProcessDLQueue(); + coreState = CORE_RUNNING_CPU; + break; + } } } diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 6f024b25dd..e934c86554 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -26,6 +26,7 @@ #include "GPU/GPUCommon.h" #include "GPU/GPUState.h" #include "Core/Config.h" +#include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/Debugger/MemBlockInfo.h" #include "Core/MemMap.h" @@ -465,7 +466,7 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer 1) return SCE_KERNEL_ERROR_INVALID_MODE; @@ -829,6 +838,8 @@ int GPUCommon::GetNextListIndex() { } } +// This is now called when coreState == CORE_RUNNING_GE. +// TODO: It should return the next action.. (break into debugger or continue running) void GPUCommon::ProcessDLQueue() { startingTicks = CoreTiming::GetTicks(); cyclesExecuted = 0; @@ -861,6 +872,7 @@ void GPUCommon::ProcessDLQueue() { drawCompleteTicks = startingTicks + cyclesExecuted; busyTicks = std::max(busyTicks, drawCompleteTicks); + __GeTriggerSync(GPU_SYNC_DRAW, 1, drawCompleteTicks); // Since the event is in CoreTiming, we're in sync. Just set 0 now. } @@ -1528,7 +1540,7 @@ void GPUCommon::InterruptEnd(int listid) { } } - ProcessDLQueue(); + SwitchToGe(); } // TODO: Maybe cleaner to keep this in GE and trigger the clear directly? diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index ece0385ab8..2328406165 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -114,7 +114,7 @@ public: virtual void PreExecuteOp(u32 op, u32 diff) {} bool InterpretList(DisplayList &list); - void ProcessDLQueue(); + void ProcessDLQueue() override; u32 UpdateStall(int listid, u32 newstall) override; u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer args, bool head) override; u32 DequeueList(int listid) override; @@ -128,6 +128,9 @@ public: u32 Continue() override; u32 Break(int mode) override; void ReapplyGfxState() override; + + void SwitchToGe(); + uint32_t SetAddrTranslation(uint32_t value) override; uint32_t GetAddrTranslation() override; diff --git a/GPU/GPUInterface.h b/GPU/GPUInterface.h index efaf4f776d..08ea90db82 100644 --- a/GPU/GPUInterface.h +++ b/GPU/GPUInterface.h @@ -197,6 +197,8 @@ public: virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer args, bool head) = 0; virtual u32 DequeueList(int listid) = 0; virtual u32 UpdateStall(int listid, u32 newstall) = 0; + virtual void ProcessDLQueue() = 0; + virtual u32 DrawSync(int mode) = 0; virtual int ListSync(int listid, int mode) = 0; virtual u32 Continue() = 0; diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 3156c09636..fd65a2bce4 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -945,6 +945,10 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c } } + if (coreState == CORE_STEPPING_GE || coreState == CORE_RUNNING_GE) { + ImGui::Text("!!! Currently stepping the Ge. See that window (when implemented)"); + } + ImGui::BeginDisabled(coreState != CORE_STEPPING_CPU); if (ImGui::SmallButton("Run")) { Core_Resume(); @@ -958,6 +962,8 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c } ImGui::EndDisabled(); + ImGui::BeginDisabled(coreState != CORE_STEPPING_CPU); + ImGui::SameLine(); if (ImGui::SmallButton("Step Into")) { u32 stepSize = disasmView_.getInstructionSizeAt(mipsDebug->GetPC()); @@ -975,6 +981,8 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c Core_RequestSingleStep(CPUStepType::Out, 0); } + ImGui::EndDisabled(); + ImGui::SameLine(); if (ImGui::SmallButton("Goto PC")) { disasmView_.gotoPC();