aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rw-r--r--src/swapchain_monitor.cc58
-rw-r--r--src/swapchain_monitor.hh10
3 files changed, 33 insertions, 40 deletions
diff --git a/README.md b/README.md
index 5ebd619..e8f789e 100644
--- a/README.md
+++ b/README.md
@@ -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;