blob: 820e4b284c51904bf13a3b091048f63ca94ebea5 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <vector>
#include "lib/escher/forward_declarations.h"
#include "lib/escher/vk/vulkan_context.h"
#include "lib/fxl/memory/ref_counted.h"
namespace escher {
class TimestampProfiler : public fxl::RefCountedThreadSafe<TimestampProfiler> {
public:
TimestampProfiler(vk::Device device, float timestamp_period);
~TimestampProfiler();
// Add a Vulkan timestamp-query that will mark the time that all previous
// commands in |cmd_buf| have finished the pipeline stage specified by
// |flags|. For example, use eVertexShader to mark the time that vertex
// shaders have been applied to all vertices from previous draw-calls.
//
// Note: you should understand the caveats in the Vulkan spec regarding the
// accuracy of these timestamps.
void AddTimestamp(impl::CommandBuffer* cmd_buf,
vk::PipelineStageFlagBits flags,
std::string name);
struct Result {
uint64_t raw_nanoseconds; // nanoseconds according to some timebase.
uint64_t time; // microseconds elapsed since the first timestamp.
uint64_t elapsed; // microseconds elapsed since the previous timestamp.
std::string name;
};
std::vector<Result> GetQueryResults();
private:
// Each QueryRange keeps track of current usage of a separate vk::QueryPool.
// A new pool (and hence a new QueryRange) is used whenever:
// - the capacity of the previous pool is reached.
// - a different CommandBuffer is passed to AddTimestamp().
struct QueryRange {
vk::QueryPool pool;
vk::CommandBuffer command_buffer;
uint32_t start_index; // within the pool
uint32_t count;
};
QueryRange* ObtainRange(impl::CommandBuffer* cmd_buf);
QueryRange* CreateRange(impl::CommandBuffer* cmd_buf);
QueryRange* CreateRangeAndPool(impl::CommandBuffer* cmd_buf);
std::vector<QueryRange> ranges_;
std::vector<vk::QueryPool> pools_;
// Remembers timestamp names, and will eventually be filled in with timestamp
// values before returning results.
std::vector<Result> results_;
uint32_t query_count_ = 0;
uint32_t current_pool_index_ = 0;
const vk::Device device_;
const float timestamp_period_;
};
} // namespace escher