aboutsummaryrefslogtreecommitdiff
path: root/src/strategies
diff options
context:
space:
mode:
Diffstat (limited to 'src/strategies')
-rw-r--r--src/strategies/anti_lag/device_strategy.cc59
-rw-r--r--src/strategies/anti_lag/device_strategy.hh17
-rw-r--r--src/strategies/anti_lag/queue_strategy.cc52
-rw-r--r--src/strategies/anti_lag/queue_strategy.hh19
-rw-r--r--src/strategies/device_strategy.hh4
-rw-r--r--src/strategies/low_latency2/queue_strategy.cc8
-rw-r--r--src/strategies/low_latency2/queue_strategy.hh6
-rw-r--r--src/strategies/queue_strategy.hh12
8 files changed, 177 insertions, 0 deletions
diff --git a/src/strategies/anti_lag/device_strategy.cc b/src/strategies/anti_lag/device_strategy.cc
index 5032c97..8a32daa 100644
--- a/src/strategies/anti_lag/device_strategy.cc
+++ b/src/strategies/anti_lag/device_strategy.cc
@@ -1,4 +1,9 @@
#include "device_strategy.hh"
+#include "device_context.hh"
+
+#include "queue_strategy.hh"
+
+#include <vulkan/vulkan_core.h>
namespace low_latency {
@@ -7,4 +12,58 @@ AntiLagDeviceStrategy::AntiLagDeviceStrategy(DeviceContext& device)
AntiLagDeviceStrategy::~AntiLagDeviceStrategy() {}
+void AntiLagDeviceStrategy::notify_update(const VkAntiLagDataAMD& data) {
+ const auto lock = std::scoped_lock{this->mutex};
+
+ this->is_enabled = !(data.mode == VK_ANTI_LAG_MODE_OFF_AMD);
+
+ this->delay = [&]() -> std::chrono::microseconds {
+ using namespace std::chrono;
+ if (!data.maxFPS) {
+ return 0us;
+ }
+ return duration_cast<microseconds>(1s / data.maxFPS);
+ }();
+
+ if (!data.pPresentationInfo) {
+ return;
+ }
+
+ // If we're at the input stage, start marking submissions as relevant.
+ // If we're at the present stage, stop collecting submissions by making
+ // our frame_index nullopt.
+ if (data.pPresentationInfo->stage == VK_ANTI_LAG_STAGE_PRESENT_AMD) {
+ this->frame_index.reset();
+ return;
+ }
+ this->frame_index.emplace(data.pPresentationInfo->frameIndex);
+
+ // We're in input now. Wait for all queue submissions to complete.
+ const auto device_lock = std::shared_lock{this->device.mutex};
+ for (const auto& iter : this->device.queues) {
+ const auto& queue = iter.second;
+
+ const auto strategy =
+ dynamic_cast<AntiLagQueueStrategy*>(queue->strategy.get());
+ assert(strategy);
+
+ strategy->await_complete();
+ }
+}
+
+bool AntiLagDeviceStrategy::should_track_submissions() {
+ const auto lock = std::shared_lock{this->mutex};
+
+ if (!this->is_enabled) {
+ return false;
+ }
+
+ // Don't track submissions if our frame index is nullopt!
+ if (!this->frame_index.has_value()) {
+ return false;
+ }
+
+ return true;
+}
+
} // namespace low_latency \ No newline at end of file
diff --git a/src/strategies/anti_lag/device_strategy.hh b/src/strategies/anti_lag/device_strategy.hh
index 8a9afee..46197b0 100644
--- a/src/strategies/anti_lag/device_strategy.hh
+++ b/src/strategies/anti_lag/device_strategy.hh
@@ -3,14 +3,31 @@
#include "strategies/device_strategy.hh"
+#include <vulkan/vulkan.h>
+
+#include <optional>
+#include <shared_mutex>
+
namespace low_latency {
class DeviceContext;
class AntiLagDeviceStrategy final : public DeviceStrategy {
+ private:
+ std::shared_mutex mutex{};
+ // If this is nullopt don't track the submission.
+ std::optional<std::uint64_t> frame_index{};
+ std::chrono::microseconds delay{};
+ bool is_enabled{};
+
public:
AntiLagDeviceStrategy(DeviceContext& device);
virtual ~AntiLagDeviceStrategy();
+
+ public:
+ void notify_update(const VkAntiLagDataAMD& data);
+
+ bool should_track_submissions();
};
} // namespace low_latency
diff --git a/src/strategies/anti_lag/queue_strategy.cc b/src/strategies/anti_lag/queue_strategy.cc
index ba60535..9dbe127 100644
--- a/src/strategies/anti_lag/queue_strategy.cc
+++ b/src/strategies/anti_lag/queue_strategy.cc
@@ -1,4 +1,7 @@
#include "queue_strategy.hh"
+#include "device_context.hh"
+#include "device_strategy.hh"
+#include "queue_context.hh"
namespace low_latency {
@@ -7,4 +10,53 @@ AntiLagQueueStrategy::AntiLagQueueStrategy(QueueContext& queue)
AntiLagQueueStrategy::~AntiLagQueueStrategy() {}
+void AntiLagQueueStrategy::notify_submit(
+ [[maybe_unused]] const VkSubmitInfo& submit,
+ std::unique_ptr<Submission> submission) {
+
+ const auto strategy =
+ dynamic_cast<AntiLagDeviceStrategy*>(this->queue.device.strategy.get());
+ assert(strategy);
+ if (!strategy->should_track_submissions()) {
+ return;
+ }
+
+ const auto lock = std::scoped_lock(this->mutex);
+ this->pending_submissions.push_back(std::move(submission));
+}
+
+void AntiLagQueueStrategy::notify_submit(
+ [[maybe_unused]] const VkSubmitInfo2& submit,
+ std::unique_ptr<Submission> submission) {
+
+ const auto strategy =
+ dynamic_cast<AntiLagDeviceStrategy*>(this->queue.device.strategy.get());
+ assert(strategy);
+ if (!strategy->should_track_submissions()) {
+ return;
+ }
+
+ const auto lock = std::scoped_lock(this->mutex);
+ this->pending_submissions.push_back(std::move(submission));
+}
+
+void AntiLagQueueStrategy::await_complete() {
+
+ // Grab submissions while under a lock.
+ const auto submissions = [&]() -> std::deque<std::unique_ptr<Submission>> {
+ const auto lock = std::scoped_lock{this->mutex};
+
+ auto submissions = std::move(this->pending_submissions);
+ this->pending_submissions.clear();
+ return submissions;
+ }();
+
+ // Wait for completion on the last submission.
+ if (submissions.empty()) {
+ return;
+ }
+ const auto& last = submissions.back();
+ last->end->await_time();
+}
+
} // namespace low_latency
diff --git a/src/strategies/anti_lag/queue_strategy.hh b/src/strategies/anti_lag/queue_strategy.hh
index 81ae653..3887474 100644
--- a/src/strategies/anti_lag/queue_strategy.hh
+++ b/src/strategies/anti_lag/queue_strategy.hh
@@ -3,14 +3,33 @@
#include "strategies/queue_strategy.hh"
+#include <deque>
+#include <memory>
+#include <mutex>
+
namespace low_latency {
class QueueContext;
class AntiLagQueueStrategy final : public QueueStrategy {
+ private:
+ std::mutex mutex;
+ std::deque<std::unique_ptr<Submission>> pending_submissions;
+
public:
AntiLagQueueStrategy(QueueContext& queue);
virtual ~AntiLagQueueStrategy();
+
+ public:
+ virtual void notify_submit(const VkSubmitInfo& submit,
+ std::unique_ptr<Submission> submission) override;
+ virtual void notify_submit(const VkSubmitInfo2& submit,
+ std::unique_ptr<Submission> submission) override;
+
+ public:
+ // Wait for all pending submissions to complete. Resets pending submissions
+ // once done.
+ void await_complete();
};
} // namespace low_latency
diff --git a/src/strategies/device_strategy.hh b/src/strategies/device_strategy.hh
index 1b95e11..7b7bacd 100644
--- a/src/strategies/device_strategy.hh
+++ b/src/strategies/device_strategy.hh
@@ -6,11 +6,15 @@ namespace low_latency {
class DeviceContext;
class DeviceStrategy {
+ protected:
DeviceContext& device;
public:
DeviceStrategy(DeviceContext& device);
virtual ~DeviceStrategy();
+
+ public:
+
};
} // namespace low_latency
diff --git a/src/strategies/low_latency2/queue_strategy.cc b/src/strategies/low_latency2/queue_strategy.cc
index 85e1aae..e67d279 100644
--- a/src/strategies/low_latency2/queue_strategy.cc
+++ b/src/strategies/low_latency2/queue_strategy.cc
@@ -7,4 +7,12 @@ LowLatency2QueueStrategy::LowLatency2QueueStrategy(QueueContext& queue)
LowLatency2QueueStrategy::~LowLatency2QueueStrategy() {}
+void LowLatency2QueueStrategy::notify_submit(
+ [[maybe_unused]] const VkSubmitInfo& submit,
+ [[maybe_unused]] std::unique_ptr<Submission> submission) {}
+
+void LowLatency2QueueStrategy::notify_submit(
+ [[maybe_unused]] const VkSubmitInfo2& submit,
+ [[maybe_unused]] std::unique_ptr<Submission> submission) {}
+
} // namespace low_latency
diff --git a/src/strategies/low_latency2/queue_strategy.hh b/src/strategies/low_latency2/queue_strategy.hh
index 9688cf4..ad31df4 100644
--- a/src/strategies/low_latency2/queue_strategy.hh
+++ b/src/strategies/low_latency2/queue_strategy.hh
@@ -11,6 +11,12 @@ class LowLatency2QueueStrategy final : public QueueStrategy {
public:
LowLatency2QueueStrategy(QueueContext& queue);
virtual ~LowLatency2QueueStrategy();
+
+ public:
+ virtual void notify_submit(const VkSubmitInfo& submit,
+ std::unique_ptr<Submission> submission) override;
+ virtual void notify_submit(const VkSubmitInfo2& submit,
+ std::unique_ptr<Submission> submission) override;
};
} // namespace low_latency
diff --git a/src/strategies/queue_strategy.hh b/src/strategies/queue_strategy.hh
index 0b9edc8..37bad02 100644
--- a/src/strategies/queue_strategy.hh
+++ b/src/strategies/queue_strategy.hh
@@ -1,16 +1,28 @@
#ifndef STRATEGIES_QUEUE_STRATEGY_HH_
#define STRATEGIES_QUEUE_STRATEGY_HH_
+#include "submission.hh"
+#include "timestamp_pool.hh"
+
+#include <vulkan/vulkan.h>
+
namespace low_latency {
class QueueContext;
class QueueStrategy {
+ protected:
QueueContext& queue;
public:
QueueStrategy(QueueContext& queue);
virtual ~QueueStrategy();
+
+ public:
+ virtual void notify_submit(const VkSubmitInfo& submit,
+ std::unique_ptr<Submission> submission) = 0;
+ virtual void notify_submit(const VkSubmitInfo2& submit,
+ std::unique_ptr<Submission> submission) = 0;
};
} // namespace low_latency