@@ -205,6 +205,8 @@ namespace dxvk {
205205 bool isFifoMode = m_presentMode == VK_PRESENT_MODE_FIFO_KHR
206206 || m_presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR ;
207207
208+ bool waitForPresent = m_hasPresentWait && isFifoMode;
209+
208210 VkPresentTimingInfoEXT timingInfo = { VK_STRUCTURE_TYPE_PRESENT_TIMING_INFO_EXT };
209211 timingInfo.presentStageQueries = m_timingMode.presentStage ;
210212 timingInfo.timeDomainId = m_timingMode.timeDomainId ;
@@ -225,6 +227,10 @@ namespace dxvk {
225227
226228 frameDeadline = timingInfo.targetTime + m_timingMode.frameIntervalNs ;
227229 }
230+
231+ // Skip present_wait in fixed refresh mode if the frame is timed
232+ if (!m_timingDisplayInfo || !m_timingDisplayInfo->isVariableRefresh )
233+ waitForPresent = waitForPresent && !timingInfo.targetTime ;
228234 }
229235
230236 VkPresentTimingsInfoEXT timingsInfo = { VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT };
@@ -287,18 +293,17 @@ namespace dxvk {
287293 }
288294
289295 // Add frame to waiter queue with current properties
290- if (m_hasPresentWait) {
291- PresenterFrame frame;
292- frame.frameId = frameId;
293- frame.tracker = tracker;
294- frame.mode = m_presentMode;
295- frame.result = status;
296- frame.targetTime = frameDeadline ? timingInfo.targetTime : 0u ;
297- frame.deadline = frameDeadline;
298- frame.isTimed = bool (timingInfo.targetTime );
299-
300- pushFrame (frame);
301- }
296+ PresenterFrame frame;
297+ frame.frameId = frameId;
298+ frame.tracker = tracker;
299+ frame.mode = m_presentMode;
300+ frame.result = status;
301+ frame.targetTime = frameDeadline ? timingInfo.targetTime : 0u ;
302+ frame.deadline = frameDeadline;
303+ frame.isTimed = bool (timingInfo.targetTime );
304+ frame.doWait = waitForPresent;
305+
306+ pushFrame (frame);
302307
303308 // On a successful present, try to acquire next image already, in
304309 // order to hide potential delays from the application thread.
@@ -335,24 +340,16 @@ namespace dxvk {
335340 if (m_signal == nullptr || !frameId)
336341 return ;
337342
338- if (m_hasPresentWait) {
339- bool canSignal = false ;
343+ bool canSignal = false ;
340344
341- { std::unique_lock lock (m_frameMutex);
345+ { std::unique_lock lock (m_frameMutex);
342346
343- m_lastSignaled = frameId;
344- canSignal = m_lastCompleted >= frameId;
345- }
347+ m_lastSignaled = frameId;
348+ canSignal = m_lastCompleted >= frameId;
349+ }
346350
347- if (canSignal)
348- m_signal->signal (frameId);
349- } else {
350- m_fpsLimiter.delay ();
351+ if (canSignal)
351352 m_signal->signal (frameId);
352-
353- if (tracker)
354- tracker->notifyGpuPresentEnd (frameId);
355- }
356353 }
357354
358355
@@ -968,7 +965,7 @@ namespace dxvk {
968965 if (m_device->features ().khrIncrementalPresent )
969966 m_hasIncrementalPresent = caps.surfaceCapabilities .currentTransform == VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR ;
970967
971- if (m_signal && m_hasPresentWait && !m_frameThread.joinable ())
968+ if (m_signal && !m_frameThread.joinable ())
972969 m_frameThread = dxvk::thread ([this ] { runFrameThread (); });
973970
974971 m_presentRepaint = true ;
@@ -1949,7 +1946,7 @@ namespace dxvk {
19491946 // If the present operation has succeeded, actually wait for it to complete.
19501947 // Don't bother with it on MAILBOX / IMMEDIATE modes since doing so would
19511948 // restrict us to the display refresh rate on some platforms (XWayland).
1952- if (frame.result >= 0 && ( frame.mode == VK_PRESENT_MODE_FIFO_KHR || frame. mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR ) ) {
1949+ if (frame.result >= 0 && frame.doWait ) {
19531950 VkResult vr;
19541951
19551952 if (m_device->features ().khrPresentWait2 .presentWait2 ) {
0 commit comments