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

[dxvk] Avoid locking built-in latency tracker when calling into presenter

Same reason as for the Reflex one.
This commit is contained in:
Philip Rebohle 2025-02-11 13:24:23 +01:00 committed by Philip Rebohle
parent b1174a1bdf
commit 70492b2954
2 changed files with 47 additions and 41 deletions

View File

@ -59,10 +59,7 @@ namespace dxvk {
void DxvkBuiltInLatencyTracker::notifyCsRenderBegin(
uint64_t frameId) {
std::unique_lock lock(m_mutex);
auto frame = findFrame(frameId);
if (frame && m_useNvLowLatency2) {
if (forwardLatencyMarkerNv(frameId)) {
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_SIMULATION_END_NV);
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_RENDERSUBMIT_START_NV);
}
@ -71,10 +68,7 @@ namespace dxvk {
void DxvkBuiltInLatencyTracker::notifyCsRenderEnd(
uint64_t frameId) {
std::unique_lock lock(m_mutex);
auto frame = findFrame(frameId);
if (frame && m_useNvLowLatency2)
if (forwardLatencyMarkerNv(frameId))
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_RENDERSUBMIT_END_NV);
}
@ -91,10 +85,7 @@ namespace dxvk {
void DxvkBuiltInLatencyTracker::notifyQueuePresentBegin(
uint64_t frameId) {
std::unique_lock lock(m_mutex);
auto frame = findFrame(frameId);
if (frame && m_useNvLowLatency2)
if (forwardLatencyMarkerNv(frameId))
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_PRESENT_START_NV);
}
@ -102,18 +93,19 @@ namespace dxvk {
void DxvkBuiltInLatencyTracker::notifyQueuePresentEnd(
uint64_t frameId,
VkResult status) {
std::unique_lock lock(m_mutex);
auto frame = findFrame(frameId);
{ std::unique_lock lock(m_mutex);
auto frame = findFrame(frameId);
if (frame) {
frame->presentStatus = status;
frame->queuePresent = dxvk::high_resolution_clock::now();
if (frame) {
frame->presentStatus = status;
frame->queuePresent = dxvk::high_resolution_clock::now();
}
if (m_useNvLowLatency2)
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_PRESENT_END_NV);
m_cond.notify_one();
}
m_cond.notify_one();
if (forwardLatencyMarkerNv(frameId))
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_PRESENT_END_NV);
}
@ -169,11 +161,12 @@ namespace dxvk {
? sleepNv(frameId, maxFrameRate)
: sleepBuiltin(frameId, maxFrameRate);
std::unique_lock lock(m_mutex);
{ std::unique_lock lock(m_mutex);
auto next = initFrame(frameId);
next->frameStart = dxvk::high_resolution_clock::now();
next->sleepDuration = duration;
auto next = initFrame(frameId);
next->frameStart = dxvk::high_resolution_clock::now();
next->sleepDuration = duration;
}
if (m_useNvLowLatency2) {
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_SIMULATION_START_NV);
@ -211,26 +204,26 @@ namespace dxvk {
DxvkBuiltInLatencyTracker::duration DxvkBuiltInLatencyTracker::sleepNv(
uint64_t frameId,
double maxFrameRate) {
// Set up low latency mode for subsequent frames. The presenter
// will figure out whether to reapply latency state or not.
VkLatencySleepModeInfoNV latencyMode = { VK_STRUCTURE_TYPE_LATENCY_SLEEP_MODE_INFO_NV };
latencyMode.lowLatencyMode = VK_TRUE;
latencyMode.lowLatencyBoost = VK_TRUE;
latencyMode.minimumIntervalUs = 0;
if (m_envFpsLimit > 0.0)
maxFrameRate = m_envFpsLimit;
if (maxFrameRate > 0.0)
latencyMode.minimumIntervalUs = uint64_t(1'000'000.0 / maxFrameRate);
m_presenter->setLatencySleepModeNv(latencyMode);
// Wait for previous present call to complete in order to
// avoid potential issues with oscillating frame times
bool presentSuccessful = false;
{ std::unique_lock lock(m_mutex);
// Set up low latency mode for subsequent frames
VkLatencySleepModeInfoNV latencyMode = { VK_STRUCTURE_TYPE_LATENCY_SLEEP_MODE_INFO_NV };
latencyMode.lowLatencyMode = VK_TRUE;
latencyMode.lowLatencyBoost = VK_TRUE;
latencyMode.minimumIntervalUs = 0;
if (m_envFpsLimit > 0.0)
maxFrameRate = m_envFpsLimit;
if (maxFrameRate > 0.0)
latencyMode.minimumIntervalUs = uint64_t(1'000'000.0 / maxFrameRate);
m_presenter->setLatencySleepModeNv(latencyMode);
// Wait for previous present call to complete in order to
// avoid potential issues with oscillating frame times
auto curr = findFrame(frameId - 1u);
if (curr && curr->cpuPresentEnd != time_point()) {
@ -369,6 +362,16 @@ namespace dxvk {
}
bool DxvkBuiltInLatencyTracker::forwardLatencyMarkerNv(
uint64_t frameId) {
if (!m_useNvLowLatency2)
return false;
std::unique_lock lock(m_mutex);
return findFrame(frameId) != nullptr;
}
DxvkBuiltInLatencyTracker::duration DxvkBuiltInLatencyTracker::computeFrameInterval(
double maxFrameRate) {
if (m_envFpsLimit > 0.0)

View File

@ -109,6 +109,9 @@ namespace dxvk {
DxvkLatencyFrameData* findFrame(
uint64_t frameId);
bool forwardLatencyMarkerNv(
uint64_t frameId);
duration computeFrameInterval(
double maxFrameRate);