diff --git a/Core/Config.h b/Core/Config.h index a7a8c039f815..4b1e85578375 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -241,7 +241,7 @@ struct Config { float fCwCheatScrollPosition; float fGameListScrollPosition; int iBloomHack; //0 = off, 1 = safe, 2 = balanced, 3 = aggressive - int iSkipGPUReadbackMode; // 0 = off, 1 = skip, 2 = to texture + int iSkipGPUReadbackMode; // 0 = off, 1 = skip, 2 = to texture, 3 = half skip int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High bool bHardwareTessellation; bool bShaderCache; // Hidden ini-only setting, useful for debugging shader compile times. diff --git a/Core/ConfigValues.h b/Core/ConfigValues.h index 3e762d632ca9..e4be9dde4148 100644 --- a/Core/ConfigValues.h +++ b/Core/ConfigValues.h @@ -182,6 +182,7 @@ enum class SkipGPUReadbackMode : int { NO_SKIP, SKIP, COPY_TO_TEXTURE, + HALF_SKIP, }; enum class RemoteISOShareType : int { diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index f705277f5833..8fdf0a47e2ac 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -50,6 +50,9 @@ #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" +bool HalfSkipDownloadFramebufferOnSwitch = false; +bool HalfSkipShouldDownloadFramebufferDepth = false; + static size_t FormatFramebufferName(const VirtualFramebuffer *vfb, char *tag, size_t len) { return snprintf(tag, len, "FB_%08x_%08x_%dx%d_%s", vfb->fb_address, vfb->z_address, vfb->bufferWidth, vfb->bufferHeight, GeBufferFormatToString(vfb->fb_format)); } @@ -1033,11 +1036,14 @@ 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. - if (g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::NO_SKIP && !PSP_CoreParameter().compat.flags().DisableFirstFrameReadback) { - 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; - vfb->safeHeight = 0; + HalfSkipDownloadFramebufferOnSwitch = !HalfSkipDownloadFramebufferOnSwitch; + if (!PSP_CoreParameter().compat.flags().DisableFirstFrameReadback) { + if (g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::NO_SKIP || g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::HALF_SKIP && HalfSkipDownloadFramebufferOnSwitch) { + 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; + vfb->safeHeight = 0; + } } } } @@ -1049,7 +1055,8 @@ bool FramebufferManagerCommon::ShouldDownloadFramebufferColor(const VirtualFrame bool FramebufferManagerCommon::ShouldDownloadFramebufferDepth(const VirtualFramebuffer *vfb) const { // Download depth buffer for Syphon Filter lens flares - if (!PSP_CoreParameter().compat.flags().ReadbackDepth || g_Config.iSkipGPUReadbackMode != (int)SkipGPUReadbackMode::NO_SKIP) { + HalfSkipShouldDownloadFramebufferDepth = !HalfSkipShouldDownloadFramebufferDepth; + if (!PSP_CoreParameter().compat.flags().ReadbackDepth || g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::SKIP || g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::COPY_TO_TEXTURE || g_Config.iSkipGPUReadbackMode == (int)SkipGPUReadbackMode::HALF_SKIP && HalfSkipShouldDownloadFramebufferDepth) { return false; } return (vfb->usageFlags & FB_USAGE_RENDER_DEPTH) != 0 && vfb->width >= 480 && vfb->height >= 272; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 6b0c4dec2a2a..638cd5f94570 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -436,7 +436,7 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) CheckBox *disableCulling = graphicsSettings->Add(new CheckBox(&g_Config.bDisableRangeCulling, gr->T("Disable culling"))); disableCulling->SetDisabledPtr(&g_Config.bSoftwareRendering); - static const char *skipGpuReadbackModes[] = { "No (default)", "Skip", "Copy to texture" }; + static const char *skipGpuReadbackModes[] = { "No (default)", "Skip", "Copy to texture" , "Half skip"}; PopupMultiChoice *skipGPUReadbacks = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iSkipGPUReadbackMode, gr->T("Skip GPU Readbacks"), skipGpuReadbackModes, 0, ARRAY_SIZE(skipGpuReadbackModes), I18NCat::GRAPHICS, screenManager())); skipGPUReadbacks->SetDisabledPtr(&g_Config.bSoftwareRendering);