1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-23 19:54:16 +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( void DxvkBuiltInLatencyTracker::notifyCsRenderBegin(
uint64_t frameId) { uint64_t frameId) {
std::unique_lock lock(m_mutex); if (forwardLatencyMarkerNv(frameId)) {
auto frame = findFrame(frameId);
if (frame && m_useNvLowLatency2) {
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_SIMULATION_END_NV); m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_SIMULATION_END_NV);
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_RENDERSUBMIT_START_NV); m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_RENDERSUBMIT_START_NV);
} }
@ -71,10 +68,7 @@ namespace dxvk {
void DxvkBuiltInLatencyTracker::notifyCsRenderEnd( void DxvkBuiltInLatencyTracker::notifyCsRenderEnd(
uint64_t frameId) { uint64_t frameId) {
std::unique_lock lock(m_mutex); if (forwardLatencyMarkerNv(frameId))
auto frame = findFrame(frameId);
if (frame && m_useNvLowLatency2)
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_RENDERSUBMIT_END_NV); m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_RENDERSUBMIT_END_NV);
} }
@ -91,10 +85,7 @@ namespace dxvk {
void DxvkBuiltInLatencyTracker::notifyQueuePresentBegin( void DxvkBuiltInLatencyTracker::notifyQueuePresentBegin(
uint64_t frameId) { uint64_t frameId) {
std::unique_lock lock(m_mutex); if (forwardLatencyMarkerNv(frameId))
auto frame = findFrame(frameId);
if (frame && m_useNvLowLatency2)
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_PRESENT_START_NV); m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_PRESENT_START_NV);
} }
@ -102,20 +93,21 @@ namespace dxvk {
void DxvkBuiltInLatencyTracker::notifyQueuePresentEnd( void DxvkBuiltInLatencyTracker::notifyQueuePresentEnd(
uint64_t frameId, uint64_t frameId,
VkResult status) { VkResult status) {
std::unique_lock lock(m_mutex); { std::unique_lock lock(m_mutex);
auto frame = findFrame(frameId); auto frame = findFrame(frameId);
if (frame) { if (frame) {
frame->presentStatus = status; frame->presentStatus = status;
frame->queuePresent = dxvk::high_resolution_clock::now(); 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);
}
void DxvkBuiltInLatencyTracker::notifyGpuExecutionBegin( void DxvkBuiltInLatencyTracker::notifyGpuExecutionBegin(
uint64_t frameId) { uint64_t frameId) {
@ -169,11 +161,12 @@ namespace dxvk {
? sleepNv(frameId, maxFrameRate) ? sleepNv(frameId, maxFrameRate)
: sleepBuiltin(frameId, maxFrameRate); : sleepBuiltin(frameId, maxFrameRate);
std::unique_lock lock(m_mutex); { std::unique_lock lock(m_mutex);
auto next = initFrame(frameId); auto next = initFrame(frameId);
next->frameStart = dxvk::high_resolution_clock::now(); next->frameStart = dxvk::high_resolution_clock::now();
next->sleepDuration = duration; next->sleepDuration = duration;
}
if (m_useNvLowLatency2) { if (m_useNvLowLatency2) {
m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_SIMULATION_START_NV); m_presenter->setLatencyMarkerNv(frameId, VK_LATENCY_MARKER_SIMULATION_START_NV);
@ -211,11 +204,8 @@ namespace dxvk {
DxvkBuiltInLatencyTracker::duration DxvkBuiltInLatencyTracker::sleepNv( DxvkBuiltInLatencyTracker::duration DxvkBuiltInLatencyTracker::sleepNv(
uint64_t frameId, uint64_t frameId,
double maxFrameRate) { double maxFrameRate) {
bool presentSuccessful = false; // Set up low latency mode for subsequent frames. The presenter
// will figure out whether to reapply latency state or not.
{ std::unique_lock lock(m_mutex);
// Set up low latency mode for subsequent frames
VkLatencySleepModeInfoNV latencyMode = { VK_STRUCTURE_TYPE_LATENCY_SLEEP_MODE_INFO_NV }; VkLatencySleepModeInfoNV latencyMode = { VK_STRUCTURE_TYPE_LATENCY_SLEEP_MODE_INFO_NV };
latencyMode.lowLatencyMode = VK_TRUE; latencyMode.lowLatencyMode = VK_TRUE;
latencyMode.lowLatencyBoost = VK_TRUE; latencyMode.lowLatencyBoost = VK_TRUE;
@ -231,6 +221,9 @@ namespace dxvk {
// Wait for previous present call to complete in order to // Wait for previous present call to complete in order to
// avoid potential issues with oscillating frame times // avoid potential issues with oscillating frame times
bool presentSuccessful = false;
{ std::unique_lock lock(m_mutex);
auto curr = findFrame(frameId - 1u); auto curr = findFrame(frameId - 1u);
if (curr && curr->cpuPresentEnd != time_point()) { 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( DxvkBuiltInLatencyTracker::duration DxvkBuiltInLatencyTracker::computeFrameInterval(
double maxFrameRate) { double maxFrameRate) {
if (m_envFpsLimit > 0.0) if (m_envFpsLimit > 0.0)

View File

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