#ifndef TIMESTAMP_POOL_HH_ #define TIMESTAMP_POOL_HH_ // The purpose of this file is to provide the definition of a 'timestamp pool'. // It manages blocks of timestamp query pools, hands them out when requested, // and allocates more when (if) we run out. // Usage: // 1. Get handle with .acquire(). // 2. Write start/end timestamp operations with the handle's pool and index // into the provided command buffer. Will return nullopt if they're // not yet available. // 3. Destruct the handle to return the key to the pool. #include #include #include #include #include namespace low_latency { class QueueContext; class TimestampPool final { private: QueueContext& queue_context; // A chunk of data which is useful for making timestamp queries. // Allows association of an index to a query pool and command buffer. // We reuse these when they're released. struct QueryChunk final { private: using free_indices_t = std::unordered_set; static constexpr auto CHUNK_SIZE = 512u; public: VkQueryPool query_pool; std::unique_ptr free_indices; std::unique_ptr> command_buffers; public: QueryChunk(const QueueContext& queue_context); QueryChunk(const QueryChunk& handle) = delete; QueryChunk(QueryChunk&&) = delete; QueryChunk operator=(const QueryChunk& handle) = delete; QueryChunk operator=(QueryChunk&&) = delete; ~QueryChunk(); }; std::unordered_set> query_chunks; public: // A handle represents a VkCommandBuffer and a query index. // Once the Handle goes out of scope, the query index will be returned // to the parent pool. struct Handle final { private: friend class TimestampPool; private: const std::weak_ptr origin_chunk; public: const VkQueryPool query_pool; const std::uint64_t query_index; const VkCommandBuffer command_buffer; public: Handle(const std::shared_ptr& origin_chunk, const std::uint64_t& query_index); Handle(const Handle& handle) = delete; Handle(Handle&&) = delete; Handle operator=(const Handle& handle) = delete; Handle operator=(Handle&&) = delete; ~Handle(); public: void setup_command_buffers(const Handle& tail, const QueueContext& queue_context) const; std::optional get_ticks(const TimestampPool& pool); }; public: TimestampPool(QueueContext& queue_context); TimestampPool(const TimestampPool&) = delete; TimestampPool(TimestampPool&&) = delete; TimestampPool operator=(const TimestampPool&) = delete; TimestampPool operator=(TimestampPool&&) = delete; ~TimestampPool(); public: // Hands out a Handle! std::shared_ptr acquire(); }; } // namespace low_latency #endif