Skip to content

Commit 09926a3

Browse files
committed
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.
1 parent d02382d commit 09926a3

File tree

8 files changed

+17
-1
lines changed

8 files changed

+17
-1
lines changed

src/core/gpu_presenter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,7 @@ bool GPUPresenter::PresentFrame(GPUPresenter* presenter, GPUBackend* backend, bo
12751275
g_gpu_device->SubmitPresent(swap_chain);
12761276
}
12771277

1278+
swap_chain->UpdateLastFramePresentedTime();
12781279
ImGuiManager::NewFrame();
12791280
}
12801281
else

src/util/d3d11_device.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ void D3D11Device::EndPresent(GPUSwapChain* swap_chain, bool explicit_present, u6
734734
const UINT flags =
735735
(SC->GetVSyncMode() == GPUVSyncMode::Disabled && SC->IsUsingAllowTearing()) ? DXGI_PRESENT_ALLOW_TEARING : 0;
736736
SC->GetSwapChain()->Present(sync_interval, flags);
737+
SC->UpdateLastFramePresentedTime();
737738

738739
if (m_gpu_timing_enabled)
739740
StartTimestampQuery();

src/util/d3d12_device.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,7 @@ void D3D12Device::SubmitPresent(GPUSwapChain* swap_chain)
12661266
const UINT flags =
12671267
(SC->GetVSyncMode() == GPUVSyncMode::Disabled && SC->IsUsingAllowTearing()) ? DXGI_PRESENT_ALLOW_TEARING : 0;
12681268
SC->GetSwapChain()->Present(sync_interval, flags);
1269+
SC->UpdateLastFramePresentedTime();
12691270
}
12701271

12711272
#ifdef ENABLE_GPU_OBJECT_NAMES

src/util/gpu_device.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,15 @@ bool GPUSwapChain::ShouldSkipPresentingFrame()
300300
if (diff < throttle_period)
301301
return true;
302302

303-
m_last_frame_displayed_time = now;
304303
return false;
305304
}
306305

306+
void GPUSwapChain::UpdateLastFramePresentedTime(u64 presented_time)
307+
{
308+
if (m_allow_present_throttle)
309+
m_last_frame_displayed_time = (presented_time != 0) ? presented_time : Timer::GetCurrentValue();
310+
}
311+
307312
void GPUSwapChain::ThrottlePresentation()
308313
{
309314
const float throttle_rate = (m_window_info.surface_refresh_rate > 0.0f) ? m_window_info.surface_refresh_rate : 60.0f;

src/util/gpu_device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ class GPUSwapChain
488488
virtual bool IsExclusiveFullscreen() const;
489489

490490
bool ShouldSkipPresentingFrame();
491+
void UpdateLastFramePresentedTime(u64 presented_time = 0);
491492
void ThrottlePresentation();
492493

493494
static GSVector4i PreRotateClipRect(WindowInfo::PreRotation prerotation, const GSVector2i surface_size,

src/util/metal_device.mm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,23 +2592,28 @@ static void RunOnMainThread(F&& f)
25922592
EndAnyEncoding();
25932593

25942594
Timer::Value current_time;
2595+
Timer::Value presented_time;
25952596
if (present_time != 0 && (current_time = Timer::GetCurrentValue()) < present_time)
25962597
{
25972598
// Need to convert to mach absolute time. Time values should already be in nanoseconds.
25982599
const u64 mach_time_nanoseconds = CocoaTools::ConvertMachTimeBaseToNanoseconds(mach_absolute_time());
25992600
const double mach_present_time = static_cast<double>(mach_time_nanoseconds + (present_time - current_time)) / 1e+9;
26002601
[m_render_cmdbuf presentDrawable:m_layer_drawable atTime:mach_present_time];
2602+
presented_time = present_time;
26012603
}
26022604
else
26032605
{
26042606
[m_render_cmdbuf presentDrawable:m_layer_drawable];
2607+
presented_time = 0;
26052608
}
26062609

26072610
DeferRelease(m_layer_drawable);
26082611
m_layer_drawable = nil;
26092612

26102613
SubmitCommandBuffer();
26112614
TrimTexturePool();
2615+
2616+
swap_chain->UpdateLastFramePresentedTime(presented_time);
26122617
}
26132618

26142619
void MetalDevice::SubmitPresent(GPUSwapChain* swap_chainwel)

src/util/opengl_device.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,7 @@ void OpenGLDevice::EndPresent(GPUSwapChain* swap_chain, bool explicit_present, u
803803
}
804804

805805
m_gl_context->SwapBuffers();
806+
swap_chain->UpdateLastFramePresentedTime();
806807

807808
if (swap_chain == m_main_swap_chain.get() && m_gpu_timing_enabled)
808809
StartTimestampQuery();

src/util/vulkan_device.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,7 @@ void VulkanDevice::QueuePresent(VulkanSwapChain* present_swap_chain)
12541254
// submission. Don't care if it fails, we'll deal with that at the presentation call site.
12551255
// Credit to dxvk for the idea.
12561256
present_swap_chain->AcquireNextImage(false);
1257+
present_swap_chain->UpdateLastFramePresentedTime();
12571258
}
12581259

12591260
void VulkanDevice::BeginCommandBuffer(u32 index)

0 commit comments

Comments
 (0)