mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-21 18:29:05 +02:00
GPU: Save the next display list id, and restart frame dumps on load
- Which list slot and id the next sceGeListEnQueue gets wasn't saved, so after a load it depended on the session before it, and replays and rewinds diverged. Older states start it at 0, and also get the default EDRAM translation and visible matrices they don't carry, rather than the previous session's. - A frame dump recording during a load replayed the loaded state's commands on the registers from before it. It now starts over from the loaded state. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
814593ee4d
commit
130ea9ced9
3 files changed
+37
-1
No files matched your search
@@ -695,6 +695,22 @@ bool Recorder::RecordNextFrame(const std::function<void(const Path &)> callback)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Recorder::RestartAfterLoad() {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
NOTICE_LOG(Log::System, "Savestate loaded, restarting the recording");
|
||||
commands.clear();
|
||||
pushbuf.clear();
|
||||
lastVRAM.clear();
|
||||
lastEdramTrans = 0x400;
|
||||
flipLastAction = gpuStats.totals.numFlips;
|
||||
flipFinishAt = -1;
|
||||
std::lock_guard<std::mutex> guard(callbackLock_);
|
||||
active = false;
|
||||
nextFrame = true;
|
||||
}
|
||||
|
||||
void Recorder::FinishRecording() {
|
||||
// We're done - this was just to write the result out.
|
||||
if (!active) {
|
||||
|
||||
@@ -50,6 +50,9 @@ public:
|
||||
return nextFrame || active;
|
||||
}
|
||||
bool RecordNextFrame(const std::function<void(const Path &)> callback);
|
||||
// A savestate load replaced everything a recording in progress started from. It starts over
|
||||
// from the loaded state, at the next frame.
|
||||
void RestartAfterLoad();
|
||||
void ClearCallback() {
|
||||
std::lock_guard<std::mutex> guard(callbackLock_);
|
||||
writeCallback = nullptr;
|
||||
|
||||
+18
-1
@@ -1953,7 +1953,7 @@ struct DisplayList_v2 {
|
||||
};
|
||||
|
||||
void GPUCommon::DoState(PointerWrap &p) {
|
||||
auto s = p.Section("GPUCommon", 1, 7);
|
||||
auto s = p.Section("GPUCommon", 1, 8);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
@@ -2056,9 +2056,26 @@ void GPUCommon::DoState(PointerWrap &p) {
|
||||
|
||||
if (s >= 5) {
|
||||
Do(p, matrixVisible.all);
|
||||
} else if (p.mode == PointerWrap::MODE_READ) {
|
||||
ResetMatrices();
|
||||
}
|
||||
if (s >= 6) {
|
||||
Do(p, edramTranslation_);
|
||||
} else if (p.mode == PointerWrap::MODE_READ) {
|
||||
edramTranslation_ = 0x400;
|
||||
}
|
||||
// Which slot (and so which id) the next list gets. Older states start over at 0, rather than
|
||||
// carry on from the session before the load.
|
||||
if (s >= 8) {
|
||||
Do(p, nextListID);
|
||||
} else {
|
||||
nextListID = 0;
|
||||
}
|
||||
if (p.mode == PointerWrap::MODE_READ) {
|
||||
if (nextListID < 0 || nextListID > DisplayListMaxCount) {
|
||||
nextListID = 0;
|
||||
}
|
||||
recorder_.RestartAfterLoad();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user