diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index dded201b05..15a6a1b9e5 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -688,7 +688,6 @@ bool StartVRRender() { vrCompat[VR_COMPAT_SKYPLANE] = PSP_CoreParameter().compat.vrCompat().Skyplane; // Set customizations - __DisplaySetFramerate(g_Config.bForce72Hz ? 72 : 60); VR_SetConfigFloat(VR_CONFIG_CANVAS_DISTANCE, vrScene && (appMode == VR_GAME_MODE) ? g_Config.fCanvas3DDistance : g_Config.fCanvasDistance); VR_SetConfig(VR_CONFIG_PASSTHROUGH, g_Config.bPassthrough); return true; diff --git a/Core/Config.cpp b/Core/Config.cpp index ae3d05327a..7fdd75511e 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -693,6 +693,8 @@ static const ConfigSetting graphicsSettings[] = { ConfigSetting("UberShaderVertex", &g_Config.bUberShaderVertex, true, CfgFlag::DEFAULT), ConfigSetting("UberShaderFragment", &g_Config.bUberShaderFragment, true, CfgFlag::DEFAULT), + + ConfigSetting("DisplayRefreshRate", &g_Config.iDisplayRefreshRate, g_Config.iDisplayRefreshRate, CfgFlag::PER_GAME), }; static const ConfigSetting soundSettings[] = { diff --git a/Core/Config.h b/Core/Config.h index fdacd88fc5..846029f16f 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -160,6 +160,7 @@ public: std::string sMicDevice; bool bCameraMirrorHorizontal; int iDisplayFramerateMode; // enum DisplayFramerateMode. Android-only. + int iDisplayRefreshRate = 60; bool bSoftwareRendering; bool bSoftwareRenderingJit; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 7283b4d814..cca85b09fd 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -106,10 +106,10 @@ static int height; static bool wasPaused; static bool flippedThisFrame; -static int framerate = 60; +static int framerate; // 1.001f to compensate for the classic 59.94 NTSC framerate that the PSP seems to have. -static double timePerVblank = 1.001 / framerate; +static double timePerVblank; // Don't include this in the state, time increases regardless of state. static double curFrameTime; @@ -131,7 +131,7 @@ const double vblankMs = 0.7315; // These are guesses based on tests. const double vsyncStartMs = 0.5925; const double vsyncEndMs = 0.7265; -double frameMs = 1001.0 / (double)framerate; +double frameMs; enum { PSP_DISPLAY_SETBUF_IMMEDIATE = 0, @@ -152,6 +152,7 @@ void __DisplayVblankBeginCallback(SceUID threadID, SceUID prevCallbackId); void __DisplayVblankEndCallback(SceUID threadID, SceUID prevCallbackId); void __DisplayFlip(int cyclesLate); +static void __DisplaySetFramerate(void); static bool UseLagSync() { return g_Config.bForceLagSync && !g_Config.bAutoFrameSkip; @@ -171,6 +172,7 @@ static void ScheduleLagSync(int over = 0) { } void __DisplayInit() { + __DisplaySetFramerate(); DisplayHWInit(); hasSetMode = false; mode = 0; @@ -562,6 +564,8 @@ static void NotifyUserIfSlow() { } void __DisplayFlip(int cyclesLate) { + __DisplaySetFramerate(); + flippedThisFrame = true; // We flip only if the framebuffer was dirty. This eliminates flicker when using // non-buffered rendering. The interaction with frame skipping seems to need @@ -1126,8 +1130,12 @@ void Register_sceDisplay_driver() { RegisterModule("sceDisplay_driver", ARRAY_SIZE(sceDisplay), sceDisplay); } -void __DisplaySetFramerate(int value) { - framerate = value; +static void __DisplaySetFramerate(void) { + if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_VR) + framerate = g_Config.bForce72Hz ? 72 : 60; + else + framerate = g_Config.iDisplayRefreshRate; + timePerVblank = 1.001 / (double)framerate; frameMs = 1001.0 / (double)framerate; } diff --git a/Core/HLE/sceDisplay.h b/Core/HLE/sceDisplay.h index b68133e8a2..bb134af815 100644 --- a/Core/HLE/sceDisplay.h +++ b/Core/HLE/sceDisplay.h @@ -34,5 +34,3 @@ void __DisplaySetWasPaused(); void Register_sceDisplay_driver(); void __DisplayWaitForVblanks(const char* reason, int vblanks, bool callbacks = false); - -void __DisplaySetFramerate(int value); diff --git a/Core/HW/Display.cpp b/Core/HW/Display.cpp index 0759d8a9ee..146aaf8cf2 100644 --- a/Core/HW/Display.cpp +++ b/Core/HW/Display.cpp @@ -78,7 +78,7 @@ static void CalculateFPS() { actualFps = (float)(actualFlips - lastActualFlips); fps = frames / (now - lastFpsTime); - flips = (float)(60.0 * (double)(gpuStats.numFlips - lastNumFlips) / frames); + flips = (float)(g_Config.iDisplayRefreshRate * (double)(gpuStats.numFlips - lastNumFlips) / frames); lastFpsFrame = numVBlanks; lastNumFlips = gpuStats.numFlips; diff --git a/UI/DebugOverlay.cpp b/UI/DebugOverlay.cpp index 3d23e036d4..c432a42201 100644 --- a/UI/DebugOverlay.cpp +++ b/UI/DebugOverlay.cpp @@ -437,7 +437,7 @@ void DrawFPS(UIContext *ctx, const Bounds &bounds) { char fpsbuf[256]{}; if (g_Config.iShowStatusFlags == ((int)ShowStatusFlags::FPS_COUNTER | (int)ShowStatusFlags::SPEED_COUNTER)) { - snprintf(fpsbuf, sizeof(fpsbuf), "%0.0f/%0.0f (%0.1f%%)", actual_fps, fps, vps / (59.94f / 100.0f)); + snprintf(fpsbuf, sizeof(fpsbuf), "%0.0f/%0.0f (%0.1f%%)", actual_fps, fps, vps / ((g_Config.iDisplayRefreshRate / 60.0f * 59.94f) / 100.0f)); } else { if (g_Config.iShowStatusFlags & (int)ShowStatusFlags::FPS_COUNTER) { snprintf(fpsbuf, sizeof(fpsbuf), "FPS: %0.1f", actual_fps); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 526d88644b..f3340e6248 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1888,6 +1888,9 @@ void DeveloperToolsScreen::CreateViews() { ffMode->SetEnabledFunc([]() { return !g_Config.bVSync; }); ffMode->HideChoice(1); // not used + auto displayRefreshRate = list->Add(new PopupSliderChoice(&g_Config.iDisplayRefreshRate, 60, 1000, 60, dev->T("Display refresh rate"), 1, screenManager())); + displayRefreshRate->SetFormat(dev->T("%d Hz")); + Draw::DrawContext *draw = screenManager()->getDrawContext(); list->Add(new ItemHeader(dev->T("Ubershaders")));