diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame_span.cc | 24 | ||||
| -rw-r--r-- | src/frame_span.hh | 37 | ||||
| -rw-r--r-- | src/layer.cc | 30 | ||||
| -rw-r--r-- | src/strategies/anti_lag/device_strategy.cc | 26 | ||||
| -rw-r--r-- | src/strategies/anti_lag/queue_strategy.cc | 33 | ||||
| -rw-r--r-- | src/strategies/anti_lag/queue_strategy.hh | 21 | ||||
| -rw-r--r-- | src/strategies/low_latency2/device_strategy.cc | 10 | ||||
| -rw-r--r-- | src/strategies/low_latency2/queue_strategy.cc | 44 | ||||
| -rw-r--r-- | src/strategies/low_latency2/queue_strategy.hh | 21 | ||||
| -rw-r--r-- | src/strategies/low_latency2/swapchain_monitor.cc | 33 | ||||
| -rw-r--r-- | src/strategies/low_latency2/swapchain_monitor.hh | 16 | ||||
| -rw-r--r-- | src/strategies/queue_strategy.hh | 11 | ||||
| -rw-r--r-- | src/submission.cc | 5 | ||||
| -rw-r--r-- | src/submission.hh | 17 | ||||
| -rw-r--r-- | src/timestamp_pool.cc | 14 | ||||
| -rw-r--r-- | src/timestamp_pool.hh | 12 |
16 files changed, 186 insertions, 168 deletions
diff --git a/src/frame_span.cc b/src/frame_span.cc new file mode 100644 index 0000000..732d6f3 --- /dev/null +++ b/src/frame_span.cc @@ -0,0 +1,24 @@ +#include "frame_span.hh" + +namespace low_latency { + +FrameSpan::FrameSpan(std::shared_ptr<TimestampPool::Handle> handle) + : head_handle(std::move(handle)) { + assert(this->head_handle); // Must not be null +} + +FrameSpan::~FrameSpan() {} + +void FrameSpan::update(std::shared_ptr<TimestampPool::Handle> handle) { + this->tail_handle = std::move(handle); +} + +void FrameSpan::await_completed() const { + if (this->tail_handle) { + this->tail_handle->await_end(); + return; + } + this->head_handle->await_end(); +} + +} // namespace low_latency
\ No newline at end of file diff --git a/src/frame_span.hh b/src/frame_span.hh new file mode 100644 index 0000000..5220702 --- /dev/null +++ b/src/frame_span.hh @@ -0,0 +1,37 @@ +#ifndef FRAME_SPAN_HH_ +#define FRAME_SPAN_HH_ + +#include "timestamp_pool.hh" + +namespace low_latency { + +// A class which contains timestamps that represent a Queue's contribution to +// a frame. It reduces the (possibly) huge amount of TimestampPool::Handle's +// that a queue needs to keep track of. It only keeps at max two - the first +// head handle and the tail handle, which is allowed to be null in the case of +// only a single submission for that queue. +class FrameSpan { + public: + const std::shared_ptr<TimestampPool::Handle> head_handle; + std::shared_ptr<TimestampPool::Handle> tail_handle; + + public: + FrameSpan(std::shared_ptr<TimestampPool::Handle> handle); + FrameSpan(const FrameSpan&) = delete; + FrameSpan(FrameSpan&&) = delete; + FrameSpan operator=(const FrameSpan&) = delete; + FrameSpan operator=(FrameSpan&&) = delete; + ~FrameSpan(); + + public: + // Update the framespan's tail to include this timestamp. + void update(std::shared_ptr<TimestampPool::Handle> handle); + + public: + // Wait for for GPU work to complete. + void await_completed() const; +}; + +} // namespace low_latency + +#endif
\ No newline at end of file diff --git a/src/layer.cc b/src/layer.cc index 6c275ba..5df896a 100644 --- a/src/layer.cc +++ b/src/layer.cc @@ -394,19 +394,14 @@ vkQueueSubmit(VkQueue queue, std::uint32_t submit_count, // pointers to our command buffer arrays - of which the position in memory // of can change on vector reallocation. So we use unique_ptrs here. auto next_cbs = std::vector<std::unique_ptr<cbs_t>>{}; - auto submissions = std::vector<std::unique_ptr<Submission>>{}; + auto handles = std::vector<std::shared_ptr<TimestampPool::Handle>>{}; - const auto now = DeviceClock::now(); const auto submit_span = std::span{submit_infos, submit_count}; std::ranges::transform( submit_span, std::back_inserter(next_submits), [&](const auto& submit) { const auto handle = context->timestamp_pool->acquire(); - - submissions.push_back(std::make_unique<Submission>(Submission{ - .handle = handle, - .time = now, - })); + handles.push_back(handle); next_cbs.emplace_back([&]() -> auto { auto cbs = std::make_unique<cbs_t>(); @@ -431,10 +426,8 @@ vkQueueSubmit(VkQueue queue, std::uint32_t submit_count, // We have to notify after we submit - otherwise we have a race where we // wait for work that wasn't submitted. - for (auto&& [submit, submission] : - std::views::zip(submit_span, submissions)) { - - context->strategy->notify_submit(submit, std::move(submission)); + for (auto&& [submit, handle] : std::views::zip(submit_span, handles)) { + context->strategy->notify_submit(submit, std::move(handle)); } return result; @@ -455,19 +448,14 @@ vkQueueSubmit2(VkQueue queue, std::uint32_t submit_count, using cbs_t = std::vector<VkCommandBufferSubmitInfo>; auto next_submits = std::vector<VkSubmitInfo2>{}; auto next_cbs = std::vector<std::unique_ptr<cbs_t>>{}; - auto submissions = std::vector<std::unique_ptr<Submission>>{}; + auto handles = std::vector<std::shared_ptr<TimestampPool::Handle>>{}; - const auto now = DeviceClock::now(); const auto submit_span = std::span{submit_infos, submit_count}; std::ranges::transform( submit_span, std::back_inserter(next_submits), [&](const auto& submit) { const auto handle = context->timestamp_pool->acquire(); - - submissions.push_back(std::make_unique<Submission>(Submission{ - .handle = handle, - .time = now, - })); + handles.push_back(handle); next_cbs.emplace_back([&]() -> auto { auto cbs = std::make_unique<cbs_t>(); @@ -496,10 +484,8 @@ vkQueueSubmit2(VkQueue queue, std::uint32_t submit_count, queue, static_cast<std::uint32_t>(std::size(next_submits)), std::data(next_submits), fence); - for (auto&& [submit, submission] : - std::views::zip(submit_span, submissions)) { - - context->strategy->notify_submit(submit, std::move(submission)); + for (auto&& [submit, handle] : std::views::zip(submit_span, handles)) { + context->strategy->notify_submit(submit, std::move(handle)); } return result; diff --git a/src/strategies/anti_lag/device_strategy.cc b/src/strategies/anti_lag/device_strategy.cc index b391371..2d1d9ad 100644 --- a/src/strategies/anti_lag/device_strategy.cc +++ b/src/strategies/anti_lag/device_strategy.cc @@ -15,7 +15,7 @@ AntiLagDeviceStrategy::AntiLagDeviceStrategy(DeviceContext& device) AntiLagDeviceStrategy::~AntiLagDeviceStrategy() {} void AntiLagDeviceStrategy::notify_update(const VkAntiLagDataAMD& data) { - const auto lock = std::scoped_lock{this->mutex}; + auto lock = std::unique_lock{this->mutex}; this->is_enabled = !(data.mode == VK_ANTI_LAG_MODE_OFF_AMD); @@ -37,11 +37,14 @@ void AntiLagDeviceStrategy::notify_update(const VkAntiLagDataAMD& data) { this->frame_index.reset(); return; } - // If we're at the input stage, start marking submissions as relevant. this->frame_index.emplace(data.pPresentationInfo->frameIndex); - { // Input stage needs to wait for all queue submissions to complete. + lock.unlock(); + // We need to collect all queue submission and wait on them in this thread. + // Input stage needs to wait for all queue submissions to complete. + const auto queue_frame_spans = [&]() -> auto { + auto queue_frame_spans = std::vector<std::unique_ptr<FrameSpan>>{}; const auto device_lock = std::shared_lock{this->device.mutex}; for (const auto& iter : this->device.queues) { const auto& queue = iter.second; @@ -50,15 +53,30 @@ void AntiLagDeviceStrategy::notify_update(const VkAntiLagDataAMD& data) { dynamic_cast<AntiLagQueueStrategy*>(queue->strategy.get()); assert(strategy); - strategy->await_complete(); + // Grab it from the queue, don't hold the lock. + const auto queue_lock = std::scoped_lock{strategy->mutex}; + queue_frame_spans.emplace_back(std::move(strategy->frame_span)); + strategy->frame_span.reset(); + } + return queue_frame_spans; + }(); + + // Wait on them and relock the mutex. + for (const auto& frame_span : queue_frame_spans) { + if (frame_span) { // Can still be null here. + frame_span->await_completed(); } } + lock.lock(); + // We might need to wait a little more time to meet our frame limit. using namespace std::chrono; if (this->delay != 0us && this->previous_input_release.has_value()) { + lock.unlock(); std::this_thread::sleep_until(*this->previous_input_release + this->delay); + lock.lock(); } this->previous_input_release = steady_clock::now(); diff --git a/src/strategies/anti_lag/queue_strategy.cc b/src/strategies/anti_lag/queue_strategy.cc index 27a9337..9c49e7c 100644 --- a/src/strategies/anti_lag/queue_strategy.cc +++ b/src/strategies/anti_lag/queue_strategy.cc @@ -12,7 +12,7 @@ AntiLagQueueStrategy::~AntiLagQueueStrategy() {} void AntiLagQueueStrategy::notify_submit( [[maybe_unused]] const VkSubmitInfo& submit, - std::unique_ptr<Submission> submission) { + std::shared_ptr<TimestampPool::Handle> handle) { const auto strategy = dynamic_cast<AntiLagDeviceStrategy*>(this->queue.device.strategy.get()); @@ -22,12 +22,16 @@ void AntiLagQueueStrategy::notify_submit( } const auto lock = std::scoped_lock(this->mutex); - this->pending_submissions.push_back(std::move(submission)); + if (this->frame_span) { + this->frame_span->update(std::move(handle)); + } else { + this->frame_span = std::make_unique<FrameSpan>(std::move(handle)); + } } void AntiLagQueueStrategy::notify_submit( [[maybe_unused]] const VkSubmitInfo2& submit, - std::unique_ptr<Submission> submission) { + std::shared_ptr<TimestampPool::Handle> handle) { const auto strategy = dynamic_cast<AntiLagDeviceStrategy*>(this->queue.device.strategy.get()); @@ -37,26 +41,11 @@ void AntiLagQueueStrategy::notify_submit( } 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; + if (this->frame_span) { + this->frame_span->update(std::move(handle)); + } else { + this->frame_span = std::make_unique<FrameSpan>(std::move(handle)); } - const auto& last = submissions.back(); - last->handle->await_end_time(); } // Stub - AntiLag doesn't care about presents. diff --git a/src/strategies/anti_lag/queue_strategy.hh b/src/strategies/anti_lag/queue_strategy.hh index 37c44a5..b1ae3e6 100644 --- a/src/strategies/anti_lag/queue_strategy.hh +++ b/src/strategies/anti_lag/queue_strategy.hh @@ -3,7 +3,7 @@ #include "strategies/queue_strategy.hh" -#include <deque> +#include "frame_span.hh" #include <memory> #include <mutex> @@ -12,25 +12,22 @@ namespace low_latency { class QueueContext; class AntiLagQueueStrategy final : public QueueStrategy { - private: + public: std::mutex mutex; - std::deque<std::unique_ptr<Submission>> pending_submissions; + std::unique_ptr<FrameSpan> frame_span; // Null represents no work. 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; + virtual void + notify_submit(const VkSubmitInfo& submit, + std::shared_ptr<TimestampPool::Handle> handle) override; + virtual void + notify_submit(const VkSubmitInfo2& submit, + std::shared_ptr<TimestampPool::Handle> handle) override; virtual void notify_present(const VkPresentInfoKHR& present) 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/low_latency2/device_strategy.cc b/src/strategies/low_latency2/device_strategy.cc index 32ff981..227c385 100644 --- a/src/strategies/low_latency2/device_strategy.cc +++ b/src/strategies/low_latency2/device_strategy.cc @@ -68,8 +68,8 @@ void LowLatency2DeviceStrategy::submit_swapchain_present_id( // Iterate through all queues and grab any work that's associated with this // present_id. Turn it into a vector of work that we give to our swapchain // monitor. - auto work = [&]() -> std::vector<std::deque<std::unique_ptr<Submission>>> { - auto work = std::vector<std::deque<std::unique_ptr<Submission>>>{}; + auto work = [&]() -> std::vector<std::unique_ptr<FrameSpan>> { + auto work = std::vector<std::unique_ptr<FrameSpan>>{}; const auto lock = std::scoped_lock{this->device.mutex}; for (const auto& queue_iter : this->device.queues) { const auto& queue = queue_iter.second; @@ -84,14 +84,14 @@ void LowLatency2DeviceStrategy::submit_swapchain_present_id( // Need the lock now - we're modifying it. const auto strategy_lock = std::unique_lock{strategy->mutex}; - const auto iter = strategy->present_id_submissions.find(present_id); - if (iter == std::end(strategy->present_id_submissions)) { + const auto iter = strategy->frame_spans.find(present_id); + if (iter == std::end(strategy->frame_spans)) { continue; } // Make sure we clean it up from the present as well. work.push_back(std::move(iter->second)); - strategy->present_id_submissions.erase(iter); + strategy->frame_spans.erase(iter); } return work; }(); diff --git a/src/strategies/low_latency2/queue_strategy.cc b/src/strategies/low_latency2/queue_strategy.cc index 9a68b78..a020c0d 100644 --- a/src/strategies/low_latency2/queue_strategy.cc +++ b/src/strategies/low_latency2/queue_strategy.cc @@ -16,50 +16,48 @@ LowLatency2QueueStrategy::~LowLatency2QueueStrategy() {} template <typename T> static void notify_submit_impl(LowLatency2QueueStrategy& strategy, const T& submit, - std::unique_ptr<Submission> submission) { + std::shared_ptr<TimestampPool::Handle> handle) { // It's actually not a requirement that we have this present id. - const auto lspi = find_next<VkLatencySubmissionPresentIdNV>( - &submit, VK_STRUCTURE_TYPE_LATENCY_SUBMISSION_PRESENT_ID_NV); - const auto present_id = lspi ? lspi->presentID : 0; + const auto present_id = [&]() -> std::uint64_t { + const auto lspi = find_next<VkLatencySubmissionPresentIdNV>( + &submit, VK_STRUCTURE_TYPE_LATENCY_SUBMISSION_PRESENT_ID_NV); + return lspi ? lspi->presentID : 0; + }(); const auto lock = std::scoped_lock{strategy.mutex}; - const auto [iter, inserted] = - strategy.present_id_submissions.try_emplace(present_id); - iter->second.push_back(std::move(submission)); - - // Remove stale submissions if we're presenting a lot to the same - // present_id. This doesn't affect anything because we're waiting on the - // last. It begs the question: should we should just store the last only? - if (std::size(iter->second) >= - LowLatency2QueueStrategy::MAX_TRACKED_OBJECTS) { - - iter->second.pop_front(); + const auto [iter, inserted] = strategy.frame_spans.try_emplace(present_id); + if (inserted) { + iter->second = std::make_unique<FrameSpan>(std::move(handle)); + } else { + iter->second->update(std::move(handle)); } // Add our present_id to our ring tracking if it's non-zero. if (inserted && present_id) { - strategy.present_id_ring.push_back(present_id); + strategy.stale_present_ids.push_back(present_id); } // Remove stale present_id's if they weren't presented to. - if (std::size(strategy.present_id_ring) > - LowLatency2QueueStrategy::MAX_TRACKED_OBJECTS) { + if (std::size(strategy.stale_present_ids) > + LowLatency2QueueStrategy::MAX_TRACKED_PRESENTS) { - const auto to_remove = strategy.present_id_ring.front(); - strategy.present_id_ring.pop_front(); - strategy.present_id_submissions.erase(to_remove); + const auto stale_present_id = strategy.stale_present_ids.front(); + strategy.stale_present_ids.pop_front(); + strategy.frame_spans.erase(stale_present_id); } } void LowLatency2QueueStrategy::notify_submit( - const VkSubmitInfo& submit, std::unique_ptr<Submission> submission) { + const VkSubmitInfo& submit, + std::shared_ptr<TimestampPool::Handle> submission) { notify_submit_impl(*this, submit, std::move(submission)); } void LowLatency2QueueStrategy::notify_submit( - const VkSubmitInfo2& submit, std::unique_ptr<Submission> submission) { + const VkSubmitInfo2& submit, + std::shared_ptr<TimestampPool::Handle> submission) { notify_submit_impl(*this, submit, std::move(submission)); } diff --git a/src/strategies/low_latency2/queue_strategy.hh b/src/strategies/low_latency2/queue_strategy.hh index a090e1b..6d41027 100644 --- a/src/strategies/low_latency2/queue_strategy.hh +++ b/src/strategies/low_latency2/queue_strategy.hh @@ -1,8 +1,8 @@ #ifndef STRATEGIES_LOW_LATENCY2_QUEUE_STRATEGY_HH_ #define STRATEGIES_LOW_LATENCY2_QUEUE_STRATEGY_HH_ +#include "frame_span.hh" #include "strategies/queue_strategy.hh" -#include "submission.hh" #include <atomic> #include <deque> @@ -16,26 +16,27 @@ class QueueContext; class LowLatency2QueueStrategy final : public QueueStrategy { public: - static constexpr auto MAX_TRACKED_OBJECTS = 50; + static constexpr auto MAX_TRACKED_PRESENTS = 50; // Mapping of present_id's to submissions. Grabbed later by the device // strategy when we present and actually can associate them to some // vkSwapchainKHR. std::mutex mutex{}; - std::unordered_map<std::uint64_t, std::deque<std::unique_ptr<Submission>>> - present_id_submissions{}; - std::deque<std::uint64_t> present_id_ring{}; - std::atomic<bool> is_out_of_band{}; // atomic so we don't need a lock check + std::unordered_map<std::uint64_t, std::unique_ptr<FrameSpan>> frame_spans{}; + std::deque<std::uint64_t> stale_present_ids{}; + std::atomic<bool> is_out_of_band{}; // atomic to avoid lock 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; + virtual void + notify_submit(const VkSubmitInfo& submit, + std::shared_ptr<TimestampPool::Handle> handle) override; + virtual void + notify_submit(const VkSubmitInfo2& submit, + std::shared_ptr<TimestampPool::Handle> handle) override; virtual void notify_present(const VkPresentInfoKHR& present) override; public: diff --git a/src/strategies/low_latency2/swapchain_monitor.cc b/src/strategies/low_latency2/swapchain_monitor.cc index b6d4dd0..a70fa6c 100644 --- a/src/strategies/low_latency2/swapchain_monitor.cc +++ b/src/strategies/low_latency2/swapchain_monitor.cc @@ -35,32 +35,29 @@ void SwapchainMonitor::do_monitor(const std::stop_token stoken) { for (;;) { auto lock = std::unique_lock{this->mutex}; this->cv.wait(lock, stoken, - [&]() { return this->semaphore_submission.has_value(); }); + [&]() { return this->semaphore_spans.has_value(); }); // Stop only if we're stopped and we have nothing to signal. - if (stoken.stop_requested() && - !this->semaphore_submission.has_value()) { + if (stoken.stop_requested() && !this->semaphore_spans.has_value()) { break; } // Grab the most recent semaphore. When work completes, signal it. - const auto semaphore_submission = - std::move(*this->semaphore_submission); - this->semaphore_submission.reset(); + const auto semaphore_span = std::move(*this->semaphore_spans); + this->semaphore_spans.reset(); // If we're stopping, signal the semaphore and don't worry about work // actually completing. if (stoken.stop_requested()) { - semaphore_submission.wakeup_semaphore.signal(this->device); + semaphore_span.wakeup_semaphore.signal(this->device); break; } // Unlock, wait for work to finish, lock again. lock.unlock(); - for (const auto& submission : semaphore_submission.submissions) { - if (!submission.empty()) { - const auto& last = submission.back(); - last->handle->await_end_time(); + for (const auto& frame_span : semaphore_span.frame_spans) { + if (frame_span) { + frame_span->await_completed(); } } @@ -78,7 +75,7 @@ void SwapchainMonitor::do_monitor(const std::stop_token stoken) { } lock.unlock(); - semaphore_submission.wakeup_semaphore.signal(this->device); + semaphore_span.wakeup_semaphore.signal(this->device); } } @@ -97,29 +94,29 @@ void SwapchainMonitor::notify_semaphore(const VkSemaphore& timeline_semaphore, } // Signal immediately if we have no outstanding work. - if (this->pending_submissions.empty()) { + if (this->pending_frame_spans.empty()) { wakeup_semaphore.signal(this->device); return; } - this->semaphore_submission.emplace(SemaphoreSubmissions{ + this->semaphore_spans.emplace(SemaphoreSpans{ .wakeup_semaphore = wakeup_semaphore, - .submissions = std::move(this->pending_submissions), + .frame_spans = std::move(this->pending_frame_spans), }); - this->pending_submissions.clear(); + this->pending_frame_spans.clear(); lock.unlock(); this->cv.notify_one(); } void SwapchainMonitor::attach_work( - std::vector<std::deque<std::unique_ptr<Submission>>> submissions) { + std::vector<std::unique_ptr<FrameSpan>> frame_spans) { const auto lock = std::scoped_lock{this->mutex}; if (!this->was_low_latency_requested) { return; } - this->pending_submissions = std::move(submissions); + this->pending_frame_spans = std::move(frame_spans); } } // namespace low_latency
\ No newline at end of file diff --git a/src/strategies/low_latency2/swapchain_monitor.hh b/src/strategies/low_latency2/swapchain_monitor.hh index 47c3a75..837f8e4 100644 --- a/src/strategies/low_latency2/swapchain_monitor.hh +++ b/src/strategies/low_latency2/swapchain_monitor.hh @@ -2,17 +2,16 @@ #ifndef SWAPCHAIN_MONITOR_HH_ #define SWAPCHAIN_MONITOR_HH_ +#include "frame_span.hh" + #include <vulkan/vulkan.h> #include <chrono> #include <condition_variable> -#include <deque> #include <memory> #include <mutex> #include <thread> -#include "submission.hh" - namespace low_latency { class DeviceContext; @@ -28,15 +27,15 @@ class SwapchainMonitor final { }; // An empty vector here represents our 'no work' state. - std::vector<std::deque<std::unique_ptr<Submission>>> pending_submissions{}; + std::vector<std::unique_ptr<FrameSpan>> pending_frame_spans{}; // A pairing of semaphore -> submissions. // If the Submissions completes then signal the bundled semaphore. - struct SemaphoreSubmissions { + struct SemaphoreSpans { WakeupSemaphore wakeup_semaphore{}; - std::vector<std::deque<std::unique_ptr<Submission>>> submissions{}; + std::vector<std::unique_ptr<FrameSpan>> frame_spans{}; }; - std::optional<SemaphoreSubmissions> semaphore_submission{}; + std::optional<SemaphoreSpans> semaphore_spans{}; protected: const DeviceContext& device; @@ -67,8 +66,7 @@ class SwapchainMonitor final { void notify_semaphore(const VkSemaphore& timeline_semaphore, const std::uint64_t& value); - void attach_work( - std::vector<std::deque<std::unique_ptr<Submission>>> submissions); + void attach_work(std::vector<std::unique_ptr<FrameSpan>> submissions); }; } // namespace low_latency diff --git a/src/strategies/queue_strategy.hh b/src/strategies/queue_strategy.hh index b4fbcb9..0bc0dbb 100644 --- a/src/strategies/queue_strategy.hh +++ b/src/strategies/queue_strategy.hh @@ -1,7 +1,6 @@ #ifndef STRATEGIES_QUEUE_STRATEGY_HH_ #define STRATEGIES_QUEUE_STRATEGY_HH_ -#include "submission.hh" #include "timestamp_pool.hh" #include <vulkan/vulkan.h> @@ -19,10 +18,12 @@ class QueueStrategy { 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; + virtual void + notify_submit(const VkSubmitInfo& submit, + std::shared_ptr<TimestampPool::Handle> handle) = 0; + virtual void + notify_submit(const VkSubmitInfo2& submit, + std::shared_ptr<TimestampPool::Handle> handle) = 0; virtual void notify_present(const VkPresentInfoKHR& present) = 0; }; diff --git a/src/submission.cc b/src/submission.cc deleted file mode 100644 index 1a6cb72..0000000 --- a/src/submission.cc +++ /dev/null @@ -1,5 +0,0 @@ -#include "submission.hh" - -namespace low_latency { - -} // namespace low_latency
\ No newline at end of file diff --git a/src/submission.hh b/src/submission.hh deleted file mode 100644 index ba721c2..0000000 --- a/src/submission.hh +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef SUBMISSIONS_HH_ -#define SUBMISSIONS_HH_ - -#include "device_clock.hh" -#include "timestamp_pool.hh" - -namespace low_latency { - -class Submission { - public: - std::shared_ptr<TimestampPool::Handle> handle; - DeviceClock::time_point_t time; -}; - -} // namespace low_latency - -#endif
\ No newline at end of file diff --git a/src/timestamp_pool.cc b/src/timestamp_pool.cc index b52e8f8..afb12f7 100644 --- a/src/timestamp_pool.cc +++ b/src/timestamp_pool.cc @@ -164,7 +164,7 @@ void TimestampPool::do_reaper(const std::stop_token stoken) { // Allow more to go on the queue while we wait for it to finish. lock.unlock(); - handle_ptr->await_end_time(); + handle_ptr->await_end(); // Lock our mutex, allow the queue to use it again and delete it. lock.lock(); @@ -185,7 +185,7 @@ const VkCommandBuffer& TimestampPool::Handle::get_end_buffer() const { return command_buffers[this->query_index + 1]; } -DeviceClock::time_point_t +std::uint64_t TimestampPool::Handle::await_time_impl(const std::uint32_t offset) const { const auto& context = this->timestamp_pool.queue_context.device; @@ -201,15 +201,11 @@ TimestampPool::Handle::await_time_impl(const std::uint32_t offset) const { VK_QUERY_RESULT_WAIT_BIT)); assert(query_result[1]); - return context.clock->ticks_to_time(query_result[0]); + return query_result[0]; } -DeviceClock::time_point_t TimestampPool::Handle::await_start_time() const { - return this->await_time_impl(0); -} -DeviceClock::time_point_t TimestampPool::Handle::await_end_time() const { - return this->await_time_impl(1); -} +void TimestampPool::Handle::await_start() const { this->await_time_impl(0); } +void TimestampPool::Handle::await_end() const { this->await_time_impl(1); } TimestampPool::~TimestampPool() {} diff --git a/src/timestamp_pool.hh b/src/timestamp_pool.hh index 9044864..809c6a4 100644 --- a/src/timestamp_pool.hh +++ b/src/timestamp_pool.hh @@ -14,8 +14,6 @@ #include <unordered_set> #include <vector> -#include "device_clock.hh" - namespace low_latency { class QueueContext; @@ -125,13 +123,13 @@ class TimestampPool final { const VkCommandBuffer& get_end_buffer() const; private: - DeviceClock::time_point_t - await_time_impl(const std::uint32_t offset) const; + // Returns the device ticks. FIXME wrap device ticks. + std::uint64_t await_time_impl(const std::uint32_t offset) const; public: - // Waits until the time is available and returns it. - DeviceClock::time_point_t await_start_time() const; - DeviceClock::time_point_t await_end_time() const; + // Blocks until the time is available. + void await_start() const; + void await_end() const; }; private: |
