Skip to content

Commit

Permalink
GS/Vulkan: Prefer mailbox presentation for vsync-on
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed May 23, 2024
1 parent 68bbc2c commit 99e38bc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 24 deletions.
46 changes: 22 additions & 24 deletions pcsx2/GS/Renderers/Vulkan/VKSwapChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "GS/Renderers/Vulkan/GSDeviceVK.h"
#include "GS/Renderers/Vulkan/VKBuilders.h"
#include "GS/Renderers/Vulkan/VKSwapChain.h"
#include "VMManager.h"

#include "common/Assertions.h"
#include "common/CocoaTools.h"
Expand Down Expand Up @@ -250,28 +251,22 @@ std::optional<VkPresentModeKHR> VKSwapChain::SelectPresentMode(VkSurfaceKHR surf
return it != present_modes.end();
};

// Use preferred mode if available.
VkPresentModeKHR selected_mode;
if (CheckForMode(requested_mode))
{
selected_mode = requested_mode;
}
else if (requested_mode != VK_PRESENT_MODE_FIFO_KHR && CheckForMode(VK_PRESENT_MODE_MAILBOX_KHR))
{
// Prefer mailbox over fifo for adaptive vsync/no-vsync. This way it'll only delay one frame.
selected_mode = VK_PRESENT_MODE_MAILBOX_KHR;
}
else if (requested_mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR && CheckForMode(VK_PRESENT_MODE_FIFO_KHR))
{
// Fallback to FIFO if we're using any kind of vsync.
// This should never fail, FIFO is mandated.
selected_mode = VK_PRESENT_MODE_FIFO_KHR;
}
else
{
// Fall back to whatever is available.
selected_mode = present_modes[0];
}
// Use preferred mode if available.
VkPresentModeKHR selected_mode;
if (CheckForMode(requested_mode))
{
selected_mode = requested_mode;
}
else if (requested_mode == VK_PRESENT_MODE_IMMEDIATE_KHR && CheckForMode(VK_PRESENT_MODE_MAILBOX_KHR))
{
// Prefer mailbox over FIFO for vsync-off, since we don't want to block.
selected_mode = VK_PRESENT_MODE_MAILBOX_KHR;
}
else
{
// Fallback to FIFO if we we can't use mailbox. This should never fail, FIFO is mandated.
selected_mode = VK_PRESENT_MODE_FIFO_KHR;
}

DevCon.WriteLn("(SwapChain) Preferred present mode: %s, selected: %s", PresentModeToString(requested_mode),
PresentModeToString(selected_mode));
Expand All @@ -284,9 +279,12 @@ bool VKSwapChain::CreateSwapChain()
// Select swap chain format and present mode
std::optional<VkSurfaceFormatKHR> surface_format = SelectSurfaceFormat(m_surface);

// Prefer relaxed vsync if available, stalling is bad.
// Prefer mailbox if not syncing to host refresh, because that requires "real" vsync.
const VkPresentModeKHR requested_mode =
m_vsync_enabled ? VK_PRESENT_MODE_FIFO_RELAXED_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR;
m_vsync_enabled ? (VMManager::IsUsingVSyncForTiming() ?
VK_PRESENT_MODE_FIFO_KHR :
VK_PRESENT_MODE_MAILBOX_KHR) :
VK_PRESENT_MODE_IMMEDIATE_KHR;
std::optional<VkPresentModeKHR> present_mode = SelectPresentMode(m_surface, requested_mode);
if (!surface_format.has_value() || !present_mode.has_value())
return false;
Expand Down
5 changes: 5 additions & 0 deletions pcsx2/VMManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2105,6 +2105,11 @@ bool VMManager::IsTargetSpeedAdjustedToHost()
return s_target_speed_synced_to_host;
}

bool VMManager::IsUsingVSyncForTiming()
{
return s_use_vsync_for_timing;
}

float VMManager::GetFrameRate()
{
return GetVerticalFrequency();
Expand Down
3 changes: 3 additions & 0 deletions pcsx2/VMManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ namespace VMManager
/// Returns true if the target speed is being synchronized with the host's refresh rate.
bool IsTargetSpeedAdjustedToHost();

/// Returns true if host vsync is being used for frame timing/pacing, and not its internal throttler.
bool IsUsingVSyncForTiming();

/// Returns the current frame rate of the virtual machine.
float GetFrameRate();

Expand Down

0 comments on commit 99e38bc

Please sign in to comment.