Add a flag to use the display vfb for screenshots.

This fixes proportions of reporting, savestate screenshots, and TAS
recording for PS1 ports, mainly.
This commit is contained in:
Unknown W. Brackets 2016-09-25 16:31:38 -07:00
parent 246f3aa68d
commit fa0e88f1b7
16 changed files with 66 additions and 34 deletions

View File

@ -142,7 +142,7 @@ static void PreparePacket(AVPacket* pkt)
void AVIDump::AddFrame()
{
gpuDebug->GetCurrentFramebuffer(buf);
gpuDebug->GetCurrentFramebuffer(buf, GPU_DBG_FRAMEBUF_DISPLAY);
u32 w = buf.GetStride();
u32 h = buf.GetHeight();
CheckResolution(w, h);

View File

@ -223,7 +223,7 @@ bool TakeGameScreenshot(const char *filename, ScreenshotFormat fmt, ScreenshotTy
if (type == SCREENSHOT_RENDER) {
if (gpuDebug) {
success = gpuDebug->GetCurrentFramebuffer(buf, maxRes);
success = gpuDebug->GetCurrentFramebuffer(buf, GPU_DBG_FRAMEBUF_DISPLAY, maxRes);
}
// Only crop to the top left when using a render screenshot.

View File

@ -191,6 +191,13 @@ public:
return displayFramebuf_ ? (0x04000000 | displayFramebuf_->fb_address) : 0;
}
u32 DisplayFramebufStride() {
return displayFramebuf_ ? displayStride_ : 0;
}
GEBufferFormat DisplayFramebufFormat() {
return displayFramebuf_ ? displayFormat_ : GE_FORMAT_INVALID;
}
bool MayIntersectFramebuffer(u32 start) {
// Clear the cache/kernel bits.
start = start & 0x3FFFFFFF;

View File

@ -66,6 +66,13 @@ enum GPUDebugBufferFormat {
GPU_DBG_FORMAT_888_RGB = 0x20,
};
enum GPUDebugFramebufferType {
// The current render target.
GPU_DBG_FRAMEBUF_RENDER,
// The current display target (not the displayed screen, though.)
GPU_DBG_FRAMEBUF_DISPLAY,
};
inline GPUDebugBufferFormat &operator |=(GPUDebugBufferFormat &lhs, const GPUDebugBufferFormat &rhs) {
lhs = GPUDebugBufferFormat((int)lhs | (int)rhs);
return lhs;
@ -206,7 +213,7 @@ public:
// Needs to be called from the GPU thread, so on the same thread as a notification is fine.
// Calling from a separate thread (e.g. UI) may fail.
virtual bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes = -1) {
virtual bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes = -1) {
// False means unsupported.
return false;
}

View File

@ -49,6 +49,7 @@ static volatile bool actionComplete;
// Below are values used to perform actions that return results.
static bool bufferResult;
static GPUDebugFramebufferType bufferType = GPU_DBG_FRAMEBUF_RENDER;
static GPUDebugBuffer bufferFrame;
static GPUDebugBuffer bufferDepth;
static GPUDebugBuffer bufferStencil;
@ -84,7 +85,7 @@ static void RunPauseAction() {
break;
case PAUSE_GETFRAMEBUF:
bufferResult = gpuDebug->GetCurrentFramebuffer(bufferFrame);
bufferResult = gpuDebug->GetCurrentFramebuffer(bufferFrame, bufferType);
break;
case PAUSE_GETDEPTHBUF:
@ -160,7 +161,8 @@ static bool GetBuffer(const GPUDebugBuffer *&buffer, PauseAction type, const GPU
return bufferResult;
}
bool GPU_GetCurrentFramebuffer(const GPUDebugBuffer *&buffer) {
bool GPU_GetCurrentFramebuffer(const GPUDebugBuffer *&buffer, GPUDebugFramebufferType type) {
bufferType = type;
return GetBuffer(buffer, PAUSE_GETFRAMEBUF, bufferFrame);
}
@ -201,4 +203,4 @@ void ForceUnpause() {
actionWait.notify_one();
}
};
};

View File

@ -28,7 +28,7 @@ namespace GPUStepping {
bool EnterStepping(std::function<void()> callback);
bool IsStepping();
bool GPU_GetCurrentFramebuffer(const GPUDebugBuffer *&buffer);
bool GPU_GetCurrentFramebuffer(const GPUDebugBuffer *&buffer, GPUDebugFramebufferType type);
bool GPU_GetCurrentDepthbuffer(const GPUDebugBuffer *&buffer);
bool GPU_GetCurrentStencilbuffer(const GPUDebugBuffer *&buffer);
bool GPU_GetCurrentTexture(const GPUDebugBuffer *&buffer, int level);
@ -37,4 +37,4 @@ namespace GPUStepping {
void ResumeFromStepping();
void ForceUnpause();
};
};

View File

@ -1311,9 +1311,10 @@ namespace DX9 {
resized_ = true;
}
bool FramebufferManagerDX9::GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
bool FramebufferManagerDX9::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
u32 fb_address = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.getFrameBufRawAddress() : displayFramebufPtr_;
int fb_stride = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufStride() : displayStride_;
GEBufferFormat fb_format = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufFormat() : displayFormat_;
VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) {
@ -1322,7 +1323,7 @@ namespace DX9 {
if (!vfb) {
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointer(fb_address | 0x04000000), fb_stride, 512, gstate.FrameBufFormat());
buffer = GPUDebugBuffer(Memory::GetPointer(fb_address | 0x04000000), fb_stride, 512, fb_format);
return true;
}

View File

@ -82,7 +82,7 @@ public:
void DestroyFramebuf(VirtualFramebuffer *vfb) override;
void ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u16 h, bool force = false, bool skipCopy = false) override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes);
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes);
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer);
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
static bool GetDisplayFramebuffer(GPUDebugBuffer &buffer);

