Merge pull request #11569 from unknownbrackets/ge-dump

GE Debugger: Support record for more render types
This commit is contained in:
Henrik Rydgård 2018-11-18 10:10:28 +01:00 committed by GitHub
commit 90c2d7fb5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -52,7 +52,7 @@ static const int MIN_VERSION = 2;
static bool active = false;
static bool nextFrame = false;
static bool writePending = false;
static int flipLastAction = -1;
static std::function<void(const std::string &)> writeCallback;
enum class CommandType : u8 {
@ -389,6 +389,12 @@ static std::string GenRecordingFilename() {
}
static void BeginRecording() {
active = true;
nextFrame = false;
lastTextures.clear();
lastRenderTargets.clear();
flipLastAction = gpuStats.numFlips;
u32 ptr = (u32)pushbuf.size();
u32 sz = 512 * 4;
pushbuf.resize(pushbuf.size() + sz);
@ -603,10 +609,10 @@ static void FlushPrimState(int vcount) {
u32 vbytes = 0;
GetVertDataSizes(vcount, indices, vbytes, ibytes);
if (indices) {
if (indices && ibytes > 0) {
EmitCommandWithRAM(CommandType::INDICES, indices, ibytes);
}
if (verts) {
if (verts && vbytes > 0) {
EmitCommandWithRAM(CommandType::VERTICES, verts, vbytes);
}
}
@ -631,7 +637,9 @@ static void EmitTransfer(u32 op) {
u32 srcBytes = ((srcY + height - 1) * srcStride + (srcX + width)) * bpp;
srcBytes = Memory::ValidSize(srcBasePtr, srcBytes);
EmitCommandWithRAM(CommandType::TRANSFERSRC, Memory::GetPointerUnchecked(srcBasePtr), srcBytes);
if (srcBytes != 0) {
EmitCommandWithRAM(CommandType::TRANSFERSRC, Memory::GetPointerUnchecked(srcBasePtr), srcBytes);
}
lastRegisters.push_back(op);
}
@ -641,7 +649,9 @@ static void EmitClut(u32 op) {
u32 bytes = (op & 0x3F) * 32;
bytes = Memory::ValidSize(addr, bytes);
EmitCommandWithRAM(CommandType::CLUT, Memory::GetPointerUnchecked(addr), bytes);
if (bytes != 0) {
EmitCommandWithRAM(CommandType::CLUT, Memory::GetPointerUnchecked(addr), bytes);
}
lastRegisters.push_back(op);
}
@ -671,6 +681,7 @@ bool IsActivePending() {
bool Activate() {
if (!nextFrame) {
nextFrame = true;
flipLastAction = gpuStats.numFlips;
return true;
}
return false;
@ -687,8 +698,8 @@ static void FinishRecording() {
pushbuf.clear();
NOTICE_LOG(SYSTEM, "Recording finished");
writePending = false;
active = false;
flipLastAction = gpuStats.numFlips;
if (writeCallback)
writeCallback(filename);
@ -699,10 +710,6 @@ void NotifyCommand(u32 pc) {
if (!active) {
return;
}
if (writePending) {
FinishRecording();
return;
}
const u32 op = Memory::Read_U32(pc);
const GECommand cmd = GECommand(op >> 24);
@ -763,7 +770,9 @@ void NotifyMemcpy(u32 dest, u32 src, u32 sz) {
memcpy(pushbuf.data() + cmd.ptr, &dest, sizeof(dest));
sz = Memory::ValidSize(dest, sz);
EmitCommandWithRAM(CommandType::MEMCPYDATA, Memory::GetPointer(dest), sz);
if (sz != 0) {
EmitCommandWithRAM(CommandType::MEMCPYDATA, Memory::GetPointer(dest), sz);
}
}
}
@ -796,6 +805,14 @@ void NotifyUpload(u32 dest, u32 sz) {
}
void NotifyDisplay(u32 framebuf, int stride, int fmt) {
bool writePending = false;
if (active && !commands.empty()) {
writePending = true;
}
if (nextFrame && (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0) {
NOTICE_LOG(SYSTEM, "Recording starting on display...");
BeginRecording();
}
if (!active) {
return;
}
@ -814,20 +831,39 @@ void NotifyDisplay(u32 framebuf, int stride, int fmt) {
memcpy(pushbuf.data() + ptr, &disp, sz);
commands.push_back({ CommandType::DISPLAY, sz, ptr });
if (writePending) {
NOTICE_LOG(SYSTEM, "Recording complete on display");
FinishRecording();
}
}
void NotifyFrame() {
if (active && !writePending && !commands.empty()) {
// Delay write until the first command of the next frame, so we get the right display buf.
NOTICE_LOG(SYSTEM, "Recording complete - waiting to get display buffer");
writePending = true;
const bool noDisplayAction = flipLastAction + 4 < gpuStats.numFlips;
// We do this only to catch things that don't call NotifyDisplay.
if (active && !commands.empty() && noDisplayAction) {
NOTICE_LOG(SYSTEM, "Recording complete on frame");
struct DisplayBufData {
PSPPointer<u8> topaddr;
u32 linesize, pixelFormat;
};
DisplayBufData disp;
__DisplayGetFramebuf(&disp.topaddr, &disp.linesize, &disp.pixelFormat, 0);
FlushRegisters();
u32 ptr = (u32)pushbuf.size();
u32 sz = (u32)sizeof(disp);
pushbuf.resize(pushbuf.size() + sz);
memcpy(pushbuf.data() + ptr, &disp, sz);
commands.push_back({ CommandType::DISPLAY, sz, ptr });
FinishRecording();
}
if (nextFrame && (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0) {
NOTICE_LOG(SYSTEM, "Recording starting...");
active = true;
nextFrame = false;
lastTextures.clear();
lastRenderTargets.clear();
if (nextFrame && (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0 && noDisplayAction) {
NOTICE_LOG(SYSTEM, "Recording starting on frame...");
BeginRecording();
}
}