From 91c2b383bc71da9d3648a1647409bf08825ce638 Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Tue, 24 Dec 2024 19:04:09 +0300 Subject: [PATCH] Move present to main thread and frame limit after presenting. --- UnleashedRecomp/gpu/video.cpp | 79 +++++++++++++++++-------- UnleashedRecomp/gpu/video.h | 2 +- UnleashedRecomp/patches/fps_patches.cpp | 26 +------- UnleashedRecomp/ui/installer_wizard.cpp | 2 +- UnleashedRecompLib/config/SWA.toml | 6 +- 5 files changed, 58 insertions(+), 57 deletions(-) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index fdc1a2aa..7c1b64cd 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -629,7 +629,8 @@ enum class RenderCommandType UnlockBuffer16, UnlockBuffer32, DrawImGui, - Present, + ExecuteCommandList, + BeginCommandList, StretchRect, SetRenderTarget, SetDepthStencilSurface, @@ -2179,14 +2180,14 @@ void Video::WaitOnSwapChain() } static bool g_shouldPrecompilePipelines; -static std::atomic g_presented; +static std::atomic g_executedCommandList; -void Video::HostPresent() +void Video::Present() { DrawImGui(); RenderCommand cmd; - cmd.type = RenderCommandType::Present; + cmd.type = RenderCommandType::ExecuteCommandList; g_renderQueue.enqueue(cmd); // All the shaders are available at this point. We can precompile embedded PSOs then. @@ -2201,8 +2202,44 @@ void Video::HostPresent() g_shouldPrecompilePipelines = false; } - g_presented.wait(false); - g_presented = false; + g_executedCommandList.wait(false); + g_executedCommandList = false; + + if (g_swapChainValid) + { + RenderCommandSemaphore* signalSemaphores[] = { g_renderSemaphores[g_frame].get() }; + g_swapChainValid = g_swapChain->present(g_backBufferIndex, signalSemaphores, std::size(signalSemaphores)); + } + + CheckSwapChain(); + + cmd.type = RenderCommandType::BeginCommandList; + g_renderQueue.enqueue(cmd); + + if (Config::FPS >= FPS_MIN && Config::FPS < FPS_MAX) + { + using namespace std::chrono_literals; + + static std::chrono::steady_clock::time_point g_next; + + auto now = std::chrono::steady_clock::now(); + + if (now < g_next) + { + std::this_thread::sleep_for(std::chrono::floor(g_next - now - 2ms)); + + while ((now = std::chrono::steady_clock::now()) < g_next) + std::this_thread::yield(); + } + else + { + g_next = now; + } + + g_next += 1000000000ns / Config::FPS; + } + + g_presentProfiler.Reset(); } void Video::StartPipelinePrecompilation() @@ -2210,11 +2247,6 @@ void Video::StartPipelinePrecompilation() g_shouldPrecompilePipelines = true; } -static void GuestPresent() -{ - Video::HostPresent(); -} - static void SetRootDescriptor(const UploadAllocation& allocation, size_t index) { auto& commandList = g_commandLists[g_frame]; @@ -2225,7 +2257,7 @@ static void SetRootDescriptor(const UploadAllocation& allocation, size_t index) commandList->setGraphicsRootDescriptor(allocation.buffer->at(allocation.offset), index); } -static void ProcPresent(const RenderCommand& cmd) +static void ProcExecuteCommandList(const RenderCommand& cmd) { if (g_swapChainValid) { @@ -2308,8 +2340,6 @@ static void ProcPresent(const RenderCommand& cmd) waitSemaphores, std::size(waitSemaphores), signalSemaphores, std::size(signalSemaphores), g_commandFences[g_frame].get()); - - g_swapChainValid = g_swapChain->present(g_backBufferIndex, signalSemaphores, std::size(signalSemaphores)); } else { @@ -2323,14 +2353,15 @@ static void ProcPresent(const RenderCommand& cmd) g_dirtyStates = DirtyStates(true); g_uploadAllocators[g_frame].reset(); + g_triangleFanIndexData.reset(); + g_quadIndexData.reset(); - CheckSwapChain(); - - g_presentProfiler.Reset(); - - g_presented = true; - g_presented.notify_one(); + g_executedCommandList = true; + g_executedCommandList.notify_one(); +} +static void ProcBeginCommandList(const RenderCommand& cmd) +{ if (g_commandListStates[g_frame]) { g_queue->waitForCommandFence(g_commandFences[g_frame].get()); @@ -2338,9 +2369,6 @@ static void ProcPresent(const RenderCommand& cmd) } DestructTempResources(); - g_triangleFanIndexData.reset(); - g_quadIndexData.reset(); - BeginCommandList(); } @@ -4207,7 +4235,8 @@ static std::thread g_renderThread([] case RenderCommandType::UnlockBuffer16: ProcUnlockBuffer16(cmd); break; case RenderCommandType::UnlockBuffer32: ProcUnlockBuffer32(cmd); break; case RenderCommandType::DrawImGui: ProcDrawImGui(cmd); break; - case RenderCommandType::Present: ProcPresent(cmd); break; + case RenderCommandType::ExecuteCommandList: ProcExecuteCommandList(cmd); break; + case RenderCommandType::BeginCommandList: ProcBeginCommandList(cmd); break; case RenderCommandType::StretchRect: ProcStretchRect(cmd); break; case RenderCommandType::SetRenderTarget: ProcSetRenderTarget(cmd); break; case RenderCommandType::SetDepthStencilSurface: ProcSetDepthStencilSurface(cmd); break; @@ -6041,7 +6070,7 @@ GUEST_FUNCTION_HOOK(sub_82BE96F0, GetSurfaceDesc); GUEST_FUNCTION_HOOK(sub_82BE04B0, GetVertexDeclaration); GUEST_FUNCTION_HOOK(sub_82BE0530, HashVertexDeclaration); -GUEST_FUNCTION_HOOK(sub_82BDA8C0, GuestPresent); +GUEST_FUNCTION_HOOK(sub_82BDA8C0, Video::Present); GUEST_FUNCTION_HOOK(sub_82BDD330, GetBackBuffer); GUEST_FUNCTION_HOOK(sub_82BE9498, CreateTexture); diff --git a/UnleashedRecomp/gpu/video.h b/UnleashedRecomp/gpu/video.h index f6a0add8..87d67edf 100644 --- a/UnleashedRecomp/gpu/video.h +++ b/UnleashedRecomp/gpu/video.h @@ -16,7 +16,7 @@ struct Video { static void CreateHostDevice(const char *sdlVideoDriver); static void WaitOnSwapChain(); - static void HostPresent(); + static void Present(); static void StartPipelinePrecompilation(); static void WaitForGPU(); }; diff --git a/UnleashedRecomp/patches/fps_patches.cpp b/UnleashedRecomp/patches/fps_patches.cpp index 14652c57..70886c2d 100644 --- a/UnleashedRecomp/patches/fps_patches.cpp +++ b/UnleashedRecomp/patches/fps_patches.cpp @@ -79,30 +79,6 @@ void Camera2DSlopeLerpFixMidAsmHook(PPCRegister& t, PPCRegister& deltaTime) using namespace std::chrono_literals; -static std::chrono::steady_clock::time_point g_next; - -void ApplicationUpdateMidAsmHook() -{ - //if (Config::FPS >= FPS_MIN && Config::FPS < FPS_MAX) - //{ - // auto now = std::chrono::steady_clock::now(); - - // if (now < g_next) - // { - // std::this_thread::sleep_for(std::chrono::floor(g_next - now - 2ms)); - - // while ((now = std::chrono::steady_clock::now()) < g_next) - // std::this_thread::yield(); - // } - // else - // { - // g_next = now; - // } - - // g_next += 1000000000ns / Config::FPS; - //} -} - static std::chrono::steady_clock::time_point g_prev; bool LoadingUpdateMidAsmHook(PPCRegister& r31) @@ -117,7 +93,7 @@ bool LoadingUpdateMidAsmHook(PPCRegister& r31) g_ppcContext->r3.u32 = application; g_ppcContext->f1.f64 = deltaTime; - //reinterpret_cast(g_codeCache.Find(update))(*g_ppcContext, base); + reinterpret_cast(g_codeCache.Find(update))(*g_ppcContext, base); bool loading = PPC_LOAD_U8(0x83367A4C); if (loading) diff --git a/UnleashedRecomp/ui/installer_wizard.cpp b/UnleashedRecomp/ui/installer_wizard.cpp index 09bcd44b..40a0d0a9 100644 --- a/UnleashedRecomp/ui/installer_wizard.cpp +++ b/UnleashedRecomp/ui/installer_wizard.cpp @@ -1478,7 +1478,7 @@ bool InstallerWizard::Run(std::filesystem::path installPath, bool skipGame) SDL_PumpEvents(); SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); GameWindow::Update(); - Video::HostPresent(); + Video::Present(); } GameWindow::SetFullscreenCursorVisibility(false); diff --git a/UnleashedRecompLib/config/SWA.toml b/UnleashedRecompLib/config/SWA.toml index 6436a26b..91084cc8 100644 --- a/UnleashedRecompLib/config/SWA.toml +++ b/UnleashedRecompLib/config/SWA.toml @@ -584,13 +584,9 @@ name = "PostureDPadSupportMidAsmHook" address = 0x823CDA2C registers = ["r3"] -[[midasm_hook]] -name = "ApplicationUpdateMidAsmHook" -address = 0x822C0EC8 - [[midasm_hook]] name = "LoadingUpdateMidAsmHook" address = 0x825360C8 registers = ["r31"] jump_address_on_true = 0x825360C8 -jump_address_on_false = 0x82536140 \ No newline at end of file +jump_address_on_false = 0x82536140