summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/VideoBackendBase.cpp
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-10-27 18:14:57 -0500
committerJordan Woyak <jordan.woyak@gmail.com>2025-11-11 20:01:52 -0600
commitcc331feb020d71f109d41b7f841bd69caa96bbb3 (patch)
treed3e40a1a211a5d2e477bfe0d15d91e2f8302a0e8 /Source/Core/VideoCommon/VideoBackendBase.cpp
parentd4f68cb1647ca87e5364431f09ab38b3178ed3cd (diff)
VideoCommon: Make Presenter aware of the next swap time to eliminate unsafe usage of GetTicks() with ImmediateXFB + DualCore.
Diffstat (limited to 'Source/Core/VideoCommon/VideoBackendBase.cpp')
-rw-r--r--Source/Core/VideoCommon/VideoBackendBase.cpp27
1 files changed, 24 insertions, 3 deletions
diff --git a/Source/Core/VideoCommon/VideoBackendBase.cpp b/Source/Core/VideoCommon/VideoBackendBase.cpp
index 676349b65b..23d9d6e7f4 100644
--- a/Source/Core/VideoCommon/VideoBackendBase.cpp
+++ b/Source/Core/VideoCommon/VideoBackendBase.cpp
@@ -21,6 +21,8 @@
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/DolphinAnalytics.h"
+#include "Core/HW/SystemTimers.h"
+#include "Core/HW/VideoInterface.h"
#include "Core/System.h"
// TODO: ugly
@@ -93,16 +95,35 @@ std::string VideoBackendBase::BadShaderFilename(const char* shader_stage, int co
void VideoBackendBase::Video_OutputXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height,
u64 ticks)
{
- if (m_initialized && g_presenter && !g_ActiveConfig.bImmediateXFB)
+ if (!m_initialized || !g_presenter)
+ return;
+
+ auto& system = Core::System::GetInstance();
+ auto& core_timing = system.GetCoreTiming();
+
+ if (!g_ActiveConfig.bImmediateXFB)
{
- auto& system = Core::System::GetInstance();
system.GetFifo().SyncGPU(Fifo::SyncGPUReason::Swap);
- const TimePoint presentation_time = system.GetCoreTiming().GetTargetHostTime(ticks);
+ const TimePoint presentation_time = core_timing.GetTargetHostTime(ticks);
AsyncRequests::GetInstance()->PushEvent([=] {
g_presenter->ViSwap(xfb_addr, fb_width, fb_stride, fb_height, ticks, presentation_time);
});
}
+
+ // Inform the Presenter of the next estimated swap time.
+
+ auto& vi = system.GetVideoInterface();
+ const s64 refresh_rate_den = vi.GetTargetRefreshRateDenominator();
+ const s64 refresh_rate_num = vi.GetTargetRefreshRateNumerator();
+
+ const auto next_swap_estimated_ticks =
+ ticks + (system.GetSystemTimers().GetTicksPerSecond() * refresh_rate_den / refresh_rate_num);
+ const auto next_swap_estimated_time = core_timing.GetTargetHostTime(next_swap_estimated_ticks);
+
+ AsyncRequests::GetInstance()->PushEvent([=] {
+ g_presenter->SetNextSwapEstimatedTime(next_swap_estimated_ticks, next_swap_estimated_time);
+ });
}
u32 VideoBackendBase::Video_GetQueryResult(PerfQueryType type)