diff --git a/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp b/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp
index eac83237b2..996daa206d 100644
--- a/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp
+++ b/pcsx2-qt/Settings/GraphicsSettingsWidget.cpp
@@ -226,6 +226,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useBlitSwapChain, "EmuCore/GS", "UseBlitSwapChain", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useDebugDevice, "EmuCore/GS", "UseDebugDevice", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.skipPresentingDuplicateFrames, "EmuCore/GS", "SkipDuplicateFrames", false);
+ SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableMailboxPresentation, "EmuCore/GS", "DisableMailboxPresentation", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.threadedPresentation, "EmuCore/GS", "DisableThreadedPresentation", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.exclusiveFullscreenControl, "EmuCore/GS", "ExclusiveFullscreenControl", -1, -1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overrideTextureBarriers, "EmuCore/GS", "OverrideTextureBarriers", -1, -1);
@@ -332,6 +333,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
m_ui.gsDumpCompression = nullptr;
m_ui.exclusiveFullscreenControl = nullptr;
m_ui.useBlitSwapChain = nullptr;
+ m_ui.disableMailboxPresentation = nullptr;
m_ui.skipPresentingDuplicateFrames = nullptr;
m_ui.threadedPresentation = nullptr;
m_ui.overrideTextureBarriers = nullptr;
@@ -761,6 +763,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
"fluctuations when the CPU/GPU are near maximum utilization, but makes frame pacing more inconsistent and can increase "
"input lag."));
+ dialog->registerWidgetHelp(m_ui.disableMailboxPresentation, tr("Disable Mailbox Presentation"), tr("Unchecked"),
+ tr("Forces the use of FIFO over Mailbox presentation, i.e. double buffering instead of triple buffering. "
+ "Usually results in worse frame pacing."));
+
dialog->registerWidgetHelp(m_ui.threadedPresentation, tr("Disable Threaded Presentation"), tr("Unchecked"),
tr("Presents frames on the main GS thread instead of a worker thread. Used for debugging frametime issues. "
"Could reduce chance of missing a frame or reduce tearing at the expense of more erratic frame times. "
diff --git a/pcsx2-qt/Settings/GraphicsSettingsWidget.ui b/pcsx2-qt/Settings/GraphicsSettingsWidget.ui
index aff4e41564..350e8db764 100644
--- a/pcsx2-qt/Settings/GraphicsSettingsWidget.ui
+++ b/pcsx2-qt/Settings/GraphicsSettingsWidget.ui
@@ -2058,6 +2058,13 @@
+ -
+
+
+ Disable Mailbox Presentation
+
+
+
-
diff --git a/pcsx2/Config.h b/pcsx2/Config.h
index 2ad5df8e2b..acc30a64cd 100644
--- a/pcsx2/Config.h
+++ b/pcsx2/Config.h
@@ -591,6 +591,7 @@ struct Pcsx2Config
bool
SynchronousMTGS : 1,
VsyncEnable : 1,
+ DisableMailboxPresentation : 1,
PCRTCAntiBlur : 1,
DisableInterlaceOffset : 1,
PCRTCOffsets : 1,
diff --git a/pcsx2/ImGui/FullscreenUI.cpp b/pcsx2/ImGui/FullscreenUI.cpp
index cd63060eb4..394539a7e0 100644
--- a/pcsx2/ImGui/FullscreenUI.cpp
+++ b/pcsx2/ImGui/FullscreenUI.cpp
@@ -3903,6 +3903,10 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
DrawToggleSetting(bsi, FSUI_CSTR("Disable Threaded Presentation"),
FSUI_CSTR("Presents frames on the main GS thread instead of a worker thread. Used for debugging frametime issues."),
"EmuCore/GS", "DisableThreadedPresentation", false);
+ DrawToggleSetting(bsi, FSUI_CSTR("Disable Mailbox Presentation"),
+ FSUI_CSTR("Forces the use of FIFO over Mailbox presentation, i.e. double buffering instead of triple buffering. "
+ "Usually results in worse frame pacing."),
+ "EmuCore/GS", "DisableMailboxPresentation", false);
if (IsEditingGameSettings(bsi))
{
DrawIntListSetting(bsi, FSUI_CSTR("Hardware Download Mode"), FSUI_CSTR("Changes synchronization behavior for GS downloads."),
@@ -6953,12 +6957,14 @@ TRANSLATE_NOOP("FullscreenUI", "Maximum Frame Latency");
TRANSLATE_NOOP("FullscreenUI", "Sets the number of frames which can be queued.");
TRANSLATE_NOOP("FullscreenUI", "Optimal Frame Pacing");
TRANSLATE_NOOP("FullscreenUI", "Synchronize EE and GS threads after each frame. Lowest input latency, but increases system requirements.");
-TRANSLATE_NOOP("FullscreenUI", "Scale To Host Refresh Rate");
+TRANSLATE_NOOP("FullscreenUI", "Vertical Sync (VSync)");
+TRANSLATE_NOOP("FullscreenUI", "Synchronizes frame presentation with host refresh.");
+TRANSLATE_NOOP("FullscreenUI", "Sync to Host Refresh Rate");
TRANSLATE_NOOP("FullscreenUI", "Speeds up emulation so that the guest refresh rate matches the host.");
+TRANSLATE_NOOP("FullscreenUI", "Use Host VSync Timing");
+TRANSLATE_NOOP("FullscreenUI", "Disables PCSX2's internal frame timing, and uses host vsync instead.");
TRANSLATE_NOOP("FullscreenUI", "Renderer");
TRANSLATE_NOOP("FullscreenUI", "Selects the API used to render the emulated GS.");
-TRANSLATE_NOOP("FullscreenUI", "Sync To Host Refresh (VSync)");
-TRANSLATE_NOOP("FullscreenUI", "Synchronizes frame presentation with host refresh.");
TRANSLATE_NOOP("FullscreenUI", "Display");
TRANSLATE_NOOP("FullscreenUI", "Aspect Ratio");
TRANSLATE_NOOP("FullscreenUI", "Selects the aspect ratio to display the game content at.");
@@ -6994,8 +7000,6 @@ TRANSLATE_NOOP("FullscreenUI", "Enables internal Anti-Blur hacks. Less accurate
TRANSLATE_NOOP("FullscreenUI", "Rendering");
TRANSLATE_NOOP("FullscreenUI", "Internal Resolution");
TRANSLATE_NOOP("FullscreenUI", "Multiplies the render resolution by the specified factor (upscaling).");
-TRANSLATE_NOOP("FullscreenUI", "Mipmapping");
-TRANSLATE_NOOP("FullscreenUI", "Determines how mipmaps are used when rendering textures.");
TRANSLATE_NOOP("FullscreenUI", "Bilinear Filtering");
TRANSLATE_NOOP("FullscreenUI", "Selects where bilinear filtering is utilized when rendering textures.");
TRANSLATE_NOOP("FullscreenUI", "Trilinear Filtering");
@@ -7008,13 +7012,14 @@ TRANSLATE_NOOP("FullscreenUI", "Blending Accuracy");
TRANSLATE_NOOP("FullscreenUI", "Determines the level of accuracy when emulating blend modes not supported by the host graphics API.");
TRANSLATE_NOOP("FullscreenUI", "Texture Preloading");
TRANSLATE_NOOP("FullscreenUI", "Uploads full textures to the GPU on use, rather than only the utilized regions. Can improve performance in some games.");
+TRANSLATE_NOOP("FullscreenUI", "Mipmapping");
+TRANSLATE_NOOP("FullscreenUI", "Enables emulation of the GS's texture mipmapping.");
TRANSLATE_NOOP("FullscreenUI", "Software Rendering Threads");
TRANSLATE_NOOP("FullscreenUI", "Number of threads to use in addition to the main GS thread for rasterization.");
TRANSLATE_NOOP("FullscreenUI", "Auto Flush (Software)");
TRANSLATE_NOOP("FullscreenUI", "Force a primitive flush when a framebuffer is also an input texture.");
TRANSLATE_NOOP("FullscreenUI", "Edge AA (AA1)");
TRANSLATE_NOOP("FullscreenUI", "Enables emulation of the GS's edge anti-aliasing (AA1).");
-TRANSLATE_NOOP("FullscreenUI", "Enables emulation of the GS's texture mipmapping.");
TRANSLATE_NOOP("FullscreenUI", "Hardware Fixes");
TRANSLATE_NOOP("FullscreenUI", "Manual Hardware Fixes");
TRANSLATE_NOOP("FullscreenUI", "Disables automatic hardware fixes, allowing you to set fixes manually.");
@@ -7105,6 +7110,8 @@ TRANSLATE_NOOP("FullscreenUI", "Skip Presenting Duplicate Frames");
TRANSLATE_NOOP("FullscreenUI", "Skips displaying frames that don't change in 25/30fps games. Can improve speed, but increase input lag/make frame pacing worse.");
TRANSLATE_NOOP("FullscreenUI", "Disable Threaded Presentation");
TRANSLATE_NOOP("FullscreenUI", "Presents frames on the main GS thread instead of a worker thread. Used for debugging frametime issues.");
+TRANSLATE_NOOP("FullscreenUI", "Disable Mailbox Presentation");
+TRANSLATE_NOOP("FullscreenUI", "Forces the use of FIFO over Mailbox presentation, i.e. double buffering instead of triple buffering. Usually results in worse frame pacing.");
TRANSLATE_NOOP("FullscreenUI", "Hardware Download Mode");
TRANSLATE_NOOP("FullscreenUI", "Changes synchronization behavior for GS downloads.");
TRANSLATE_NOOP("FullscreenUI", "Allow Exclusive Fullscreen");
@@ -7430,8 +7437,6 @@ TRANSLATE_NOOP("FullscreenUI", "5x Native (~1620p)");
TRANSLATE_NOOP("FullscreenUI", "6x Native (~2160p/4K)");
TRANSLATE_NOOP("FullscreenUI", "7x Native (~2520p)");
TRANSLATE_NOOP("FullscreenUI", "8x Native (~2880p)");
-TRANSLATE_NOOP("FullscreenUI", "Basic (Generated Mipmaps)");
-TRANSLATE_NOOP("FullscreenUI", "Full (PS2 Mipmaps)");
TRANSLATE_NOOP("FullscreenUI", "Nearest");
TRANSLATE_NOOP("FullscreenUI", "Bilinear (Forced)");
TRANSLATE_NOOP("FullscreenUI", "Bilinear (PS2)");
@@ -7441,6 +7446,7 @@ TRANSLATE_NOOP("FullscreenUI", "Trilinear (PS2)");
TRANSLATE_NOOP("FullscreenUI", "Trilinear (Forced)");
TRANSLATE_NOOP("FullscreenUI", "Scaled");
TRANSLATE_NOOP("FullscreenUI", "Unscaled (Default)");
+TRANSLATE_NOOP("FullscreenUI", "Force 32bit");
TRANSLATE_NOOP("FullscreenUI", "Minimum");
TRANSLATE_NOOP("FullscreenUI", "Basic (Recommended)");
TRANSLATE_NOOP("FullscreenUI", "Medium");
diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp
index b2aaf55555..e892f2b791 100644
--- a/pcsx2/Pcsx2Config.cpp
+++ b/pcsx2/Pcsx2Config.cpp
@@ -693,8 +693,6 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
return (
OpEqu(bitset) &&
- OpEqu(VsyncEnable) &&
-
OpEqu(InterlaceMode) &&
OpEqu(LinearPresent) &&
@@ -797,6 +795,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
#endif
SettingsWrapBitBool(VsyncEnable);
+ SettingsWrapBitBool(DisableMailboxPresentation);
SettingsWrapEntry(VsyncQueueSize);
diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp
index a1ad6f1864..f4796f94f3 100644
--- a/pcsx2/VMManager.cpp
+++ b/pcsx2/VMManager.cpp
@@ -2602,8 +2602,11 @@ GSVSyncMode VMManager::GetEffectiveVSyncMode()
// Try to keep the same present mode whether we're running or not, since it'll avoid flicker.
const VMState state = GetState();
const bool valid_vm = (state != VMState::Shutdown && state != VMState::Stopping);
- if (s_target_speed_can_sync_to_host || (!valid_vm && EmuConfig.EmulationSpeed.SyncToHostRefreshRate))
+ if (s_target_speed_can_sync_to_host || (!valid_vm && EmuConfig.EmulationSpeed.SyncToHostRefreshRate) ||
+ EmuConfig.GS.DisableMailboxPresentation)
+ {
return GSVSyncMode::FIFO;
+ }
// For PAL games, we always want to triple buffer, because otherwise we'll be tearing.
// Or for when we aren't using sync-to-host-refresh, to avoid dropping frames.
@@ -2795,7 +2798,8 @@ void VMManager::CheckForGSConfigChanges(const Pcsx2Config& old_config)
UpdateVSyncRate(false);
UpdateTargetSpeed();
}
- else if (EmuConfig.GS.VsyncEnable != old_config.GS.VsyncEnable)
+ else if (EmuConfig.GS.VsyncEnable != old_config.GS.VsyncEnable ||
+ EmuConfig.GS.DisableMailboxPresentation != old_config.GS.DisableMailboxPresentation)
{
// Still need to update target speed, because of sync-to-host-refresh.
UpdateTargetSpeed();