Get the CORE_RUNNING_GE coreState working!

This commit is contained in:
Henrik Rydgård 2024-12-01 22:00:15 +01:00
parent 96c4a10e8c
commit e94defbb15
8 changed files with 67 additions and 26 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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<Ps
drawCompleteTicks = (u64)-1;
// TODO save context when starting the list if param is set
ProcessDLQueue();
SwitchToGe();
}
return id;
@ -490,7 +491,6 @@ u32 GPUCommon::DequeueList(int listid) {
__GeTriggerWait(GPU_SYNC_LIST, listid);
CheckDrawSync();
return 0;
}
@ -503,8 +503,7 @@ u32 GPUCommon::UpdateStall(int listid, u32 newstall) {
dl.stall = newstall & 0x0FFFFFFF;
ProcessDLQueue();
SwitchToGe();
return 0;
}
@ -544,10 +543,20 @@ u32 GPUCommon::Continue() {
return -1;
}
ProcessDLQueue();
SwitchToGe();
return 0;
}
void GPUCommon::SwitchToGe() {
// Old method, although may make sense for performance if the ImDebugger isn't active.
#if 1
ProcessDLQueue();
#else
// New method, will allow ImDebugger to step the GPU
Core_SwitchToGe();
#endif
}
u32 GPUCommon::Break(int mode) {
if (mode < 0 || mode > 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?

View File

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

View File

@ -197,6 +197,8 @@ public:
virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> 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;

View File

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