diff --git a/src/core/host_display.cpp b/src/core/host_display.cpp
index e1682f070..d97f88064 100644
--- a/src/core/host_display.cpp
+++ b/src/core/host_display.cpp
@@ -5,6 +5,7 @@
 #include "common/log.h"
 #include "common/string_util.h"
 #include "common/timer.h"
+#include "host_interface.h"
 #include "stb_image.h"
 #include "stb_image_resize.h"
 #include "stb_image_write.h"
@@ -15,11 +16,6 @@
 #include <vector>
 Log_SetChannel(HostDisplay);
 
-#ifdef _WIN32
-#include "common/windows_headers.h"
-#include <dwmapi.h>
-#endif
-
 HostDisplayTexture::~HostDisplayTexture() = default;
 
 HostDisplay::~HostDisplay() = default;
@@ -92,39 +88,7 @@ bool HostDisplay::SetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32
 
 bool HostDisplay::GetHostRefreshRate(float* refresh_rate)
 {
-#ifdef _WIN32
-  static HMODULE dwm_module = nullptr;
-  static HRESULT(STDAPICALLTYPE * get_timing_info)(HWND hwnd, DWM_TIMING_INFO * pTimingInfo) = nullptr;
-  static bool load_tried = false;
-  if (!load_tried)
-  {
-    load_tried = true;
-    dwm_module = LoadLibrary("dwmapi.dll");
-    if (dwm_module)
-    {
-      std::atexit([]() {
-        FreeLibrary(dwm_module);
-        dwm_module = nullptr;
-      });
-      get_timing_info =
-        reinterpret_cast<decltype(get_timing_info)>(GetProcAddress(dwm_module, "DwmGetCompositionTimingInfo"));
-    }
-  }
-
-  DWM_TIMING_INFO ti = {};
-  ti.cbSize = sizeof(ti);
-  HRESULT hr = get_timing_info(nullptr, &ti);
-  if (SUCCEEDED(hr))
-  {
-    if (ti.rateRefresh.uiNumerator == 0 || ti.rateRefresh.uiDenominator == 0)
-      return false;
-
-    *refresh_rate = static_cast<float>(ti.rateRefresh.uiNumerator) / static_cast<float>(ti.rateRefresh.uiDenominator);
-    return true;
-  }
-#endif
-
-  return false;
+  return g_host_interface->GetMainDisplayRefreshRate(refresh_rate);
 }
 
 void HostDisplay::SetSoftwareCursor(std::unique_ptr<HostDisplayTexture> texture, float scale /*= 1.0f*/)
diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp
index c8fe8b9cc..63f8f5215 100644
--- a/src/core/host_interface.cpp
+++ b/src/core/host_interface.cpp
@@ -24,6 +24,11 @@
 #include <stdlib.h>
 Log_SetChannel(HostInterface);
 
+#ifdef _WIN32
+#include "common/windows_headers.h"
+#include <dwmapi.h>
+#endif
+
 HostInterface* g_host_interface;
 
 HostInterface::HostInterface()
@@ -931,6 +936,43 @@ std::string HostInterface::TranslateStdString(const char* context, const char* s
   return str;
 }
 
+bool HostInterface::GetMainDisplayRefreshRate(float* refresh_rate)
+{
+#ifdef _WIN32
+  static HMODULE dwm_module = nullptr;
+  static HRESULT(STDAPICALLTYPE * get_timing_info)(HWND hwnd, DWM_TIMING_INFO * pTimingInfo) = nullptr;
+  static bool load_tried = false;
+  if (!load_tried)
+  {
+    load_tried = true;
+    dwm_module = LoadLibrary("dwmapi.dll");
+    if (dwm_module)
+    {
+      std::atexit([]() {
+        FreeLibrary(dwm_module);
+        dwm_module = nullptr;
+      });
+      get_timing_info =
+        reinterpret_cast<decltype(get_timing_info)>(GetProcAddress(dwm_module, "DwmGetCompositionTimingInfo"));
+    }
+  }
+
+  DWM_TIMING_INFO ti = {};
+  ti.cbSize = sizeof(ti);
+  HRESULT hr = get_timing_info(nullptr, &ti);
+  if (SUCCEEDED(hr))
+  {
+    if (ti.rateRefresh.uiNumerator == 0 || ti.rateRefresh.uiDenominator == 0)
+      return false;
+
+    *refresh_rate = static_cast<float>(ti.rateRefresh.uiNumerator) / static_cast<float>(ti.rateRefresh.uiDenominator);
+    return true;
+  }
+#endif
+
+  return false;
+}
+
 void HostInterface::ToggleSoftwareRendering()
 {
   if (System::IsShutdown() || g_settings.gpu_renderer == GPURenderer::Software)
diff --git a/src/core/host_interface.h b/src/core/host_interface.h
index 557c8d1b6..ed5b09704 100644
--- a/src/core/host_interface.h
+++ b/src/core/host_interface.h
@@ -119,6 +119,10 @@ public:
   virtual TinyString TranslateString(const char* context, const char* str) const;
   virtual std::string TranslateStdString(const char* context, const char* str) const;
 
+  /// Returns the refresh rate for the "main" display. Use when it's not possible to query the graphics API for the
+  /// refresh rate of the monitor the window is running in.
+  virtual bool GetMainDisplayRefreshRate(float* refresh_rate);
+
   /// Returns the path to the directory to search for BIOS images.
   virtual std::string GetBIOSDirectory();