From c18c039089bdc27cbccf92a9053ed80bb161a9b9 Mon Sep 17 00:00:00 2001
From: Jordan Woyak <jordan.woyak@gmail.com>
Date: Fri, 7 Mar 2025 14:43:39 -0600
Subject: [PATCH] VideoCommon: Move backend_info out of VideoConfig struct.

---
 Source/Core/Core/DolphinAnalytics.cpp         |  41 +++--
 .../Config/Graphics/AdvancedWidget.cpp        |  15 +-
 .../Config/Graphics/EnhancementsWidget.cpp    |  14 +-
 .../Config/Graphics/GeneralWidget.cpp         |   4 +-
 .../DolphinQt/Config/Graphics/HacksWidget.cpp |   7 +-
 Source/Core/VideoBackends/D3D/D3DMain.cpp     | 107 ++++++------
 Source/Core/VideoBackends/D3D/D3DState.cpp    |   4 +-
 Source/Core/VideoBackends/D3D/DXPipeline.cpp  |   3 +-
 Source/Core/VideoBackends/D3D/DXTexture.cpp   |   2 +-
 Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp  |   3 +-
 .../Core/VideoBackends/D3D12/VideoBackend.cpp |  92 +++++-----
 Source/Core/VideoBackends/Metal/MTLGfx.mm     |   2 +-
 Source/Core/VideoBackends/Metal/MTLMain.mm    |  16 +-
 .../VideoBackends/Metal/MTLObjectCache.mm     |   2 +-
 .../VideoBackends/Metal/MTLStateTracker.mm    |   5 +-
 Source/Core/VideoBackends/Metal/MTLUtil.h     |   7 +-
 Source/Core/VideoBackends/Metal/MTLUtil.mm    | 115 ++++++-------
 .../Core/VideoBackends/Null/NullBackend.cpp   |  80 +++++----
 Source/Core/VideoBackends/OGL/OGLConfig.cpp   | 161 +++++++++---------
 Source/Core/VideoBackends/OGL/OGLGfx.cpp      |  10 +-
 Source/Core/VideoBackends/OGL/OGLMain.cpp     |  74 ++++----
 Source/Core/VideoBackends/OGL/OGLPipeline.cpp |   2 +-
 Source/Core/VideoBackends/OGL/OGLShader.cpp   |   4 +-
 Source/Core/VideoBackends/OGL/OGLTexture.cpp  |   2 +-
 .../VideoBackends/OGL/OGLVertexManager.cpp    |   7 +-
 .../VideoBackends/OGL/ProgramShaderCache.cpp  |  46 +++--
 .../Core/VideoBackends/OGL/SamplerCache.cpp   |   2 +-
 Source/Core/VideoBackends/Software/SWmain.cpp |  58 +++----
 .../Core/VideoBackends/Vulkan/ObjectCache.cpp |  10 +-
 .../VideoBackends/Vulkan/StateTracker.cpp     |  13 +-
 Source/Core/VideoBackends/Vulkan/VKGfx.cpp    |   2 +-
 Source/Core/VideoBackends/Vulkan/VKMain.cpp   |  23 +--
 .../Core/VideoBackends/Vulkan/VKPipeline.cpp  |   8 +-
 Source/Core/VideoBackends/Vulkan/VKShader.cpp |   4 +-
 .../Core/VideoBackends/Vulkan/VKSwapChain.cpp |   6 +-
 .../Core/VideoBackends/Vulkan/VKTexture.cpp   |   2 +-
 .../VideoBackends/Vulkan/VulkanContext.cpp    | 152 ++++++++---------
 .../Core/VideoBackends/Vulkan/VulkanContext.h |   8 +-
 Source/Core/VideoCommon/AbstractGfx.cpp       |   6 +-
 .../VideoCommon/Assets/CustomTextureData.cpp  |   4 +-
 Source/Core/VideoCommon/BPFunctions.cpp       |   8 +-
 Source/Core/VideoCommon/BoundingBox.cpp       |  12 +-
 .../Core/VideoCommon/FramebufferManager.cpp   |  42 +++--
 .../Core/VideoCommon/FramebufferShaderGen.cpp |   8 +-
 Source/Core/VideoCommon/GeometryShaderGen.cpp |   4 +-
 .../Runtime/CustomShaderCache.cpp             |   2 +-
 Source/Core/VideoCommon/IndexGenerator.cpp    |   4 +-
 Source/Core/VideoCommon/PixelShaderGen.cpp    |   7 +-
 Source/Core/VideoCommon/PostProcessing.cpp    |  12 +-
 Source/Core/VideoCommon/Present.cpp           |   2 +-
 Source/Core/VideoCommon/RenderBase.cpp        |   4 +-
 Source/Core/VideoCommon/ShaderCache.cpp       |  57 +++----
 Source/Core/VideoCommon/ShaderGenCommon.cpp   |  43 +++--
 Source/Core/VideoCommon/Statistics.cpp        |   2 +-
 Source/Core/VideoCommon/TextureCacheBase.cpp  |  13 +-
 .../VideoCommon/TextureConversionShader.cpp   |   6 +-
 .../VideoCommon/TextureConverterShaderGen.cpp |   6 +-
 Source/Core/VideoCommon/VertexManagerBase.cpp |  14 +-
 .../Core/VideoCommon/VertexShaderManager.cpp  |   6 +-
 Source/Core/VideoCommon/VideoBackendBase.cpp  |   8 +-
 Source/Core/VideoCommon/VideoConfig.cpp       |  16 +-
 Source/Core/VideoCommon/VideoConfig.h         | 130 +++++++-------
 62 files changed, 741 insertions(+), 788 deletions(-)

diff --git a/Source/Core/Core/DolphinAnalytics.cpp b/Source/Core/Core/DolphinAnalytics.cpp
index ebd855f2c4..1fcae02393 100644
--- a/Source/Core/Core/DolphinAnalytics.cpp
+++ b/Source/Core/Core/DolphinAnalytics.cpp
@@ -396,32 +396,31 @@ void DolphinAnalytics::MakePerGameBuilder()
   builder.AddData("cfg-gfx-vertex-rounding", g_Config.UseVertexRounding());
 
   // GPU features.
-  if (g_Config.iAdapter < static_cast<int>(g_Config.backend_info.Adapters.size()))
+  if (g_Config.iAdapter < static_cast<int>(g_backend_info.Adapters.size()))
   {
-    builder.AddData("gpu-adapter", g_Config.backend_info.Adapters[g_Config.iAdapter]);
+    builder.AddData("gpu-adapter", g_backend_info.Adapters[g_Config.iAdapter]);
   }
-  else if (!g_Config.backend_info.AdapterName.empty())
+  else if (!g_backend_info.AdapterName.empty())
   {
-    builder.AddData("gpu-adapter", g_Config.backend_info.AdapterName);
+    builder.AddData("gpu-adapter", g_backend_info.AdapterName);
   }
-  builder.AddData("gpu-has-exclusive-fullscreen",
-                  g_Config.backend_info.bSupportsExclusiveFullscreen);
-  builder.AddData("gpu-has-dual-source-blend", g_Config.backend_info.bSupportsDualSourceBlend);
-  builder.AddData("gpu-has-primitive-restart", g_Config.backend_info.bSupportsPrimitiveRestart);
-  builder.AddData("gpu-has-geometry-shaders", g_Config.backend_info.bSupportsGeometryShaders);
-  builder.AddData("gpu-has-3d-vision", g_Config.backend_info.bSupports3DVision);
-  builder.AddData("gpu-has-early-z", g_Config.backend_info.bSupportsEarlyZ);
-  builder.AddData("gpu-has-binding-layout", g_Config.backend_info.bSupportsBindingLayout);
-  builder.AddData("gpu-has-bbox", g_Config.backend_info.bSupportsBBox);
+  builder.AddData("gpu-has-exclusive-fullscreen", g_backend_info.bSupportsExclusiveFullscreen);
+  builder.AddData("gpu-has-dual-source-blend", g_backend_info.bSupportsDualSourceBlend);
+  builder.AddData("gpu-has-primitive-restart", g_backend_info.bSupportsPrimitiveRestart);
+  builder.AddData("gpu-has-geometry-shaders", g_backend_info.bSupportsGeometryShaders);
+  builder.AddData("gpu-has-3d-vision", g_backend_info.bSupports3DVision);
+  builder.AddData("gpu-has-early-z", g_backend_info.bSupportsEarlyZ);
+  builder.AddData("gpu-has-binding-layout", g_backend_info.bSupportsBindingLayout);
+  builder.AddData("gpu-has-bbox", g_backend_info.bSupportsBBox);
   builder.AddData("gpu-has-fragment-stores-and-atomics",
-                  g_Config.backend_info.bSupportsFragmentStoresAndAtomics);
-  builder.AddData("gpu-has-gs-instancing", g_Config.backend_info.bSupportsGSInstancing);
-  builder.AddData("gpu-has-post-processing", g_Config.backend_info.bSupportsPostProcessing);
-  builder.AddData("gpu-has-palette-conversion", g_Config.backend_info.bSupportsPaletteConversion);
-  builder.AddData("gpu-has-clip-control", g_Config.backend_info.bSupportsClipControl);
-  builder.AddData("gpu-has-ssaa", g_Config.backend_info.bSupportsSSAA);
-  builder.AddData("gpu-has-logic-ops", g_Config.backend_info.bSupportsLogicOp);
-  builder.AddData("gpu-has-framebuffer-fetch", g_Config.backend_info.bSupportsFramebufferFetch);
+                  g_backend_info.bSupportsFragmentStoresAndAtomics);
+  builder.AddData("gpu-has-gs-instancing", g_backend_info.bSupportsGSInstancing);
+  builder.AddData("gpu-has-post-processing", g_backend_info.bSupportsPostProcessing);
+  builder.AddData("gpu-has-palette-conversion", g_backend_info.bSupportsPaletteConversion);
+  builder.AddData("gpu-has-clip-control", g_backend_info.bSupportsClipControl);
+  builder.AddData("gpu-has-ssaa", g_backend_info.bSupportsSSAA);
+  builder.AddData("gpu-has-logic-ops", g_backend_info.bSupportsLogicOp);
+  builder.AddData("gpu-has-framebuffer-fetch", g_backend_info.bSupportsFramebufferFetch);
 
   // NetPlay / recording.
   builder.AddData("netplay", NetPlay::IsNetPlayRunning());
diff --git a/Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp
index a3d6ae7c57..ff14b26ad2 100644
--- a/Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp
@@ -271,10 +271,9 @@ void AdvancedWidget::ConnectWidgets()
 
 void AdvancedWidget::OnBackendChanged()
 {
-  m_backend_multithreading->setEnabled(g_Config.backend_info.bSupportsMultithreading);
-  m_prefer_vs_for_point_line_expansion->setEnabled(
-      g_Config.backend_info.bSupportsGeometryShaders &&
-      g_Config.backend_info.bSupportsVSLinePointExpand);
+  m_backend_multithreading->setEnabled(g_backend_info.bSupportsMultithreading);
+  m_prefer_vs_for_point_line_expansion->setEnabled(g_backend_info.bSupportsGeometryShaders &&
+                                                   g_backend_info.bSupportsVSLinePointExpand);
   AddDescriptions();
 }
 
@@ -492,12 +491,12 @@ void AdvancedWidget::AddDescriptions()
   m_enable_prog_scan->SetDescription(tr(TR_PROGRESSIVE_SCAN_DESCRIPTION));
   m_backend_multithreading->SetDescription(tr(TR_BACKEND_MULTITHREADING_DESCRIPTION));
   QString vsexpand_extra;
-  if (!g_Config.backend_info.bSupportsGeometryShaders)
+  if (!g_backend_info.bSupportsGeometryShaders)
     vsexpand_extra = tr("Forced on because %1 doesn't support geometry shaders.")
-                         .arg(tr(g_Config.backend_info.DisplayName.c_str()));
-  else if (!g_Config.backend_info.bSupportsVSLinePointExpand)
+                         .arg(tr(g_backend_info.DisplayName.c_str()));
+  else if (!g_backend_info.bSupportsVSLinePointExpand)
     vsexpand_extra = tr("Forced off because %1 doesn't support VS expansion.")
