1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-23 19:54:16 +01:00

[dxvk] Add latency tracker to presenter

This commit is contained in:
Philip Rebohle 2025-01-18 00:23:24 +01:00
parent 26ff3d9817
commit fa6c32684a
3 changed files with 31 additions and 10 deletions

View File

@ -228,7 +228,10 @@ namespace dxvk {
}
void Presenter::signalFrame(VkResult result, uint64_t frameId) {
void Presenter::signalFrame(
VkResult result,
uint64_t frameId,
const Rc<DxvkLatencyTracker>& tracker) {
if (m_signal == nullptr || !frameId)
return;
@ -236,15 +239,19 @@ namespace dxvk {
std::lock_guard<dxvk::mutex> lock(m_frameMutex);
PresenterFrame frame = { };
frame.result = result;
frame.mode = m_presentMode;
frame.frameId = frameId;
frame.frameId = frameId;
frame.tracker = tracker;
frame.mode = m_presentMode;
frame.result = result;
m_frameQueue.push(frame);
m_frameCond.notify_one();
} else {
m_fpsLimiter.delay();
m_signal->signal(frameId);
if (tracker)
tracker->notifyGpuPresentEnd(frameId);
}
m_lastFrameId.store(frameId, std::memory_order_release);
@ -1058,6 +1065,13 @@ namespace dxvk {
Logger::err(str::format("Presenter: vkWaitForPresentKHR failed: ", vr));
}
// Signal latency tracker right away to get more accurate
// measurements if the frame rate limiter is enabled.
if (frame.tracker) {
frame.tracker->notifyGpuPresentEnd(frame.frameId);
frame.tracker = nullptr;
}
// Apply FPS limtier here to align it as closely with scanout as we can,
// and delay signaling the frame latency event to emulate behaviour of a
// low refresh rate display as closely as we can.

View File

@ -18,6 +18,7 @@
#include "dxvk_format.h"
#include "dxvk_image.h"
#include "dxvk_latency.h"
namespace dxvk {
@ -55,9 +56,10 @@ namespace dxvk {
* \brief Queued frame
*/
struct PresenterFrame {
uint64_t frameId = 0u;
VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
VkResult result = VK_NOT_READY;
uint64_t frameId = 0u;
Rc<DxvkLatencyTracker> tracker = nullptr;
VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
VkResult result = VK_NOT_READY;
};
/**
@ -135,9 +137,13 @@ namespace dxvk {
* called before GPU work prior to the present submission has
* completed in order to maintain consistency.
* \param [in] result Presentation result
* \param [in] frameId Frame number
* \param [in] frameId Frame ID
* \param [in] tracker Latency tracker
*/
void signalFrame(VkResult result, uint64_t frameId);
void signalFrame(
VkResult result,
uint64_t frameId,
const Rc<DxvkLatencyTracker>& tracker);
/**
* \brief Changes sync interval

View File

@ -260,7 +260,8 @@ namespace dxvk {
// Signal the frame and then immediately destroy the reference.
// This is necessary since the front-end may want to explicitly
// destroy the presenter object.
entry.present.presenter->signalFrame(entry.result, entry.present.frameId);
entry.present.presenter->signalFrame(entry.result,
entry.present.frameId, entry.latency.tracker);
entry.present.presenter = nullptr;
}