From 8a45801199a869e9f98de47be3962b2f05f50e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= <159546+serprex@users.noreply.github.com> Date: Sun, 12 Jul 2026 04:01:51 +0000 Subject: [PATCH] optimize frame interpolation memory (#6901) don't generate all matrices for game tick upfront, interpolate per frame --- soh/soh/OTRGlobals.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 410936f315..2069d4c4c3 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1771,7 +1771,8 @@ extern "C" void Graph_StartFrame() { #endif } -void RunCommands(Gfx* Commands, const std::vector>& mtx_replacements) { +// Interpolated frames of a tick are evenly spaced numerators time+step, time+2*step, ... over denom. +void RunCommands(Gfx* Commands, int time, int step, int denom, int count) { auto wnd = std::dynamic_pointer_cast(OTRGlobals::Instance->context->GetWindow()); if (wnd == nullptr) { @@ -1787,8 +1788,11 @@ void RunCommands(Gfx* Commands, const std::vector UIWidgets::Colors themeColor = static_cast(CVarGetInteger(CVAR_SETTING("Menu.Theme"), UIWidgets::Colors::LightBlue)); ImGui::PushStyleColor(ImGuiCol_TitleBgActive, UIWidgets::ColorValues.at(themeColor)); - for (const auto& m : mtx_replacements) { - wnd->DrawAndRunGraphicsCommands(Commands, m); + for (int i = 0; i < count; i++) { + time += step; + std::unordered_map mtx_replacements = + (time == denom) ? std::unordered_map() : FrameInterpolation_Interpolate((float)time / denom); + wnd->DrawAndRunGraphicsCommands(Commands, mtx_replacements); intp->mInterpolationIndex++; } ImGui::PopStyleColor(); @@ -1802,7 +1806,6 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { } audio.cv_to_thread.notify_one(); - std::vector> mtx_replacements; int target_fps = OTRGlobals::Instance->GetInterpolationFPS(); static int last_fps; static int last_update_rate; @@ -1822,13 +1825,11 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { // time_base = fps * original_fps (one second) int next_original_frame = fps; + int start_time = time; + int count = 0; while (time + original_fps <= next_original_frame) { time += original_fps; - if (time != next_original_frame) { - mtx_replacements.push_back(FrameInterpolation_Interpolate((float)time / next_original_frame)); - } else { - mtx_replacements.emplace_back(); - } + count++; } time -= fps; @@ -1837,13 +1838,15 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { wnd->SetTargetFps(fps); } + int step = original_fps; // When the gfx debugger is active, only run with the final mtx if (GfxDebuggerIsDebugging()) { - mtx_replacements.clear(); - mtx_replacements.emplace_back(); + start_time = next_original_frame; + step = 0; + count = 1; } - RunCommands(commands, mtx_replacements); + RunCommands(commands, start_time, step, next_original_frame, count); last_fps = fps; last_update_rate = R_UPDATE_RATE;