-                         .arg(tr(g_Config.backend_info.DisplayName.c_str()));
+                         .arg(tr(g_backend_info.DisplayName.c_str()));
   else
     vsexpand_extra = tr(IF_UNSURE_UNCHECKED);
   m_prefer_vs_for_point_line_expansion->SetDescription(
diff --git a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
index f04d8fec2a..0e63fb894b 100644
--- a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
@@ -343,19 +343,19 @@ void EnhancementsWidget::LoadPPShaders()
 
 void EnhancementsWidget::OnBackendChanged()
 {
-  m_output_resampling_combo->setEnabled(g_Config.backend_info.bSupportsPostProcessing);
-  m_configure_color_correction->setEnabled(g_Config.backend_info.bSupportsPostProcessing);
-  m_hdr->setEnabled(g_Config.backend_info.bSupportsHDROutput);
+  m_output_resampling_combo->setEnabled(g_backend_info.bSupportsPostProcessing);
+  m_configure_color_correction->setEnabled(g_backend_info.bSupportsPostProcessing);
+  m_hdr->setEnabled(g_backend_info.bSupportsHDROutput);
 
   // Stereoscopy
-  const bool supports_stereoscopy = g_Config.backend_info.bSupportsGeometryShaders;
+  const bool supports_stereoscopy = g_backend_info.bSupportsGeometryShaders;
   m_3d_mode->setEnabled(supports_stereoscopy);
   m_3d_convergence->setEnabled(supports_stereoscopy);
   m_3d_depth->setEnabled(supports_stereoscopy);
   m_3d_swap_eyes->setEnabled(supports_stereoscopy);
 
   // PostProcessing
-  const bool supports_postprocessing = g_Config.backend_info.bSupportsPostProcessing;
+  const bool supports_postprocessing = g_backend_info.bSupportsPostProcessing;
   if (!supports_postprocessing)
   {
     m_configure_pp_effect->setEnabled(false);
@@ -421,14 +421,14 @@ void EnhancementsWidget::UpdateAAOptions()
   m_aa_combo->Reset();
   m_aa_combo->Add(tr("None"), (u32)1, false);
 
-  std::vector<u32> aa_modes = g_Config.backend_info.AAModes;
+  const std::vector<u32>& aa_modes = g_backend_info.AAModes;
   for (const u32 aa_mode : aa_modes)
   {
     if (aa_mode > 1)
       m_aa_combo->Add(tr("%1x MSAA").arg(aa_mode), aa_mode, false);
   }
 
-  if (g_Config.backend_info.bSupportsSSAA)
+  if (g_backend_info.bSupportsSSAA)
   {
     for (const u32 aa_mode : aa_modes)
     {
diff --git a/Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp
index f87190fa9a..8d69589f29 100644
--- a/Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp
@@ -226,7 +226,7 @@ void GeneralWidget::OnEmulationStateChanged(bool running)
   m_render_main_window->setEnabled(!running);
   m_enable_fullscreen->setEnabled(!running);
 
-  const bool supports_adapters = !g_Config.backend_info.Adapters.empty();
+  const bool supports_adapters = !g_backend_info.Adapters.empty();
   m_adapter_combo->setEnabled(!running && supports_adapters);
 
   std::string current_backend = m_backend_combo->currentData().toString().toStdString();
@@ -362,7 +362,7 @@ void GeneralWidget::OnBackendChanged(const QString& backend_name)
 
   m_adapter_combo->clear();
 
-  const auto& adapters = g_Config.backend_info.Adapters;
+  const auto& adapters = g_backend_info.Adapters;
 
   for (const auto& adapter : adapters)
     m_adapter_combo->addItem(QString::fromStdString(adapter));
diff --git a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp
index da32111155..30d12e9bba 100644
--- a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp
@@ -11,14 +11,11 @@
 
 #include "Core/Config/GraphicsSettings.h"
 #include "Core/Config/MainSettings.h"
-#include "Core/ConfigManager.h"
 
 #include "DolphinQt/Config/ConfigControls/ConfigBool.h"
 #include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
 #include "DolphinQt/Config/GameConfigWidget.h"
 #include "DolphinQt/Config/Graphics/GraphicsWindow.h"
-#include "DolphinQt/Config/ToolTipControls/ToolTipSlider.h"
-#include "DolphinQt/Settings.h"
 
 #include "VideoCommon/VideoConfig.h"
 
@@ -135,8 +132,8 @@ void HacksWidget::CreateWidgets()
 
 void HacksWidget::OnBackendChanged(const QString& backend_name)
 {
-  const bool bbox = g_Config.backend_info.bSupportsBBox;
-  const bool gpu_texture_decoding = g_Config.backend_info.bSupportsGPUTextureDecoding;
+  const bool bbox = g_backend_info.bSupportsBBox;
+  const bool gpu_texture_decoding = g_backend_info.bSupportsGPUTextureDecoding;
 
   m_gpu_texture_decoding->setEnabled(gpu_texture_decoding);
   m_disable_bounding_box->setEnabled(bbox);
diff --git a/Source/Core/VideoBackends/D3D/D3DMain.cpp b/Source/Core/VideoBackends/D3D/D3DMain.cpp
index 9a25c1abde..c6803057e3 100644
--- a/Source/Core/VideoBackends/D3D/D3DMain.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DMain.cpp
@@ -75,68 +75,67 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
 
 void VideoBackend::FillBackendInfo()
 {
-  g_Config.backend_info.api_type = APIType::D3D;
-  g_Config.backend_info.MaxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
-  g_Config.backend_info.bUsesLowerLeftOrigin = false;
-  g_Config.backend_info.bSupportsExclusiveFullscreen = true;
-  g_Config.backend_info.bSupportsDualSourceBlend = true;
-  g_Config.backend_info.bSupportsPrimitiveRestart = true;
-  g_Config.backend_info.bSupportsGeometryShaders = true;
-  g_Config.backend_info.bSupportsComputeShaders = false;
-  g_Config.backend_info.bSupports3DVision = true;
-  g_Config.backend_info.bSupportsPostProcessing = true;
-  g_Config.backend_info.bSupportsPaletteConversion = true;
-  g_Config.backend_info.bSupportsClipControl = true;
-  g_Config.backend_info.bSupportsDepthClamp = true;
-  g_Config.backend_info.bSupportsReversedDepthRange = false;
-  g_Config.backend_info.bSupportsMultithreading = false;
-  g_Config.backend_info.bSupportsGPUTextureDecoding = true;
-  g_Config.backend_info.bSupportsCopyToVram = true;
-  g_Config.backend_info.bSupportsLargePoints = false;
-  g_Config.backend_info.bSupportsDepthReadback = true;
-  g_Config.backend_info.bSupportsPartialDepthCopies = false;
-  g_Config.backend_info.bSupportsBitfield = false;
-  g_Config.backend_info.bSupportsDynamicSamplerIndexing = false;
-  g_Config.backend_info.bSupportsFramebufferFetch = false;
-  g_Config.backend_info.bSupportsBackgroundCompiling = true;
-  g_Config.backend_info.bSupportsST3CTextures = true;
-  g_Config.backend_info.bSupportsBPTCTextures = true;
-  g_Config.backend_info.bSupportsEarlyZ = true;
-  g_Config.backend_info.bSupportsBBox = true;
-  g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true;
-  g_Config.backend_info.bSupportsGSInstancing = true;
-  g_Config.backend_info.bSupportsSSAA = true;
-  g_Config.backend_info.bSupportsShaderBinaries = true;
-  g_Config.backend_info.bSupportsPipelineCacheData = false;
-  g_Config.backend_info.bSupportsCoarseDerivatives = true;
-  g_Config.backend_info.bSupportsTextureQueryLevels = true;
-  g_Config.backend_info.bSupportsLodBiasInSampler = true;
-  g_Config.backend_info.bSupportsLogicOp = D3D::SupportsLogicOp(g_Config.iAdapter);
-  g_Config.backend_info.bSupportsSettingObjectNames = true;
-  g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
-  g_Config.backend_info.bSupportsDynamicVertexLoader = false;
-  g_Config.backend_info.bSupportsHDROutput = true;
+  g_backend_info.api_type = APIType::D3D;
+  g_backend_info.MaxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+  g_backend_info.bUsesLowerLeftOrigin = false;
+  g_backend_info.bSupportsExclusiveFullscreen = true;
+  g_backend_info.bSupportsDualSourceBlend = true;
+  g_backend_info.bSupportsPrimitiveRestart = true;
+  g_backend_info.bSupportsGeometryShaders = true;
+  g_backend_info.bSupportsComputeShaders = false;
+  g_backend_info.bSupports3DVision = true;
+  g_backend_info.bSupportsPostProcessing = true;
+  g_backend_info.bSupportsPaletteConversion = true;
+  g_backend_info.bSupportsClipControl = true;
+  g_backend_info.bSupportsDepthClamp = true;
+  g_backend_info.bSupportsReversedDepthRange = false;
+  g_backend_info.bSupportsMultithreading = false;
+  g_backend_info.bSupportsGPUTextureDecoding = true;
+  g_backend_info.bSupportsCopyToVram = true;
+  g_backend_info.bSupportsLargePoints = false;
+  g_backend_info.bSupportsDepthReadback = true;
+  g_backend_info.bSupportsPartialDepthCopies = false;
+  g_backend_info.bSupportsBitfield = false;
+  g_backend_info.bSupportsDynamicSamplerIndexing = false;
+  g_backend_info.bSupportsFramebufferFetch = false;
+  g_backend_info.bSupportsBackgroundCompiling = true;
+  g_backend_info.bSupportsST3CTextures = true;
+  g_backend_info.bSupportsBPTCTextures = true;
+  g_backend_info.bSupportsEarlyZ = true;
+  g_backend_info.bSupportsBBox = true;
+  g_backend_info.bSupportsFragmentStoresAndAtomics = true;
+  g_backend_info.bSupportsGSInstancing = true;
+  g_backend_info.bSupportsSSAA = true;
+  g_backend_info.bSupportsShaderBinaries = true;
+  g_backend_info.bSupportsPipelineCacheData = false;
+  g_backend_info.bSupportsCoarseDerivatives = true;
+  g_backend_info.bSupportsTextureQueryLevels = true;
+  g_backend_info.bSupportsLodBiasInSampler = true;
+  g_backend_info.bSupportsLogicOp = D3D::SupportsLogicOp(g_Config.iAdapter);
+  g_backend_info.bSupportsSettingObjectNames = true;
+  g_backend_info.bSupportsPartialMultisampleResolve = true;
+  g_backend_info.bSupportsDynamicVertexLoader = false;
+  g_backend_info.bSupportsHDROutput = true;
 
-  g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames();
-  g_Config.backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter);
+  g_backend_info.Adapters = D3DCommon::GetAdapterNames();
+  g_backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter);
 
   // Override optional features if we are actually booting.
   if (D3D::device)
   {
-    g_Config.backend_info.bSupportsST3CTextures =
-        D3D::SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
-        D3D::SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
-        D3D::SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM);
-    g_Config.backend_info.bSupportsBPTCTextures = D3D::SupportsTextureFormat(DXGI_FORMAT_BC7_UNORM);
+    g_backend_info.bSupportsST3CTextures = D3D::SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
+                                           D3D::SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
+                                           D3D::SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM);
+    g_backend_info.bSupportsBPTCTextures = D3D::SupportsTextureFormat(DXGI_FORMAT_BC7_UNORM);
 
     // Features only supported with a FL11.0+ device.
     const bool shader_model_5_supported = D3D::feature_level >= D3D_FEATURE_LEVEL_11_0;
-    g_Config.backend_info.bSupportsEarlyZ = shader_model_5_supported;
-    g_Config.backend_info.bSupportsBBox = shader_model_5_supported;
-    g_Config.backend_info.bSupportsFragmentStoresAndAtomics = shader_model_5_supported;
-    g_Config.backend_info.bSupportsGSInstancing = shader_model_5_supported;
-    g_Config.backend_info.bSupportsSSAA = shader_model_5_supported;
-    g_Config.backend_info.bSupportsGPUTextureDecoding = shader_model_5_supported;
+    g_backend_info.bSupportsEarlyZ = shader_model_5_supported;
+    g_backend_info.bSupportsBBox = shader_model_5_supported;
+    g_backend_info.bSupportsFragmentStoresAndAtomics = shader_model_5_supported;
+    g_backend_info.bSupportsGSInstancing = shader_model_5_supported;
+    g_backend_info.bSupportsSSAA = shader_model_5_supported;
+    g_backend_info.bSupportsGPUTextureDecoding = shader_model_5_supported;
   }
 }
 
diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp
index f3aed1c1f2..08b3d9a7f7 100644
--- a/Source/Core/VideoBackends/D3D/D3DState.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DState.cpp
@@ -35,7 +35,7 @@ void StateManager::Apply()
   // our bindings and sets them to null to prevent hazards.
   if (m_dirtyFlags.test(DirtyFlag_Framebuffer))
   {
-    if (g_ActiveConfig.backend_info.bSupportsBBox)
+    if (g_backend_info.bSupportsBBox)
     {
       D3D::context->OMSetRenderTargetsAndUnorderedAccessViews(
           m_pending.framebuffer->GetNumRTVs(),
@@ -363,7 +363,7 @@ ID3D11BlendState* StateCache::Get(BlendingState state)
   if (it != m_blend.end())
     return it->second.Get();
 
-  if (state.logicopenable && g_ActiveConfig.backend_info.bSupportsLogicOp)
+  if (state.logicopenable && g_backend_info.bSupportsLogicOp)
   {
     D3D11_BLEND_DESC1 desc = {};
     D3D11_RENDER_TARGET_BLEND_DESC1& tdesc = desc.RenderTarget[0];
diff --git a/Source/Core/VideoBackends/D3D/DXPipeline.cpp b/Source/Core/VideoBackends/D3D/DXPipeline.cpp
index b17aeea59b..dfc3da0613 100644
--- a/Source/Core/VideoBackends/D3D/DXPipeline.cpp
+++ b/Source/Core/VideoBackends/D3D/DXPipeline.cpp
@@ -54,8 +54,7 @@ std::unique_ptr<DXPipeline> DXPipeline::Create(const AbstractPipelineConfig& con
           nullptr;
 
   // Only use the integer RTV if logic op is supported, and enabled.
-  const bool use_logic_op =
-      config.blending_state.logicopenable && g_ActiveConfig.backend_info.bSupportsLogicOp;
+  const bool use_logic_op = config.blending_state.logicopenable && g_backend_info.bSupportsLogicOp;
 
   return std::make_unique<DXPipeline>(config, input_layout, vertex_shader->GetD3DVertexShader(),
                                       geometry_shader ? geometry_shader->GetD3DGeometryShader() :
diff --git a/Source/Core/VideoBackends/D3D/DXTexture.cpp b/Source/Core/VideoBackends/D3D/DXTexture.cpp
index 5d791b5246..a535400f76 100644
--- a/Source/Core/VideoBackends/D3D/DXTexture.cpp
+++ b/Source/Core/VideoBackends/D3D/DXTexture.cpp
@@ -452,7 +452,7 @@ DXFramebuffer::Create(DXTexture* color_attachment, DXTexture* depth_attachment,
     // Only create the integer RTV when logic ops are supported (Win8+).
     DXGI_FORMAT integer_format =
         D3DCommon::GetRTVFormatForAbstractFormat(color_attachment->GetFormat(), true);
-    if (g_ActiveConfig.backend_info.bSupportsLogicOp && integer_format != desc.Format)
+    if (g_backend_info.bSupportsLogicOp && integer_format != desc.Format)
     {
       desc.Format = integer_format;
       hr = D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc,
diff --git a/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp b/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp
index 49b63fe07f..b579262f09 100644
--- a/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp
+++ b/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp
@@ -23,8 +23,7 @@ namespace DX12
 static bool UsesDynamicVertexLoader(const AbstractPipeline* pipeline)
 {
   const AbstractPipelineUsage usage = static_cast<const DXPipeline*>(pipeline)->GetUsage();
-  return (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader &&
-          usage == AbstractPipelineUsage::GXUber) ||
+  return (g_backend_info.bSupportsDynamicVertexLoader && usage == AbstractPipelineUsage::GXUber) ||
          (g_ActiveConfig.UseVSForLinePointExpand() && usage != AbstractPipelineUsage::Utility);
 }
 
diff --git a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp
index 171455cf34..25e092afa2 100644
--- a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp
+++ b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp
@@ -47,59 +47,59 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
 
 void VideoBackend::FillBackendInfo()
 {
-  g_Config.backend_info.api_type = APIType::D3D;
-  g_Config.backend_info.bUsesLowerLeftOrigin = false;
-  g_Config.backend_info.bSupportsExclusiveFullscreen = true;
-  g_Config.backend_info.bSupportsDualSourceBlend = true;
-  g_Config.backend_info.bSupportsPrimitiveRestart = true;
-  g_Config.backend_info.bSupportsGeometryShaders = true;
-  g_Config.backend_info.bSupports3DVision = false;
-  g_Config.backend_info.bSupportsEarlyZ = true;
-  g_Config.backend_info.bSupportsBindingLayout = false;
-  g_Config.backend_info.bSupportsBBox = true;
-  g_Config.backend_info.bSupportsGSInstancing = true;
-  g_Config.backend_info.bSupportsPaletteConversion = true;
-  g_Config.backend_info.bSupportsPostProcessing = true;
-  g_Config.backend_info.bSupportsClipControl = true;
-  g_Config.backend_info.bSupportsSSAA = true;
-  g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true;
-  g_Config.backend_info.bSupportsDepthClamp = true;
-  g_Config.backend_info.bSupportsReversedDepthRange = false;
-  g_Config.backend_info.bSupportsComputeShaders = true;
-  g_Config.backend_info.bSupportsLogicOp = true;
-  g_Config.backend_info.bSupportsMultithreading = false;
-  g_Config.backend_info.bSupportsGPUTextureDecoding = true;
-  g_Config.backend_info.bSupportsST3CTextures = false;
-  g_Config.backend_info.bSupportsCopyToVram = true;
-  g_Config.backend_info.bSupportsBitfield = false;
-  g_Config.backend_info.bSupportsDynamicSamplerIndexing = false;
-  g_Config.backend_info.bSupportsBPTCTextures = false;
-  g_Config.backend_info.bSupportsFramebufferFetch = false;
-  g_Config.backend_info.bSupportsBackgroundCompiling = true;
-  g_Config.backend_info.bSupportsLargePoints = false;
-  g_Config.backend_info.bSupportsDepthReadback = true;
-  g_Config.backend_info.bSupportsPartialDepthCopies = false;
-  g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames();
-  g_Config.backend_info.AAModes = DXContext::GetAAModes(g_Config.iAdapter);
-  g_Config.backend_info.bSupportsShaderBinaries = true;
-  g_Config.backend_info.bSupportsPipelineCacheData = true;
-  g_Config.backend_info.bSupportsCoarseDerivatives = true;
-  g_Config.backend_info.bSupportsTextureQueryLevels = true;
-  g_Config.backend_info.bSupportsLodBiasInSampler = true;
-  g_Config.backend_info.bSupportsSettingObjectNames = true;
-  g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
-  g_Config.backend_info.bSupportsDynamicVertexLoader = true;
-  g_Config.backend_info.bSupportsVSLinePointExpand = true;
-  g_Config.backend_info.bSupportsHDROutput = true;
+  g_backend_info.api_type = APIType::D3D;
+  g_backend_info.bUsesLowerLeftOrigin = false;
+  g_backend_info.bSupportsExclusiveFullscreen = true;
+  g_backend_info.bSupportsDualSourceBlend = true;
+  g_backend_info.bSupportsPrimitiveRestart = true;
+  g_backend_info.bSupportsGeometryShaders = true;
+  g_backend_info.bSupports3DVision = false;
+  g_backend_info.bSupportsEarlyZ = true;
+  g_backend_info.bSupportsBindingLayout = false;
+  g_backend_info.bSupportsBBox = true;
+  g_backend_info.bSupportsGSInstancing = true;
+  g_backend_info.bSupportsPaletteConversion = true;
+  g_backend_info.bSupportsPostProcessing = true;
+  g_backend_info.bSupportsClipControl = true;
+  g_backend_info.bSupportsSSAA = true;
+  g_backend_info.bSupportsFragmentStoresAndAtomics = true;
+  g_backend_info.bSupportsDepthClamp = true;
+  g_backend_info.bSupportsReversedDepthRange = false;
+  g_backend_info.bSupportsComputeShaders = true;
+  g_backend_info.bSupportsLogicOp = true;
+  g_backend_info.bSupportsMultithreading = false;
+  g_backend_info.bSupportsGPUTextureDecoding = true;
+  g_backend_info.bSupportsST3CTextures = false;
+  g_backend_info.bSupportsCopyToVram = true;
+  g_backend_info.bSupportsBitfield = false;
+  g_backend_info.bSupportsDynamicSamplerIndexing = false;
+  g_backend_info.bSupportsBPTCTextures = false;
+  g_backend_info.bSupportsFramebufferFetch = false;
+  g_backend_info.bSupportsBackgroundCompiling = true;
+  g_backend_info.bSupportsLargePoints = false;
+  g_backend_info.bSupportsDepthReadback = true;
+  g_backend_info.bSupportsPartialDepthCopies = false;
+  g_backend_info.Adapters = D3DCommon::GetAdapterNames();
+  g_backend_info.AAModes = DXContext::GetAAModes(g_Config.iAdapter);
+  g_backend_info.bSupportsShaderBinaries = true;
+  g_backend_info.bSupportsPipelineCacheData = true;
+  g_backend_info.bSupportsCoarseDerivatives = true;
+  g_backend_info.bSupportsTextureQueryLevels = true;
+  g_backend_info.bSupportsLodBiasInSampler = true;
+  g_backend_info.bSupportsSettingObjectNames = true;
+  g_backend_info.bSupportsPartialMultisampleResolve = true;
+  g_backend_info.bSupportsDynamicVertexLoader = true;
+  g_backend_info.bSupportsVSLinePointExpand = true;
+  g_backend_info.bSupportsHDROutput = true;
 
   // We can only check texture support once we have a device.
   if (g_dx_context)
   {
-    g_Config.backend_info.bSupportsST3CTextures =
+    g_backend_info.bSupportsST3CTextures =
         g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
         g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
         g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM);
-    g_Config.backend_info.bSupportsBPTCTextures =
+    g_backend_info.bSupportsBPTCTextures =
         g_dx_context->SupportsTextureFormat(DXGI_FORMAT_BC7_UNORM);
   }
 }
diff --git a/Source/Core/VideoBackends/Metal/MTLGfx.mm b/Source/Core/VideoBackends/Metal/MTLGfx.mm
index a61c3d79d4..d4236bd503 100644
--- a/Source/Core/VideoBackends/Metal/MTLGfx.mm
+++ b/Source/Core/VideoBackends/Metal/MTLGfx.mm
@@ -334,7 +334,7 @@ void Metal::Gfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool col
             static_cast<double>((color >> 24) & 0xFF) / 255.0);
         // clang-format on
         float z_normalized = static_cast<float>(z & 0xFFFFFF) / 16777216.0f;
-        if (!g_Config.backend_info.bSupportsReversedDepthRange)
+        if (!g_backend_info.bSupportsReversedDepthRange)
           z_normalized = 1.f - z_normalized;
         g_state_tracker->BeginClearRenderPass(clear_color, z_normalized);
         return;
diff --git a/Source/Core/VideoBackends/Metal/MTLMain.mm b/Source/Core/VideoBackends/Metal/MTLMain.mm
index 56c9b3c68f..bcb031f843 100644
--- a/Source/Core/VideoBackends/Metal/MTLMain.mm
+++ b/Source/Core/VideoBackends/Metal/MTLMain.mm
@@ -81,8 +81,8 @@ bool Metal::VideoBackend::Initialize(const WindowSystemInfo& wsi)
       return false;
     }
 
-    Util::PopulateBackendInfo(&g_Config);
-    Util::PopulateBackendInfoAdapters(&g_Config, devs);
+    Util::PopulateBackendInfo(&g_backend_info);
+    Util::PopulateBackendInfoAdapters(&g_backend_info, devs);
 
     // Since we haven't called InitializeShared yet, iAdapter may be out of range,
     // so we have to check it ourselves.
@@ -93,7 +93,7 @@ bool Metal::VideoBackend::Initialize(const WindowSystemInfo& wsi)
       selected_adapter_index = 0;
     }
     MRCOwned<id<MTLDevice>> adapter = std::move(devs[selected_adapter_index]);
-    Util::PopulateBackendInfoFeatures(&g_Config, adapter);
+    Util::PopulateBackendInfoFeatures(g_Config, &g_backend_info, adapter);
 
 #if TARGET_OS_OSX
 // This should be available on all macOS 13.3+ systems – but when using OCLP drivers, some devices
@@ -143,16 +143,16 @@ void Metal::VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
 {
   @autoreleasepool
   {
-    Util::PopulateBackendInfo(&g_Config);
+    Util::PopulateBackendInfo(&g_backend_info);
     auto adapters = Util::GetAdapterList();
-    Util::PopulateBackendInfoAdapters(&g_Config, adapters);
+    Util::PopulateBackendInfoAdapters(&g_backend_info, adapters);
     if (!adapters.empty())
     {
       // Use the selected adapter, or the first to fill features.
       size_t index = static_cast<size_t>(g_Config.iAdapter);
       if (index >= adapters.size())
         index = 0;
-      Util::PopulateBackendInfoFeatures(&g_Config, adapters[index]);
+      Util::PopulateBackendInfoFeatures(g_Config, &g_backend_info, adapters[index]);
     }
   }
 }
@@ -165,9 +165,9 @@ void Metal::VideoBackend::PrepareWindow(WindowSystemInfo& wsi)
   NSView* view = static_cast<NSView*>(wsi.render_surface);
   CAMetalLayer* layer = [CAMetalLayer layer];
 
-  Util::PopulateBackendInfo(&g_Config);
+  Util::PopulateBackendInfo(&g_backend_info);
 
-  if (g_Config.backend_info.bSupportsHDROutput && g_Config.bHDR)
+  if (g_backend_info.bSupportsHDROutput && g_Config.bHDR)
   {
     [layer setWantsExtendedDynamicRangeContent:YES];
     [layer setPixelFormat:MTLPixelFormatRGBA16Float];
diff --git a/Source/Core/VideoBackends/Metal/MTLObjectCache.mm b/Source/Core/VideoBackends/Metal/MTLObjectCache.mm
index db0e338ae5..8edcfc2031 100644
--- a/Source/Core/VideoBackends/Metal/MTLObjectCache.mm
+++ b/Source/Core/VideoBackends/Metal/MTLObjectCache.mm
@@ -57,7 +57,7 @@ void Metal::ObjectCache::Shutdown()
 
 static MTLCompareFunction Convert(CompareMode mode)
 {
-  const bool invert_depth = !g_Config.backend_info.bSupportsReversedDepthRange;
+  const bool invert_depth = !g_backend_info.bSupportsReversedDepthRange;
   switch (mode)
   {
   case CompareMode::Never:   return MTLCompareFunctionNever;
diff --git a/Source/Core/VideoBackends/Metal/MTLStateTracker.mm b/Source/Core/VideoBackends/Metal/MTLStateTracker.mm
index 131c7c2568..c2cd685a82 100644
--- a/Source/Core/VideoBackends/Metal/MTLStateTracker.mm
+++ b/Source/Core/VideoBackends/Metal/MTLStateTracker.mm
@@ -737,9 +737,8 @@ void Metal::StateTracker::PrepareRender()
       m_current.depth_stencil = pipe->DepthStencil();
       [enc setDepthStencilState:g_object_cache->GetDepthStencil(m_current.depth_stencil)];
     }
-    MTLDepthClipMode clip = is_gx && g_ActiveConfig.backend_info.bSupportsDepthClamp ?
-                                MTLDepthClipModeClamp :
-                                MTLDepthClipModeClip;
+    MTLDepthClipMode clip =
+        is_gx && g_backend_info.bSupportsDepthClamp ? MTLDepthClipModeClamp : MTLDepthClipModeClip;
     if (clip != m_current.depth_clip_mode)
     {
       m_current.depth_clip_mode = clip;
diff --git a/Source/Core/VideoBackends/Metal/MTLUtil.h b/Source/Core/VideoBackends/Metal/MTLUtil.h
index a5663b5e35..812ce39e5a 100644
--- a/Source/Core/VideoBackends/Metal/MTLUtil.h
+++ b/Source/Core/VideoBackends/Metal/MTLUtil.h
@@ -41,10 +41,11 @@ struct Viewport
 
 /// Gets the list of Metal devices, ordered so the system default device is first
 std::vector<MRCOwned<id<MTLDevice>>> GetAdapterList();
-void PopulateBackendInfo(VideoConfig* config);
-void PopulateBackendInfoAdapters(VideoConfig* config,
+void PopulateBackendInfo(BackendInfo* backend_info);
+void PopulateBackendInfoAdapters(BackendInfo* backend_info,
                                  const std::vector<MRCOwned<id<MTLDevice>>>& adapters);
-void PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice> device);
+void PopulateBackendInfoFeatures(const VideoConfig& config, BackendInfo* backend_info,
+                                 id<MTLDevice> device);
 
 AbstractTextureFormat ToAbstract(MTLPixelFormat format);
 MTLPixelFormat FromAbstract(AbstractTextureFormat format);
diff --git a/Source/Core/VideoBackends/Metal/MTLUtil.mm b/Source/Core/VideoBackends/Metal/MTLUtil.mm
index de073280d7..469e4f7df8 100644
--- a/Source/Core/VideoBackends/Metal/MTLUtil.mm
+++ b/Source/Core/VideoBackends/Metal/MTLUtil.mm
@@ -36,58 +36,58 @@ std::vector<MRCOwned<id<MTLDevice>>> Metal::Util::GetAdapterList()
   return list;
 }
 
-void Metal::Util::PopulateBackendInfo(VideoConfig* config)
+void Metal::Util::PopulateBackendInfo(BackendInfo* backend_info)
 {
-  config->backend_info.api_type = APIType::Metal;
-  config->backend_info.bUsesLowerLeftOrigin = false;
-  config->backend_info.bSupportsExclusiveFullscreen = false;
-  config->backend_info.bSupportsDualSourceBlend = true;
-  config->backend_info.bSupportsPrimitiveRestart = true;
-  config->backend_info.bSupportsGeometryShaders = false;
-  config->backend_info.bSupportsComputeShaders = true;
-  config->backend_info.bSupports3DVision = false;
-  config->backend_info.bSupportsEarlyZ = true;
-  config->backend_info.bSupportsBindingLayout = true;
-  config->backend_info.bSupportsBBox = true;
-  config->backend_info.bSupportsGSInstancing = false;
-  config->backend_info.bSupportsPostProcessing = true;
-  config->backend_info.bSupportsPaletteConversion = true;
-  config->backend_info.bSupportsClipControl = true;
-  config->backend_info.bSupportsSSAA = true;
-  config->backend_info.bSupportsFragmentStoresAndAtomics = true;
-  config->backend_info.bSupportsReversedDepthRange = false;
-  config->backend_info.bSupportsLogicOp = false;
-  config->backend_info.bSupportsMultithreading = false;
-  config->backend_info.bSupportsGPUTextureDecoding = true;
-  config->backend_info.bSupportsCopyToVram = true;
-  config->backend_info.bSupportsBitfield = true;
-  config->backend_info.bSupportsDynamicSamplerIndexing = true;
-  config->backend_info.bSupportsFramebufferFetch = false;
-  config->backend_info.bSupportsBackgroundCompiling = true;
-  config->backend_info.bSupportsLargePoints = true;
-  config->backend_info.bSupportsPartialDepthCopies = true;
-  config->backend_info.bSupportsDepthReadback = true;
-  config->backend_info.bSupportsShaderBinaries = false;
-  config->backend_info.bSupportsPipelineCacheData = false;
-  config->backend_info.bSupportsCoarseDerivatives = false;
-  config->backend_info.bSupportsTextureQueryLevels = true;
-  config->backend_info.bSupportsLodBiasInSampler = false;
-  config->backend_info.bSupportsSettingObjectNames = true;
+  backend_info->api_type = APIType::Metal;
+  backend_info->bUsesLowerLeftOrigin = false;
+  backend_info->bSupportsExclusiveFullscreen = false;
+  backend_info->bSupportsDualSourceBlend = true;
+  backend_info->bSupportsPrimitiveRestart = true;
+  backend_info->bSupportsGeometryShaders = false;
+  backend_info->bSupportsComputeShaders = true;
+  backend_info->bSupports3DVision = false;
+  backend_info->bSupportsEarlyZ = true;
+  backend_info->bSupportsBindingLayout = true;
+  backend_info->bSupportsBBox = true;
+  backend_info->bSupportsGSInstancing = false;
+  backend_info->bSupportsPostProcessing = true;
+  backend_info->bSupportsPaletteConversion = true;
+  backend_info->bSupportsClipControl = true;
+  backend_info->bSupportsSSAA = true;
+  backend_info->bSupportsFragmentStoresAndAtomics = true;
+  backend_info->bSupportsReversedDepthRange = false;
+  backend_info->bSupportsLogicOp = false;
+  backend_info->bSupportsMultithreading = false;
+  backend_info->bSupportsGPUTextureDecoding = true;
+  backend_info->bSupportsCopyToVram = true;
+  backend_info->bSupportsBitfield = true;
+  backend_info->bSupportsDynamicSamplerIndexing = true;
+  backend_info->bSupportsFramebufferFetch = false;
+  backend_info->bSupportsBackgroundCompiling = true;
+  backend_info->bSupportsLargePoints = true;
+  backend_info->bSupportsPartialDepthCopies = true;
+  backend_info->bSupportsDepthReadback = true;
+  backend_info->bSupportsShaderBinaries = false;
+  backend_info->bSupportsPipelineCacheData = false;
+  backend_info->bSupportsCoarseDerivatives = false;
+  backend_info->bSupportsTextureQueryLevels = true;
+  backend_info->bSupportsLodBiasInSampler = false;
+  backend_info->bSupportsSettingObjectNames = true;
   // Metal requires multisample resolve to be done on a render pass
-  config->backend_info.bSupportsPartialMultisampleResolve = false;
-  config->backend_info.bSupportsDynamicVertexLoader = true;
-  config->backend_info.bSupportsVSLinePointExpand = true;
-  config->backend_info.bSupportsHDROutput =
+  backend_info->bSupportsPartialMultisampleResolve = false;
+  backend_info->bSupportsDynamicVertexLoader = true;
+  backend_info->bSupportsVSLinePointExpand = true;
+  backend_info->bSupportsHDROutput =
       1.0 < [[NSScreen deepestScreen] maximumPotentialExtendedDynamicRangeColorComponentValue];
 }
 
-void Metal::Util::PopulateBackendInfoAdapters(VideoConfig* config,
+void Metal::Util::PopulateBackendInfoAdapters(BackendInfo* backend_info,
                                               const std::vector<MRCOwned<id<MTLDevice>>>& adapters)
 {
-  config->backend_info.Adapters.clear();
+  backend_info->Adapters.clear();
   for (id<MTLDevice> adapter : adapters)
   {
-    config->backend_info.Adapters.push_back([[adapter name] UTF8String]);
+    backend_info->Adapters.push_back([[adapter name] UTF8String]);
   }
 }
 
@@ -238,7 +238,8 @@ fragment float4 is_helper_test() {
   return DetectionResult::Unsure;
 }
 
-void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice> device)
+void Metal::Util::PopulateBackendInfoFeatures(const VideoConfig& config, BackendInfo* backend_info,
+                                              id<MTLDevice> device)
 {
   // Initialize DriverDetails first so we can use it later
   DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN;
@@ -257,9 +258,9 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice>
                       DriverDetails::Family::UNKNOWN, std::move(name));
 
 #if TARGET_OS_OSX
-  config->backend_info.bSupportsDepthClamp = true;
-  config->backend_info.bSupportsST3CTextures = true;
-  config->backend_info.bSupportsBPTCTextures = true;
+  backend_info->bSupportsDepthClamp = true;
+  backend_info->bSupportsST3CTextures = true;
+  backend_info->bSupportsBPTCTextures = true;
 #else
   bool supports_apple4 = false;
   bool supports_bcn = false;
@@ -269,21 +270,21 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice>
     supports_apple4 = [device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1];
   if (@available(iOS 16.4, *))
     supports_bcn = [device supportsBCTextureCompression];
-  config->backend_info.bSupportsDepthClamp = supports_apple4;
-  config->backend_info.bSupportsST3CTextures = supports_bcn;
-  config->backend_info.bSupportsBPTCTextures = supports_bcn;
+  backend_info->bSupportsDepthClamp = supports_apple4;
+  backend_info->bSupportsST3CTextures = supports_bcn;
+  backend_info->bSupportsBPTCTextures = supports_bcn;
 
-  config->backend_info.bSupportsFramebufferFetch = true;
+  backend_info->bSupportsFramebufferFetch = true;
 #endif
 
-  config->backend_info.AAModes.clear();
+  backend_info->AAModes.clear();
   for (u32 i = 1; i <= 64; i <<= 1)
   {
     if ([device supportsTextureSampleCount:i])
-      config->backend_info.AAModes.push_back(i);
+      backend_info->AAModes.push_back(i);
   }
 
-  switch (config->iManuallyUploadBuffers)
+  switch (config.iManuallyUploadBuffers)
   {
   case TriState::Off:
     g_features.manual_buffer_upload = false;
@@ -310,7 +311,7 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice>
     // Requires SIMD-scoped reduction operations
     g_features.subgroup_ops =
         [device supportsFamily:MTLGPUFamilyMac2] || [device supportsFamily:MTLGPUFamilyApple7];
-    config->backend_info.bSupportsFramebufferFetch = [device supportsFamily:MTLGPUFamilyApple1];
+    backend_info->bSupportsFramebufferFetch = [device supportsFamily:MTLGPUFamilyApple1];
   }
   if (g_features.subgroup_ops)
   {
@@ -325,10 +326,10 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id<MTLDevice>
 #if TARGET_OS_OSX
   if (@available(macOS 11, *))
     if (vendor == DriverDetails::VENDOR_INTEL)
-      config->backend_info.bSupportsFramebufferFetch |= DetectIntelGPUFBFetch(device);
+      backend_info->bSupportsFramebufferFetch |= DetectIntelGPUFBFetch(device);
 #endif
   if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING))
-    config->backend_info.bSupportsDynamicSamplerIndexing = false;
+    backend_info->bSupportsDynamicSamplerIndexing = false;
 }
 
 // clang-format off
diff --git a/Source/Core/VideoBackends/Null/NullBackend.cpp b/Source/Core/VideoBackends/Null/NullBackend.cpp
index 28afcce4dc..016613bd48 100644
--- a/Source/Core/VideoBackends/Null/NullBackend.cpp
+++ b/Source/Core/VideoBackends/Null/NullBackend.cpp
@@ -9,7 +9,6 @@
 #include "VideoBackends/Null/VideoBackend.h"
 
 #include "Common/Common.h"
-#include "Common/MsgHandler.h"
 
 #include "VideoBackends/Null/NullBoundingBox.h"
 #include "VideoBackends/Null/NullGfx.h"
@@ -17,9 +16,6 @@
 #include "VideoBackends/Null/PerfQuery.h"
 #include "VideoBackends/Null/TextureCache.h"
 
-#include "VideoCommon/FramebufferManager.h"
-#include "VideoCommon/Present.h"
-#include "VideoCommon/VideoBackendBase.h"
 #include "VideoCommon/VideoCommon.h"
 #include "VideoCommon/VideoConfig.h"
 
@@ -27,46 +23,46 @@ namespace Null
 {
 void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
 {
-  g_Config.backend_info.api_type = APIType::Nothing;
-  g_Config.backend_info.MaxTextureSize = 16384;
-  g_Config.backend_info.bSupportsExclusiveFullscreen = true;
-  g_Config.backend_info.bSupportsDualSourceBlend = true;
-  g_Config.backend_info.bSupportsPrimitiveRestart = true;
-  g_Config.backend_info.bSupportsGeometryShaders = true;
-  g_Config.backend_info.bSupportsComputeShaders = false;
-  g_Config.backend_info.bSupports3DVision = false;
-  g_Config.backend_info.bSupportsEarlyZ = true;
-  g_Config.backend_info.bSupportsBindingLayout = true;
-  g_Config.backend_info.bSupportsBBox = true;
-  g_Config.backend_info.bSupportsGSInstancing = true;
-  g_Config.backend_info.bSupportsPostProcessing = false;
-  g_Config.backend_info.bSupportsPaletteConversion = true;
-  g_Config.backend_info.bSupportsClipControl = true;
-  g_Config.backend_info.bSupportsSSAA = true;
-  g_Config.backend_info.bSupportsDepthClamp = true;
-  g_Config.backend_info.bSupportsReversedDepthRange = true;
-  g_Config.backend_info.bSupportsMultithreading = false;
-  g_Config.backend_info.bSupportsGPUTextureDecoding = false;
-  g_Config.backend_info.bSupportsST3CTextures = false;
-  g_Config.backend_info.bSupportsBPTCTextures = false;
-  g_Config.backend_info.bSupportsFramebufferFetch = false;
-  g_Config.backend_info.bSupportsBackgroundCompiling = false;
-  g_Config.backend_info.bSupportsLogicOp = false;
-  g_Config.backend_info.bSupportsLargePoints = false;
-  g_Config.backend_info.bSupportsDepthReadback = false;
-  g_Config.backend_info.bSupportsPartialDepthCopies = false;
-  g_Config.backend_info.bSupportsShaderBinaries = false;
-  g_Config.backend_info.bSupportsPipelineCacheData = false;
-  g_Config.backend_info.bSupportsCoarseDerivatives = false;
-  g_Config.backend_info.bSupportsTextureQueryLevels = false;
-  g_Config.backend_info.bSupportsLodBiasInSampler = false;
-  g_Config.backend_info.bSupportsSettingObjectNames = false;
-  g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
-  g_Config.backend_info.bSupportsDynamicVertexLoader = false;
+  g_backend_info.api_type = APIType::Nothing;
+  g_backend_info.MaxTextureSize = 16384;
+  g_backend_info.bSupportsExclusiveFullscreen = true;
+  g_backend_info.bSupportsDualSourceBlend = true;
+  g_backend_info.bSupportsPrimitiveRestart = true;
+  g_backend_info.bSupportsGeometryShaders = true;
+  g_backend_info.bSupportsComputeShaders = false;
+  g_backend_info.bSupports3DVision = false;
+  g_backend_info.bSupportsEarlyZ = true;
+  g_backend_info.bSupportsBindingLayout = true;
+  g_backend_info.bSupportsBBox = true;
+  g_backend_info.bSupportsGSInstancing = true;
+  g_backend_info.bSupportsPostProcessing = false;
+  g_backend_info.bSupportsPaletteConversion = true;
+  g_backend_info.bSupportsClipControl = true;
+  g_backend_info.bSupportsSSAA = true;
+  g_backend_info.bSupportsDepthClamp = true;
+  g_backend_info.bSupportsReversedDepthRange = true;
+  g_backend_info.bSupportsMultithreading = false;
+  g_backend_info.bSupportsGPUTextureDecoding = false;
+  g_backend_info.bSupportsST3CTextures = false;
+  g_backend_info.bSupportsBPTCTextures = false;
+  g_backend_info.bSupportsFramebufferFetch = false;
+  g_backend_info.bSupportsBackgroundCompiling = false;
+  g_backend_info.bSupportsLogicOp = false;
+  g_backend_info.bSupportsLargePoints = false;
+  g_backend_info.bSupportsDepthReadback = false;
+  g_backend_info.bSupportsPartialDepthCopies = false;
+  g_backend_info.bSupportsShaderBinaries = false;
+  g_backend_info.bSupportsPipelineCacheData = false;
+  g_backend_info.bSupportsCoarseDerivatives = false;
+  g_backend_info.bSupportsTextureQueryLevels = false;
+  g_backend_info.bSupportsLodBiasInSampler = false;
+  g_backend_info.bSupportsSettingObjectNames = false;
+  g_backend_info.bSupportsPartialMultisampleResolve = true;
+  g_backend_info.bSupportsDynamicVertexLoader = false;
 
   // aamodes: We only support 1 sample, so no MSAA
-  g_Config.backend_info.Adapters.clear();
-  g_Config.backend_info.AAModes = {1};
+  g_backend_info.Adapters.clear();
+  g_backend_info.AAModes = {1};
 }
 
 bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
diff --git a/Source/Core/VideoBackends/OGL/OGLConfig.cpp b/Source/Core/VideoBackends/OGL/OGLConfig.cpp
index 4b1e5308a2..1da407e664 100644
--- a/Source/Core/VideoBackends/OGL/OGLConfig.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLConfig.cpp
@@ -283,25 +283,24 @@ bool PopulateConfig(GLContext* m_main_gl_context)
   }
 
   // Copy the GPU name to g_Config, so Analytics can see it.
-  g_Config.backend_info.AdapterName = g_ogl_config.gl_renderer;
+  g_backend_info.AdapterName = g_ogl_config.gl_renderer;
 
-  g_Config.backend_info.bSupportsDualSourceBlend =
-      (GLExtensions::Supports("GL_ARB_blend_func_extended") ||
-       GLExtensions::Supports("GL_EXT_blend_func_extended"));
-  g_Config.backend_info.bSupportsPrimitiveRestart =
+  g_backend_info.bSupportsDualSourceBlend = (GLExtensions::Supports("GL_ARB_blend_func_extended") ||
+                                             GLExtensions::Supports("GL_EXT_blend_func_extended"));
+  g_backend_info.bSupportsPrimitiveRestart =
       !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART) &&
       ((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart"));
-  g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5");
-  g_Config.backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") &&
-                                        GLExtensions::Supports("GL_ARB_sample_shading");
-  g_Config.backend_info.bSupportsGeometryShaders =
+  g_backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5");
+  g_backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") &&
+                                 GLExtensions::Supports("GL_ARB_sample_shading");
+  g_backend_info.bSupportsGeometryShaders =
       GLExtensions::Version() >= 320 &&
       !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_GEOMETRY_SHADERS);
-  g_Config.backend_info.bSupportsPaletteConversion =
+  g_backend_info.bSupportsPaletteConversion =
       GLExtensions::Supports("GL_ARB_texture_buffer_object") ||
       GLExtensions::Supports("GL_OES_texture_buffer") ||
       GLExtensions::Supports("GL_EXT_texture_buffer");
-  g_Config.backend_info.bSupportsClipControl = GLExtensions::Supports("GL_ARB_clip_control");
+  g_backend_info.bSupportsClipControl = GLExtensions::Supports("GL_ARB_clip_control");
   g_ogl_config.bSupportsCopySubImage =
       (GLExtensions::Supports("GL_ARB_copy_image") || GLExtensions::Supports("GL_NV_copy_image") ||
        GLExtensions::Supports("GL_EXT_copy_image") ||
@@ -311,17 +310,15 @@ bool PopulateConfig(GLContext* m_main_gl_context)
 
   // Desktop OpenGL supports the binding layout if it supports 420pack
   // OpenGL ES 3.1 supports it implicitly without an extension
-  g_Config.backend_info.bSupportsBindingLayout =
-      GLExtensions::Supports("GL_ARB_shading_language_420pack");
+  g_backend_info.bSupportsBindingLayout = GLExtensions::Supports("GL_ARB_shading_language_420pack");
 
   // Clip distance support is useless without a method to clamp the depth range
-  g_Config.backend_info.bSupportsDepthClamp = GLExtensions::Supports("GL_ARB_depth_clamp");
+  g_backend_info.bSupportsDepthClamp = GLExtensions::Supports("GL_ARB_depth_clamp");
 
   // Desktop OpenGL supports bitfield manulipation and dynamic sampler indexing if it supports
   // shader5. OpenGL ES 3.1 supports it implicitly without an extension
-  g_Config.backend_info.bSupportsBitfield = GLExtensions::Supports("GL_ARB_gpu_shader5");
-  g_Config.backend_info.bSupportsDynamicSamplerIndexing =
-      GLExtensions::Supports("GL_ARB_gpu_shader5");
+  g_backend_info.bSupportsBitfield = GLExtensions::Supports("GL_ARB_gpu_shader5");
+  g_backend_info.bSupportsDynamicSamplerIndexing = GLExtensions::Supports("GL_ARB_gpu_shader5");
 
   g_ogl_config.bIsES = m_main_gl_context->IsGLES();
   supports_glsl_cache = GLExtensions::Supports("GL_ARB_get_program_binary");
@@ -341,14 +338,12 @@ bool PopulateConfig(GLContext* m_main_gl_context)
   g_ogl_config.bSupportsImageLoadStore = GLExtensions::Supports("GL_ARB_shader_image_load_store");
   g_ogl_config.bSupportsConservativeDepth = GLExtensions::Supports("GL_ARB_conservative_depth");
   g_ogl_config.bSupportsAniso = GLExtensions::Supports("GL_EXT_texture_filter_anisotropic");
-  g_Config.backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader");
-  g_Config.backend_info.bSupportsST3CTextures =
-      GLExtensions::Supports("GL_EXT_texture_compression_s3tc");
-  g_Config.backend_info.bSupportsBPTCTextures =
-      GLExtensions::Supports("GL_ARB_texture_compression_bptc");
-  g_Config.backend_info.bSupportsCoarseDerivatives =
+  g_backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader");
+  g_backend_info.bSupportsST3CTextures = GLExtensions::Supports("GL_EXT_texture_compression_s3tc");
+  g_backend_info.bSupportsBPTCTextures = GLExtensions::Supports("GL_ARB_texture_compression_bptc");
+  g_backend_info.bSupportsCoarseDerivatives =
       GLExtensions::Supports("GL_ARB_derivative_control") || GLExtensions::Version() >= 450;
-  g_Config.backend_info.bSupportsTextureQueryLevels =
+  g_backend_info.bSupportsTextureQueryLevels =
       GLExtensions::Supports("GL_ARB_texture_query_levels") || GLExtensions::Version() >= 430;
 
   if (GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"))
@@ -357,13 +352,13 @@ bool PopulateConfig(GLContext* m_main_gl_context)
     GLint vs = 0;
     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &fs);
     glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &vs);
-    g_Config.backend_info.bSupportsFragmentStoresAndAtomics = fs >= 1;
-    g_Config.backend_info.bSupportsVSLinePointExpand = vs >= 1;
+    g_backend_info.bSupportsFragmentStoresAndAtomics = fs >= 1;
+    g_backend_info.bSupportsVSLinePointExpand = vs >= 1;
   }
   else
   {
-    g_Config.backend_info.bSupportsFragmentStoresAndAtomics = false;
-    g_Config.backend_info.bSupportsVSLinePointExpand = false;
+    g_backend_info.bSupportsFragmentStoresAndAtomics = false;
+    g_backend_info.bSupportsVSLinePointExpand = false;
   }
 
   if (GLExtensions::Supports("GL_EXT_shader_framebuffer_fetch"))
@@ -378,7 +373,7 @@ bool PopulateConfig(GLContext* m_main_gl_context)
   {
     g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchNone;
   }
-  g_Config.backend_info.bSupportsFramebufferFetch =
+  g_backend_info.bSupportsFramebufferFetch =
       g_ogl_config.SupportedFramebufferFetch != EsFbFetchType::FbFetchNone;
 
   if (m_main_gl_context->IsGLES())
@@ -398,67 +393,67 @@ bool PopulateConfig(GLContext* m_main_gl_context)
 
     // TODO: Implement support for GL_EXT_clip_cull_distance when there is an extension for
     // depth clamping.
-    g_Config.backend_info.bSupportsDepthClamp = false;
+    g_backend_info.bSupportsDepthClamp = false;
 
     // GLES does not support logic op.
-    g_Config.backend_info.bSupportsLogicOp = false;
+    g_backend_info.bSupportsLogicOp = false;
 
     // glReadPixels() can't be used with non-color formats. But, if we support
     // ARB_get_texture_sub_image (unlikely, except maybe on NVIDIA), we can use that instead.
-    g_Config.backend_info.bSupportsDepthReadback = g_ogl_config.bSupportsTextureSubImage;
+    g_backend_info.bSupportsDepthReadback = g_ogl_config.bSupportsTextureSubImage;
 
     // GL_TEXTURE_LOD_BIAS is not supported on GLES.
-    g_Config.backend_info.bSupportsLodBiasInSampler = false;
+    g_backend_info.bSupportsLodBiasInSampler = false;
 
     if (GLExtensions::Version() == 300)
     {
       g_ogl_config.eSupportedGLSLVersion = GlslEs300;
       g_ogl_config.bSupportsAEP = false;
       g_ogl_config.bSupportsTextureStorage = true;
-      g_Config.backend_info.bSupportsGeometryShaders = false;
+      g_backend_info.bSupportsGeometryShaders = false;
     }
     else if (GLExtensions::Version() == 310)
     {
       g_ogl_config.eSupportedGLSLVersion = GlslEs310;
       g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a");
-      g_Config.backend_info.bSupportsBindingLayout = true;
+      g_backend_info.bSupportsBindingLayout = true;
       g_ogl_config.bSupportsImageLoadStore = true;
-      g_Config.backend_info.bSupportsGeometryShaders = g_ogl_config.bSupportsAEP;
-      g_Config.backend_info.bSupportsComputeShaders = true;
-      g_Config.backend_info.bSupportsGSInstancing =
-          g_Config.backend_info.bSupportsGeometryShaders &&
+      g_backend_info.bSupportsGeometryShaders = g_ogl_config.bSupportsAEP;
+      g_backend_info.bSupportsComputeShaders = true;
+      g_backend_info.bSupportsGSInstancing =
+          g_backend_info.bSupportsGeometryShaders &&
           g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone;
-      g_Config.backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP;
-      g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true;
+      g_backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP;
+      g_backend_info.bSupportsFragmentStoresAndAtomics = true;
       g_ogl_config.bSupportsMSAA = true;
       g_ogl_config.bSupportsTextureStorage = true;
       if (GLExtensions::Supports("GL_OES_texture_storage_multisample_2d_array"))
         g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageOes;
-      g_Config.backend_info.bSupportsBitfield = true;
-      g_Config.backend_info.bSupportsDynamicSamplerIndexing = g_ogl_config.bSupportsAEP;
+      g_backend_info.bSupportsBitfield = true;
+      g_backend_info.bSupportsDynamicSamplerIndexing = g_ogl_config.bSupportsAEP;
     }
     else
     {
       g_ogl_config.eSupportedGLSLVersion = GlslEs320;
       g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a");
-      g_Config.backend_info.bSupportsBindingLayout = true;
+      g_backend_info.bSupportsBindingLayout = true;
       g_ogl_config.bSupportsImageLoadStore = true;
-      g_Config.backend_info.bSupportsGeometryShaders = true;
-      g_Config.backend_info.bSupportsComputeShaders = true;
-      g_Config.backend_info.bSupportsGSInstancing =
+      g_backend_info.bSupportsGeometryShaders = true;
+      g_backend_info.bSupportsComputeShaders = true;
+      g_backend_info.bSupportsGSInstancing =
           g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone;
-      g_Config.backend_info.bSupportsPaletteConversion = true;
-      g_Config.backend_info.bSupportsSSAA = true;
-      g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true;
+      g_backend_info.bSupportsPaletteConversion = true;
+      g_backend_info.bSupportsSSAA = true;
+      g_backend_info.bSupportsFragmentStoresAndAtomics = true;
       g_ogl_config.bSupportsCopySubImage = true;
       g_ogl_config.bSupportsGLBaseVertex = true;
       g_ogl_config.bSupportsDebug = true;
       g_ogl_config.bSupportsMSAA = true;
       g_ogl_config.bSupportsTextureStorage = true;
       g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore;
-      g_Config.backend_info.bSupportsBitfield = true;
-      g_Config.backend_info.bSupportsDynamicSamplerIndexing = true;
-      g_Config.backend_info.bSupportsSettingObjectNames = true;
+      g_backend_info.bSupportsBitfield = true;
+      g_backend_info.bSupportsDynamicSamplerIndexing = true;
+      g_backend_info.bSupportsSettingObjectNames = true;
     }
   }
   else
@@ -480,7 +475,7 @@ bool PopulateConfig(GLContext* m_main_gl_context)
       g_ogl_config.bSupportsImageLoadStore = false;  // layout keyword is only supported on glsl150+
       g_ogl_config.bSupportsConservativeDepth =
           false;  // layout keyword is only supported on glsl150+
-      g_Config.backend_info.bSupportsGeometryShaders =
+      g_backend_info.bSupportsGeometryShaders =
           false;  // geometry shaders are only supported on glsl150+
     }
     else if (GLExtensions::Version() == 310)
@@ -489,7 +484,7 @@ bool PopulateConfig(GLContext* m_main_gl_context)
       g_ogl_config.bSupportsImageLoadStore = false;  // layout keyword is only supported on glsl150+
       g_ogl_config.bSupportsConservativeDepth =
           false;  // layout keyword is only supported on glsl150+
-      g_Config.backend_info.bSupportsGeometryShaders =
+      g_backend_info.bSupportsGeometryShaders =
           false;  // geometry shaders are only supported on glsl150+
     }
     else if (GLExtensions::Version() == 320)
@@ -517,18 +512,18 @@ bool PopulateConfig(GLContext* m_main_gl_context)
       g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore;
       g_ogl_config.bSupportsImageLoadStore = true;
       g_ogl_config.bSupportsExplicitLayoutInShader = true;
-      g_Config.backend_info.bSupportsSSAA = true;
-      g_Config.backend_info.bSupportsSettingObjectNames = true;
+      g_backend_info.bSupportsSSAA = true;
+      g_backend_info.bSupportsSettingObjectNames = true;
 
       // Compute shaders are core in GL4.3.
-      g_Config.backend_info.bSupportsComputeShaders = true;
+      g_backend_info.bSupportsComputeShaders = true;
       if (GLExtensions::Version() >= 450)
         g_ogl_config.bSupportsTextureSubImage = true;
     }
     else
     {
       g_ogl_config.eSupportedGLSLVersion = Glsl400;
-      g_Config.backend_info.bSupportsSSAA = true;
+      g_backend_info.bSupportsSSAA = true;
 
       if (GLExtensions::Version() == 420)
       {
@@ -547,16 +542,16 @@ bool PopulateConfig(GLContext* m_main_gl_context)
   }
 
   // Supported by all GS-supporting ES and 4.3+
-  g_Config.backend_info.bSupportsGLLayerInFS = g_Config.backend_info.bSupportsGeometryShaders &&
-                                               g_ogl_config.eSupportedGLSLVersion >= Glsl430;
+  g_backend_info.bSupportsGLLayerInFS =
+      g_backend_info.bSupportsGeometryShaders && g_ogl_config.eSupportedGLSLVersion >= Glsl430;
 
-  g_Config.backend_info.bSupportsBBox = g_Config.backend_info.bSupportsFragmentStoresAndAtomics;
+  g_backend_info.bSupportsBBox = g_backend_info.bSupportsFragmentStoresAndAtomics;
 
   // Either method can do early-z tests. See PixelShaderGen for details.
-  g_Config.backend_info.bSupportsEarlyZ =
+  g_backend_info.bSupportsEarlyZ =
       g_ogl_config.bSupportsImageLoadStore || g_ogl_config.bSupportsConservativeDepth;
 
-  g_Config.backend_info.AAModes.clear();
+  g_backend_info.AAModes.clear();
   if (g_ogl_config.bSupportsMSAA)
   {
     bool supportsGetInternalFormat =
@@ -628,13 +623,13 @@ bool PopulateConfig(GLContext* m_main_gl_context)
       // It also says "Only positive values are returned", but does not specify whether 1 is
       // included or not; it seems like NVIDIA and Intel GPUs do not include it.
       // We've inserted 1 at the back of both if not present to handle this.
-      g_Config.backend_info.AAModes.clear();
-      g_Config.backend_info.AAModes.reserve(std::min(color_aa_modes.size(), depth_aa_modes.size()));
+      g_backend_info.AAModes.clear();
+      g_backend_info.AAModes.reserve(std::min(color_aa_modes.size(), depth_aa_modes.size()));
       // We only want AA modes that are supported for both the color and depth textures. Probably
       // the support is the same, though. views::reverse is used to swap the order ahead of time.
       std::ranges::set_intersection(color_aa_modes | std::views::reverse,
                                     depth_aa_modes | std::views::reverse,
-                                    std::back_inserter(g_Config.backend_info.AAModes));
+                                    std::back_inserter(g_backend_info.AAModes));
     }
     else
     {
@@ -656,17 +651,17 @@ bool PopulateConfig(GLContext* m_main_gl_context)
 
       while (supported_max_samples > 1)
       {
-        g_Config.backend_info.AAModes.push_back(supported_max_samples);
+        g_backend_info.AAModes.push_back(supported_max_samples);
         supported_max_samples /= 2;
       }
-      g_Config.backend_info.AAModes.push_back(1);
+      g_backend_info.AAModes.push_back(1);
       // The UI wants ascending order
-      std::ranges::reverse(g_Config.backend_info.AAModes);
+      std::ranges::reverse(g_backend_info.AAModes);
     }
   }
   else
   {
-    g_Config.backend_info.AAModes = {1};
+    g_backend_info.AAModes = {1};
   }
 
   const bool bSupportsIsHelperInvocation = g_ogl_config.bIsES ?
