Move present to main thread and frame limit after presenting.

This commit is contained in:
Skyth 2024-12-24 19:04:09 +03:00
parent c961541f31
commit 91c2b383bc
5 changed files with 58 additions and 57 deletions

View file

@ -629,7 +629,8 @@ enum class RenderCommandType
UnlockBuffer16, UnlockBuffer16,
UnlockBuffer32, UnlockBuffer32,
DrawImGui, DrawImGui,
Present, ExecuteCommandList,
BeginCommandList,
StretchRect, StretchRect,
SetRenderTarget, SetRenderTarget,
SetDepthStencilSurface, SetDepthStencilSurface,
@ -2179,14 +2180,14 @@ void Video::WaitOnSwapChain()
} }
static bool g_shouldPrecompilePipelines; static bool g_shouldPrecompilePipelines;
static std::atomic<bool> g_presented; static std::atomic<bool> g_executedCommandList;
void Video::HostPresent() void Video::Present()
{ {
DrawImGui(); DrawImGui();
RenderCommand cmd; RenderCommand cmd;
cmd.type = RenderCommandType::Present; cmd.type = RenderCommandType::ExecuteCommandList;
g_renderQueue.enqueue(cmd); g_renderQueue.enqueue(cmd);
// All the shaders are available at this point. We can precompile embedded PSOs then. // 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_shouldPrecompilePipelines = false;
} }
g_presented.wait(false); g_executedCommandList.wait(false);
g_presented = 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<std::chrono::milliseconds>(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() void Video::StartPipelinePrecompilation()
@ -2210,11 +2247,6 @@ void Video::StartPipelinePrecompilation()
g_shouldPrecompilePipelines = true; g_shouldPrecompilePipelines = true;
} }
static void GuestPresent()
{
Video::HostPresent();
}
static void SetRootDescriptor(const UploadAllocation& allocation, size_t index) static void SetRootDescriptor(const UploadAllocation& allocation, size_t index)
{ {
auto& commandList = g_commandLists[g_frame]; 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); commandList->setGraphicsRootDescriptor(allocation.buffer->at(allocation.offset), index);
} }
static void ProcPresent(const RenderCommand& cmd) static void ProcExecuteCommandList(const RenderCommand& cmd)
{ {
if (g_swapChainValid) if (g_swapChainValid)
{ {
@ -2308,8 +2340,6 @@ static void ProcPresent(const RenderCommand& cmd)
waitSemaphores, std::size(waitSemaphores), waitSemaphores, std::size(waitSemaphores),
signalSemaphores, std::size(signalSemaphores), signalSemaphores, std::size(signalSemaphores),
g_commandFences[g_frame].get()); g_commandFences[g_frame].get());
g_swapChainValid = g_swapChain->present(g_backBufferIndex, signalSemaphores, std::size(signalSemaphores));
} }
else else
{ {
@ -2323,14 +2353,15 @@ static void ProcPresent(const RenderCommand& cmd)
g_dirtyStates = DirtyStates(true); g_dirtyStates = DirtyStates(true);
g_uploadAllocators[g_frame].reset(); g_uploadAllocators[g_frame].reset();
g_triangleFanIndexData.reset();
g_quadIndexData.reset();
CheckSwapChain(); g_executedCommandList = true;
g_executedCommandList.notify_one();
g_presentProfiler.Reset(); }
g_presented = true;
g_presented.notify_one();
static void ProcBeginCommandList(const RenderCommand& cmd)
{
if (g_commandListStates[g_frame]) if (g_commandListStates[g_frame])
{ {
g_queue->waitForCommandFence(g_commandFences[g_frame].get()); g_queue->waitForCommandFence(g_commandFences[g_frame].get());
@ -2338,9 +2369,6 @@ static void ProcPresent(const RenderCommand& cmd)
} }
DestructTempResources(); DestructTempResources();
g_triangleFanIndexData.reset();
g_quadIndexData.reset();
BeginCommandList(); BeginCommandList();
} }
@ -4207,7 +4235,8 @@ static std::thread g_renderThread([]
case RenderCommandType::UnlockBuffer16: ProcUnlockBuffer16(cmd); break; case RenderCommandType::UnlockBuffer16: ProcUnlockBuffer16(cmd); break;
case RenderCommandType::UnlockBuffer32: ProcUnlockBuffer32(cmd); break; case RenderCommandType::UnlockBuffer32: ProcUnlockBuffer32(cmd); break;
case RenderCommandType::DrawImGui: ProcDrawImGui(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::StretchRect: ProcStretchRect(cmd); break;
case RenderCommandType::SetRenderTarget: ProcSetRenderTarget(cmd); break; case RenderCommandType::SetRenderTarget: ProcSetRenderTarget(cmd); break;
case RenderCommandType::SetDepthStencilSurface: ProcSetDepthStencilSurface(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_82BE04B0, GetVertexDeclaration);
GUEST_FUNCTION_HOOK(sub_82BE0530, HashVertexDeclaration); 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_82BDD330, GetBackBuffer);
GUEST_FUNCTION_HOOK(sub_82BE9498, CreateTexture); GUEST_FUNCTION_HOOK(sub_82BE9498, CreateTexture);

View file

@ -16,7 +16,7 @@ struct Video
{ {
static void CreateHostDevice(const char *sdlVideoDriver); static void CreateHostDevice(const char *sdlVideoDriver);
static void WaitOnSwapChain(); static void WaitOnSwapChain();
static void HostPresent(); static void Present();
static void StartPipelinePrecompilation(); static void StartPipelinePrecompilation();
static void WaitForGPU(); static void WaitForGPU();
}; };

View file

@ -79,30 +79,6 @@ void Camera2DSlopeLerpFixMidAsmHook(PPCRegister& t, PPCRegister& deltaTime)
using namespace std::chrono_literals; 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<std::chrono::milliseconds>(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; static std::chrono::steady_clock::time_point g_prev;
bool LoadingUpdateMidAsmHook(PPCRegister& r31) bool LoadingUpdateMidAsmHook(PPCRegister& r31)
@ -117,7 +93,7 @@ bool LoadingUpdateMidAsmHook(PPCRegister& r31)
g_ppcContext->r3.u32 = application; g_ppcContext->r3.u32 = application;
g_ppcContext->f1.f64 = deltaTime; g_ppcContext->f1.f64 = deltaTime;
//reinterpret_cast<PPCFunc*>(g_codeCache.Find(update))(*g_ppcContext, base); reinterpret_cast<PPCFunc*>(g_codeCache.Find(update))(*g_ppcContext, base);
bool loading = PPC_LOAD_U8(0x83367A4C); bool loading = PPC_LOAD_U8(0x83367A4C);
if (loading) if (loading)

View file

@ -1478,7 +1478,7 @@ bool InstallerWizard::Run(std::filesystem::path installPath, bool skipGame)
SDL_PumpEvents(); SDL_PumpEvents();
SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
GameWindow::Update(); GameWindow::Update();
Video::HostPresent(); Video::Present();
} }
GameWindow::SetFullscreenCursorVisibility(false); GameWindow::SetFullscreenCursorVisibility(false);

View file

@ -584,13 +584,9 @@ name = "PostureDPadSupportMidAsmHook"
address = 0x823CDA2C address = 0x823CDA2C
registers = ["r3"] registers = ["r3"]
[[midasm_hook]]
name = "ApplicationUpdateMidAsmHook"
address = 0x822C0EC8
[[midasm_hook]] [[midasm_hook]]
name = "LoadingUpdateMidAsmHook" name = "LoadingUpdateMidAsmHook"
address = 0x825360C8 address = 0x825360C8
registers = ["r31"] registers = ["r31"]
jump_address_on_true = 0x825360C8 jump_address_on_true = 0x825360C8
jump_address_on_false = 0x82536140 jump_address_on_false = 0x82536140