Flutter Impeller
gpu_tracer_vk.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <memory>
6 #include <thread>
7 
10 #include "vulkan/vulkan_handles.hpp"
11 
12 namespace impeller {
13 
14 class GPUProbe;
15 
16 /// @brief A class that uses timestamp queries to record the approximate GPU
17 /// execution time.
18 class GPUTracerVK : public std::enable_shared_from_this<GPUTracerVK> {
19  public:
20  explicit GPUTracerVK(const std::shared_ptr<DeviceHolder>& device_holder);
21 
22  ~GPUTracerVK() = default;
23 
24  /// @brief Create a GPUProbe to trace the execution of a command buffer on the
25  /// GPU.
26  std::unique_ptr<GPUProbe> CreateGPUProbe();
27 
28  /// @brief Signal the start of a frame workload.
29  ///
30  /// Any cmd buffers that are created after this call and before
31  /// [MarkFrameEnd] will be attributed to the current frame.
32  void MarkFrameStart();
33 
34  /// @brief Signal the end of a frame workload.
35  void MarkFrameEnd();
36 
37  // visible for testing.
38  bool IsEnabled() const;
39 
40  private:
41  friend class GPUProbe;
42 
43  static const constexpr size_t kTraceStatesSize = 32u;
44 
45  /// @brief Signal that the cmd buffer is completed.
46  ///
47  /// If [frame_index] is std::nullopt, this frame recording is ignored.
48  void OnFenceComplete(size_t frame);
49 
50  /// @brief Record a timestamp query into the provided cmd buffer to record
51  /// start time.
52  void RecordCmdBufferStart(const vk::CommandBuffer& buffer, GPUProbe& probe);
53 
54  /// @brief Record a timestamp query into the provided cmd buffer to record end
55  /// time.
56  void RecordCmdBufferEnd(const vk::CommandBuffer& buffer, GPUProbe& probe);
57 
58  const std::shared_ptr<DeviceHolder> device_holder_;
59 
60  struct GPUTraceState {
61  size_t current_index = 0;
62  size_t pending_buffers = 0;
63  vk::UniqueQueryPool query_pool;
64  };
65 
66  mutable Mutex trace_state_mutex_;
67  GPUTraceState trace_states_[kTraceStatesSize] IPLR_GUARDED_BY(
68  trace_state_mutex_);
69  size_t current_state_ IPLR_GUARDED_BY(trace_state_mutex_) = 0u;
70 
71  // The number of nanoseconds for each timestamp unit.
72  float timestamp_period_ = 1;
73 
74  // If in_frame_ is not true, then this cmd buffer was started as a part of
75  // some non-frame workload like image decoding. We should not record this as
76  // part of the frame workload, as the gap between this non-frame and a
77  // frameworkload may be substantial. For example, support the engine creates a
78  // cmd buffer to perform an image upload at timestamp 0 and then 30 ms later
79  // actually renders a frame. Without the in_frame_ guard, the GPU frame time
80  // would include this 30ms gap during which the engine was idle.
81  bool in_frame_ = false;
82 
83  // Track the raster thread id to avoid recording mipmap/image cmd buffers
84  // that are not guaranteed to start/end according to frame boundaries.
85  std::thread::id raster_thread_id_;
86  bool enabled_ = false;
87 };
88 
89 class GPUProbe {
90  public:
91  explicit GPUProbe(const std::weak_ptr<GPUTracerVK>& tracer);
92 
93  GPUProbe(GPUProbe&&) = delete;
94  GPUProbe& operator=(GPUProbe&&) = delete;
95 
96  ~GPUProbe();
97 
98  /// @brief Record a timestamp query into the provided cmd buffer to record
99  /// start time.
100  void RecordCmdBufferStart(const vk::CommandBuffer& buffer);
101 
102  /// @brief Record a timestamp query into the provided cmd buffer to record end
103  /// time.
104  void RecordCmdBufferEnd(const vk::CommandBuffer& buffer);
105 
106  private:
107  friend class GPUTracerVK;
108 
109  std::weak_ptr<GPUTracerVK> tracer_;
110  std::optional<size_t> index_ = std::nullopt;
111 };
112 
113 } // namespace impeller
impeller::GPUProbe::~GPUProbe
~GPUProbe()
Definition: gpu_tracer_vk.cc:185
impeller::GPUTracerVK::MarkFrameStart
void MarkFrameStart()
Signal the start of a frame workload.
Definition: gpu_tracer_vk.cc:40
device_holder.h
impeller::GPUProbe::GPUProbe
GPUProbe(const std::weak_ptr< GPUTracerVK > &tracer)
Definition: gpu_tracer_vk.cc:182
impeller::GPUTracerVK::GPUTracerVK
GPUTracerVK(const std::shared_ptr< DeviceHolder > &device_holder)
Definition: gpu_tracer_vk.cc:21
impeller::GPUTracerVK::MarkFrameEnd
void MarkFrameEnd()
Signal the end of a frame workload.
Definition: gpu_tracer_vk.cc:46
impeller::GPUTracerVK
A class that uses timestamp queries to record the approximate GPU execution time.
Definition: gpu_tracer_vk.h:18
impeller::GPUProbe::operator=
GPUProbe & operator=(GPUProbe &&)=delete
impeller::GPUProbe
Definition: gpu_tracer_vk.h:89
impeller::GPUProbe::RecordCmdBufferStart
void RecordCmdBufferStart(const vk::CommandBuffer &buffer)
Record a timestamp query into the provided cmd buffer to record start time.
Definition: gpu_tracer_vk.cc:196
context_vk.h
impeller::GPUTracerVK::CreateGPUProbe
std::unique_ptr< GPUProbe > CreateGPUProbe()
Create a GPUProbe to trace the execution of a command buffer on the GPU.
Definition: gpu_tracer_vk.cc:67
impeller::GPUTracerVK::IsEnabled
bool IsEnabled() const
Definition: gpu_tracer_vk.cc:36
impeller::GPUProbe::RecordCmdBufferEnd
void RecordCmdBufferEnd(const vk::CommandBuffer &buffer)
Record a timestamp query into the provided cmd buffer to record end time.
Definition: gpu_tracer_vk.cc:204
impeller
Definition: aiks_context.cc:10
impeller::GPUTracerVK::~GPUTracerVK
~GPUTracerVK()=default