@@ -690,12 +685,12 @@ bool PopulateConfig(GLContext* m_main_gl_context)
   // We require texel buffers, image load store, and compute shaders to enable GPU texture decoding.
   // If the driver doesn't expose the extensions, but supports GL4.3/GLES3.1, it will still be
   // enabled in the version check below.
-  g_Config.backend_info.bSupportsGPUTextureDecoding =
-      g_Config.backend_info.bSupportsPaletteConversion &&
-      g_Config.backend_info.bSupportsComputeShaders && g_ogl_config.bSupportsImageLoadStore;
+  g_backend_info.bSupportsGPUTextureDecoding = g_backend_info.bSupportsPaletteConversion &&
+                                               g_backend_info.bSupportsComputeShaders &&
+                                               g_ogl_config.bSupportsImageLoadStore;
 
   // Background compiling is supported only when shared contexts aren't broken.
-  g_Config.backend_info.bSupportsBackgroundCompiling =
+  g_backend_info.bSupportsBackgroundCompiling =
       !DriverDetails::HasBug(DriverDetails::BUG_SHARED_CONTEXT_SHADER_COMPILATION);
 
   // Program binaries are supported on GL4.1+, ARB_get_program_binary, or ES3.
@@ -706,7 +701,7 @@ bool PopulateConfig(GLContext* m_main_gl_context)
     glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_formats);
     supports_glsl_cache = num_formats > 0;
   }
