| 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
8 #include "impeller/renderer/backend/vulkan/context_vk.h"
9 #include "impeller/renderer/backend/vulkan/device_holder.h"
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