mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-25 01:00:01 +00:00
Support save/restore of context on list run/finish.
This commit is contained in:
parent
a1f3591960
commit
4078dcd917
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user