Fix issue with raw screenshots not always being cropped correctly

Fixes #21664
This commit is contained in:
Henrik Rydgård
2026-05-12 10:12:20 +02:00
parent 575960c57f
commit e0d6664e85
3 changed files with 14 additions and 7 deletions

View File

@@ -394,6 +394,10 @@ bool ScreenshotNotifyPostGameRender(Draw::DrawContext *draw) {
if (buf.IsBackBuffer()) {
w = buf.GetStride();
h = buf.GetHeight();
} else if (maxRes < 0 && buf.GetScaleFactor() > 0) {
// Normal case. Crop to the current screen size if it's larger (some games render to large buffers and display a subset).
w = 480 * buf.GetScaleFactor();
h = 272 * buf.GetScaleFactor();
} else {
w = maxRes > 0 ? 480 * maxRes : buf.GetStride();
h = maxRes > 0 ? 272 * maxRes : buf.GetHeight();
@@ -491,7 +495,7 @@ bool Save8888RGBAScreenshot(std::vector<uint8_t> &bufferPNG, const u8 *bufferRGB
return success;
}
void TakeUserScreenshotImpl() {
void TakeUserScreenshot() {
Path path = GetSysDirectory(DIRECTORY_SCREENSHOT);
// Make sure the screenshot directory exists.
File::CreateDir(path);
@@ -553,9 +557,3 @@ void TakeUserScreenshotImpl() {
// TODO: What to do about ScreenshotNotPossible?
});
}
void TakeUserScreenshot() {
System_RunOnMainThread([]() {
TakeUserScreenshotImpl();
});
}

View File

@@ -3043,6 +3043,7 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB
return false;
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointerWriteUnchecked(fb_address), fb_stride, 512, format);
buffer.SetScaleFactor(1);
return true;
}
@@ -3083,6 +3084,7 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB
buffer.Allocate(w, h, GE_FORMAT_8888, flipY);
bool retval = draw_->CopyFramebufferToMemory(bound, Draw::Aspect::COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), w, Draw::ReadbackMode::BLOCK, "GetFramebuffer");
buffer.SetScaleFactor(vfb->renderScaleFactor);
// Don't need to increment gpu stats for readback count here, this is a debugger-only function.
// After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe.
@@ -3103,6 +3105,7 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32
return false;
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointerWriteUnchecked(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT);
buffer.SetScaleFactor(1);
return true;
}
@@ -3134,6 +3137,7 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
// That may have unbound the framebuffer, rebind to avoid crashes when debugging.
RebindFramebuffer("RebindFramebuffer - GetDepthbuffer");
buffer.SetScaleFactor(vfb->renderScaleFactor);
return retval;
}

View File

@@ -123,6 +123,7 @@ struct GPUDebugBuffer {
stride_ = other.stride_;
flipped_ = other.flipped_;
isBackBuffer_ = other.isBackBuffer_;
scaleFactor_ = other.scaleFactor_;
fmt_ = other.fmt_;
other.alloc_ = false;
other.data_ = nullptr;
@@ -142,6 +143,7 @@ struct GPUDebugBuffer {
flipped_ = other.flipped_;
fmt_ = other.fmt_;
isBackBuffer_ = other.isBackBuffer_;
scaleFactor_ = other.scaleFactor_;
other.alloc_ = false;
other.data_ = nullptr;
}
@@ -186,6 +188,8 @@ struct GPUDebugBuffer {
void SetIsBackbuffer(bool isBackBuffer) { isBackBuffer_ = isBackBuffer; }
bool IsBackBuffer() const { return isBackBuffer_; }
void SetScaleFactor(int scaleFactor) { scaleFactor_ = scaleFactor; }
int GetScaleFactor() const { return scaleFactor_; }
private:
bool alloc_ = false;
@@ -195,6 +199,7 @@ private:
GPUDebugBufferFormat fmt_ = GPU_DBG_FORMAT_INVALID;
bool flipped_ = false;
bool isBackBuffer_ = false;
int scaleFactor_ = 0;
};
struct GPUDebugVertex {