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:
parent
26ff3d9817
commit
fa6c32684a
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user