mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-04 05:04:33 +00:00
GPUDevice: Update last presented time after present
Instead of before. Makes present skipping much more effective against NVIDIA's global framerate cap if enabled, on my system with the cap at 60fps it went from 120fps to 1400fps. Still about half of the true uncapped speed, but when the present call blocks for a few milliseconds this is all you can do. Can't stop presenting frames entirely.
This commit is contained in:
@@ -1275,6 +1275,7 @@ bool GPUPresenter::PresentFrame(GPUPresenter* presenter, GPUBackend* backend, bo
|
||||
g_gpu_device->SubmitPresent(swap_chain);
|
||||
}
|
||||
|
||||
swap_chain->UpdateLastFramePresentedTime();
|
||||
ImGuiManager::NewFrame();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -734,6 +734,7 @@ void D3D11Device::EndPresent(GPUSwapChain* swap_chain, bool explicit_present, u6
|
||||
const UINT flags =
|
||||
(SC->GetVSyncMode() == GPUVSyncMode::Disabled && SC->IsUsingAllowTearing()) ? DXGI_PRESENT_ALLOW_TEARING : 0;
|
||||
SC->GetSwapChain()->Present(sync_interval, flags);
|
||||
SC->UpdateLastFramePresentedTime();
|
||||
|
||||
if (m_gpu_timing_enabled)
|
||||
StartTimestampQuery();
|
||||
|
||||
@@ -1266,6 +1266,7 @@ void D3D12Device::SubmitPresent(GPUSwapChain* swap_chain)
|
||||
const UINT flags =
|
||||
(SC->GetVSyncMode() == GPUVSyncMode::Disabled && SC->IsUsingAllowTearing()) ? DXGI_PRESENT_ALLOW_TEARING : 0;
|
||||
SC->GetSwapChain()->Present(sync_interval, flags);
|
||||
SC->UpdateLastFramePresentedTime();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GPU_OBJECT_NAMES
|
||||
|
||||
@@ -300,10 +300,15 @@ bool GPUSwapChain::ShouldSkipPresentingFrame()
|
||||
if (diff < throttle_period)
|
||||
return true;
|
||||
|
||||
m_last_frame_displayed_time = now;
|
||||
return false;
|
||||
}
|
||||
|
||||
void GPUSwapChain::UpdateLastFramePresentedTime(u64 presented_time)
|
||||
{
|
||||
if (m_allow_present_throttle)
|
||||
m_last_frame_displayed_time = (presented_time != 0) ? presented_time : Timer::GetCurrentValue();
|
||||
}
|
||||
|
||||
void GPUSwapChain::ThrottlePresentation()
|
||||
{
|
||||
const float throttle_rate = (m_window_info.surface_refresh_rate > 0.0f) ? m_window_info.surface_refresh_rate : 60.0f;
|
||||
|
||||
@@ -488,6 +488,7 @@ public:
|
||||
virtual bool IsExclusiveFullscreen() const;
|
||||
|
||||
bool ShouldSkipPresentingFrame();
|
||||
void UpdateLastFramePresentedTime(u64 presented_time = 0);
|
||||
void ThrottlePresentation();
|
||||
|
||||
static GSVector4i PreRotateClipRect(WindowInfo::PreRotation prerotation, const GSVector2i surface_size,
|
||||
|
||||
@@ -2592,16 +2592,19 @@ void MetalDevice::EndPresent(GPUSwapChain* swap_chain, bool explicit_present, u6
|
||||
EndAnyEncoding();
|
||||
|
||||
Timer::Value current_time;
|
||||
Timer::Value presented_time;
|
||||
if (present_time != 0 && (current_time = Timer::GetCurrentValue()) < present_time)
|
||||
{
|
||||
// Need to convert to mach absolute time. Time values should already be in nanoseconds.
|
||||
const u64 mach_time_nanoseconds = CocoaTools::ConvertMachTimeBaseToNanoseconds(mach_absolute_time());
|
||||
const double mach_present_time = static_cast<double>(mach_time_nanoseconds + (present_time - current_time)) / 1e+9;
|
||||
[m_render_cmdbuf presentDrawable:m_layer_drawable atTime:mach_present_time];
|
||||
presented_time = present_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
[m_render_cmdbuf presentDrawable:m_layer_drawable];
|
||||
presented_time = 0;
|
||||
}
|
||||
|
||||
DeferRelease(m_layer_drawable);
|
||||
@@ -2609,6 +2612,8 @@ void MetalDevice::EndPresent(GPUSwapChain* swap_chain, bool explicit_present, u6
|
||||
|
||||
SubmitCommandBuffer();
|
||||
TrimTexturePool();
|
||||
|
||||
swap_chain->UpdateLastFramePresentedTime(presented_time);
|
||||
}
|
||||
|
||||
void MetalDevice::SubmitPresent(GPUSwapChain* swap_chainwel)
|
||||
|
||||
@@ -803,6 +803,7 @@ void OpenGLDevice::EndPresent(GPUSwapChain* swap_chain, bool explicit_present, u
|
||||
}
|
||||
|
||||
m_gl_context->SwapBuffers();
|
||||
swap_chain->UpdateLastFramePresentedTime();
|
||||
|
||||
if (swap_chain == m_main_swap_chain.get() && m_gpu_timing_enabled)
|
||||
StartTimestampQuery();
|
||||
|
||||
@@ -1254,6 +1254,7 @@ void VulkanDevice::QueuePresent(VulkanSwapChain* present_swap_chain)
|
||||
// submission. Don't care if it fails, we'll deal with that at the presentation call site.
|
||||
// Credit to dxvk for the idea.
|
||||
present_swap_chain->AcquireNextImage(false);
|
||||
present_swap_chain->UpdateLastFramePresentedTime();
|
||||
}
|
||||
|
||||
void VulkanDevice::BeginCommandBuffer(u32 index)
|
||||
|
||||
Reference in New Issue
Block a user