Skip to content

Commit 09ba292

Browse files
committed
[dxvk] Request present timing if available
1 parent 33599b3 commit 09ba292

2 files changed

Lines changed: 45 additions & 4 deletions

File tree

src/dxvk/dxvk_presenter.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ namespace dxvk {
169169
VkResult Presenter::presentImage(uint64_t frameId, const Rc<DxvkLatencyTracker>& tracker) {
170170
PresenterSync& currSync = m_semaphores.at(m_frameIndex);
171171

172+
uint64_t frameDeadline = 0u;
173+
172174
VkPresentIdKHR presentId = { VK_STRUCTURE_TYPE_PRESENT_ID_KHR };
173175
presentId.swapchainCount = 1;
174176
presentId.pPresentIds = &frameId;
@@ -185,6 +187,33 @@ namespace dxvk {
185187
modeInfo.swapchainCount = 1;
186188
modeInfo.pPresentModes = &m_presentMode;
187189

190+
VkPresentTimingInfoEXT timingInfo = { VK_STRUCTURE_TYPE_PRESENT_TIMING_INFO_EXT };
191+
timingInfo.presentStageQueries = m_timingMode.presentStage;
192+
193+
if (m_timingMode.presentStage) {
194+
std::lock_guard lock(m_timingMutex);
195+
196+
if (m_timingMode.relativeTiming) {
197+
timingInfo.flags |= VK_PRESENT_TIMING_INFO_PRESENT_AT_RELATIVE_TIME_BIT_EXT;
198+
timingInfo.targetTime = m_timingMode.frameIntervalNs;
199+
timingInfo.targetTimeDomainPresentStage = m_timingMode.presentStage;
200+
timingInfo.timeDomainId = m_timingMode.timeDomainId;
201+
} else if (m_timingMode.absoluteTiming && m_timingMode.referenceFrameId) {
202+
frameDeadline = m_timingMode.referenceTime + (frameId - m_timingMode.referenceFrameId) * m_timingMode.frameIntervalNs;
203+
204+
timingInfo.targetTime = frameDeadline;
205+
timingInfo.targetTimeDomainPresentStage = m_timingMode.presentStage;
206+
timingInfo.timeDomainId = m_timingMode.timeDomainId;
207+
208+
if (m_timingDisplayInfo && !m_timingDisplayInfo->isVariableRefresh)
209+
timingInfo.flags |= VK_PRESENT_TIMING_INFO_PRESENT_AT_NEAREST_REFRESH_CYCLE_BIT_EXT;
210+
}
211+
}
212+
213+
VkPresentTimingsInfoEXT timingsInfo = { VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT };
214+
timingsInfo.swapchainCount = 1u;
215+
timingsInfo.pTimingInfos = &timingInfo;
216+
188217
VkPresentInfoKHR info = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
189218
info.waitSemaphoreCount = 1;
190219
info.pWaitSemaphores = &currSync.present;
@@ -197,6 +226,9 @@ namespace dxvk {
197226
presentId2.pNext = const_cast<void*>(std::exchange(info.pNext, &presentId2));
198227
else
199228
presentId.pNext = const_cast<void*>(std::exchange(info.pNext, &presentId));
229+
230+
if (timingInfo.presentStageQueries)
231+
timingsInfo.pNext = std::exchange(info.pNext, &timingsInfo);
200232
}
201233

202234
if (m_hasSwapchainMaintenance1) {
@@ -241,6 +273,7 @@ namespace dxvk {
241273
frame.tracker = tracker;
242274
frame.mode = m_presentMode;
243275
frame.result = status;
276+
frame.deadline = frameDeadline;
244277

245278
pushFrame(frame);
246279
}
@@ -1456,6 +1489,7 @@ namespace dxvk {
14561489
if (m_timingMode.presentStage)
14571490
return false;
14581491

1492+
// Need to access both timing stuff and the frame queue here
14591493
std::lock_guard lock(m_timingMutex);
14601494

14611495
// Still need to drain the queue even if everything is messed up
@@ -1503,8 +1537,11 @@ namespace dxvk {
15031537
if (updateMode)
15041538
updateTimingMode(presentMode);
15051539

1506-
// Find latest available report and update present statistics
1507-
bool hasValidReport = false;
1540+
// Find latest available report and update present statistics. If we run
1541+
// absolute timing and any given frame missed its deadline, restart the
1542+
// sequence.
1543+
std::lock_guard frameLock(m_frameMutex);
1544+
bool hasMissedDeadline = false;
15081545

15091546
for (size_t i = 0u; i < timingProperties.presentationTimingCount; i++) {
15101547
const auto& time = stageTimes[i];
@@ -1530,11 +1567,14 @@ namespace dxvk {
15301567
m_timingMode.lastFrameTimeLocal = reportTimeLocal;
15311568
m_timingMode.lastFrameTimeQpc = reportTimeQpc;
15321569

1533-
hasValidReport = true;
1570+
for (const auto& frame : m_frameQueue) {
1571+
if (frame.frameId == report.presentId)
1572+
hasMissedDeadline = reportTimeLocal > frame.deadline;
1573+
}
15341574
}
15351575
}
15361576

1537-
if (!m_timingMode.referenceFrameId && hasValidReport) {
1577+
if (!m_timingMode.referenceFrameId || hasMissedDeadline) {
15381578
m_timingMode.referenceFrameId = m_timingMode.lastFrameId;
15391579
m_timingMode.referenceTime = m_timingMode.lastFrameTimeLocal;
15401580
}

src/dxvk/dxvk_presenter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ namespace dxvk {
6060
Rc<DxvkLatencyTracker> tracker = nullptr;
6161
VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
6262
VkResult result = VK_NOT_READY;
63+
uint64_t deadline = 0u;
6364
};
6465

6566
/**

0 commit comments

Comments
 (0)