Lift out running the display list to the callers.

This has one tricky case though...
This commit is contained in:
Henrik Rydgård
2024-12-03 22:35:36 +01:00
parent 63c0305301
commit e977906d75
4 changed files with 58 additions and 27 deletions
+32 -11
View File
@@ -139,10 +139,13 @@ public:
ge_pending_cb.pop_front();
gpu->InterruptEnd(intrdata.listid);
// Seen in GoW.
if (subintr >= 0)
DEBUG_LOG(Log::sceGe, "Ignoring interrupt for display list %d, already been released.", intrdata.listid);
// Hm. This might be really tricky to get to behave the same in both modes. Here we are in __KernelReschedule, CoreTiming::Advance, ProcessEvents, GeExecuteInterrupt, ... .... __RunOnePendingInterrupt
// But not sure how much it will matter. The test pause2 hits here.
gpu->RunGe();
return false;
}
@@ -178,6 +181,8 @@ public:
}
gpu->InterruptEnd(intrdata.listid);
// This is the last thing done here in the syscall (__KernelReturnFromInterrupt) so switching coreState should just work.
gpu->RunGe();
}
};
@@ -339,12 +344,16 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId, u32 optP
listAddress, stallAddress, callbackId, optParamAddr, CoreTiming::GetTicks());
auto optParam = PSPPointer<PspGeListArgs>::Create(optParamAddr);
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, false);
hleEatCycles(490);
CoreTiming::ForceCheck();
bool runList;
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, false, &runList);
if ((int)listID >= 0)
listID = LIST_ID_MAGIC ^ listID;
if (runList) {
gpu->RunGe();
}
// The stuff here below must be deferred...
hleEatCycles(490);
CoreTiming::ForceCheck();
return hleLogSuccessX(Log::sceGe, listID);
}
@@ -354,12 +363,15 @@ u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, u32
listAddress, stallAddress, callbackId, optParamAddr, CoreTiming::GetTicks());
auto optParam = PSPPointer<PspGeListArgs>::Create(optParamAddr);
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, true);
hleEatCycles(480);
CoreTiming::ForceCheck();
bool runList;
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, true, &runList);
if ((int)listID >= 0)
listID = LIST_ID_MAGIC ^ listID;
if (runList) {
gpu->RunGe();
}
hleEatCycles(480);
CoreTiming::ForceCheck();
return hleLogSuccessX(Log::sceGe, listID);
}
@@ -377,7 +389,12 @@ static int sceGeListUpdateStallAddr(u32 displayListID, u32 stallAddress) {
CoreTiming::ForceCheck();
DEBUG_LOG(Log::sceGe, "sceGeListUpdateStallAddr(dlid=%i, stalladdr=%08x)", displayListID, stallAddress);
return gpu->UpdateStall(LIST_ID_MAGIC ^ displayListID, stallAddress);
bool runList;
int retval = gpu->UpdateStall(LIST_ID_MAGIC ^ displayListID, stallAddress, &runList);
if (runList) {
gpu->RunGe();
}
return retval;
}
// 0 : wait for completion. 1:check and return
@@ -399,7 +416,11 @@ static u32 sceGeDrawSync(u32 mode) {
static int sceGeContinue() {
DEBUG_LOG(Log::sceGe, "sceGeContinue()");
int ret = gpu->Continue();
bool runList;
int ret = gpu->Continue(&runList);
if (runList) {
gpu->RunGe();
}
hleEatCycles(220);
hleReSchedule("ge continue");
return ret;
+10 -2
View File
@@ -334,7 +334,11 @@ void DumpExecute::SyncStall() {
return;
}
gpu->UpdateStall(execListID, execListPos);
bool runList;
gpu->UpdateStall(execListID, execListPos, &runList);
if (runList) {
gpu->RunGe();
}
s64 listTicks = gpu->GetListTicks(execListID);
if (listTicks != -1) {
s64 nowTicks = CoreTiming::GetTicks();
@@ -365,7 +369,11 @@ bool DumpExecute::SubmitCmds(const void *p, u32 sz) {
gpu->EnableInterrupts(false);
auto optParam = PSPPointer<PspGeListArgs>::Create(0);
execListID = gpu->EnqueueList(execListBuf, execListPos, -1, optParam, false);
bool runList;
execListID = gpu->EnqueueList(execListBuf, execListPos, -1, optParam, false, &runList);
if (runList) {
gpu->RunGe();
}
gpu->EnableInterrupts(true);
}
+12 -10
View File
@@ -359,7 +359,9 @@ void GPUCommon::ResetMatrices() {
gstate_c.Dirty(DIRTY_WORLDMATRIX | DIRTY_VIEWMATRIX | DIRTY_PROJMATRIX | DIRTY_TEXMATRIX | DIRTY_FRAGMENTSHADER_STATE | DIRTY_BONE_UNIFORMS);
}
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head) {
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head, bool *runList) {
*runList = false;
// TODO Check the stack values in missing arg and ajust the stack depth
// Check alignment
@@ -468,7 +470,7 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<Ps
// TODO save context when starting the list if param is set
// LATER: Wait, what? Please explain.
SwitchToGe();
*runList = true;
}
return id;
}
@@ -495,7 +497,8 @@ u32 GPUCommon::DequeueList(int listid) {
return 0;
}
u32 GPUCommon::UpdateStall(int listid, u32 newstall) {
u32 GPUCommon::UpdateStall(int listid, u32 newstall, bool *runList) {
*runList = false;
if (listid < 0 || listid >= DisplayListMaxCount || dls[listid].state == PSP_GE_DL_STATE_NONE)
return SCE_KERNEL_ERROR_INVALID_ID;
auto &dl = dls[listid];
@@ -503,12 +506,13 @@ u32 GPUCommon::UpdateStall(int listid, u32 newstall) {
return SCE_KERNEL_ERROR_ALREADY;
dl.stall = newstall & 0x0FFFFFFF;
SwitchToGe();
*runList = true;
return 0;
}
u32 GPUCommon::Continue() {
u32 GPUCommon::Continue(bool *runList) {
*runList = false;
if (!currentList)
return 0;
@@ -544,11 +548,11 @@ u32 GPUCommon::Continue() {
return -1;
}
SwitchToGe();
*runList = true;
return 0;
}
void GPUCommon::SwitchToGe() {
void GPUCommon::RunGe() {
// Old method, although may make sense for performance if the ImDebugger isn't active.
#if 1
// Call ProcessDLQueue directly.
@@ -1552,8 +1556,6 @@ void GPUCommon::InterruptEnd(int listid) {
dlQueue.remove(listid);
}
}
SwitchToGe();
}
// TODO: Maybe cleaner to keep this in GE and trigger the clear directly?
+4 -4
View File
@@ -245,8 +245,8 @@ public:
DLResult ProcessDLQueue(bool fromCore);
u32 UpdateStall(int listid, u32 newstall);
u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head);
u32 UpdateStall(int listid, u32 newstall, bool *runList);
u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head, bool *runList);
u32 DequeueList(int listid);
virtual int ListSync(int listid, int mode);
virtual u32 DrawSync(int mode);
@@ -255,7 +255,7 @@ public:
virtual void ResetMatrices();
virtual void DoState(PointerWrap &p);
bool BusyDrawing();
u32 Continue();
u32 Continue(bool *runList);
u32 Break(int mode);
virtual bool FramebufferDirty() = 0;
@@ -266,7 +266,7 @@ public:
virtual void DeviceLost() = 0;
virtual void DeviceRestore(Draw::DrawContext *draw) = 0;
void SwitchToGe();
void RunGe();
void DrawImGuiDebugger();