Support save/restore of context on list run/finish.

This commit is contained in:
Unknown W. Brackets 2013-09-20 09:42:09 -07:00
parent a1f3591960
commit 4078dcd917
6 changed files with 37 additions and 10 deletions

View File

@ -333,12 +333,12 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId,
DEBUG_LOG(SCEGE,
"sceGeListEnQueue(addr=%08x, stall=%08x, cbid=%08x, param=%08x)",
listAddress, stallAddress, callbackId, optParamAddr);
//if (!stallAddress)
// stallAddress = listAddress;
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), false);
PSPPointer<PspGeListArgs> optParam;
optParam = optParamAddr;
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, false);
DEBUG_LOG(SCEGE, "List %i enqueued.", listID);
//return display list ID
return listID;
}
@ -348,7 +348,10 @@ u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId,
DEBUG_LOG(SCEGE,
"sceGeListEnQueueHead(addr=%08x, stall=%08x, cbid=%08x, param=%08x)",
listAddress, stallAddress, callbackId, optParamAddr);
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), true);
PSPPointer<PspGeListArgs> optParam;
optParam = optParamAddr;
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, true);
DEBUG_LOG(SCEGE, "List %i enqueued.", listID);
return listID;

View File

@ -36,6 +36,14 @@ struct PspGeCallbackData
u32_le finish_arg;
};
struct PspGeListArgs
{
SceSize_le size;
PSPPointer<u32_le> context;
u32_le numStacks;
u32_le unknown1;
};
void Register_sceGe_user();
void __GeInit();

View File

@ -157,7 +157,7 @@ int GPUCommon::ListSync(int listid, int mode) {
return PSP_GE_LIST_COMPLETED;
}
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head) {
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head) {
easy_guard guard(listLock);
// TODO Check the stack values in missing arg and ajust the stack depth
@ -219,6 +219,11 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head) {
dl.interrupted = false;
dl.waitTicks = (u64)-1;
dl.interruptsEnabled = interruptsEnabled_;
dl.started = false;
if (args.IsValid() && args->context.IsValid())
dl.context = args->context;
else
dl.context = NULL;
if (head) {
if (currentList) {
@ -409,6 +414,11 @@ bool GPUCommon::InterpretList(DisplayList &list) {
// return false;
currentList = &list;
if (!list.started && list.context != NULL) {
gstate.Save(list.context);
}
list.started = true;
// I don't know if this is the correct place to zero this, but something
// need to do it. See Sol Trigger title screen.
// TODO: Maybe this is per list? Should a stalled list remember the old value?
@ -884,6 +894,9 @@ void GPUCommon::InterruptEnd(int listid) {
dl.pendingInterrupt = false;
// TODO: Unless the signal handler could change it?
if (dl.state == PSP_GE_DL_STATE_COMPLETED || dl.state == PSP_GE_DL_STATE_NONE) {
if (dl.started && dl.context != NULL) {
gstate.Restore(dl.context);
}
dl.waitTicks = 0;
__GeTriggerWait(WAITTYPE_GELISTSYNC, listid);
}

View File

@ -30,7 +30,7 @@ public:
virtual bool InterpretList(DisplayList &list);
virtual bool ProcessDLQueue();
virtual u32 UpdateStall(int listid, u32 newstall);
virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head);
virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head);
virtual u32 DequeueList(int listid);
virtual int ListSync(int listid, int mode);
virtual u32 DrawSync(int mode);

View File

@ -20,6 +20,7 @@
#include "Globals.h"
#include "GPU/GPUState.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceGe.h"
#include <list>
#include <string>
@ -130,6 +131,8 @@ struct DisplayList
u64 waitTicks;
bool interruptsEnabled;
bool pendingInterrupt;
bool started;
u32_le *context;
};
enum GPUInvalidationType {
@ -186,7 +189,7 @@ public:
// Draw queue management
virtual DisplayList* getList(int listid) = 0;
// TODO: Much of this should probably be shared between the different GPU implementations.
virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head) = 0;
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 u32 DrawSync(int mode) = 0;

View File

@ -139,7 +139,7 @@ void GPUgstate::Save(u32_le *ptr) {
ptr[6] = gstate_c.indexAddr;
ptr[7] = gstate_c.offsetAddr;
// Command values start 17 bytes in.
// Command values start 17 ints in.
u32_le *cmds = ptr + 17;
for (size_t i = 0; i < ARRAY_SIZE(contextCmdRanges); ++i) {
for (int n = contextCmdRanges[i].start; n <= contextCmdRanges[i].end; ++n) {
@ -171,7 +171,7 @@ void GPUgstate::Restore(u32_le *ptr) {
gstate_c.indexAddr = ptr[6];
gstate_c.offsetAddr = ptr[7];
// Command values start 17 bytes in.
// Command values start 17 ints in.
u32_le *cmds = ptr + 17;
for (size_t i = 0; i < ARRAY_SIZE(contextCmdRanges); ++i) {
for (int n = contextCmdRanges[i].start; n <= contextCmdRanges[i].end; ++n) {