View File

@ -2146,8 +2146,8 @@ void GPU_DX9::DoState(PointerWrap &p) {
}
}
bool GPU_DX9::GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes) {
return framebufferManager_.GetCurrentFramebuffer(buffer, maxRes);
bool GPU_DX9::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
return framebufferManager_.GetCurrentFramebuffer(buffer, type, maxRes);
}
bool GPU_DX9::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {

View File

@ -76,7 +76,7 @@ public:
}
std::vector<FramebufferInfo> GetFramebufferList() override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes = -1) override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes = -1) override;
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;

View File

@ -2417,10 +2417,10 @@ void GPU_GLES::DoState(PointerWrap &p) {
}
}
bool GPU_GLES::GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
GEBufferFormat format = gstate.FrameBufFormat();
bool GPU_GLES::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
u32 fb_address = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.getFrameBufRawAddress() : framebufferManager_.DisplayFramebufAddr();
int fb_stride = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufStride() : framebufferManager_.DisplayFramebufStride();
GEBufferFormat format = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufFormat() : framebufferManager_.DisplayFramebufFormat();
return framebufferManager_.GetFramebuffer(fb_address, fb_stride, format, buffer, maxRes);
}

View File

@ -81,7 +81,7 @@ public:
}
std::vector<FramebufferInfo> GetFramebufferList() override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes) override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) override;
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;

View File

@ -825,19 +825,34 @@ bool SoftGPU::FramebufferDirty() {
return true;
}
bool SoftGPU::GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes)
bool SoftGPU::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes)
{
const int w = gstate.getRegionX2() - gstate.getRegionX1() + 1;
const int h = gstate.getRegionY2() - gstate.getRegionY1() + 1;
buffer.Allocate(w, h, gstate.FrameBufFormat());
int x1 = gstate.getRegionX1();
int y1 = gstate.getRegionY1();
int x2 = gstate.getRegionX2() + 1;
int y2 = gstate.getRegionY2() + 1;
int stride = gstate.FrameBufStride();
GEBufferFormat fmt = gstate.FrameBufFormat();
const int depth = gstate.FrameBufFormat() == GE_FORMAT_8888 ? 4 : 2;
const u8 *src = fb.data + gstate.FrameBufStride() * depth * gstate.getRegionY1();
if (type == GPU_DBG_FRAMEBUF_DISPLAY) {
x1 = 0;
y1 = 0;
x2 = 480;
y2 = 272;
stride = displayStride_;
fmt = displayFormat_;
}
buffer.Allocate(x2 - x1, y2 - y1, fmt);
const int depth = fmt == GE_FORMAT_8888 ? 4 : 2;
const u8 *src = fb.data + stride * depth * y1;
u8 *dst = buffer.GetData();
for (int y = gstate.getRegionY1(); y <= gstate.getRegionY2(); ++y) {
memcpy(dst, src + gstate.getRegionX1(), (gstate.getRegionX2() + 1) * depth);
dst += w * depth;
src += gstate.FrameBufStride() * depth;
const int byteWidth = (x2 - x1) * depth;
for (int y = y1; y < y2; ++y) {
memcpy(dst, src + x1, byteWidth);
dst += byteWidth;
src += stride * depth;
}
return true;
}

View File

@ -84,7 +84,7 @@ public:
return !(gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME);
}
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, int maxRes = -1) override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes = -1) override;
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;

View File

@ -256,7 +256,7 @@ void CGEDebugger::UpdatePrimaryPreview(const GPUgstate &state) {
} else {
switch (PrimaryDisplayType(fbTabs->CurrentTabIndex())) {
case PRIMARY_FRAMEBUF:
bufferResult = GPU_GetCurrentFramebuffer(primaryBuffer_);
bufferResult = GPU_GetCurrentFramebuffer(primaryBuffer_, GPU_DBG_FRAMEBUF_RENDER);
break;
case PRIMARY_DEPTHBUF:

View File

@ -100,7 +100,7 @@ void WindowsHeadlessHost::SendDebugScreenshot(const u8 *pixbuf, u32 w, u32 h)
const static u32 FRAME_HEIGHT = 272;
GPUDebugBuffer buffer;
gpuDebug->GetCurrentFramebuffer(buffer);
gpuDebug->GetCurrentFramebuffer(buffer, GPU_DBG_FRAMEBUF_RENDER);
const std::vector<u32> pixels = TranslateDebugBufferToCompare(&buffer, 512, 272);
std::string error;