diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 8a309dff25..43bddcd208 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1047,8 +1047,9 @@ void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *v // Saving each frame would be slow. // TODO: This type of download could be made async, for less stutter on framebuffer creation. - halfSkipDownloadFramebufferOnSwitch_ = !halfSkipDownloadFramebufferOnSwitch_; - if (g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::NO_SKIP || (g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::HALF_SKIP && halfSkipDownloadFramebufferOnSwitch_)) { + + bool performReadback = ShouldReadback(&halfSkipDownloadFramebufferOnSwitch_); + if (performReadback) { ReadFramebufferToMemory(vfb, 0, 0, vfb->safeWidth, vfb->safeHeight, RASTER_COLOR, Draw::ReadbackMode::BLOCK); vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD | FB_USAGE_FIRST_FRAME_SAVED) & ~FB_USAGE_DOWNLOAD_CLEAR; vfb->safeWidth = 0; @@ -1062,27 +1063,30 @@ bool FramebufferManagerCommon::ShouldDownloadFramebufferColor(const VirtualFrame return PSP_CoreParameter().compat.flags().Force04154000Download && vfb->fb_address == 0x04154000; } +bool FramebufferManagerCommon::ShouldReadback(bool *toggle) { + bool performReadback = true; + switch (GetSkipGPUReadbackMode()) { + case SkipGPUReadbackMode::SKIP: + performReadback = false; + break; + case SkipGPUReadbackMode::HALF_SKIP: + *toggle = !*toggle; + performReadback = *toggle; + break; + case SkipGPUReadbackMode::COPY_TO_TEXTURE: + case SkipGPUReadbackMode::NO_SKIP: + break; + } + return performReadback; +} + bool FramebufferManagerCommon::ShouldDownloadFramebufferDepth(const VirtualFramebuffer *vfb) { // Download depth buffer for Syphon Filter lens flares if (!PSP_CoreParameter().compat.flags().ReadbackDepth) { return false; } - bool performDepthReadback = true; - - switch (GetSkipGPUReadbackMode()) { - case SkipGPUReadbackMode::SKIP: - performDepthReadback = false; - break; - case SkipGPUReadbackMode::HALF_SKIP: - halfSkipShouldDownloadFramebufferDepth_ = !halfSkipShouldDownloadFramebufferDepth_; - performDepthReadback = halfSkipShouldDownloadFramebufferDepth_; - break; - case SkipGPUReadbackMode::COPY_TO_TEXTURE: - case SkipGPUReadbackMode::NO_SKIP: - break; - } - + bool performDepthReadback = ShouldReadback(&halfSkipShouldDownloadFramebufferDepth_); return performDepthReadback && (vfb->usageFlags & FB_USAGE_RENDER_DEPTH) != 0 && vfb->width >= 480 && vfb->height >= 272; } @@ -2190,9 +2194,10 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, FlushBeforeCopy(); // TODO: In Hot Shots Golf, check if we can do a readback to a framebuffer here. // Again we have the problem though that it's doing a lot of small copies here, one for each line. + if (srcH == 0 || srcY + srcH > srcBuffer->bufferHeight) { WARN_LOG_ONCE(btdcpyheight, Log::FrameBuf, "Memcpy fbo download %08x -> %08x skipped, %d+%d is taller than %d", src, dst, srcY, srcH, srcBuffer->bufferHeight); - } else if (GetSkipGPUReadbackMode() == SkipGPUReadbackMode::NO_SKIP && (!srcBuffer->memoryUpdated || channel == RASTER_DEPTH)) { + } else if ((!srcBuffer->memoryUpdated || channel == RASTER_DEPTH) && ShouldReadback(&halfSkipDownloadFramebufferOnCopy_)) { Draw::ReadbackMode readbackMode = Draw::ReadbackMode::BLOCK; if (PSP_CoreParameter().compat.flags().AllowDelayedReadbacks) { readbackMode = Draw::ReadbackMode::OLD_DATA_OK; diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 8ccd5051c4..1b18ebf021 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -652,7 +652,10 @@ protected: // Half-skip toggles. bool halfSkipDownloadFramebufferOnSwitch_ = false; + bool halfSkipDownloadFramebufferOnCopy_ = false; bool halfSkipShouldDownloadFramebufferDepth_ = false; + + bool ShouldReadback(bool *toggle); }; // Should probably live elsewhere.