-  g_Config.backend_info.bSupportsPipelineCacheData = supports_glsl_cache;
+  g_backend_info.bSupportsPipelineCacheData = supports_glsl_cache;
 
   int samples;
   glGetIntegerv(GL_SAMPLES, &samples);
@@ -746,19 +741,19 @@ bool PopulateConfig(GLContext* m_main_gl_context)
 
   const std::string missing_extensions = fmt::format(
       "{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
-      g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
-      g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ",
-      g_ActiveConfig.backend_info.bSupportsEarlyZ ? "" : "EarlyZ ",
+      g_backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
+      g_backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ",
+      g_backend_info.bSupportsEarlyZ ? "" : "EarlyZ ",
       g_ogl_config.bSupportsGLPinnedMemory ? "" : "PinnedMemory ",
       supports_glsl_cache ? "" : "ShaderCache ",
       g_ogl_config.bSupportsGLBaseVertex ? "" : "BaseVertex ",
       g_ogl_config.bSupportsGLBufferStorage ? "" : "BufferStorage ",
       g_ogl_config.bSupportsGLSync ? "" : "Sync ", g_ogl_config.bSupportsMSAA ? "" : "MSAA ",
-      g_ActiveConfig.backend_info.bSupportsSSAA ? "" : "SSAA ",
-      g_ActiveConfig.backend_info.bSupportsGSInstancing ? "" : "GSInstancing ",
-      g_ActiveConfig.backend_info.bSupportsClipControl ? "" : "ClipControl ",
+      g_backend_info.bSupportsSSAA ? "" : "SSAA ",
+      g_backend_info.bSupportsGSInstancing ? "" : "GSInstancing ",
+      g_backend_info.bSupportsClipControl ? "" : "ClipControl ",
       g_ogl_config.bSupportsCopySubImage ? "" : "CopyImageSubData ",
-      g_ActiveConfig.backend_info.bSupportsDepthClamp ? "" : "DepthClamp ");
+      g_backend_info.bSupportsDepthClamp ? "" : "DepthClamp ");
 
   if (missing_extensions.empty())
     INFO_LOG_FMT(VIDEO, "All used OGL Extensions are available.");
diff --git a/Source/Core/VideoBackends/OGL/OGLGfx.cpp b/Source/Core/VideoBackends/OGL/OGLGfx.cpp
index 6a97aa5982..910f54ab5e 100644
--- a/Source/Core/VideoBackends/OGL/OGLGfx.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLGfx.cpp
@@ -177,10 +177,10 @@ OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scal
   if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC))
     m_main_gl_context->SwapInterval(g_ActiveConfig.bVSyncActive);
 
-  if (g_ActiveConfig.backend_info.bSupportsClipControl)
+  if (g_backend_info.bSupportsClipControl)
     glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
 
-  if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
+  if (g_backend_info.bSupportsDepthClamp)
   {
     glEnable(GL_CLIP_DISTANCE0);
     glEnable(GL_CLIP_DISTANCE1);
@@ -192,7 +192,7 @@ OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scal
   glGenFramebuffers(1, &m_shared_read_framebuffer);
   glGenFramebuffers(1, &m_shared_draw_framebuffer);
 
-  if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart)
+  if (g_backend_info.bSupportsPrimitiveRestart)
     GLUtil::EnablePrimitiveRestart(m_main_gl_context.get());
 
   UpdateActiveConfig();
