diff options
Diffstat (limited to 'src/strategies')
| -rw-r--r-- | src/strategies/anti_lag/device_strategy.cc | 59 | ||||
| -rw-r--r-- | src/strategies/anti_lag/device_strategy.hh | 17 | ||||
| -rw-r--r-- | src/strategies/anti_lag/queue_strategy.cc | 52 | ||||
| -rw-r--r-- | src/strategies/anti_lag/queue_strategy.hh | 19 | ||||
| -rw-r--r-- | src/strategies/device_strategy.hh | 4 | ||||
| -rw-r--r-- | src/strategies/low_latency2/queue_strategy.cc | 8 | ||||
| -rw-r--r-- | src/strategies/low_latency2/queue_strategy.hh | 6 | ||||
| -rw-r--r-- | src/strategies/queue_strategy.hh | 12 |
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 |
