GPU: Further improve vsync handling
This commit is contained in:
@ -201,7 +201,7 @@ u32 D3D11Device::GetSwapChainBufferCount() const
|
||||
{
|
||||
// With vsync off, we only need two buffers. Same for blocking vsync.
|
||||
// With triple buffering, we need three.
|
||||
return (m_vsync_enabled && m_vsync_prefer_triple_buffer) ? 3 : 2;
|
||||
return (m_vsync_mode == GPUVSyncMode::TripleBuffered) ? 3 : 2;
|
||||
}
|
||||
|
||||
bool D3D11Device::CreateSwapChain()
|
||||
@ -357,10 +357,6 @@ bool D3D11Device::CreateSwapChainRTV()
|
||||
m_window_info.surface_refresh_rate = static_cast<float>(desc.BufferDesc.RefreshRate.Numerator) /
|
||||
static_cast<float>(desc.BufferDesc.RefreshRate.Denominator);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_window_info.surface_refresh_rate = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -592,31 +588,13 @@ void D3D11Device::InvalidateRenderTarget(GPUTexture* t)
|
||||
static_cast<D3D11Texture*>(t)->CommitClear(m_context.Get());
|
||||
}
|
||||
|
||||
std::optional<float> D3D11Device::GetHostRefreshRate()
|
||||
void D3D11Device::SetVSyncMode(GPUVSyncMode mode)
|
||||
{
|
||||
if (m_swap_chain && m_is_exclusive_fullscreen)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
if (SUCCEEDED(m_swap_chain->GetDesc(&desc)) && desc.BufferDesc.RefreshRate.Numerator > 0 &&
|
||||
desc.BufferDesc.RefreshRate.Denominator > 0)
|
||||
{
|
||||
DEV_LOG("using fs rr: {} {}", desc.BufferDesc.RefreshRate.Numerator, desc.BufferDesc.RefreshRate.Denominator);
|
||||
return static_cast<float>(desc.BufferDesc.RefreshRate.Numerator) /
|
||||
static_cast<float>(desc.BufferDesc.RefreshRate.Denominator);
|
||||
}
|
||||
}
|
||||
|
||||
return GPUDevice::GetHostRefreshRate();
|
||||
}
|
||||
|
||||
void D3D11Device::SetVSyncEnabled(bool enabled, bool prefer_triple_buffer)
|
||||
{
|
||||
if (m_vsync_enabled == enabled && m_vsync_prefer_triple_buffer == prefer_triple_buffer)
|
||||
if (m_vsync_mode == mode)
|
||||
return;
|
||||
|
||||
const u32 old_buffer_count = GetSwapChainBufferCount();
|
||||
m_vsync_enabled = enabled;
|
||||
m_vsync_prefer_triple_buffer = prefer_triple_buffer;
|
||||
m_vsync_mode = mode;
|
||||
if (!m_swap_chain)
|
||||
return;
|
||||
|
||||
@ -656,7 +634,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 (IsVSyncModeBlocking() && m_gpu_timing_enabled)
|
||||
PopTimestampQuery();
|
||||
|
||||
static constexpr float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
@ -674,12 +652,12 @@ void D3D11Device::EndPresent(bool explicit_present)
|
||||
DebugAssert(!explicit_present);
|
||||
DebugAssert(m_num_current_render_targets == 0 && !m_current_depth_target);
|
||||
|
||||
if (!m_vsync_enabled && m_gpu_timing_enabled)
|
||||
if (!IsVSyncModeBlocking() && m_gpu_timing_enabled)
|
||||
PopTimestampQuery();
|
||||
|
||||
// DirectX has no concept of tear-or-sync. I guess if we measured times ourselves, we could implement it.
|
||||
if (m_vsync_enabled)
|
||||
m_swap_chain->Present(BoolToUInt32(1), 0);
|
||||
if (IsVSyncModeBlocking())
|
||||
m_swap_chain->Present(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
|
||||
|
||||
Reference in New Issue
Block a user