@@ -487,7 +487,7 @@ void OGLGfx::CheckForSurfaceResize()
 void OGLGfx::BeginUtilityDrawing()
 {
   AbstractGfx::BeginUtilityDrawing();
-  if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
+  if (g_backend_info.bSupportsDepthClamp)
   {
     glDisable(GL_CLIP_DISTANCE0);
     glDisable(GL_CLIP_DISTANCE1);
@@ -497,7 +497,7 @@ void OGLGfx::BeginUtilityDrawing()
 void OGLGfx::EndUtilityDrawing()
 {
   AbstractGfx::EndUtilityDrawing();
-  if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
+  if (g_backend_info.bSupportsDepthClamp)
   {
     glEnable(GL_CLIP_DISTANCE0);
     glEnable(GL_CLIP_DISTANCE1);
diff --git a/Source/Core/VideoBackends/OGL/OGLMain.cpp b/Source/Core/VideoBackends/OGL/OGLMain.cpp
index 13f47a054f..92dd021e3e 100644
--- a/Source/Core/VideoBackends/OGL/OGLMain.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLMain.cpp
@@ -113,53 +113,53 @@ bool VideoBackend::FillBackendInfo(GLContext* context)
   if (!InitializeGLExtensions(context))
     return false;
 
-  g_Config.backend_info.api_type = APIType::OpenGL;
-  g_Config.backend_info.MaxTextureSize = 16384;
-  g_Config.backend_info.bUsesLowerLeftOrigin = true;
-  g_Config.backend_info.bSupportsExclusiveFullscreen = false;
-  g_Config.backend_info.bSupportsGeometryShaders = true;
-  g_Config.backend_info.bSupportsComputeShaders = false;
-  g_Config.backend_info.bSupports3DVision = false;
-  g_Config.backend_info.bSupportsPostProcessing = true;
-  g_Config.backend_info.bSupportsSSAA = true;
-  g_Config.backend_info.bSupportsReversedDepthRange = true;
-  g_Config.backend_info.bSupportsLogicOp = true;
-  g_Config.backend_info.bSupportsMultithreading = false;
-  g_Config.backend_info.bSupportsCopyToVram = true;
-  g_Config.backend_info.bSupportsLargePoints = true;
-  g_Config.backend_info.bSupportsDepthReadback = true;
-  g_Config.backend_info.bSupportsPartialDepthCopies = true;
-  g_Config.backend_info.bSupportsShaderBinaries = false;
-  g_Config.backend_info.bSupportsPipelineCacheData = false;
-  g_Config.backend_info.bSupportsLodBiasInSampler = true;
-  g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
+  g_backend_info.api_type = APIType::OpenGL;
+  g_backend_info.MaxTextureSize = 16384;
+  g_backend_info.bUsesLowerLeftOrigin = true;
+  g_backend_info.bSupportsExclusiveFullscreen = false;
+  g_backend_info.bSupportsGeometryShaders = true;
+  g_backend_info.bSupportsComputeShaders = false;
+  g_backend_info.bSupports3DVision = false;
+  g_backend_info.bSupportsPostProcessing = true;
+  g_backend_info.bSupportsSSAA = true;
+  g_backend_info.bSupportsReversedDepthRange = true;
+  g_backend_info.bSupportsLogicOp = true;
+  g_backend_info.bSupportsMultithreading = false;
+  g_backend_info.bSupportsCopyToVram = true;
+  g_backend_info.bSupportsLargePoints = true;
+  g_backend_info.bSupportsDepthReadback = true;
+  g_backend_info.bSupportsPartialDepthCopies = true;
+  g_backend_info.bSupportsShaderBinaries = false;
+  g_backend_info.bSupportsPipelineCacheData = false;
+  g_backend_info.bSupportsLodBiasInSampler = true;
+  g_backend_info.bSupportsPartialMultisampleResolve = true;
   // Unneccessary since OGL doesn't use pipelines
-  g_Config.backend_info.bSupportsDynamicVertexLoader = false;
+  g_backend_info.bSupportsDynamicVertexLoader = false;
 
   // TODO: There is a bug here, if texel buffers or SSBOs/atomics are not supported the graphics
   // options will show the option when it is not supported. The only way around this would be
   // creating a context when calling this function to determine what is available.
-  g_Config.backend_info.bSupportsGPUTextureDecoding = true;
-  g_Config.backend_info.bSupportsBBox = true;
+  g_backend_info.bSupportsGPUTextureDecoding = true;
+  g_backend_info.bSupportsBBox = true;
 
   // Overwritten in OGLConfig.cpp later
-  g_Config.backend_info.bSupportsDualSourceBlend = true;
-  g_Config.backend_info.bSupportsPrimitiveRestart = true;
-  g_Config.backend_info.bSupportsPaletteConversion = true;
-  g_Config.backend_info.bSupportsClipControl = true;
-  g_Config.backend_info.bSupportsDepthClamp = true;
-  g_Config.backend_info.bSupportsST3CTextures = false;
-  g_Config.backend_info.bSupportsBPTCTextures = false;
-  g_Config.backend_info.bSupportsCoarseDerivatives = false;
-  g_Config.backend_info.bSupportsTextureQueryLevels = false;
-  g_Config.backend_info.bSupportsSettingObjectNames = false;
+  g_backend_info.bSupportsDualSourceBlend = true;
+  g_backend_info.bSupportsPrimitiveRestart = true;
+  g_backend_info.bSupportsPaletteConversion = true;
+  g_backend_info.bSupportsClipControl = true;
+  g_backend_info.bSupportsDepthClamp = true;
+  g_backend_info.bSupportsST3CTextures = false;
+  g_backend_info.bSupportsBPTCTextures = false;
+  g_backend_info.bSupportsCoarseDerivatives = false;
+  g_backend_info.bSupportsTextureQueryLevels = false;
+  g_backend_info.bSupportsSettingObjectNames = false;
 
-  g_Config.backend_info.bUsesExplictQuadBuffering = true;
+  g_backend_info.bUsesExplictQuadBuffering = true;
 
-  g_Config.backend_info.Adapters.clear();
+  g_backend_info.Adapters.clear();
 
   // aamodes - 1 is to stay consistent with D3D (means no AA)
-  g_Config.backend_info.AAModes = {1, 2, 4, 8};
+  g_backend_info.AAModes = {1, 2, 4, 8};
 
   // check for the max vertex attributes
   GLint numvertexattribs = 0;
@@ -175,7 +175,7 @@ bool VideoBackend::FillBackendInfo(GLContext* context)
   // check the max texture width and height
   GLint max_texture_size = 0;
   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
-  g_Config.backend_info.MaxTextureSize = static_cast<u32>(max_texture_size);
+  g_backend_info.MaxTextureSize = static_cast<u32>(max_texture_size);
   if (max_texture_size < 1024)
   {
     PanicAlertFmtT("GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024.", max_texture_size);
diff --git a/Source/Core/VideoBackends/OGL/OGLPipeline.cpp b/Source/Core/VideoBackends/OGL/OGLPipeline.cpp
index b5837d409f..aabfd4fce1 100644
--- a/Source/Core/VideoBackends/OGL/OGLPipeline.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLPipeline.cpp
@@ -50,7 +50,7 @@ AbstractPipeline::CacheData OGLPipeline::GetCacheData() const
   // copies of the same program combination, we set a flag on the program object so that it can't
   // be retrieved again. When booting, the pipeline cache is loaded in-order, so the additional
   // pipelines which use the program combination will re-use the already-created object.
-  if (!g_ActiveConfig.backend_info.bSupportsPipelineCacheData || m_program->binary_retrieved)
+  if (!g_backend_info.bSupportsPipelineCacheData || m_program->binary_retrieved)
     return {};
 
   GLint program_size = 0;
diff --git a/Source/Core/VideoBackends/OGL/OGLShader.cpp b/Source/Core/VideoBackends/OGL/OGLShader.cpp
index 3338087132..9c100a5e30 100644
--- a/Source/Core/VideoBackends/OGL/OGLShader.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLShader.cpp
@@ -31,7 +31,7 @@ OGLShader::OGLShader(ShaderStage stage, GLenum gl_type, GLuint gl_id, std::strin
     : AbstractShader(stage), m_id(ProgramShaderCache::GenerateShaderID()), m_type(gl_type),
       m_gl_id(gl_id), m_source(std::move(source)), m_name(std::move(name))
 {
-  if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames)
+  if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
   {
     glObjectLabel(GL_SHADER, m_gl_id, (GLsizei)m_name.size(), m_name.c_str());
   }
@@ -42,7 +42,7 @@ OGLShader::OGLShader(GLuint gl_compute_program_id, std::string source, std::stri
       m_type(GL_COMPUTE_SHADER), m_gl_compute_program_id(gl_compute_program_id),
       m_source(std::move(source)), m_name(std::move(name))
 {
-  if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames)
+  if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
   {
     glObjectLabel(GL_PROGRAM, m_gl_compute_program_id, (GLsizei)m_name.size(), m_name.c_str());
   }
diff --git a/Source/Core/VideoBackends/OGL/OGLTexture.cpp b/Source/Core/VideoBackends/OGL/OGLTexture.cpp
index 58f1b10a04..e60c36285d 100644
--- a/Source/Core/VideoBackends/OGL/OGLTexture.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLTexture.cpp
@@ -132,7 +132,7 @@ OGLTexture::OGLTexture(const TextureConfig& tex_config, std::string_view name)
   glActiveTexture(GL_MUTABLE_TEXTURE_INDEX);
   glBindTexture(target, m_texId);
 
-  if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames)
+  if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
   {
     glObjectLabel(GL_TEXTURE, m_texId, (GLsizei)m_name.size(), m_name.c_str());
   }
diff --git a/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp b/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
index 03b2f71ac8..9c08b238da 100644
--- a/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
@@ -38,7 +38,7 @@ VertexManager::VertexManager() = default;
 
 VertexManager::~VertexManager()
 {
-  if (g_ActiveConfig.backend_info.bSupportsPaletteConversion)
+  if (g_backend_info.bSupportsPaletteConversion)
   {
     glDeleteTextures(static_cast<GLsizei>(m_texel_buffer_views.size()),
                      m_texel_buffer_views.data());
@@ -58,13 +58,12 @@ bool VertexManager::Initialize()
 
   m_vertex_buffer = StreamBuffer::Create(GL_ARRAY_BUFFER, VERTEX_STREAM_BUFFER_SIZE);
   m_index_buffer = StreamBuffer::Create(GL_ELEMENT_ARRAY_BUFFER, INDEX_STREAM_BUFFER_SIZE);
-  if (g_ActiveConfig.UseVSForLinePointExpand() ||
-      g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
+  if (g_ActiveConfig.UseVSForLinePointExpand() || g_backend_info.bSupportsDynamicVertexLoader)
   {
     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_vertex_buffer->GetGLBufferId());
   }
 
-  if (g_ActiveConfig.backend_info.bSupportsPaletteConversion)
+  if (g_backend_info.bSupportsPaletteConversion)
   {
     // The minimum MAX_TEXTURE_BUFFER_SIZE that the spec mandates is 65KB, we are asking for a 1MB
     // buffer here. This buffer is also used as storage for undecoded textures when compute shader
diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
index fdf2fe347d..3241d217e0 100644
--- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
+++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
@@ -88,7 +88,7 @@ static std::string GetGLSLVersionString()
 
 void SHADER::SetProgramVariables()
 {
-  if (g_ActiveConfig.backend_info.bSupportsBindingLayout)
+  if (g_backend_info.bSupportsBindingLayout)
     return;
 
   // To set uniform blocks/uniforms, the program must be active. We restore the
@@ -132,7 +132,7 @@ void SHADER::SetProgramBindings(bool is_compute)
   }
   if (!is_compute)
   {
-    if (g_ActiveConfig.backend_info.bSupportsDualSourceBlend)
+    if (g_backend_info.bSupportsDualSourceBlend)
     {
       // So we do support extended blending
       // So we need to set a few more things here.
@@ -298,8 +298,7 @@ bool ProgramShaderCache::CompileComputeShader(SHADER& shader, std::string_view c
   // We need to enable GL_ARB_compute_shader for drivers that support the extension,
   // but not GLSL 4.3. Mesa is one example.
   std::string full_code;
-  if (g_ActiveConfig.backend_info.bSupportsComputeShaders &&
-      g_ogl_config.eSupportedGLSLVersion < Glsl430)
+  if (g_backend_info.bSupportsComputeShaders && g_ogl_config.eSupportedGLSLVersion < Glsl430)
   {
     full_code = "#extension GL_ARB_compute_shader : enable\n";
   }
@@ -616,7 +615,7 @@ PipelineProgram* ProgramShaderCache::GetPipelineProgram(const GLVertexFormat* ve
       glAttachShader(prog->shader.glprogid, geometry_shader->GetGLShaderID());
     }
 
-    if (g_ActiveConfig.backend_info.bSupportsPipelineCacheData)
+    if (g_backend_info.bSupportsPipelineCacheData)
       glProgramParameteri(prog->shader.glprogid, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
 
     // Link program.
@@ -709,7 +708,7 @@ void ProgramShaderCache::CreateHeader()
   }
 
   std::string earlyz_string;
-  if (g_ActiveConfig.backend_info.bSupportsEarlyZ)
+  if (g_backend_info.bSupportsEarlyZ)
   {
     if (g_ogl_config.bSupportsImageLoadStore)
     {
@@ -748,7 +747,7 @@ void ProgramShaderCache::CreateHeader()
       g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone;
 
   std::string binding_layout;
-  if (g_ActiveConfig.backend_info.bSupportsBindingLayout)
+  if (g_backend_info.bSupportsBindingLayout)
   {
     if (g_ogl_config.bSupportsExplicitLayoutInShader)
     {
@@ -854,29 +853,28 @@ void ProgramShaderCache::CreateHeader()
       ,
       GetGLSLVersionString(), v < Glsl140 ? "#extension GL_ARB_uniform_buffer_object : enable" : "",
       earlyz_string,
-      (g_ActiveConfig.backend_info.bSupportsBindingLayout && v < GlslEs310) ?
+      (g_backend_info.bSupportsBindingLayout && v < GlslEs310) ?
           "#extension GL_ARB_shading_language_420pack : enable" :
           "",
       (g_ogl_config.bSupportsMSAA && v < Glsl150) ?
           "#extension GL_ARB_texture_multisample : enable" :
           "",
       binding_layout.c_str(), varying_location.c_str(),
-      !is_glsles && g_ActiveConfig.backend_info.bSupportsFragmentStoresAndAtomics ?
+      !is_glsles && g_backend_info.bSupportsFragmentStoresAndAtomics ?
           "#extension GL_ARB_shader_storage_buffer_object : enable" :
           "",
-      v < Glsl400 && g_ActiveConfig.backend_info.bSupportsGSInstancing ?
+      v < Glsl400 && g_backend_info.bSupportsGSInstancing ?
           "#extension GL_ARB_gpu_shader5 : enable" :
           "",
-      v < Glsl400 && g_ActiveConfig.backend_info.bSupportsSSAA ?
-          "#extension GL_ARB_sample_shading : enable" :
-          "",
+      v < Glsl400 && g_backend_info.bSupportsSSAA ? "#extension GL_ARB_sample_shading : enable" :
+                                                    "",
       SupportedESPointSize,
       g_ogl_config.bSupportsAEP ? "#extension GL_ANDROID_extension_pack_es31a : enable" : "",
-      v < Glsl140 && g_ActiveConfig.backend_info.bSupportsPaletteConversion ?
+      v < Glsl140 && g_backend_info.bSupportsPaletteConversion ?
           "#extension GL_ARB_texture_buffer_object : enable" :
           "",
       SupportedESTextureBuffer,
-      is_glsles && g_ActiveConfig.backend_info.bSupportsDualSourceBlend ?
+      is_glsles && g_backend_info.bSupportsDualSourceBlend ?
           "#extension GL_EXT_blend_func_extended : enable" :
           ""
 
@@ -886,10 +884,9 @@ void ProgramShaderCache::CreateHeader()
           "#extension GL_ARB_shader_image_load_store : enable" :
           "",
       framebuffer_fetch_string, shader_shuffle_string,
-      g_ActiveConfig.backend_info.bSupportsCoarseDerivatives ?
-          "#extension GL_ARB_derivative_control : enable" :
-          "",
-      g_ActiveConfig.backend_info.bSupportsTextureQueryLevels ?
+      g_backend_info.bSupportsCoarseDerivatives ? "#extension GL_ARB_derivative_control : enable" :
+                                                  "",
+      g_backend_info.bSupportsTextureQueryLevels ?
           "#extension GL_ARB_texture_query_levels : enable" :
           "",
       // Note: GL_ARB_texture_storage_multisample doesn't have an #extension, as it doesn't
@@ -900,9 +897,8 @@ void ProgramShaderCache::CreateHeader()
           "",
       is_glsles ? "precision highp float;" : "", is_glsles ? "precision highp int;" : "",
       is_glsles ? "precision highp sampler2DArray;" : "",
-      (is_glsles && g_ActiveConfig.backend_info.bSupportsPaletteConversion) ?
-          "precision highp usamplerBuffer;" :
-          "",
+      (is_glsles && g_backend_info.bSupportsPaletteConversion) ? "precision highp usamplerBuffer;" :
+                                                                 "",
       use_multisample_2d_array_precision ? "precision highp sampler2DMSArray;" : "",
       v >= GlslEs310 ? "precision highp image2DArray;" : "");
 }
@@ -936,15 +932,15 @@ bool SharedContextAsyncShaderCompiler::WorkerThreadInitWorkerThread(void* param)
   // Make the state match the main context to have a better chance of avoiding recompiles.
   if (!context->IsGLES())
     glEnable(GL_PROGRAM_POINT_SIZE);
-  if (g_ActiveConfig.backend_info.bSupportsClipControl)
+  if (g_backend_info.bSupportsClipControl)
     glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
-  if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
+  if (g_backend_info.bSupportsDepthClamp)
   {
     glEnable(GL_CLIP_DISTANCE0);
     glEnable(GL_CLIP_DISTANCE1);
     glEnable(GL_DEPTH_CLAMP);
   }
-  if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart)
+  if (g_backend_info.bSupportsPrimitiveRestart)
     GLUtil::EnablePrimitiveRestart(context);
 
   return true;
diff --git a/Source/Core/VideoBackends/OGL/SamplerCache.cpp b/Source/Core/VideoBackends/OGL/SamplerCache.cpp
index 2673fd2ddd..56246ea246 100644
--- a/Source/Core/VideoBackends/OGL/SamplerCache.cpp
+++ b/Source/Core/VideoBackends/OGL/SamplerCache.cpp
@@ -97,7 +97,7 @@ void SamplerCache::SetParameters(GLuint sampler_id, const SamplerState& params)
   glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, params.tm1.min_lod / 16.f);
   glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, params.tm1.max_lod / 16.f);
 
-  if (g_ActiveConfig.backend_info.bSupportsLodBiasInSampler)
+  if (g_backend_info.bSupportsLodBiasInSampler)
   {
     glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, params.tm0.lod_bias / 256.f);
   }
diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp
index ccb040e8ad..e33c00fe7c 100644
--- a/Source/Core/VideoBackends/Software/SWmain.cpp
+++ b/Source/Core/VideoBackends/Software/SWmain.cpp
@@ -64,37 +64,37 @@ std::optional<std::string> VideoSoftware::GetWarningMessage() const
 
 void VideoSoftware::InitBackendInfo(const WindowSystemInfo& wsi)
 {
-  g_Config.backend_info.api_type = APIType::Nothing;
-  g_Config.backend_info.MaxTextureSize = 16384;
-  g_Config.backend_info.bUsesLowerLeftOrigin = false;
-  g_Config.backend_info.bSupports3DVision = false;
-  g_Config.backend_info.bSupportsDualSourceBlend = true;
-  g_Config.backend_info.bSupportsEarlyZ = true;
-  g_Config.backend_info.bSupportsPrimitiveRestart = false;
-  g_Config.backend_info.bSupportsMultithreading = false;
-  g_Config.backend_info.bSupportsComputeShaders = false;
-  g_Config.backend_info.bSupportsGPUTextureDecoding = false;
-  g_Config.backend_info.bSupportsST3CTextures = false;
-  g_Config.backend_info.bSupportsBPTCTextures = false;
-  g_Config.backend_info.bSupportsCopyToVram = false;
-  g_Config.backend_info.bSupportsLargePoints = false;
-  g_Config.backend_info.bSupportsDepthReadback = false;
-  g_Config.backend_info.bSupportsPartialDepthCopies = false;
-  g_Config.backend_info.bSupportsFramebufferFetch = false;
-  g_Config.backend_info.bSupportsBackgroundCompiling = false;
-  g_Config.backend_info.bSupportsLogicOp = true;
-  g_Config.backend_info.bSupportsShaderBinaries = false;
-  g_Config.backend_info.bSupportsPipelineCacheData = false;
-  g_Config.backend_info.bSupportsBBox = true;
-  g_Config.backend_info.bSupportsCoarseDerivatives = false;
-  g_Config.backend_info.bSupportsTextureQueryLevels = false;
-  g_Config.backend_info.bSupportsLodBiasInSampler = false;
-  g_Config.backend_info.bSupportsSettingObjectNames = false;
-  g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
-  g_Config.backend_info.bSupportsDynamicVertexLoader = false;
+  g_backend_info.api_type = APIType::Nothing;
+  g_backend_info.MaxTextureSize = 16384;
+  g_backend_info.bUsesLowerLeftOrigin = false;
+  g_backend_info.bSupports3DVision = false;
+  g_backend_info.bSupportsDualSourceBlend = true;
+  g_backend_info.bSupportsEarlyZ = true;
+  g_backend_info.bSupportsPrimitiveRestart = false;
+  g_backend_info.bSupportsMultithreading = false;
+  g_backend_info.bSupportsComputeShaders = false;
+  g_backend_info.bSupportsGPUTextureDecoding = false;
+  g_backend_info.bSupportsST3CTextures = false;
+  g_backend_info.bSupportsBPTCTextures = false;
+  g_backend_info.bSupportsCopyToVram = false;
+  g_backend_info.bSupportsLargePoints = false;
+  g_backend_info.bSupportsDepthReadback = false;
+  g_backend_info.bSupportsPartialDepthCopies = false;
+  g_backend_info.bSupportsFramebufferFetch = false;
+  g_backend_info.bSupportsBackgroundCompiling = false;
+  g_backend_info.bSupportsLogicOp = true;
+  g_backend_info.bSupportsShaderBinaries = false;
+  g_backend_info.bSupportsPipelineCacheData = false;
+  g_backend_info.bSupportsBBox = true;
+  g_backend_info.bSupportsCoarseDerivatives = false;
+  g_backend_info.bSupportsTextureQueryLevels = false;
+  g_backend_info.bSupportsLodBiasInSampler = false;
+  g_backend_info.bSupportsSettingObjectNames = false;
+  g_backend_info.bSupportsPartialMultisampleResolve = true;
+  g_backend_info.bSupportsDynamicVertexLoader = false;
 
   // aamodes
-  g_Config.backend_info.AAModes = {1};
+  g_backend_info.AAModes = {1};
 }
 
 bool VideoSoftware::Initialize(const WindowSystemInfo& wsi)
diff --git a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp
index e32675fe57..877ad70bd2 100644
--- a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp
+++ b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp
@@ -206,18 +206,18 @@ bool ObjectCache::CreateDescriptorSetLayouts()
   // Don't set the GS bit if geometry shaders aren't available.
   if (g_ActiveConfig.UseVSForLinePointExpand())
   {
-    if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+    if (g_backend_info.bSupportsGeometryShaders)
       ubo_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].stageFlags |= VK_SHADER_STAGE_VERTEX_BIT;
     else
       ubo_bindings[UBO_DESCRIPTOR_SET_BINDING_GS].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
   }
-  else if (!g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+  else if (!g_backend_info.bSupportsGeometryShaders)
   {
     create_infos[DESCRIPTOR_SET_LAYOUT_STANDARD_UNIFORM_BUFFERS].bindingCount--;
   }
 
   // Remove the dynamic vertex loader's buffer if it'll never be needed
-  if (!g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
+  if (!g_backend_info.bSupportsDynamicVertexLoader)
     create_infos[DESCRIPTOR_SET_LAYOUT_STANDARD_SHADER_STORAGE_BUFFERS].bindingCount--;
 
   for (size_t i = 0; i < create_infos.size(); i++)
@@ -286,13 +286,13 @@ bool ObjectCache::CreatePipelineLayouts()
   }};
 
   const bool ssbos_in_standard =
-      g_ActiveConfig.backend_info.bSupportsBBox || g_ActiveConfig.UseVSForLinePointExpand();
+      g_backend_info.bSupportsBBox || g_ActiveConfig.UseVSForLinePointExpand();
 
   // If bounding box is unsupported, don't bother with the SSBO descriptor set.
   if (!ssbos_in_standard)
     pipeline_layout_info[PIPELINE_LAYOUT_STANDARD].setLayoutCount--;
   // If neither SSBO-using feature is supported, skip in ubershaders too
-  if (!ssbos_in_standard && !g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
+  if (!ssbos_in_standard && !g_backend_info.bSupportsDynamicVertexLoader)
     pipeline_layout_info[PIPELINE_LAYOUT_UBER].setLayoutCount--;
 
   for (size_t i = 0; i < pipeline_layout_info.size(); i++)
diff --git a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp
index 332cd41cbf..e55071533a 100644
--- a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp
+++ b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp
@@ -387,7 +387,7 @@ bool StateTracker::Bind()
 
   // Re-bind parts of the pipeline
   const VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer();
-  const bool needs_vertex_buffer = !g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader ||
+  const bool needs_vertex_buffer = !g_backend_info.bSupportsDynamicVertexLoader ||
                                    m_pipeline->GetUsage() != AbstractPipelineUsage::GXUber;
   if (needs_vertex_buffer && (m_dirty_flags & DIRTY_FLAG_VERTEX_BUFFER))
   {
@@ -481,8 +481,8 @@ void StateTracker::UpdateGXDescriptorSet()
   std::array<VkWriteDescriptorSet, MAX_DESCRIPTOR_WRITES> writes;
   u32 num_writes = 0;
 
-  const bool needs_gs_ubo = g_ActiveConfig.backend_info.bSupportsGeometryShaders ||
-                            g_ActiveConfig.UseVSForLinePointExpand();
+  const bool needs_gs_ubo =
+      g_backend_info.bSupportsGeometryShaders || g_ActiveConfig.UseVSForLinePointExpand();
 
   if (m_dirty_flags & DIRTY_FLAG_GX_UBOS || m_gx_descriptor_sets[0] == VK_NULL_HANDLE)
   {
@@ -535,8 +535,8 @@ void StateTracker::UpdateGXDescriptorSet()
     m_dirty_flags = (m_dirty_flags & ~DIRTY_FLAG_GX_SAMPLERS) | DIRTY_FLAG_DESCRIPTOR_SETS;
   }
 
-  const bool needs_bbox_ssbo = g_ActiveConfig.backend_info.bSupportsBBox;
-  const bool needs_vertex_ssbo = (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader &&
+  const bool needs_bbox_ssbo = g_backend_info.bSupportsBBox;
+  const bool needs_vertex_ssbo = (g_backend_info.bSupportsDynamicVertexLoader &&
                                   m_pipeline->GetUsage() == AbstractPipelineUsage::GXUber) ||
                                  g_ActiveConfig.UseVSForLinePointExpand();
   const bool needs_ssbo = needs_bbox_ssbo || needs_vertex_ssbo;
@@ -552,8 +552,7 @@ void StateTracker::UpdateGXDescriptorSet()
         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, m_gx_descriptor_sets[2], 0,      0, 1,
         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,      nullptr, &m_bindings.ssbo,        nullptr};
 
-    if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader ||
-        g_ActiveConfig.UseVSForLinePointExpand())
+    if (g_backend_info.bSupportsDynamicVertexLoader || g_ActiveConfig.UseVSForLinePointExpand())
     {
       writes[num_writes++] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
                               nullptr,
diff --git a/Source/Core/VideoBackends/Vulkan/VKGfx.cpp b/Source/Core/VideoBackends/Vulkan/VKGfx.cpp
index d65a5d4680..b30dd3894e 100644
--- a/Source/Core/VideoBackends/Vulkan/VKGfx.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKGfx.cpp
@@ -118,7 +118,7 @@ void VKGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_en
   clear_color_value.color.float32[2] = static_cast<float>((color >> 0) & 0xFF) / 255.0f;
   clear_color_value.color.float32[3] = static_cast<float>((color >> 24) & 0xFF) / 255.0f;
   clear_depth_value.depthStencil.depth = static_cast<float>(z & 0xFFFFFF) / 16777216.0f;
-  if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+  if (!g_backend_info.bSupportsReversedDepthRange)
     clear_depth_value.depthStencil.depth = 1.0f - clear_depth_value.depthStencil.depth;
 
   // If we're not in a render pass (start of the frame), we can use a clear render pass
diff --git a/Source/Core/VideoBackends/Vulkan/VKMain.cpp b/Source/Core/VideoBackends/Vulkan/VKMain.cpp
index ee49796daf..e5ecd5a4de 100644
--- a/Source/Core/VideoBackends/Vulkan/VKMain.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKMain.cpp
@@ -3,13 +3,10 @@
 
 #include "VideoBackends/Vulkan/VideoBackend.h"
 
-#include <vector>
-
 #include "Common/Logging/LogManager.h"
 #include "Common/MsgHandler.h"
 
 #include "VideoBackends/Vulkan/CommandBufferManager.h"
-#include "VideoBackends/Vulkan/Constants.h"
 #include "VideoBackends/Vulkan/ObjectCache.h"
 #include "VideoBackends/Vulkan/StateTracker.h"
 #include "VideoBackends/Vulkan/VKBoundingBox.h"
@@ -19,9 +16,7 @@
 #include "VideoBackends/Vulkan/VKVertexManager.h"
 #include "VideoBackends/Vulkan/VulkanContext.h"
 
-#include "VideoCommon/FramebufferManager.h"
 #include "VideoCommon/TextureCacheBase.h"
-#include "VideoCommon/VideoBackendBase.h"
 #include "VideoCommon/VideoConfig.h"
 
 #if defined(VK_USE_PLATFORM_METAL_EXT)
@@ -32,7 +27,7 @@ namespace Vulkan
 {
 void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
 {
-  VulkanContext::PopulateBackendInfo(&g_Config);
+  VulkanContext::PopulateBackendInfo(&g_backend_info);
 
   if (LoadVulkanLibrary())
   {
@@ -44,7 +39,7 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
       if (LoadVulkanInstanceFunctions(temp_instance))
       {
         VulkanContext::GPUList gpu_list = VulkanContext::EnumerateGPUs(temp_instance);
-        VulkanContext::PopulateBackendInfoAdapters(&g_Config, gpu_list);
+        VulkanContext::PopulateBackendInfoAdapters(&g_backend_info, gpu_list);
 
         if (!gpu_list.empty())
         {
@@ -55,8 +50,8 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
 
           VkPhysicalDevice gpu = gpu_list[device_index];
           VulkanContext::PhysicalDeviceInfo properties(gpu);
-          VulkanContext::PopulateBackendInfoFeatures(&g_Config, gpu, properties);
-          VulkanContext::PopulateBackendInfoMultisampleModes(&g_Config, gpu, properties);
+          VulkanContext::PopulateBackendInfoFeatures(&g_backend_info, gpu, properties);
+          VulkanContext::PopulateBackendInfoMultisampleModes(&g_backend_info, gpu, properties);
         }
       }
 
@@ -144,8 +139,8 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
   }
 
   // Populate BackendInfo with as much information as we can at this point.
-  VulkanContext::PopulateBackendInfo(&g_Config);
-  VulkanContext::PopulateBackendInfoAdapters(&g_Config, gpu_list);
+  VulkanContext::PopulateBackendInfo(&g_backend_info);
+  VulkanContext::PopulateBackendInfoAdapters(&g_backend_info, gpu_list);
 
   // We need the surface before we can create a device, as some parameters depend on it.
   VkSurfaceKHR surface = VK_NULL_HANDLE;
@@ -183,11 +178,11 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
 
   // Since VulkanContext maintains a copy of the device features and properties, we can use this
   // to initialize the backend information, so that we don't need to enumerate everything again.
-  VulkanContext::PopulateBackendInfoFeatures(&g_Config, g_vulkan_context->GetPhysicalDevice(),
+  VulkanContext::PopulateBackendInfoFeatures(&g_backend_info, g_vulkan_context->GetPhysicalDevice(),
                                              g_vulkan_context->GetDeviceInfo());
   VulkanContext::PopulateBackendInfoMultisampleModes(
-      &g_Config, g_vulkan_context->GetPhysicalDevice(), g_vulkan_context->GetDeviceInfo());
-  g_Config.backend_info.bSupportsExclusiveFullscreen =
+      &g_backend_info, g_vulkan_context->GetPhysicalDevice(), g_vulkan_context->GetDeviceInfo());
+  g_backend_info.bSupportsExclusiveFullscreen =
       enable_surface && g_vulkan_context->SupportsExclusiveFullscreen(wsi, surface);
 
   UpdateActiveConfig();
diff --git a/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp b/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp
index 83cd9367b5..be3aae1390 100644
--- a/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp
@@ -46,7 +46,7 @@ GetVulkanRasterizationState(const RasterizationState& state)
       {VK_CULL_MODE_NONE, VK_CULL_MODE_BACK_BIT, VK_CULL_MODE_FRONT_BIT,
        VK_CULL_MODE_FRONT_AND_BACK}};
 
-  bool depth_clamp = g_ActiveConfig.backend_info.bSupportsDepthClamp;
+  bool depth_clamp = g_backend_info.bSupportsDepthClamp;
 
   return {
       VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,  // VkStructureType sType
@@ -85,7 +85,7 @@ static VkPipelineDepthStencilStateCreateInfo GetVulkanDepthStencilState(const De
 {
   // Less/greater are swapped due to inverted depth.
   VkCompareOp compare_op;
-  bool inverted_depth = !g_ActiveConfig.backend_info.bSupportsReversedDepthRange;
+  bool inverted_depth = !g_backend_info.bSupportsReversedDepthRange;
   switch (state.func)
   {
   case CompareMode::Never:
@@ -215,7 +215,7 @@ GetVulkanColorBlendState(const BlendingState& state,
        VK_LOGIC_OP_COPY_INVERTED, VK_LOGIC_OP_OR_INVERTED, VK_LOGIC_OP_NAND, VK_LOGIC_OP_SET}};
 
   VkBool32 vk_logic_op_enable = static_cast<VkBool32>(state.logicopenable);
-  if (vk_logic_op_enable && !g_ActiveConfig.backend_info.bSupportsLogicOp)
+  if (vk_logic_op_enable && !g_backend_info.bSupportsLogicOp)
   {
     // At the time of writing, Adreno and Mali drivers didn't support logic ops.
     // The "emulation" through blending path has been removed, so just disable it completely.
@@ -306,7 +306,7 @@ std::unique_ptr<VKPipeline> VKPipeline::Create(const AbstractPipelineConfig& con
   // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
   // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
   // primitiveRestartEnable must be VK_FALSE
-  if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart &&
+  if (g_backend_info.bSupportsPrimitiveRestart &&
       IsStripPrimitiveTopology(input_assembly_state.topology))
   {
     input_assembly_state.primitiveRestartEnable = VK_TRUE;
diff --git a/Source/Core/VideoBackends/Vulkan/VKShader.cpp b/Source/Core/VideoBackends/Vulkan/VKShader.cpp
index 81d7c23789..f0848f1c92 100644
--- a/Source/Core/VideoBackends/Vulkan/VKShader.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKShader.cpp
@@ -19,7 +19,7 @@ VKShader::VKShader(ShaderStage stage, std::vector<u32> spv, VkShaderModule mod,
     : AbstractShader(stage), m_spv(std::move(spv)), m_module(mod),
       m_compute_pipeline(VK_NULL_HANDLE), m_name(name)
 {
-  if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames)
+  if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
   {
     VkDebugUtilsObjectNameInfoEXT name_info = {};
     name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
@@ -34,7 +34,7 @@ VKShader::VKShader(std::vector<u32> spv, VkPipeline compute_pipeline, std::strin
     : AbstractShader(ShaderStage::Compute), m_spv(std::move(spv)), m_module(VK_NULL_HANDLE),
       m_compute_pipeline(compute_pipeline), m_name(name)
 {
-  if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames)
+  if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
   {
     VkDebugUtilsObjectNameInfoEXT name_info = {};
     name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
diff --git a/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp b/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp
index f7260bdf0c..840a7b2c4e 100644
--- a/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp
@@ -377,8 +377,7 @@ bool SwapChain::CreateSwapChain()
       // Try without exclusive fullscreen.
       WARN_LOG_FMT(VIDEO, "Failed to create exclusive fullscreen swapchain, trying without.");
       swap_chain_info.pNext = nullptr;
-      g_Config.backend_info.bSupportsExclusiveFullscreen = false;
-      g_ActiveConfig.backend_info.bSupportsExclusiveFullscreen = false;
+      g_backend_info.bSupportsExclusiveFullscreen = false;
       m_fullscreen_supported = false;
     }
   }
@@ -601,8 +600,7 @@ bool SwapChain::RecreateSurface(void* native_handle)
 
   // Update exclusive fullscreen support (unlikely to change).
   m_fullscreen_supported = g_vulkan_context->SupportsExclusiveFullscreen(m_wsi, m_surface);
-  g_Config.backend_info.bSupportsExclusiveFullscreen = m_fullscreen_supported;
-  g_ActiveConfig.backend_info.bSupportsExclusiveFullscreen = m_fullscreen_supported;
+  g_backend_info.bSupportsExclusiveFullscreen = m_fullscreen_supported;
   m_current_fullscreen_state = false;
   m_next_fullscreen_state = false;
 
diff --git a/Source/Core/VideoBackends/Vulkan/VKTexture.cpp b/Source/Core/VideoBackends/Vulkan/VKTexture.cpp
index 6756305d1e..edccc9da14 100644
--- a/Source/Core/VideoBackends/Vulkan/VKTexture.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKTexture.cpp
@@ -32,7 +32,7 @@ VKTexture::VKTexture(const TextureConfig& tex_config, VmaAllocation alloc, VkIma
     : AbstractTexture(tex_config), m_alloc(alloc), m_image(image), m_layout(layout),
       m_compute_layout(compute_layout), m_name(name)
 {
-  if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames)
+  if (!m_name.empty() && g_backend_info.bSupportsSettingObjectNames)
   {
     VkDebugUtilsObjectNameInfoEXT name_info = {};
     name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
index 3640752231..c6ff5e148d 100644
--- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
@@ -8,11 +8,8 @@
 #include <cstring>
 
 #include "Common/Assert.h"
-#include "Common/CommonFuncs.h"
 #include "Common/Contains.h"
 #include "Common/Logging/Log.h"
-#include "Common/MsgHandler.h"
-#include "Common/StringUtil.h"
 
 #include "VideoCommon/DriverDetails.h"
 #include "VideoCommon/VideoCommon.h"
@@ -387,7 +384,7 @@ bool VulkanContext::SelectInstanceExtensions(std::vector<const char*>* extension
   // VK_EXT_debug_utils
   if (AddExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, false))
   {
-    g_Config.backend_info.bSupportsSettingObjectNames = true;
+    g_backend_info.bSupportsSettingObjectNames = true;
   }
   else if (enable_debug_utils)
   {
@@ -420,96 +417,96 @@ VulkanContext::GPUList VulkanContext::EnumerateGPUs(VkInstance instance)
   return gpus;
 }
 
-void VulkanContext::PopulateBackendInfo(VideoConfig* config)
+void VulkanContext::PopulateBackendInfo(BackendInfo* backend_info)
 {
-  config->backend_info.api_type = APIType::Vulkan;
-  config->backend_info.bSupports3DVision = false;                  // D3D-exclusive.
-  config->backend_info.bSupportsEarlyZ = true;                     // Assumed support.
-  config->backend_info.bSupportsPrimitiveRestart = true;           // Assumed support.
-  config->backend_info.bSupportsBindingLayout = false;             // Assumed support.
-  config->backend_info.bSupportsPaletteConversion = true;          // Assumed support.
-  config->backend_info.bSupportsClipControl = true;                // Assumed support.
-  config->backend_info.bSupportsMultithreading = true;             // Assumed support.
-  config->backend_info.bSupportsComputeShaders = true;             // Assumed support.
-  config->backend_info.bSupportsGPUTextureDecoding = true;         // Assumed support.
-  config->backend_info.bSupportsBitfield = true;                   // Assumed support.
-  config->backend_info.bSupportsPartialDepthCopies = true;         // Assumed support.
-  config->backend_info.bSupportsShaderBinaries = true;             // Assumed support.
-  config->backend_info.bSupportsPipelineCacheData = false;         // Handled via pipeline caches.
-  config->backend_info.bSupportsDynamicSamplerIndexing = true;     // Assumed support.
-  config->backend_info.bSupportsPostProcessing = true;             // Assumed support.
-  config->backend_info.bSupportsBackgroundCompiling = true;        // Assumed support.
-  config->backend_info.bSupportsCopyToVram = true;                 // Assumed support.
-  config->backend_info.bSupportsReversedDepthRange = true;         // Assumed support.
-  config->backend_info.bSupportsExclusiveFullscreen = false;       // Dependent on OS and features.
-  config->backend_info.bSupportsDualSourceBlend = false;           // Dependent on features.
-  config->backend_info.bSupportsGeometryShaders = false;           // Dependent on features.
-  config->backend_info.bSupportsGSInstancing = false;              // Dependent on features.
-  config->backend_info.bSupportsBBox = false;                      // Dependent on features.
-  config->backend_info.bSupportsFragmentStoresAndAtomics = false;  // Dependent on features.
-  config->backend_info.bSupportsSSAA = false;                      // Dependent on features.
-  config->backend_info.bSupportsDepthClamp = false;                // Dependent on features.
-  config->backend_info.bSupportsST3CTextures = false;              // Dependent on features.
-  config->backend_info.bSupportsBPTCTextures = false;              // Dependent on features.
-  config->backend_info.bSupportsLogicOp = false;                   // Dependent on features.
-  config->backend_info.bSupportsLargePoints = false;               // Dependent on features.
-  config->backend_info.bSupportsFramebufferFetch = false;          // Dependent on OS and features.
-  config->backend_info.bSupportsCoarseDerivatives = true;          // Assumed support.
-  config->backend_info.bSupportsTextureQueryLevels = true;         // Assumed support.
-  config->backend_info.bSupportsLodBiasInSampler = false;          // Dependent on OS.
-  config->backend_info.bSupportsSettingObjectNames = false;        // Dependent on features.
-  config->backend_info.bSupportsPartialMultisampleResolve = true;  // Assumed support.
-  config->backend_info.bSupportsDynamicVertexLoader = true;        // Assumed support.
-  config->backend_info.bSupportsVSLinePointExpand = true;          // Assumed support.
-  config->backend_info.bSupportsHDROutput = true;                  // Assumed support.
+  backend_info->api_type = APIType::Vulkan;
+  backend_info->bSupports3DVision = false;                  // D3D-exclusive.
+  backend_info->bSupportsEarlyZ = true;                     // Assumed support.
+  backend_info->bSupportsPrimitiveRestart = true;           // Assumed support.
+  backend_info->bSupportsBindingLayout = false;             // Assumed support.
+  backend_info->bSupportsPaletteConversion = true;          // Assumed support.
+  backend_info->bSupportsClipControl = true;                // Assumed support.
+  backend_info->bSupportsMultithreading = true;             // Assumed support.
+  backend_info->bSupportsComputeShaders = true;             // Assumed support.
+  backend_info->bSupportsGPUTextureDecoding = true;         // Assumed support.
+  backend_info->bSupportsBitfield = true;                   // Assumed support.
+  backend_info->bSupportsPartialDepthCopies = true;         // Assumed support.
+  backend_info->bSupportsShaderBinaries = true;             // Assumed support.
+  backend_info->bSupportsPipelineCacheData = false;         // Handled via pipeline caches.
+  backend_info->bSupportsDynamicSamplerIndexing = true;     // Assumed support.
+  backend_info->bSupportsPostProcessing = true;             // Assumed support.
+  backend_info->bSupportsBackgroundCompiling = true;        // Assumed support.
+  backend_info->bSupportsCopyToVram = true;                 // Assumed support.
+  backend_info->bSupportsReversedDepthRange = true;         // Assumed support.
+  backend_info->bSupportsExclusiveFullscreen = false;       // Dependent on OS and features.
+  backend_info->bSupportsDualSourceBlend = false;           // Dependent on features.
+  backend_info->bSupportsGeometryShaders = false;           // Dependent on features.
+  backend_info->bSupportsGSInstancing = false;              // Dependent on features.
+  backend_info->bSupportsBBox = false;                      // Dependent on features.
+  backend_info->bSupportsFragmentStoresAndAtomics = false;  // Dependent on features.
+  backend_info->bSupportsSSAA = false;                      // Dependent on features.
+  backend_info->bSupportsDepthClamp = false;                // Dependent on features.
+  backend_info->bSupportsST3CTextures = false;              // Dependent on features.
+  backend_info->bSupportsBPTCTextures = false;              // Dependent on features.
+  backend_info->bSupportsLogicOp = false;                   // Dependent on features.
+  backend_info->bSupportsLargePoints = false;               // Dependent on features.
+  backend_info->bSupportsFramebufferFetch = false;          // Dependent on OS and features.
+  backend_info->bSupportsCoarseDerivatives = true;          // Assumed support.
+  backend_info->bSupportsTextureQueryLevels = true;         // Assumed support.
+  backend_info->bSupportsLodBiasInSampler = false;          // Dependent on OS.
+  backend_info->bSupportsSettingObjectNames = false;        // Dependent on features.
+  backend_info->bSupportsPartialMultisampleResolve = true;  // Assumed support.
+  backend_info->bSupportsDynamicVertexLoader = true;        // Assumed support.
+  backend_info->bSupportsVSLinePointExpand = true;          // Assumed support.
+  backend_info->bSupportsHDROutput = true;                  // Assumed support.
 }
 
-void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list)
+void VulkanContext::PopulateBackendInfoAdapters(BackendInfo* backend_info, const GPUList& gpu_list)
 {
-  config->backend_info.Adapters.clear();
+  backend_info->Adapters.clear();
   for (VkPhysicalDevice physical_device : gpu_list)
   {
     VkPhysicalDeviceProperties properties;
     vkGetPhysicalDeviceProperties(physical_device, &properties);
-    config->backend_info.Adapters.push_back(properties.deviceName);
+    backend_info->Adapters.push_back(properties.deviceName);
   }
 }
 
-void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalDevice gpu,
+void VulkanContext::PopulateBackendInfoFeatures(BackendInfo* backend_info, VkPhysicalDevice gpu,
                                                 const PhysicalDeviceInfo& info)
 {
-  config->backend_info.MaxTextureSize = info.maxImageDimension2D;
-  config->backend_info.bUsesLowerLeftOrigin = false;
-  config->backend_info.bSupportsDualSourceBlend = info.dualSrcBlend;
-  config->backend_info.bSupportsGeometryShaders = info.geometryShader;
-  config->backend_info.bSupportsGSInstancing = info.geometryShader;
-  config->backend_info.bSupportsBBox = config->backend_info.bSupportsFragmentStoresAndAtomics =
+  backend_info->MaxTextureSize = info.maxImageDimension2D;
+  backend_info->bUsesLowerLeftOrigin = false;
+  backend_info->bSupportsDualSourceBlend = info.dualSrcBlend;
+  backend_info->bSupportsGeometryShaders = info.geometryShader;
+  backend_info->bSupportsGSInstancing = info.geometryShader;
+  backend_info->bSupportsBBox = backend_info->bSupportsFragmentStoresAndAtomics =
       info.fragmentStoresAndAtomics;
-  config->backend_info.bSupportsSSAA = info.sampleRateShading;
-  config->backend_info.bSupportsLogicOp = info.logicOp;
+  backend_info->bSupportsSSAA = info.sampleRateShading;
+  backend_info->bSupportsLogicOp = info.logicOp;
 
   // Metal doesn't support this.
-  config->backend_info.bSupportsLodBiasInSampler = info.driverID != VK_DRIVER_ID_MOLTENVK;
+  backend_info->bSupportsLodBiasInSampler = info.driverID != VK_DRIVER_ID_MOLTENVK;
 
   // Disable geometry shader when shaderTessellationAndGeometryPointSize is not supported.
   // Seems this is needed for gl_Layer.
   if (!info.shaderTessellationAndGeometryPointSize)
   {
-    config->backend_info.bSupportsGeometryShaders = VK_FALSE;
-    config->backend_info.bSupportsGSInstancing = VK_FALSE;
+    backend_info->bSupportsGeometryShaders = VK_FALSE;
+    backend_info->bSupportsGSInstancing = VK_FALSE;
   }
 
   // Depth clamping implies shaderClipDistance and depthClamp
-  config->backend_info.bSupportsDepthClamp = info.depthClamp && info.shaderClipDistance;
+  backend_info->bSupportsDepthClamp = info.depthClamp && info.shaderClipDistance;
 
   // textureCompressionBC implies BC1 through BC7, which is a superset of DXT1/3/5, which we need.
-  config->backend_info.bSupportsST3CTextures = info.textureCompressionBC;
-  config->backend_info.bSupportsBPTCTextures = info.textureCompressionBC;
+  backend_info->bSupportsST3CTextures = info.textureCompressionBC;
+  backend_info->bSupportsBPTCTextures = info.textureCompressionBC;
 
   // Some devices don't support point sizes >1 (e.g. Adreno).
   // If we can't use a point size above our maximum IR, use triangles instead for EFB pokes.
   // This means a 6x increase in the size of the vertices, though.
-  config->backend_info.bSupportsLargePoints =
+  backend_info->bSupportsLargePoints =
       info.largePoints && info.pointSizeRange[0] <= 1.0f && info.pointSizeRange[1] >= 16;
 
   std::string device_name = info.deviceName;
@@ -520,25 +517,26 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD
   // We currently use a hacked MoltenVK to implement this, so don't attempt outside of MVK
   if (is_moltenvk && (vendor_id == 0x106B || device_name.find("Apple") != std::string::npos))
   {
-    config->backend_info.bSupportsFramebufferFetch = true;
+    backend_info->bSupportsFramebufferFetch = true;
   }
 
   // Our usage of primitive restart appears to be broken on AMD's binary drivers.
   // Seems to be fine on GCN Gen 1-2, unconfirmed on GCN Gen 3, causes driver resets on GCN Gen 4.
   if (DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART))
-    config->backend_info.bSupportsPrimitiveRestart = false;
+    backend_info->bSupportsPrimitiveRestart = false;
 
   // Reversed depth range is broken on some drivers, or is broken when used in combination
   // with depth clamping. Fall back to inverted depth range for these.
   if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_REVERSED_DEPTH_RANGE))
-    config->backend_info.bSupportsReversedDepthRange = false;
+    backend_info->bSupportsReversedDepthRange = false;
 
   // Dynamic sampler indexing locks up Intel GPUs on MoltenVK/Metal
   if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING))
-    config->backend_info.bSupportsDynamicSamplerIndexing = false;
+    backend_info->bSupportsDynamicSamplerIndexing = false;
 }
 
-void VulkanContext::PopulateBackendInfoMultisampleModes(VideoConfig* config, VkPhysicalDevice gpu,
+void VulkanContext::PopulateBackendInfoMultisampleModes(BackendInfo* backend_info,
+                                                        VkPhysicalDevice gpu,
                                                         const PhysicalDeviceInfo& info)
 {
   // Query image support for the EFB texture formats.
@@ -557,32 +555,32 @@ void VulkanContext::PopulateBackendInfoMultisampleModes(VideoConfig* config, VkP
       efb_color_properties.sampleCounts & efb_depth_properties.sampleCounts;
 
   // No AA
-  config->backend_info.AAModes.clear();
-  config->backend_info.AAModes.emplace_back(1);
+  backend_info->AAModes.clear();
+  backend_info->AAModes.emplace_back(1);
 
   // 2xMSAA/SSAA
   if (supported_sample_counts & VK_SAMPLE_COUNT_2_BIT)
-    config->backend_info.AAModes.emplace_back(2);
+    backend_info->AAModes.emplace_back(2);
 
   // 4xMSAA/SSAA
   if (supported_sample_counts & VK_SAMPLE_COUNT_4_BIT)
-    config->backend_info.AAModes.emplace_back(4);
+    backend_info->AAModes.emplace_back(4);
 
   // 8xMSAA/SSAA
   if (supported_sample_counts & VK_SAMPLE_COUNT_8_BIT)
-    config->backend_info.AAModes.emplace_back(8);
+    backend_info->AAModes.emplace_back(8);
 
   // 16xMSAA/SSAA
   if (supported_sample_counts & VK_SAMPLE_COUNT_16_BIT)
-    config->backend_info.AAModes.emplace_back(16);
+    backend_info->AAModes.emplace_back(16);
 
   // 32xMSAA/SSAA
   if (supported_sample_counts & VK_SAMPLE_COUNT_32_BIT)
-    config->backend_info.AAModes.emplace_back(32);
+    backend_info->AAModes.emplace_back(32);
 
   // 64xMSAA/SSAA
   if (supported_sample_counts & VK_SAMPLE_COUNT_64_BIT)
-    config->backend_info.AAModes.emplace_back(64);
+    backend_info->AAModes.emplace_back(64);
 }
 
 std::unique_ptr<VulkanContext> VulkanContext::Create(VkInstance instance, VkPhysicalDevice gpu,
diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.h b/Source/Core/VideoBackends/Vulkan/VulkanContext.h
index d0a3b3a32d..f59c7421f4 100644
--- a/Source/Core/VideoBackends/Vulkan/VulkanContext.h
+++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.h
@@ -72,11 +72,11 @@ public:
 
   // Populates backend/video config.
   // These are public so that the backend info can be populated without creating a context.
-  static void PopulateBackendInfo(VideoConfig* config);
-  static void PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list);
-  static void PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalDevice gpu,
+  static void PopulateBackendInfo(BackendInfo* backend_info);
+  static void PopulateBackendInfoAdapters(BackendInfo* backend_info, const GPUList& gpu_list);
+  static void PopulateBackendInfoFeatures(BackendInfo* backend_info, VkPhysicalDevice gpu,
                                           const PhysicalDeviceInfo& info);
-  static void PopulateBackendInfoMultisampleModes(VideoConfig* config, VkPhysicalDevice gpu,
+  static void PopulateBackendInfoMultisampleModes(BackendInfo* backend_info, VkPhysicalDevice gpu,
                                                   const PhysicalDeviceInfo& info);
 
   // Creates a Vulkan device context.
diff --git a/Source/Core/VideoCommon/AbstractGfx.cpp b/Source/Core/VideoCommon/AbstractGfx.cpp
index 4c386b12ca..06524d04b4 100644
--- a/Source/Core/VideoCommon/AbstractGfx.cpp
+++ b/Source/Core/VideoCommon/AbstractGfx.cpp
@@ -76,7 +76,7 @@ void AbstractGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool co
                         static_cast<float>((color >> 0) & 0xFF) / 255.0f,
                         static_cast<float>((color >> 24) & 0xFF) / 255.0f},
                        static_cast<float>(z & 0xFFFFFF) / 16777216.0f};
-  if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+  if (!g_backend_info.bSupportsReversedDepthRange)
     uniforms.clear_depth = 1.0f - uniforms.clear_depth;
   g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
 
@@ -149,7 +149,7 @@ AbstractGfx::ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect, u
                                          u32 fb_height) const
 {
   MathUtil::Rectangle<int> ret = rect;
-  if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
+  if (g_backend_info.bUsesLowerLeftOrigin)
   {
     ret.top = fb_height - rect.bottom;
     ret.bottom = fb_height - rect.top;
@@ -177,5 +177,5 @@ bool AbstractGfx::UseGeometryShaderForUI() const
   // OpenGL doesn't render to a 2-layer backbuffer like D3D/Vulkan for quad-buffered stereo,
   // instead drawing twice and the eye selected by glDrawBuffer() (see Presenter::RenderXFBToScreen)
   return g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer &&
-         !g_ActiveConfig.backend_info.bUsesExplictQuadBuffering;
+         !g_backend_info.bUsesExplictQuadBuffering;
 }
diff --git a/Source/Core/VideoCommon/Assets/CustomTextureData.cpp b/Source/Core/VideoCommon/Assets/CustomTextureData.cpp
index d30532142a..8d21dc2139 100644
--- a/Source/Core/VideoCommon/Assets/CustomTextureData.cpp
+++ b/Source/Core/VideoCommon/Assets/CustomTextureData.cpp
@@ -360,7 +360,7 @@ static bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
       info->format = AbstractTextureFormat::BPTC;
       info->block_size = 4;
       info->bytes_per_block = 16;
-      if (!g_ActiveConfig.backend_info.bSupportsBPTCTextures)
+      if (!g_backend_info.bSupportsBPTCTextures)
         return false;
     }
     else
@@ -418,7 +418,7 @@ static bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
 
   // We also need to ensure the backend supports these formats natively before loading them,
   // otherwise, fallback to SOIL, which will decompress them to RGBA.
-  if (needs_s3tc && !g_ActiveConfig.backend_info.bSupportsST3CTextures)
+  if (needs_s3tc && !g_backend_info.bSupportsST3CTextures)
     return false;
 
   // Mip levels smaller than the block size are padded to multiples of the block size.
diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp
index 2c6c733710..d813d8b6e3 100644
--- a/Source/Core/VideoCommon/BPFunctions.cpp
+++ b/Source/Core/VideoCommon/BPFunctions.cpp
@@ -221,7 +221,7 @@ void SetScissorAndViewport()
   // floating-point round-trip errors. However the console GPU doesn't ever write a value
   // to the depth buffer that exceeds 2^24 - 1.
   constexpr float GX_MAX_DEPTH = 16777215.0f / 16777216.0f;
-  if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
+  if (!g_backend_info.bSupportsDepthClamp)
   {
     // There's no way to support oversized depth ranges in this situation. Let's just clamp the
     // range to the maximum value supported by the console GPU and hope for the best.
@@ -233,7 +233,7 @@ void SetScissorAndViewport()
   {
     // We need to ensure depth values are clamped the maximum value supported by the console GPU.
     // Taking into account whether the depth range is inverted or not.
-    if (xfmem.viewport.zRange < 0.0f && g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+    if (xfmem.viewport.zRange < 0.0f && g_backend_info.bSupportsReversedDepthRange)
     {
       min_depth = GX_MAX_DEPTH;
       max_depth = 0.0f;
@@ -246,7 +246,7 @@ void SetScissorAndViewport()
   }
 
   float near_depth, far_depth;
-  if (g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+  if (g_backend_info.bSupportsReversedDepthRange)
   {
     // Set the reversed depth range.
     near_depth = max_depth;
@@ -262,7 +262,7 @@ void SetScissorAndViewport()
   }
 
   // Lower-left flip.
-  if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
+  if (g_backend_info.bUsesLowerLeftOrigin)
     y = static_cast<float>(g_gfx->GetCurrentFramebuffer()->GetHeight()) - y - height;
 
   g_gfx->SetViewport(x, y, width, height, near_depth, far_depth);
diff --git a/Source/Core/VideoCommon/BoundingBox.cpp b/Source/Core/VideoCommon/BoundingBox.cpp
index 94e7eaa18c..233ea10902 100644
--- a/Source/Core/VideoCommon/BoundingBox.cpp
+++ b/Source/Core/VideoCommon/BoundingBox.cpp
@@ -29,7 +29,7 @@ void BoundingBox::Disable(PixelShaderManager& pixel_shader_manager)
 
 void BoundingBox::Flush()
 {
-  if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
+  if (!g_ActiveConfig.bBBoxEnable || !g_backend_info.bSupportsBBox)
     return;
 
   m_is_valid = false;
@@ -57,7 +57,7 @@ void BoundingBox::Flush()
 
 void BoundingBox::Readback()
 {
-  if (!g_ActiveConfig.backend_info.bSupportsBBox)
+  if (!g_backend_info.bSupportsBBox)
     return;
 
   auto read_values = Read(0, NUM_BBOX_VALUES);
@@ -76,7 +76,7 @@ u16 BoundingBox::Get(u32 index)
 {
   ASSERT(index < NUM_BBOX_VALUES);
 
-  if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
+  if (!g_ActiveConfig.bBBoxEnable || !g_backend_info.bSupportsBBox)
     return m_bounding_box_fallback[index];
 
   if (!m_is_valid)
@@ -89,7 +89,7 @@ void BoundingBox::Set(u32 index, u16 value)
 {
   ASSERT(index < NUM_BBOX_VALUES);
 
-  if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
+  if (!g_ActiveConfig.bBBoxEnable || !g_backend_info.bSupportsBBox)
   {
     m_bounding_box_fallback[index] = value;
     return;
@@ -120,12 +120,12 @@ void BoundingBox::DoState(PointerWrap& p)
   {
     p.Do(backend_values);
 
-    if (g_ActiveConfig.backend_info.bSupportsBBox)
+    if (g_backend_info.bSupportsBBox)
       Write(0, backend_values);
   }
   else
   {
-    if (g_ActiveConfig.backend_info.bSupportsBBox)
+    if (g_backend_info.bSupportsBBox)
       backend_values = Read(0, NUM_BBOX_VALUES);
 
     p.Do(backend_values);
diff --git a/Source/Core/VideoCommon/FramebufferManager.cpp b/Source/Core/VideoCommon/FramebufferManager.cpp
index 044b94a5de..98b3d83a6d 100644
--- a/Source/Core/VideoCommon/FramebufferManager.cpp
+++ b/Source/Core/VideoCommon/FramebufferManager.cpp
@@ -217,7 +217,7 @@ std::tuple<u32, u32> FramebufferManager::CalculateTargetSize()
   else
     m_efb_scale = g_ActiveConfig.iEFBScale;
 
-  const u32 max_size = g_ActiveConfig.backend_info.MaxTextureSize;
+  const u32 max_size = g_backend_info.MaxTextureSize;
   if (max_size < EFB_WIDTH * m_efb_scale)
     m_efb_scale = max_size / EFB_WIDTH;
 
@@ -253,7 +253,7 @@ bool FramebufferManager::CreateEFBFramebuffer()
   if (g_ActiveConfig.MultisamplingEnabled())
   {
     u32 flags = 0;
-    if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
+    if (!g_backend_info.bSupportsPartialMultisampleResolve)
       flags |= AbstractTextureFlag_RenderTarget;
     m_efb_resolve_color_texture = g_gfx->CreateTexture(
         TextureConfig(efb_color_texture_config.width, efb_color_texture_config.height, 1,
@@ -263,7 +263,7 @@ bool FramebufferManager::CreateEFBFramebuffer()
     if (!m_efb_resolve_color_texture)
       return false;
 
-    if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
+    if (!g_backend_info.bSupportsPartialMultisampleResolve)
     {
       m_efb_color_resolve_framebuffer =
           g_gfx->CreateFramebuffer(m_efb_resolve_color_texture.get(), nullptr);
@@ -291,8 +291,7 @@ bool FramebufferManager::CreateEFBFramebuffer()
 
   // Clear the renderable textures out.
   g_gfx->SetAndClearFramebuffer(m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}},
-                                g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f :
-                                                                                          0.0f);
+                                g_backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f);
 
   // Pixel Shader uses EFB scale as a constant, dirty that in case it changed
   Core::System::GetInstance().GetPixelShaderManager().Dirty();
@@ -328,7 +327,7 @@ AbstractTexture* FramebufferManager::ResolveEFBColorTexture(const MathUtil::Rect
   clamped_region.ClampUL(0, 0, GetEFBWidth(), GetEFBHeight());
 
   // Resolve to our already-created texture.
-  if (g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
+  if (g_backend_info.bSupportsPartialMultisampleResolve)
   {
     for (u32 layer = 0; layer < GetEFBLayers(); layer++)
     {
@@ -479,7 +478,7 @@ MathUtil::Rectangle<int> FramebufferManager::GetEFBCacheTileRect(u32 tile_index)
 u32 FramebufferManager::PeekEFBColor(u32 x, u32 y)
 {
   // The y coordinate here assumes upper-left origin, but the readback texture is lower-left in GL.
-  if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
+  if (g_backend_info.bUsesLowerLeftOrigin)
     y = EFB_HEIGHT - 1 - y;
 
   u32 tile_index;
@@ -502,7 +501,7 @@ u32 FramebufferManager::PeekEFBColor(u32 x, u32 y)
 float FramebufferManager::PeekEFBDepth(u32 x, u32 y)
 {
   // The y coordinate here assumes upper-left origin, but the readback texture is lower-left in GL.
-  if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
+  if (g_backend_info.bUsesLowerLeftOrigin)
     y = EFB_HEIGHT - 1 - y;
 
   u32 tile_index;
@@ -654,7 +653,7 @@ bool FramebufferManager::CompileReadbackPipelines()
     if (!m_efb_depth_resolve_pipeline)
       return false;
 
-    if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
+    if (!g_backend_info.bSupportsPartialMultisampleResolve)
     {
       config.framebuffer_state.color_texture_format = GetEFBColorFormat();
       auto color_resolve_shader = g_gfx->CreateShaderFromSource(
@@ -717,8 +716,8 @@ bool FramebufferManager::CreateReadbackFramebuffer()
 
   // Since we can't partially copy from a depth buffer directly to the staging texture in D3D, we
   // use an intermediate buffer to avoid copying the whole texture.
-  if (!g_ActiveConfig.backend_info.bSupportsDepthReadback ||
-      (IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) ||
+  if (!g_backend_info.bSupportsDepthReadback ||
+      (IsUsingTiledEFBCache() && !g_backend_info.bSupportsPartialDepthCopies) ||
       !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
                                                          GetEFBDepthCopyFormat()) ||
       GetEFBScale() != 1)
@@ -792,11 +791,10 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async
   // Force the path through the intermediate texture, as we can't do an image copy from a depth
   // buffer directly to a staging texture (must be the whole resource).
   const bool force_intermediate_copy =
-      depth &&
-      (!g_ActiveConfig.backend_info.bSupportsDepthReadback ||
-       (!g_ActiveConfig.backend_info.bSupportsPartialDepthCopies && IsUsingTiledEFBCache()) ||
-       !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
-                                                          GetEFBDepthCopyFormat()));
+      depth && (!g_backend_info.bSupportsDepthReadback ||
+                (!g_backend_info.bSupportsPartialDepthCopies && IsUsingTiledEFBCache()) ||
+                !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
+                                                                   GetEFBDepthCopyFormat()));
 
   // Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on.
   EFBCacheData& data = depth ? m_efb_depth_cache : m_efb_color_cache;
@@ -956,7 +954,7 @@ void FramebufferManager::PokeEFBColor(u32 x, u32 y, u32 color)
   CreatePokeVertices(&m_color_poke_vertices, x, y, 0.0f, color);
 
   // See comment above for reasoning for lower-left coordinates.
-  if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
+  if (g_backend_info.bUsesLowerLeftOrigin)
     y = EFB_HEIGHT - 1 - y;
 
   // Update the peek cache if it's valid, since we know the color of the pixel now.
@@ -974,7 +972,7 @@ void FramebufferManager::PokeEFBDepth(u32 x, u32 y, float depth)
   CreatePokeVertices(&m_depth_poke_vertices, x, y, depth, 0);
 
   // See comment above for reasoning for lower-left coordinates.
-  if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
+  if (g_backend_info.bUsesLowerLeftOrigin)
     y = EFB_HEIGHT - 1 - y;
 
   // Update the peek cache if it's valid, since we know the color of the pixel now.
@@ -988,7 +986,7 @@ void FramebufferManager::CreatePokeVertices(std::vector<EFBPokeVertex>* destinat
 {
   const float cs_pixel_width = 1.0f / EFB_WIDTH * 2.0f;
   const float cs_pixel_height = 1.0f / EFB_HEIGHT * 2.0f;
-  if (g_ActiveConfig.backend_info.bSupportsLargePoints)
+  if (g_backend_info.bSupportsLargePoints)
   {
     // GPU will expand the point to a quad.
     const float cs_x = (static_cast<float>(x) + 0.5f) * cs_pixel_width - 1.0f;
@@ -1076,8 +1074,7 @@ bool FramebufferManager::CompilePokePipelines()
   config.geometry_shader = IsEFBStereo() ? g_shader_cache->GetColorGeometryShader() : nullptr;
   config.pixel_shader = g_shader_cache->GetColorPixelShader();
   config.rasterization_state = RenderState::GetNoCullRasterizationState(
-      g_ActiveConfig.backend_info.bSupportsLargePoints ? PrimitiveType::Points :
-                                                         PrimitiveType::Triangles);
+      g_backend_info.bSupportsLargePoints ? PrimitiveType::Points : PrimitiveType::Triangles);
   config.depth_state = RenderState::GetNoDepthTestingDepthState();
   config.blending_state = RenderState::GetNoBlendingBlendState();
   config.framebuffer_state = GetEFBFramebufferState();
@@ -1155,8 +1152,7 @@ void FramebufferManager::DoLoadState(PointerWrap& p)
   {
     WARN_LOG_FMT(VIDEO, "Failed to deserialize EFB contents. Clearing instead.");
     g_gfx->SetAndClearFramebuffer(m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}},
-                                  g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f :
-                                                                                            0.0f);
+                                  g_backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f);
     return;
   }
 
diff --git a/Source/Core/VideoCommon/FramebufferShaderGen.cpp b/Source/Core/VideoCommon/FramebufferShaderGen.cpp
index 25b6581469..248146e2b6 100644
--- a/Source/Core/VideoCommon/FramebufferShaderGen.cpp
+++ b/Source/Core/VideoCommon/FramebufferShaderGen.cpp
@@ -20,7 +20,7 @@ namespace
 {
 APIType GetAPIType()
 {
-  return g_ActiveConfig.backend_info.api_type;
+  return g_backend_info.api_type;
 }
 
 void EmitUniformBufferDeclaration(ShaderCode& code)
@@ -109,7 +109,7 @@ void EmitVertexMainDeclaration(ShaderCode& code, u32 num_tex_inputs, u32 num_col
     if (position_input)
       code.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawpos;\n", ShaderAttrib::Position);
 
-    if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+    if (g_backend_info.bSupportsGeometryShaders)
     {
       code.Write("VARYING_LOCATION(0) out VertexData {{\n");
       for (u32 i = 0; i < num_tex_outputs; i++)
@@ -146,7 +146,7 @@ void EmitPixelMainDeclaration(ShaderCode& code, u32 num_tex_inputs, u32 num_colo
   case APIType::OpenGL:
   case APIType::Vulkan:
   {
-    if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+    if (g_backend_info.bSupportsGeometryShaders)
     {
       code.Write("VARYING_LOCATION(0) in VertexData {{\n");
       for (u32 i = 0; i < num_tex_inputs; i++)
@@ -406,7 +406,7 @@ std::string GenerateEFBPokeVertexShader()
   code.Write("{{\n"
              "  v_col0 = rawcolor0;\n"
              "  opos = float4(rawpos.xyz, 1.0f);\n");
-  if (g_ActiveConfig.backend_info.bSupportsLargePoints)
+  if (g_backend_info.bSupportsLargePoints)
     code.Write("  gl_PointSize = rawpos.w;\n");
 
   // NDC space is flipped in Vulkan.
diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp
index c4b6649331..2d6170ed12 100644
--- a/Source/Core/VideoCommon/GeometryShaderGen.cpp
+++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp
@@ -378,8 +378,8 @@ void EnumerateGeometryShaderUids(const std::function<void(const GeometryShaderUi
   GeometryShaderUid uid;
 
   const std::array<PrimitiveType, 3> primitive_lut = {
-      {g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
-                                                               PrimitiveType::Triangles,
+      {g_backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
+                                                  PrimitiveType::Triangles,
        PrimitiveType::Lines, PrimitiveType::Points}};
   for (PrimitiveType primitive : primitive_lut)
   {
diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.cpp
index 29d801cc52..cff6e7b6a6 100644
--- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.cpp
+++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.cpp
@@ -8,7 +8,7 @@
 
 CustomShaderCache::CustomShaderCache()
 {
-  m_api_type = g_ActiveConfig.backend_info.api_type;
+  m_api_type = g_backend_info.api_type;
   m_host_config.bits = ShaderHostConfig::GetCurrent().bits;
 
   m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler();
diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp
index 03d0815a13..91db420950 100644
--- a/Source/Core/VideoCommon/IndexGenerator.cpp
+++ b/Source/Core/VideoCommon/IndexGenerator.cpp
@@ -266,7 +266,7 @@ void IndexGenerator::Init()
 {
   using OpcodeDecoder::Primitive;
 
-  if (g_Config.backend_info.bSupportsPrimitiveRestart)
+  if (g_backend_info.bSupportsPrimitiveRestart)
   {
     m_primitive_table[Primitive::GX_DRAW_QUADS] = AddQuads<true>;
     m_primitive_table[Primitive::GX_DRAW_QUADS_2] = AddQuads_nonstandard<true>;
@@ -284,7 +284,7 @@ void IndexGenerator::Init()
   }
   if (g_Config.UseVSForLinePointExpand())
   {
-    if (g_Config.backend_info.bSupportsPrimitiveRestart)
+    if (g_backend_info.bSupportsPrimitiveRestart)
     {
       m_primitive_table[Primitive::GX_DRAW_LINES] = AddLines_VSExpand<true, false>;
       m_primitive_table[Primitive::GX_DRAW_LINE_STRIP] = AddLines_VSExpand<true, true>;
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index 0b027b2496..851d127963 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -642,7 +642,7 @@ uint WrapCoord(int coord, uint wrap, int size) {{
   int size_t = size.y;
   int num_layers = size.z;
 )");
-      if (g_ActiveConfig.backend_info.bSupportsTextureQueryLevels)
+      if (g_backend_info.bSupportsTextureQueryLevels)
       {
         out.Write("  int number_of_levels = textureQueryLevels(tex);\n");
       }
@@ -671,7 +671,7 @@ uint WrapCoord(int coord, uint wrap, int size) {{
 )");
     }
 
-    if (g_ActiveConfig.backend_info.bSupportsCoarseDerivatives)
+    if (g_backend_info.bSupportsCoarseDerivatives)
     {
       // The software renderer uses the equivalent of coarse derivatives, so use them here for
       // consistency.  This hasn't been hardware tested.
@@ -1922,8 +1922,7 @@ static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_dat
   }
   if (per_pixel_depth)
   {
-    out.Write("\t\tdepth = {};\n",
-              !g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? "0.0" : "1.0");
+    out.Write("\t\tdepth = {};\n", !g_backend_info.bSupportsReversedDepthRange ? "0.0" : "1.0");
   }
 
   // ZCOMPLOC HACK:
diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp
index e7ff694161..ada1513d1f 100644
--- a/Source/Core/VideoCommon/PostProcessing.cpp
+++ b/Source/Core/VideoCommon/PostProcessing.cpp
@@ -685,7 +685,7 @@ std::string PostProcessing::GetHeader(bool user_post_process) const
   ss << "SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n";
   ss << "SAMPLER_BINDING(1) uniform sampler2DArray samp1;\n";
 
-  if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+  if (g_backend_info.bSupportsGeometryShaders)
   {
     ss << "VARYING_LOCATION(0) in VertexData {\n";
     ss << "  float3 v_tex0;\n";
@@ -770,7 +770,7 @@ std::string PostProcessing::GetFooter() const
 static std::string GetVertexShaderBody()
 {
   std::ostringstream ss;
-  if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+  if (g_backend_info.bSupportsGeometryShaders)
   {
     ss << "VARYING_LOCATION(0) out VertexData {\n";
     ss << "  float3 v_tex0;\n";
@@ -789,12 +789,12 @@ static std::string GetVertexShaderBody()
   ss << "  v_tex0 = float3(src_rect.xy + (src_rect.zw * v_tex0.xy), float(src_layer));\n";
 
   // Vulkan Y needs to be inverted on every pass
-  if (g_ActiveConfig.backend_info.api_type == APIType::Vulkan)
+  if (g_backend_info.api_type == APIType::Vulkan)
   {
     ss << "  opos.y = -opos.y;\n";
   }
   // OpenGL Y needs to be inverted in all passes except the last one
-  else if (g_ActiveConfig.backend_info.api_type == APIType::OpenGL)
+  else if (g_backend_info.api_type == APIType::OpenGL)
   {
     ss << "  if (intermediary_buffer != 0)\n";
     ss << "    opos.y = -opos.y;\n";
@@ -887,7 +887,7 @@ void PostProcessing::FillUniformBuffer(const MathUtil::Rectangle<int>& src,
                                static_cast<float>(src.GetHeight()) * rcp_src_height};
   builtin_uniforms.src_layer = static_cast<s32>(src_layer);
   builtin_uniforms.time = static_cast<u32>(m_timer.ElapsedMs());
-  builtin_uniforms.graphics_api = static_cast<s32>(g_ActiveConfig.backend_info.api_type);
+  builtin_uniforms.graphics_api = static_cast<s32>(g_backend_info.api_type);
   builtin_uniforms.intermediary_buffer = static_cast<s32>(intermediary_buffer);
 
   builtin_uniforms.resampling_method = static_cast<s32>(g_ActiveConfig.output_resampling_mode);
@@ -1009,7 +1009,7 @@ static bool UseGeometryShaderForPostProcess(bool is_intermediary_buffer)
   switch (g_ActiveConfig.stereo_mode)
   {
   case StereoMode::QuadBuffer:
-    return !g_ActiveConfig.backend_info.bUsesExplictQuadBuffering;
+    return !g_backend_info.bUsesExplictQuadBuffering;
   case StereoMode::Anaglyph:
   case StereoMode::Passive:
     return is_intermediary_buffer;
diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp
index 6813c7a4e3..8f88c90588 100644
--- a/Source/Core/VideoCommon/Present.cpp
+++ b/Source/Core/VideoCommon/Present.cpp
@@ -787,7 +787,7 @@ void Presenter::RenderXFBToScreen(const MathUtil::Rectangle<int>& target_rc,
                                   const MathUtil::Rectangle<int>& source_rc)
 {
   if (g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer &&
-      g_ActiveConfig.backend_info.bUsesExplictQuadBuffering)
+      g_backend_info.bUsesExplictQuadBuffering)
   {
     // Quad-buffered stereo is annoying on GL.
     g_gfx->SelectLeftBuffer();
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index 61820e0c82..1486eae124 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -88,7 +88,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
   {
     // Depth buffer is inverted for improved precision near far plane
     float depth = g_framebuffer_manager->PeekEFBDepth(x, y);
-    if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+    if (!g_backend_info.bSupportsReversedDepthRange)
       depth = 1.0f - depth;
 
     // Convert to 24bit depth
@@ -133,7 +133,7 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num
       // Convert to floating-point depth.
       const EfbPokeData& point = points[i];
       float depth = float(point.data & 0xFFFFFF) / 16777216.0f;
-      if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+      if (!g_backend_info.bSupportsReversedDepthRange)
         depth = 1.0f - depth;
 
       g_framebuffer_manager->PokeEFBDepth(point.x, point.y, depth);
diff --git a/Source/Core/VideoCommon/ShaderCache.cpp b/Source/Core/VideoCommon/ShaderCache.cpp
index 587ee3cc7f..22939e9b90 100644
--- a/Source/Core/VideoCommon/ShaderCache.cpp
+++ b/Source/Core/VideoCommon/ShaderCache.cpp
@@ -39,7 +39,7 @@ ShaderCache::~ShaderCache()
 
 bool ShaderCache::Initialize()
 {
-  m_api_type = g_ActiveConfig.backend_info.api_type;
+  m_api_type = g_backend_info.api_type;
   m_host_config.bits = ShaderHostConfig::GetCurrent().bits;
 
   if (!CompileSharedPipelines())
@@ -352,7 +352,7 @@ void ShaderCache::ClearPipelineCache(T& cache, Y& disk_cache)
 void ShaderCache::LoadCaches()
 {
   // Ubershader caches, if present.
-  if (g_ActiveConfig.backend_info.bSupportsShaderBinaries)
+  if (g_backend_info.bSupportsShaderBinaries)
   {
     LoadShaderCache<ShaderStage::Vertex, UberShader::VertexShaderUid>(m_uber_vs_cache, m_api_type,
                                                                       "uber-vs", false);
@@ -371,7 +371,7 @@ void ShaderCache::LoadCaches()
                                                         true);
   }
 
-  if (g_ActiveConfig.backend_info.bSupportsPipelineCacheData)
+  if (g_backend_info.bSupportsPipelineCacheData)
   {
     LoadPipelineCache<GXPipelineUid, SerializedGXPipelineUid>(
         m_gx_pipeline_cache, m_gx_pipeline_disk_cache, m_api_type, "specialized-pipeline", true);
@@ -470,7 +470,7 @@ const AbstractShader* ShaderCache::InsertVertexShader(const VertexShaderUid& uid
 
   if (shader && !entry.shader)
   {
-    if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
+    if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
     {
       auto binary = shader->GetBinary();
       if (!binary.empty())
@@ -492,7 +492,7 @@ const AbstractShader* ShaderCache::InsertVertexUberShader(const UberShader::Vert
 
   if (shader && !entry.shader)
   {
-    if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
+    if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
     {
       auto binary = shader->GetBinary();
       if (!binary.empty())
@@ -514,7 +514,7 @@ const AbstractShader* ShaderCache::InsertPixelShader(const PixelShaderUid& uid,
 
   if (shader && !entry.shader)
   {
-    if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
+    if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
     {
       auto binary = shader->GetBinary();
       if (!binary.empty())
@@ -536,7 +536,7 @@ const AbstractShader* ShaderCache::InsertPixelUberShader(const UberShader::Pixel
 
   if (shader && !entry.shader)
   {
-    if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
+    if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
     {
       auto binary = shader->GetBinary();
       if (!binary.empty())
@@ -563,7 +563,7 @@ const AbstractShader* ShaderCache::CreateGeometryShader(const GeometryShaderUid&
 
   if (shader && !entry.shader)
   {
-    if (g_ActiveConfig.bShaderCache && g_ActiveConfig.backend_info.bSupportsShaderBinaries)
+    if (g_ActiveConfig.bShaderCache && g_backend_info.bSupportsShaderBinaries)
     {
       auto binary = shader->GetBinary();
       if (!binary.empty())
@@ -623,8 +623,8 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
 
   // If framebuffer fetch is available, we can emulate logic ops in the fragment shader
   // and don't need the below blend approximation
-  if (blend.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp &&
-      !g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
+  if (blend.logicopenable && !g_backend_info.bSupportsLogicOp &&
+      !g_backend_info.bSupportsFramebufferFetch)
   {
     if (!blend.LogicOpApproximationIsExact())
       WARN_LOG_FMT(VIDEO,
@@ -638,8 +638,7 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
   }
 
   const bool benefits_from_ps_dual_source_off =
-      (!g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
-       g_ActiveConfig.backend_info.bSupportsFramebufferFetch) ||
+      (!g_backend_info.bSupportsDualSourceBlend && g_backend_info.bSupportsFramebufferFetch) ||
       DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING);
   if (benefits_from_ps_dual_source_off && !blend.RequiresDualSrc())
   {
@@ -648,19 +647,19 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
     blend.usedualsrc = false;
   }
 
-  if (g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
+  if (g_backend_info.bSupportsFramebufferFetch)
   {
     bool fbfetch_blend = false;
     if ((DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z) ||
-         !g_ActiveConfig.backend_info.bSupportsEarlyZ) &&
+         !g_backend_info.bSupportsEarlyZ) &&
         ps->ztest == EmulatedZ::ForcedEarly)
     {
       ps->ztest = EmulatedZ::EarlyWithFBFetch;
       fbfetch_blend |= static_cast<bool>(out.blending_state.blendenable);
       ps->no_dual_src = true;
     }
-    fbfetch_blend |= blend.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp;
-    fbfetch_blend |= blend.usedualsrc && !g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
+    fbfetch_blend |= blend.logicopenable && !g_backend_info.bSupportsLogicOp;
+    fbfetch_blend |= blend.usedualsrc && !g_backend_info.bSupportsDualSourceBlend;
     if (fbfetch_blend)
     {
       ps->no_dual_src = true;
@@ -685,13 +684,13 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
   }
 
   // force dual src off if we can't support it
-  if (!g_ActiveConfig.backend_info.bSupportsDualSourceBlend)
+  if (!g_backend_info.bSupportsDualSourceBlend)
   {
     ps->no_dual_src = true;
     blend.usedualsrc = false;
   }
 
-  if (ps->ztest == EmulatedZ::ForcedEarly && !g_ActiveConfig.backend_info.bSupportsEarlyZ)
+  if (ps->ztest == EmulatedZ::ForcedEarly && !g_backend_info.bSupportsEarlyZ)
   {
     // These things should be false
     ASSERT(!ps->zfreeze);
@@ -727,9 +726,8 @@ static GXPipelineUid ApplyDriverBugs(const GXPipelineUid& in)
       vs->vs_expand = VSExpand::Point;
     else
       vs->vs_expand = VSExpand::Line;
-    PrimitiveType prim = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ?
-                             PrimitiveType::TriangleStrip :
-                             PrimitiveType::Triangles;
+    PrimitiveType prim = g_backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
+                                                                    PrimitiveType::Triangles;
     out.rasterization_state.primitive = prim;
     out.gs_uid.GetUidData()->primitive_type = static_cast<u32>(prim);
   }
@@ -785,13 +783,13 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
   // GXUberPipelineUid is not trivially copyable because RasterizationState and BlendingState aren't
   // either, but we can pretend it is for now. This will be improved after PR #10848 is finished.
   memcpy(static_cast<void*>(&out), static_cast<const void*>(&in), sizeof(out));  // Copy padding
-  if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
+  if (g_backend_info.bSupportsDynamicVertexLoader)
     out.vertex_format = nullptr;
 
   // If framebuffer fetch is available, we can emulate logic ops in the fragment shader
   // and don't need the below blend approximation
-  if (out.blending_state.logicopenable && !g_ActiveConfig.backend_info.bSupportsLogicOp &&
-      !g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
+  if (out.blending_state.logicopenable && !g_backend_info.bSupportsLogicOp &&
+      !g_backend_info.bSupportsFramebufferFetch)
   {
     if (!out.blending_state.LogicOpApproximationIsExact())
       WARN_LOG_FMT(VIDEO,
@@ -799,7 +797,7 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
     out.blending_state.ApproximateLogicOpWithBlending();
   }
 
-  if (g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
+  if (g_backend_info.bSupportsFramebufferFetch)
   {
     // Always blend in shader
     out.blending_state.hex = 0;
@@ -807,7 +805,7 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
     out.blending_state.alphaupdate = in.blending_state.alphaupdate.Value();
     out.ps_uid.GetUidData()->no_dual_src = true;
   }
-  else if (!g_ActiveConfig.backend_info.bSupportsDualSourceBlend ||
+  else if (!g_backend_info.bSupportsDualSourceBlend ||
            (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) &&
             !out.blending_state.RequiresDualSrc()))
   {
@@ -818,9 +816,8 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
   if (g_ActiveConfig.UseVSForLinePointExpand())
   {
     // All primitives are expanded to triangles in the vertex shader
-    PrimitiveType prim = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ?
-                             PrimitiveType::TriangleStrip :
-                             PrimitiveType::Triangles;
+    PrimitiveType prim = g_backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
+                                                                    PrimitiveType::Triangles;
     out.rasterization_state.primitive = prim;
     out.gs_uid.GetUidData()->primitive_type = static_cast<u32>(prim);
   }
@@ -1345,7 +1342,7 @@ void ShaderCache::QueueUberShaderPipelines()
         }
         BlendingState blend = RenderState::GetNoBlendingBlendState();
         QueueDummyPipeline(vuid, guid, cleared_puid, blend);
-        if (g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader)
+        if (g_backend_info.bSupportsDynamicVertexLoader)
         {
           // Not all GPUs need all the pipeline state compiled into shaders, so they tend to key
           // compiled shaders based on some subset of the pipeline state.
diff --git a/Source/Core/VideoCommon/ShaderGenCommon.cpp b/Source/Core/VideoCommon/ShaderGenCommon.cpp
index d132847f14..ec251c3cce 100644
--- a/Source/Core/VideoCommon/ShaderGenCommon.cpp
+++ b/Source/Core/VideoCommon/ShaderGenCommon.cpp
@@ -16,38 +16,37 @@ ShaderHostConfig ShaderHostConfig::GetCurrent()
 {
   ShaderHostConfig bits = {};
   bits.msaa = g_ActiveConfig.iMultisamples > 1;
-  bits.ssaa = g_ActiveConfig.iMultisamples > 1 && g_ActiveConfig.bSSAA &&
-              g_ActiveConfig.backend_info.bSupportsSSAA;
+  bits.ssaa =
+      g_ActiveConfig.iMultisamples > 1 && g_ActiveConfig.bSSAA && g_backend_info.bSupportsSSAA;
   bits.stereo = g_ActiveConfig.stereo_mode != StereoMode::Off;
   bits.wireframe = g_ActiveConfig.bWireFrame;
   bits.per_pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
   bits.vertex_rounding = g_ActiveConfig.UseVertexRounding();
   bits.fast_depth_calc = g_ActiveConfig.bFastDepthCalc;
   bits.bounding_box = g_ActiveConfig.bBBoxEnable;
-  bits.backend_dual_source_blend = g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
-  bits.backend_geometry_shaders = g_ActiveConfig.backend_info.bSupportsGeometryShaders;
-  bits.backend_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ;
-  bits.backend_bbox = g_ActiveConfig.backend_info.bSupportsBBox;
-  bits.backend_gs_instancing = g_ActiveConfig.backend_info.bSupportsGSInstancing;
-  bits.backend_clip_control = g_ActiveConfig.backend_info.bSupportsClipControl;
-  bits.backend_ssaa = g_ActiveConfig.backend_info.bSupportsSSAA;
-  bits.backend_atomics = g_ActiveConfig.backend_info.bSupportsFragmentStoresAndAtomics;
-  bits.backend_depth_clamp = g_ActiveConfig.backend_info.bSupportsDepthClamp;
-  bits.backend_reversed_depth_range = g_ActiveConfig.backend_info.bSupportsReversedDepthRange;
-  bits.backend_bitfield = g_ActiveConfig.backend_info.bSupportsBitfield;
-  bits.backend_dynamic_sampler_indexing =
-      g_ActiveConfig.backend_info.bSupportsDynamicSamplerIndexing;
-  bits.backend_shader_framebuffer_fetch = g_ActiveConfig.backend_info.bSupportsFramebufferFetch;
-  bits.backend_logic_op = g_ActiveConfig.backend_info.bSupportsLogicOp;
-  bits.backend_palette_conversion = g_ActiveConfig.backend_info.bSupportsPaletteConversion;
+  bits.backend_dual_source_blend = g_backend_info.bSupportsDualSourceBlend;
+  bits.backend_geometry_shaders = g_backend_info.bSupportsGeometryShaders;
+  bits.backend_early_z = g_backend_info.bSupportsEarlyZ;
+  bits.backend_bbox = g_backend_info.bSupportsBBox;
+  bits.backend_gs_instancing = g_backend_info.bSupportsGSInstancing;
+  bits.backend_clip_control = g_backend_info.bSupportsClipControl;
+  bits.backend_ssaa = g_backend_info.bSupportsSSAA;
+  bits.backend_atomics = g_backend_info.bSupportsFragmentStoresAndAtomics;
+  bits.backend_depth_clamp = g_backend_info.bSupportsDepthClamp;
+  bits.backend_reversed_depth_range = g_backend_info.bSupportsReversedDepthRange;
+  bits.backend_bitfield = g_backend_info.bSupportsBitfield;
+  bits.backend_dynamic_sampler_indexing = g_backend_info.bSupportsDynamicSamplerIndexing;
+  bits.backend_shader_framebuffer_fetch = g_backend_info.bSupportsFramebufferFetch;
+  bits.backend_logic_op = g_backend_info.bSupportsLogicOp;
+  bits.backend_palette_conversion = g_backend_info.bSupportsPaletteConversion;
   bits.enable_validation_layer = g_ActiveConfig.bEnableValidationLayer;
   bits.manual_texture_sampling = !g_ActiveConfig.bFastTextureSampling;
   bits.manual_texture_sampling_custom_texture_sizes =
       g_ActiveConfig.ManualTextureSamplingWithCustomTextureSizes();
-  bits.backend_sampler_lod_bias = g_ActiveConfig.backend_info.bSupportsLodBiasInSampler;
-  bits.backend_dynamic_vertex_loader = g_ActiveConfig.backend_info.bSupportsDynamicVertexLoader;
+  bits.backend_sampler_lod_bias = g_backend_info.bSupportsLodBiasInSampler;
+  bits.backend_dynamic_vertex_loader = g_backend_info.bSupportsDynamicVertexLoader;
   bits.backend_vs_point_line_expand = g_ActiveConfig.UseVSForLinePointExpand();
-  bits.backend_gl_layer_in_fs = g_ActiveConfig.backend_info.bSupportsGLLayerInFS;
+  bits.backend_gl_layer_in_fs = g_backend_info.bSupportsGLLayerInFS;
   return bits;
 }
 
@@ -348,7 +347,7 @@ const char* GetInterpolationQualifier(bool msaa, bool ssaa, bool in_glsl_interfa
 
   // Without GL_ARB_shading_language_420pack support, the interpolation qualifier must be
   // "centroid in" and not "centroid", even within an interface block.
-  if (in_glsl_interface_block && !g_ActiveConfig.backend_info.bSupportsBindingLayout)
+  if (in_glsl_interface_block && !g_backend_info.bSupportsBindingLayout)
   {
     if (!ssaa)
       return in ? "centroid in" : "centroid out";
diff --git a/Source/Core/VideoCommon/Statistics.cpp b/Source/Core/VideoCommon/Statistics.cpp
index 311455f16d..6326aeed82 100644
--- a/Source/Core/VideoCommon/Statistics.cpp
+++ b/Source/Core/VideoCommon/Statistics.cpp
@@ -73,7 +73,7 @@ void Statistics::Display() const
     ImGui::NextColumn();
   };
 
-  if (g_ActiveConfig.backend_info.api_type == APIType::Nothing)
+  if (g_backend_info.api_type == APIType::Nothing)
   {
     draw_statistic("Objects", "%d", this_frame.num_drawn_objects);
     draw_statistic("Vertices Loaded", "%d", this_frame.num_vertices_loaded);
diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp
index 61882476d7..bbecc6437c 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.cpp
+++ b/Source/Core/VideoCommon/TextureCacheBase.cpp
@@ -285,7 +285,7 @@ bool TextureCacheBase::DidLinkedAssetsChange(const TCacheEntry& entry)
 RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const u8* palette,
                                                     TLUTFormat tlutfmt)
 {
-  DEBUG_ASSERT(g_ActiveConfig.backend_info.bSupportsPaletteConversion);
+  DEBUG_ASSERT(g_backend_info.bSupportsPaletteConversion);
 
   const AbstractPipeline* pipeline = g_shader_cache->GetPaletteConversionPipeline(tlutfmt);
   if (!pipeline)
@@ -404,7 +404,7 @@ void TextureCacheBase::ScaleTextureCacheEntryTo(RcTcacheEntry& entry, u32 new_wi
     return;
   }
 
-  const u32 max = g_ActiveConfig.backend_info.MaxTextureSize;
+  const u32 max = g_backend_info.MaxTextureSize;
   if (max < new_width || max < new_height)
   {
     ERROR_LOG_FMT(VIDEO, "Texture too big, width = {}, height = {}", new_width, new_height);
@@ -1416,7 +1416,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
       // EFB copies have slightly different rules as EFB copy formats have different
       // meanings from texture formats.
       if ((base_hash == entry->hash &&
-           (!texture_info.GetPaletteSize() || g_Config.backend_info.bSupportsPaletteConversion)) ||
+           (!texture_info.GetPaletteSize() || g_backend_info.bSupportsPaletteConversion)) ||
           IsPlayingBackFifologWithBrokenEFBCopies)
       {
         // The texture format in VRAM must match the format that the copy was created with. Some
@@ -1451,7 +1451,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
 
         // TODO: We should check width/height/levels for EFB copies. I'm not sure what effect
         // checking width/height/levels would have.
-        if (!texture_info.GetPaletteSize() || !g_Config.backend_info.bSupportsPaletteConversion)
+        if (!texture_info.GetPaletteSize() || !g_backend_info.bSupportsPaletteConversion)
           return entry;
 
         // Note that we found an unconverted EFB copy, then continue.  We'll
@@ -2239,8 +2239,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(
   // Disadvantage of all methods: Calling this function requires the GPU to perform a pipeline flush
   // which stalls any further CPU processing.
   const bool is_xfb_copy = !is_depth_copy && !isIntensity && dstFormat == EFBCopyFormat::XFB;
-  bool copy_to_vram =
-      g_ActiveConfig.backend_info.bSupportsCopyToVram && !g_ActiveConfig.bDisableCopyToVRAM;
+  bool copy_to_vram = g_backend_info.bSupportsCopyToVram && !g_ActiveConfig.bDisableCopyToVRAM;
   bool copy_to_ram =
       !(is_xfb_copy ? g_ActiveConfig.bSkipXFBCopyToRam : g_ActiveConfig.bSkipEFBCopyToRam) ||
       !copy_to_vram;
@@ -2851,7 +2850,7 @@ bool TextureCacheBase::CreateUtilityTextures()
   if (!m_efb_encoding_framebuffer)
     return false;
 
-  if (g_ActiveConfig.backend_info.bSupportsGPUTextureDecoding)
+  if (g_backend_info.bSupportsGPUTextureDecoding)
   {
     constexpr TextureConfig decoding_texture_config(
         1024, 1024, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage,
diff --git a/Source/Core/VideoCommon/TextureConversionShader.cpp b/Source/Core/VideoCommon/TextureConversionShader.cpp
index 6962daa29b..f18f63ef8c 100644
--- a/Source/Core/VideoCommon/TextureConversionShader.cpp
+++ b/Source/Core/VideoCommon/TextureConversionShader.cpp
@@ -62,7 +62,7 @@ static void WriteHeader(ShaderCode& code, APIType api_type)
              "  float2 clamp_tb;\n"
              "  uint3 filter_coefficients;\n"
              "}};\n");
-  if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+  if (g_backend_info.bSupportsGeometryShaders)
   {
     code.Write("VARYING_LOCATION(0) in VertexData {{\n"
                "  float3 v_tex0;\n"
@@ -124,7 +124,7 @@ static void WriteSampleFunction(ShaderCode& code, const EFBCopyParams& params, A
 
   if (params.depth)
   {
-    if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+    if (!g_backend_info.bSupportsReversedDepthRange)
       code.Write("  tex_sample.x = 1.0 - tex_sample.x;\n");
 
     code.Write("  uint depth = uint(tex_sample.x * 16777216.0);\n"
@@ -1191,7 +1191,7 @@ float4 DecodePixel(int val)
   ss << "  int texel_buffer_offset;\n";
   ss << "};\n";
 
-  if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+  if (g_backend_info.bSupportsGeometryShaders)
   {
     ss << "VARYING_LOCATION(0) in VertexData {\n";
     ss << "  float3 v_tex0;\n";
diff --git a/Source/Core/VideoCommon/TextureConverterShaderGen.cpp b/Source/Core/VideoCommon/TextureConverterShaderGen.cpp
index da2e247a7f..9dcc4385e1 100644
--- a/Source/Core/VideoCommon/TextureConverterShaderGen.cpp
+++ b/Source/Core/VideoCommon/TextureConverterShaderGen.cpp
@@ -69,7 +69,7 @@ ShaderCode GenerateVertexShader(APIType api_type)
   ShaderCode out;
   WriteHeader(api_type, out);
 
-  if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+  if (g_backend_info.bSupportsGeometryShaders)
   {
     out.Write("VARYING_LOCATION(0) out VertexData {{\n"
               "  float3 v_tex0;\n"
@@ -110,7 +110,7 @@ ShaderCode GeneratePixelShader(APIType api_type, const UidData* uid_data)
             mono_depth ? "0.0" : "uv.z");
   if (uid_data->is_depth_copy)
   {
-    if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+    if (!g_backend_info.bSupportsReversedDepthRange)
       out.Write("  tex_sample.x = 1.0 - tex_sample.x;\n");
 
     out.Write("  uint depth = uint(tex_sample.x * 16777216.0);\n"
@@ -123,7 +123,7 @@ ShaderCode GeneratePixelShader(APIType api_type, const UidData* uid_data)
               "}}\n");
   }
 
-  if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
+  if (g_backend_info.bSupportsGeometryShaders)
   {
     out.Write("VARYING_LOCATION(0) in VertexData {{\n"
               "  float3 v_tex0;\n"
diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp
index 21e5905d95..7987887b86 100644
--- a/Source/Core/VideoCommon/VertexManagerBase.cpp
+++ b/Source/Core/VideoCommon/VertexManagerBase.cpp
@@ -156,7 +156,7 @@ DataReader VertexManagerBase::PrepareForAdditionalData(OpcodeDecoder::Primitive
   u32 const needed_vertex_bytes = count * stride + 4;
 
   // We can't merge different kinds of primitives, so we have to flush here
-  PrimitiveType new_primitive_type = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ?
+  PrimitiveType new_primitive_type = g_backend_info.bSupportsPrimitiveRestart ?
                                          primitive_from_gx_pr[primitive] :
                                          primitive_from_gx[primitive];
   if (m_current_primitive_type != new_primitive_type) [[unlikely]]
@@ -243,7 +243,7 @@ u32 VertexManagerBase::GetRemainingIndices(OpcodeDecoder::Primitive primitive) c
   {
     if (g_Config.UseVSForLinePointExpand())
     {
-      if (g_Config.backend_info.bSupportsPrimitiveRestart)
+      if (g_backend_info.bSupportsPrimitiveRestart)
       {
         switch (primitive)
         {
@@ -287,7 +287,7 @@ u32 VertexManagerBase::GetRemainingIndices(OpcodeDecoder::Primitive primitive) c
       }
     }
   }
-  else if (g_Config.backend_info.bSupportsPrimitiveRestart)
+  else if (g_backend_info.bSupportsPrimitiveRestart)
   {
     switch (primitive)
     {
@@ -348,8 +348,7 @@ void VertexManagerBase::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 nu
 void VertexManagerBase::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex)
 {
   // If bounding box is enabled, we need to flush any changes first, then invalidate what we have.
-  if (g_bounding_box->IsEnabled() && g_ActiveConfig.bBBoxEnable &&
-      g_ActiveConfig.backend_info.bSupportsBBox)
+  if (g_bounding_box->IsEnabled() && g_ActiveConfig.bBBoxEnable && g_backend_info.bSupportsBBox)
   {
     g_bounding_box->Flush();
   }
@@ -1090,8 +1089,7 @@ void VertexManagerBase::RenderDrawCall(
                VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(),
                m_index_generator.GetIndexLen(), &base_vertex, &base_index);
 
-  if (g_ActiveConfig.backend_info.api_type != APIType::D3D &&
-      g_ActiveConfig.UseVSForLinePointExpand() &&
+  if (g_backend_info.api_type != APIType::D3D && g_ActiveConfig.UseVSForLinePointExpand() &&
       (primitive_type == PrimitiveType::Points || primitive_type == PrimitiveType::Lines))
   {
     // VS point/line expansion puts the vertex id at gl_VertexID << 2
@@ -1131,7 +1129,7 @@ const AbstractPipeline* VertexManagerBase::GetCustomPipeline(
       {
         // D3D has issues compiling large custom ubershaders
         // use specialized shaders instead
-        if (g_ActiveConfig.backend_info.api_type == APIType::D3D)
+        if (g_backend_info.api_type == APIType::D3D)
         {
           if (auto pipeline = m_custom_shader_cache->GetPipelineAsync(
                   current_pipeline_config, custom_shaders, current_pipeline->m_config))
diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp
index 0415ac05dc..bb3a7f2910 100644
--- a/Source/Core/VideoCommon/VertexShaderManager.cpp
+++ b/Source/Core/VideoCommon/VertexShaderManager.cpp
@@ -140,7 +140,7 @@ void VertexShaderManager::SetProjectionMatrix(XFStateManager& xf_state_manager)
 bool VertexShaderManager::UseVertexDepthRange()
 {
   // We can't compute the depth range in the vertex shader if we don't support depth clamp.
-  if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
+  if (!g_backend_info.bSupportsDepthClamp)
     return false;
 
   // We need a full depth range if a ztexture is used.
@@ -148,7 +148,7 @@ bool VertexShaderManager::UseVertexDepthRange()
     return true;
 
   // If an inverted depth range is unsupported, we also need to check if the range is inverted.
-  if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+  if (!g_backend_info.bSupportsReversedDepthRange)
   {
     if (xfmem.viewport.zRange < 0.0f)
       return true;
@@ -370,7 +370,7 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures,
     {
       // Oversized depth ranges are handled in the vertex shader. We need to reverse
       // the far value to use the reversed-Z trick.
-      if (g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
+      if (g_backend_info.bSupportsReversedDepthRange)
       {
         // Sometimes the console also tries to use the reversed-Z trick. We can only do
         // that with the expected accuracy if the backend can reverse the depth range.
diff --git a/Source/Core/VideoCommon/VideoBackendBase.cpp b/Source/Core/VideoCommon/VideoBackendBase.cpp
index e8f9f91b41..271e8c74ff 100644
--- a/Source/Core/VideoCommon/VideoBackendBase.cpp
+++ b/Source/Core/VideoCommon/VideoBackendBase.cpp
@@ -187,7 +187,7 @@ u16 VideoBackendBase::Video_GetBoundingBox(int index)
     }
     warn_once = false;
   }
-  else if (!g_ActiveConfig.backend_info.bSupportsBBox)
+  else if (!g_backend_info.bSupportsBBox)
   {
     static bool warn_once = true;
     if (warn_once)
@@ -298,9 +298,9 @@ void VideoBackendBase::PopulateBackendInfo(const WindowSystemInfo& wsi)
   g_Config.Refresh();
   // Reset backend_info so if the backend forgets to initialize something it doesn't end up using
   // a value from the previously used renderer
-  g_Config.backend_info = {};
+  g_backend_info = {};
   ActivateBackend(Config::Get(Config::MAIN_GFX_BACKEND));
-  g_Config.backend_info.DisplayName = g_video_backend->GetDisplayName();
+  g_backend_info.DisplayName = g_video_backend->GetDisplayName();
   g_video_backend->InitBackendInfo(wsi);
   // We validate the config after initializing the backend info, as system-specific settings
   // such as anti-aliasing, or the selected adapter may be invalid, and should be checked.
@@ -372,7 +372,7 @@ bool VideoBackendBase::InitializeShared(std::unique_ptr<AbstractGfx> gfx,
   if (!g_vertex_manager->Initialize() || !g_shader_cache->Initialize() ||
       !g_perf_query->Initialize() || !g_presenter->Initialize() ||
       !g_framebuffer_manager->Initialize() || !g_texture_cache->Initialize() ||
-      (g_ActiveConfig.backend_info.bSupportsBBox && !g_bounding_box->Initialize()) ||
+      (g_backend_info.bSupportsBBox && !g_bounding_box->Initialize()) ||
       !g_graphics_mod_manager->Initialize())
   {
     PanicAlertFmtT("Failed to initialize renderer classes");
diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp
index 81e4c9cb05..0dec193b7a 100644
--- a/Source/Core/VideoCommon/VideoConfig.cpp
+++ b/Source/Core/VideoCommon/VideoConfig.cpp
@@ -8,7 +8,6 @@
 #include "Common/CPUDetect.h"
 #include "Common/CommonTypes.h"
 #include "Common/Contains.h"
-#include "Common/StringUtil.h"
 
 #include "Core/CPUThreadConfigCallback.h"
 #include "Core/Config/GraphicsSettings.h"
@@ -24,19 +23,16 @@
 #include "VideoCommon/Fifo.h"
 #include "VideoCommon/FramebufferManager.h"
 #include "VideoCommon/FreeLookCamera.h"
-#include "VideoCommon/GraphicsModSystem/Config/GraphicsMod.h"
 #include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
 #include "VideoCommon/OnScreenDisplay.h"
 #include "VideoCommon/PixelShaderManager.h"
-#include "VideoCommon/Present.h"
 #include "VideoCommon/ShaderGenCommon.h"
 #include "VideoCommon/TextureCacheBase.h"
 #include "VideoCommon/VertexManagerBase.h"
 
-#include "VideoCommon/VideoCommon.h"
-
 VideoConfig g_Config;
 VideoConfig g_ActiveConfig;
+BackendInfo g_backend_info;
 static bool s_has_registered_callback = false;
 
 static bool IsVSyncActive(bool enabled)
@@ -213,15 +209,15 @@ void VideoConfig::Refresh()
 void VideoConfig::VerifyValidity()
 {
   // TODO: Check iMaxAnisotropy value
-  if (iAdapter < 0 || iAdapter > ((int)backend_info.Adapters.size() - 1))
+  if (iAdapter < 0 || iAdapter > ((int)g_backend_info.Adapters.size() - 1))
     iAdapter = 0;
 
-  if (!Common::Contains(backend_info.AAModes, iMultisamples))
+  if (!Common::Contains(g_backend_info.AAModes, iMultisamples))
     iMultisamples = 1;
 
   if (stereo_mode != StereoMode::Off)
   {
-    if (!backend_info.bSupportsGeometryShaders)
+    if (!g_backend_info.bSupportsGeometryShaders)
     {
       OSD::AddMessage(
           "Stereoscopic 3D isn't supported by your GPU, support for OpenGL 3.2 is required.",
@@ -253,7 +249,7 @@ static u32 GetNumAutoShaderPreCompilerThreads()
 
 u32 VideoConfig::GetShaderCompilerThreads() const
 {
-  if (!backend_info.bSupportsBackgroundCompiling)
+  if (!g_backend_info.bSupportsBackgroundCompiling)
     return 0;
 
   if (iShaderCompilerThreads >= 0)
@@ -268,7 +264,7 @@ u32 VideoConfig::GetShaderPrecompilerThreads() const
   if (!bWaitForShadersBeforeStarting)
     return GetShaderCompilerThreads();
 
-  if (!backend_info.bSupportsBackgroundCompiling)
+  if (!g_backend_info.bSupportsBackgroundCompiling)
     return 0;
 
   if (iShaderPrecompilerThreads >= 0)
diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h
index 5076561fd0..9e7bf950a2 100644
--- a/Source/Core/VideoCommon/VideoConfig.h
+++ b/Source/Core/VideoCommon/VideoConfig.h
@@ -113,6 +113,67 @@ enum ConfigChangeBits : u32
   CONFIG_CHANGE_BIT_HDR = (1 << 10),
 };
 
+// Static config per API
+struct BackendInfo
+{
+  APIType api_type = APIType::Nothing;
+  std::string DisplayName;
+
+  std::vector<std::string> Adapters;  // for D3D
+  std::vector<u32> AAModes;
+
+  // TODO: merge AdapterName and Adapters array
+  std::string AdapterName;  // for OpenGL
+
+  u32 MaxTextureSize = 16384;
+  bool bUsesLowerLeftOrigin = false;
+  bool bUsesExplictQuadBuffering = false;
+  bool bSupportsExclusiveFullscreen = false;  // Note: Vulkan can change this at runtime.
+  bool bSupportsDualSourceBlend = false;
+  bool bSupportsPrimitiveRestart = false;
+  bool bSupportsGeometryShaders = false;
+  bool bSupportsComputeShaders = false;
+  bool bSupports3DVision = false;
+  bool bSupportsEarlyZ = false;         // needed by PixelShaderGen, so must stay in VideoCommon
+  bool bSupportsBindingLayout = false;  // Needed by ShaderGen, so must stay in VideoCommon
+  bool bSupportsBBox = false;
+  bool bSupportsGSInstancing = false;  // Needed by GeometryShaderGen, so must stay in VideoCommon
+  bool bSupportsPostProcessing = false;
+  bool bSupportsPaletteConversion = false;
+  bool bSupportsClipControl = false;  // Needed by VertexShaderGen, so must stay in VideoCommon
+  bool bSupportsSSAA = false;
+  bool bSupportsFragmentStoresAndAtomics = false;  // a.k.a. OpenGL SSBOs a.k.a. Direct3D UAVs
+  bool bSupportsDepthClamp = false;  // Needed by VertexShaderGen, so must stay in VideoCommon
+  bool bSupportsReversedDepthRange = false;
+  bool bSupportsLogicOp = false;
+  bool bSupportsMultithreading = false;
+  bool bSupportsGPUTextureDecoding = false;
+  bool bSupportsST3CTextures = false;
+  bool bSupportsCopyToVram = false;
+  bool bSupportsBitfield = false;  // Needed by UberShaders, so must stay in VideoCommon
+  // Needed by UberShaders, so must stay in VideoCommon
+  bool bSupportsDynamicSamplerIndexing = false;
+  bool bSupportsBPTCTextures = false;
+  bool bSupportsFramebufferFetch = false;  // Used as an alternative to dual-source blend on GLES
+  bool bSupportsBackgroundCompiling = false;
+  bool bSupportsLargePoints = false;
+  bool bSupportsPartialDepthCopies = false;
+  bool bSupportsDepthReadback = false;
+  bool bSupportsShaderBinaries = false;
+  bool bSupportsPipelineCacheData = false;
+  bool bSupportsCoarseDerivatives = false;
+  bool bSupportsTextureQueryLevels = false;
+  bool bSupportsLodBiasInSampler = false;
+  bool bSupportsSettingObjectNames = false;
+  bool bSupportsPartialMultisampleResolve = false;
+  bool bSupportsDynamicVertexLoader = false;
+  bool bSupportsVSLinePointExpand = false;
+  bool bSupportsGLLayerInFS = true;
+  bool bSupportsHDROutput = false;
+};
+
+extern BackendInfo g_backend_info;
+
 // NEVER inherit from this class.
 struct VideoConfig final
 {
@@ -289,84 +350,23 @@ struct VideoConfig final
   // Vertex loader
   VertexLoaderType vertex_loader_type;
 
-  // Static config per API
-  // TODO: Move this out of VideoConfig
-  struct
-  {
-    APIType api_type = APIType::Nothing;
-    std::string DisplayName;
-
-    std::vector<std::string> Adapters;  // for D3D
-    std::vector<u32> AAModes;
-
-    // TODO: merge AdapterName and Adapters array
-    std::string AdapterName;  // for OpenGL
-
-    u32 MaxTextureSize = 16384;
-    bool bUsesLowerLeftOrigin = false;
-    bool bUsesExplictQuadBuffering = false;
-
-    bool bSupportsExclusiveFullscreen = false;
-    bool bSupportsDualSourceBlend = false;
-    bool bSupportsPrimitiveRestart = false;
-    bool bSupportsGeometryShaders = false;
-    bool bSupportsComputeShaders = false;
-    bool bSupports3DVision = false;
-    bool bSupportsEarlyZ = false;         // needed by PixelShaderGen, so must stay in VideoCommon
-    bool bSupportsBindingLayout = false;  // Needed by ShaderGen, so must stay in VideoCommon
-    bool bSupportsBBox = false;
-    bool bSupportsGSInstancing = false;  // Needed by GeometryShaderGen, so must stay in VideoCommon
-    bool bSupportsPostProcessing = false;
-    bool bSupportsPaletteConversion = false;
-    bool bSupportsClipControl = false;  // Needed by VertexShaderGen, so must stay in VideoCommon
-    bool bSupportsSSAA = false;
-    bool bSupportsFragmentStoresAndAtomics = false;  // a.k.a. OpenGL SSBOs a.k.a. Direct3D UAVs
-    bool bSupportsDepthClamp = false;  // Needed by VertexShaderGen, so must stay in VideoCommon
-    bool bSupportsReversedDepthRange = false;
-    bool bSupportsLogicOp = false;
-    bool bSupportsMultithreading = false;
-    bool bSupportsGPUTextureDecoding = false;
-    bool bSupportsST3CTextures = false;
-    bool bSupportsCopyToVram = false;
-    bool bSupportsBitfield = false;  // Needed by UberShaders, so must stay in VideoCommon
-    // Needed by UberShaders, so must stay in VideoCommon
-    bool bSupportsDynamicSamplerIndexing = false;
-    bool bSupportsBPTCTextures = false;
-    bool bSupportsFramebufferFetch = false;  // Used as an alternative to dual-source blend on GLES
-    bool bSupportsBackgroundCompiling = false;
-    bool bSupportsLargePoints = false;
-    bool bSupportsPartialDepthCopies = false;
-    bool bSupportsDepthReadback = false;
-    bool bSupportsShaderBinaries = false;
-    bool bSupportsPipelineCacheData = false;
-    bool bSupportsCoarseDerivatives = false;
-    bool bSupportsTextureQueryLevels = false;
-    bool bSupportsLodBiasInSampler = false;
-    bool bSupportsSettingObjectNames = false;
-    bool bSupportsPartialMultisampleResolve = false;
-    bool bSupportsDynamicVertexLoader = false;
-    bool bSupportsVSLinePointExpand = false;
-    bool bSupportsGLLayerInFS = true;
-    bool bSupportsHDROutput = false;
-  } backend_info;
-
   // Utility
   bool UseVSForLinePointExpand() const
   {
-    if (!backend_info.bSupportsVSLinePointExpand)
+    if (!g_backend_info.bSupportsVSLinePointExpand)
       return false;
-    if (!backend_info.bSupportsGeometryShaders)
+    if (!g_backend_info.bSupportsGeometryShaders)
       return true;
     return bPreferVSForLinePointExpansion;
   }
   bool MultisamplingEnabled() const { return iMultisamples > 1; }
   bool ExclusiveFullscreenEnabled() const
   {
-    return backend_info.bSupportsExclusiveFullscreen && !bBorderlessFullscreen;
+    return g_backend_info.bSupportsExclusiveFullscreen && !bBorderlessFullscreen;
   }
   bool UseGPUTextureDecoding() const
   {
-    return backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding;
+    return g_backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding;
   }
   bool UseVertexRounding() const { return bVertexRounding && iEFBScale != 1; }
   bool ManualTextureSamplingWithCustomTextureSizes() const