GPUDevice: Add support for VRR and relaxed vsync

This commit is contained in:
Stenzek
2024-03-03 12:25:37 +10:00
parent d9e496284f
commit a1d7d214cf
27 changed files with 474 additions and 364 deletions

View File

@ -233,7 +233,8 @@ bool D3D11Device::CreateSwapChain()
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swap_chain_desc.SwapEffect = m_using_flip_model_swap_chain ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD;
m_using_allow_tearing = (m_allow_tearing_supported && m_using_flip_model_swap_chain && !m_is_exclusive_fullscreen);
m_using_allow_tearing =
(m_allow_tearing_supported && m_using_flip_model_swap_chain && !m_is_exclusive_fullscreen);
if (m_using_allow_tearing)
swap_chain_desc.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
@ -600,11 +601,6 @@ bool D3D11Device::GetHostRefreshRate(float* refresh_rate)
return GPUDevice::GetHostRefreshRate(refresh_rate);
}
void D3D11Device::SetVSync(bool enabled)
{
m_vsync_enabled = enabled;
}
bool D3D11Device::BeginPresent(bool skip_present)
{
if (skip_present)
@ -633,7 +629,7 @@ bool D3D11Device::BeginPresent(bool skip_present)
// This blows our our GPU usage number considerably, so read the timestamp before the final blit
// in this configuration. It does reduce accuracy a little, but better than seeing 100% all of
// the time, when it's more like a couple of percent.
if (m_vsync_enabled && m_gpu_timing_enabled)
if ((m_sync_mode == DisplaySyncMode::VSync || m_sync_mode == DisplaySyncMode::VSyncRelaxed) && m_gpu_timing_enabled)
PopTimestampQuery();
static constexpr float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
@ -650,13 +646,16 @@ void D3D11Device::EndPresent()
{
DebugAssert(m_num_current_render_targets == 0 && !m_current_depth_target);
if (!m_vsync_enabled && m_gpu_timing_enabled)
if (m_sync_mode != DisplaySyncMode::VSync && m_sync_mode != DisplaySyncMode::VSyncRelaxed && m_gpu_timing_enabled)
PopTimestampQuery();
if (!m_vsync_enabled && m_using_allow_tearing)
// DirectX has no concept of tear-or-sync. I guess if we measured times ourselves, we could implement it.
if (m_sync_mode == DisplaySyncMode::VSync || m_sync_mode == DisplaySyncMode::VSyncRelaxed)
m_swap_chain->Present(BoolToUInt32(1), 0);
else if (m_using_allow_tearing) // Disabled or VRR, VRR requires the allow tearing flag :/
m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
else
m_swap_chain->Present(BoolToUInt32(m_vsync_enabled), 0);
m_swap_chain->Present(0, 0);
if (m_gpu_timing_enabled)
KickTimestampQuery();