diff options
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | src/swapchain_monitor.cc | 58 | ||||
| -rw-r--r-- | src/swapchain_monitor.hh | 10 |
3 files changed, 33 insertions, 40 deletions
@@ -66,11 +66,6 @@ PROTON_FORCE_NVAPI=1 LOW_LATENCY_LAYER_EXPOSE_REFLEX=1 LOW_LATENCY_LAYER_SPOOF_N The 'Boost' mode of Reflex is supported but is functionally identical to 'On' - the layer treats both modes identically. -# Example: Enable NVIDIA spoofing -LOW_LATENCY_LAYER_SPOOF_NVIDIA=1 ./your-application -``` - - # Benchmarks WIP - not updated for reflex merge diff --git a/src/swapchain_monitor.cc b/src/swapchain_monitor.cc index a79010d..87f6205 100644 --- a/src/swapchain_monitor.cc +++ b/src/swapchain_monitor.cc @@ -57,7 +57,7 @@ void ReflexSwapchainMonitor::do_monitor(const std::stop_token stoken) { for (;;) { auto lock = std::unique_lock{this->mutex}; this->cv.wait(lock, stoken, - [&]() { return !this->wakeup_semaphores.empty(); }); + [&]() { return !this->semaphore_submissions.empty(); }); if (stoken.stop_requested()) { // Small chance an application might need outstanding semaphores @@ -65,38 +65,26 @@ void ReflexSwapchainMonitor::do_monitor(const std::stop_token stoken) { break; } - // Grab the most recent semaphore we want to signal off the queue - - // and keep the lock held. - const auto wakeup_semaphore = this->wakeup_semaphores.back(); - this->wakeup_semaphores.clear(); + // Grab the most recent semaphore we want to signal off the queue. + const auto semaphore_submission = + std::move(this->semaphore_submissions.back()); + this->semaphore_submissions.clear(); - // Look for the latest submission and make sure it's completed. - // We have to unlock while we wait. - if (!this->in_flight_submissions.empty()) { - - const auto last = std::move(this->in_flight_submissions.back()); - this->in_flight_submissions.clear(); - - lock.unlock(); - last->await_completed(); - } else { - lock.unlock(); - } - - // Signal the semaphore - wakeup_semaphore.signal(this->device); + lock.unlock(); + // Wait for work to finish and signal its associated semaphore. + semaphore_submission.submissions->await_completed(); + semaphore_submission.wakeup_semaphore.signal(this->device); } } void ReflexSwapchainMonitor::notify_semaphore( const VkSemaphore& timeline_semaphore, const std::uint64_t& value) { - const auto lock = std::scoped_lock{this->mutex}; + auto lock = std::unique_lock{this->mutex}; const auto wakeup_semaphore = WakeupSemaphore{ .timeline_semaphore = timeline_semaphore, .value = value}; - // Signal immediately if low_latency isn't requested or if we have no - // outstanding work. + if (!this->was_low_latency_requested || this->in_flight_submissions.empty()) { @@ -104,7 +92,19 @@ void ReflexSwapchainMonitor::notify_semaphore( return; } - this->wakeup_semaphores.emplace_back(timeline_semaphore, value); + if (this->in_flight_submissions.back()->has_completed()) { + this->in_flight_submissions.clear(); + wakeup_semaphore.signal(this->device); + return; + } + + this->semaphore_submissions.emplace_back(SemaphoreSubmissions{ + .wakeup_semaphore = wakeup_semaphore, + .submissions = std::move(this->in_flight_submissions.back()), + }); + this->in_flight_submissions.clear(); + + lock.unlock(); this->cv.notify_one(); } @@ -116,18 +116,8 @@ void ReflexSwapchainMonitor::notify_present( return; } - // Fast path where this work has already completed. - // In this case, don't wake up the thread - we can just signal immediately. - if (!this->wakeup_semaphores.empty() && submissions->has_completed()) { - this->wakeup_semaphores.back().signal(this->device); - this->wakeup_semaphores.clear(); - return; - } - this->in_flight_submissions.emplace_back(std::move(submissions)); this->prune_submissions(); - - this->cv.notify_one(); } AntiLagSwapchainMonitor::AntiLagSwapchainMonitor( diff --git a/src/swapchain_monitor.hh b/src/swapchain_monitor.hh index e8603b5..eaf4933 100644 --- a/src/swapchain_monitor.hh +++ b/src/swapchain_monitor.hh @@ -12,6 +12,7 @@ #include <mutex> #include <thread> +#include "instance_context.hh" #include "queue_context.hh" namespace low_latency { @@ -69,7 +70,14 @@ class ReflexSwapchainMonitor final : public SwapchainMonitor { public: void signal(const DeviceContext& device) const; }; - std::deque<WakeupSemaphore> wakeup_semaphores; + + // A pairing of semaphore -> submissions. + // If the Submissions completes then signal the bundled semaphore. + struct SemaphoreSubmissions { + WakeupSemaphore wakeup_semaphore; + std::unique_ptr<QueueContext::Submissions> submissions; + }; + std::deque<SemaphoreSubmissions> semaphore_submissions; std::mutex mutex; std::condition_variable_any cv; |
