mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 07:20:49 +00:00
GE Debugger: Record init state and display buf.
Some things are now visible, but still drawing wrong...
This commit is contained in:
parent
21153c899b
commit
82beb726fc
@ -825,13 +825,29 @@ static u32 sceDisplaySetMode(int displayMode, int displayWidth, int displayHeigh
|
||||
return DisplayWaitForVblanks("display mode", 1);
|
||||
}
|
||||
|
||||
// Some games (GTA) never call this during gameplay, so bad place to put a framerate counter.
|
||||
static u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) {
|
||||
void __DisplaySetFramebuf(u32 topaddr, int linesize, int pixelFormat, int sync) {
|
||||
FrameBufferState fbstate = {0};
|
||||
fbstate.topaddr = topaddr;
|
||||
fbstate.fmt = (GEBufferFormat)pixelformat;
|
||||
fbstate.fmt = (GEBufferFormat)pixelFormat;
|
||||
fbstate.stride = linesize;
|
||||
|
||||
if (sync == PSP_DISPLAY_SETBUF_IMMEDIATE) {
|
||||
// Write immediately to the current framebuffer parameters
|
||||
framebuf = fbstate;
|
||||
gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.stride, framebuf.fmt);
|
||||
} else {
|
||||
// Delay the write until vblank
|
||||
latchedFramebuf = fbstate;
|
||||
framebufIsLatched = true;
|
||||
|
||||
// If we update the format or stride, this affects the current framebuf immediately.
|
||||
framebuf.fmt = latchedFramebuf.fmt;
|
||||
framebuf.stride = latchedFramebuf.stride;
|
||||
}
|
||||
}
|
||||
|
||||
// Some games (GTA) never call this during gameplay, so bad place to put a framerate counter.
|
||||
u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) {
|
||||
if (sync != PSP_DISPLAY_SETBUF_IMMEDIATE && sync != PSP_DISPLAY_SETBUF_NEXTFRAME) {
|
||||
return hleLogError(SCEDISPLAY, SCE_KERNEL_ERROR_INVALID_MODE, "invalid sync mode");
|
||||
}
|
||||
@ -849,7 +865,7 @@ static u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int
|
||||
}
|
||||
|
||||
if (sync == PSP_DISPLAY_SETBUF_IMMEDIATE) {
|
||||
if (fbstate.fmt != latchedFramebuf.fmt || fbstate.stride != latchedFramebuf.stride) {
|
||||
if ((GEBufferFormat)pixelformat != latchedFramebuf.fmt || linesize != latchedFramebuf.stride) {
|
||||
return hleReportError(SCEDISPLAY, SCE_KERNEL_ERROR_INVALID_MODE, "must change latched framebuf first");
|
||||
}
|
||||
}
|
||||
@ -882,19 +898,7 @@ static u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int
|
||||
lastFlipCycles = CoreTiming::GetTicks();
|
||||
}
|
||||
|
||||
if (sync == PSP_DISPLAY_SETBUF_IMMEDIATE) {
|
||||
// Write immediately to the current framebuffer parameters
|
||||
framebuf = fbstate;
|
||||
gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.stride, framebuf.fmt);
|
||||
} else {
|
||||
// Delay the write until vblank
|
||||
latchedFramebuf = fbstate;
|
||||
framebufIsLatched = true;
|
||||
|
||||
// If we update the format or stride, this affects the current framebuf immediately.
|
||||
framebuf.fmt = latchedFramebuf.fmt;
|
||||
framebuf.stride = latchedFramebuf.stride;
|
||||
}
|
||||
__DisplaySetFramebuf(topaddr, linesize, pixelformat, sync);
|
||||
|
||||
if (delayCycles > 0) {
|
||||
// Okay, the game is going at too high a frame rate. God of War and Fat Princess both do this.
|
||||
@ -910,10 +914,10 @@ static u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int
|
||||
}
|
||||
}
|
||||
|
||||
bool __DisplayGetFramebuf(u8 **topaddr, u32 *linesize, u32 *pixelFormat, int latchedMode) {
|
||||
bool __DisplayGetFramebuf(PSPPointer<u8> *topaddr, u32 *linesize, u32 *pixelFormat, int latchedMode) {
|
||||
const FrameBufferState &fbState = latchedMode == PSP_DISPLAY_SETBUF_NEXTFRAME ? latchedFramebuf : framebuf;
|
||||
if (topaddr != nullptr)
|
||||
*topaddr = Memory::GetPointer(fbState.topaddr);
|
||||
(*topaddr).ptr = fbState.topaddr;
|
||||
if (linesize != nullptr)
|
||||
*linesize = fbState.stride;
|
||||
if (pixelFormat != nullptr)
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Core/MemMap.h"
|
||||
|
||||
void __DisplayInit();
|
||||
void __DisplayDoState(PointerWrap &p);
|
||||
void __DisplayShutdown();
|
||||
@ -27,7 +29,8 @@ void Register_sceDisplay();
|
||||
bool __DisplayFrameDone();
|
||||
|
||||
// Get information about the current framebuffer.
|
||||
bool __DisplayGetFramebuf(u8 **topaddr, u32 *linesize, u32 *pixelFormat, int mode);
|
||||
bool __DisplayGetFramebuf(PSPPointer<u8> *topaddr, u32 *linesize, u32 *pixelFormat, int mode);
|
||||
void __DisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync);
|
||||
|
||||
typedef void (*VblankCallback)();
|
||||
// Listen for vblank events. Only register during init.
|
||||
@ -44,4 +47,4 @@ int __DisplayGetFlipCount();
|
||||
// Call this when resuming to avoid a small speedup burst
|
||||
void __DisplaySetWasPaused();
|
||||
|
||||
void Register_sceDisplay_driver();
|
||||
void Register_sceDisplay_driver();
|
||||
|
@ -1825,7 +1825,8 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
|
||||
return 0;
|
||||
|
||||
case 0x20: // EMULATOR_DEVCTL__EMIT_SCREENSHOT
|
||||
u8 *topaddr;
|
||||
{
|
||||
PSPPointer<u8> topaddr;
|
||||
u32 linesize, pixelFormat;
|
||||
|
||||
__DisplayGetFramebuf(&topaddr, &linesize, &pixelFormat, 0);
|
||||
@ -1833,6 +1834,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
|
||||
host->SendDebugScreenshot(topaddr, linesize, 272);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR_LOG(SCEIO, "sceIoDevCtl: UNKNOWN PARAMETERS");
|
||||
|
||||
|
@ -47,6 +47,7 @@ static bool active = false;
|
||||
static bool nextFrame = false;
|
||||
|
||||
enum class CommandType : u8 {
|
||||
INIT = 0,
|
||||
REGISTERS = 1,
|
||||
VERTICES = 2,
|
||||
INDICES = 3,
|
||||
@ -55,6 +56,7 @@ enum class CommandType : u8 {
|
||||
MEMSET = 6,
|
||||
MEMCPYDEST = 7,
|
||||
MEMCPYDATA = 8,
|
||||
DISPLAY = 9,
|
||||
|
||||
TEXTURE0 = 0x10,
|
||||
TEXTURE1 = 0x11,
|
||||
@ -115,8 +117,35 @@ static std::string GenRecordingFilename() {
|
||||
return StringFromFormat("%s_%04d.ppdmp", prefix.c_str(), 9999);
|
||||
}
|
||||
|
||||
static void EmitDisplayBuf() {
|
||||
struct DisplayBufData {
|
||||
PSPPointer<u8> topaddr;
|
||||
u32 linesize, pixelFormat;
|
||||
};
|
||||
|
||||
DisplayBufData disp{};
|
||||
__DisplayGetFramebuf(&disp.topaddr, &disp.linesize, &disp.pixelFormat, 0);
|
||||
|
||||
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});
|
||||
}
|
||||
|
||||
static void BeginRecording() {
|
||||
u32 ptr = (u32)pushbuf.size();
|
||||
u32 sz = 512 * 4;
|
||||
pushbuf.resize(pushbuf.size() + sz);
|
||||
gstate.Save((u32_le *)(pushbuf.data() + ptr));
|
||||
|
||||
commands.push_back({CommandType::INIT, sz, ptr});
|
||||
}
|
||||
|
||||
static void WriteRecording() {
|
||||
FlushRegisters();
|
||||
EmitDisplayBuf();
|
||||
|
||||
const std::string filename = GenRecordingFilename();
|
||||
FILE *fp = File::OpenCFile(filename, "wb");
|
||||
@ -443,6 +472,7 @@ void NotifyFrame() {
|
||||
active = true;
|
||||
nextFrame = false;
|
||||
lastTextures.clear();
|
||||
BeginRecording();
|
||||
}
|
||||
}
|
||||
|
||||
@ -481,6 +511,11 @@ static void FreePSPPointer(u32 &p) {
|
||||
}
|
||||
}
|
||||
|
||||
static void ExecuteInit(u32 ptr, u32 sz) {
|
||||
gstate.Restore((u32_le *)(pushbuf.data() + ptr));
|
||||
gpu->ReapplyGfxState();
|
||||
}
|
||||
|
||||
static void ExecuteRegisters(u32 ptr, u32 sz) {
|
||||
ExecuteSubmitCmds(pushbuf.data() + ptr, sz);
|
||||
}
|
||||
@ -578,6 +613,18 @@ static void ExecuteTexture(int level, u32 ptr, u32 sz) {
|
||||
execListQueue.push_back(((GE_CMD_TEXADDR0 + level) << 24) | (pspPointer & 0x00FFFFFF));
|
||||
}
|
||||
|
||||
static void ExecuteDisplay(u32 ptr, u32 sz) {
|
||||
struct DisplayBufData {
|
||||
PSPPointer<u8> topaddr;
|
||||
u32 linesize, pixelFormat;
|
||||
};
|
||||
|
||||
DisplayBufData *disp = (DisplayBufData *)(pushbuf.data() + ptr);
|
||||
|
||||
__DisplaySetFramebuf(disp->topaddr.ptr, disp->linesize, disp->pixelFormat, 1);
|
||||
__DisplaySetFramebuf(disp->topaddr.ptr, disp->linesize, disp->pixelFormat, 0);
|
||||
}
|
||||
|
||||
static void ExecuteFree() {
|
||||
FreePSPPointer(execIndPtr);
|
||||
FreePSPPointer(execVertPtr);
|
||||
@ -594,6 +641,10 @@ static bool ExecuteCommands() {
|
||||
for (size_t i = 0; i < commands.size(); ++i) {
|
||||
const Command &cmd = commands[i];
|
||||
switch (cmd.type) {
|
||||
case CommandType::INIT:
|
||||
ExecuteInit(cmd.ptr, cmd.sz);
|
||||
break;
|
||||
|
||||
case CommandType::REGISTERS:
|
||||
ExecuteRegisters(cmd.ptr, cmd.sz);
|
||||
break;
|
||||
@ -637,6 +688,10 @@ static bool ExecuteCommands() {
|
||||
ExecuteTexture((int)cmd.type - (int)CommandType::TEXTURE0, cmd.ptr, cmd.sz);
|
||||
break;
|
||||
|
||||
case CommandType::DISPLAY:
|
||||
ExecuteDisplay(cmd.ptr, cmd.sz);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(SYSTEM, "Unsupported GE dump command: %d", cmd.type);
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user