1/*
2 * Copyright © 2020 Collabora, Ltd.
3 * Author: Antonio Caggiano <antonio.caggiano@collabora.com>
4 * Author: Rohan Garg <rohan.garg@collabora.com>
5 * Author: Robert Beckett <bob.beckett@collabora.com>
6 *
7 * SPDX-License-Identifier: MIT
8 */
9
10#pragma once
11
12#include <functional>
13#include <string>
14#include <variant>
15#include <vector>
16
17namespace pps
18{
19struct CounterGroup {
20   std::string name;
21
22   uint32_t id;
23
24   /// List of counters ID belonging to this group
25   std::vector<int32_t> counters;
26
27   std::vector<CounterGroup> subgroups;
28};
29
30class Driver;
31
32class Counter
33{
34   public:
35   /// @brief A counter value can be of different types depending on what it represents:
36   /// cycles, cycles-per-instruction, percentages, bytes, and so on.
37   enum class Units {
38      Percent,
39      Byte,
40      Hertz,
41      None,
42   };
43
44   using Value = std::variant<int64_t, double>;
45
46   /// @param c Counter which we want to retrieve a value
47   /// @param d Driver used to sample performance counters
48   /// @return The value of the counter
49   using Getter = Value(const Counter &c, const Driver &d);
50
51   Counter() = default;
52   virtual ~Counter() = default;
53
54   /// @param id ID of the counter
55   /// @param name Name of the counter
56   /// @param group Group ID this counter belongs to
57   Counter(int32_t id, const std::string &name, int32_t group);
58
59   bool operator==(const Counter &c) const;
60
61   /// @param get New getter function for this counter
62   void set_getter(const std::function<Getter> &get);
63
64   /// @brief d Driver used to sample performance counters
65   /// @return Last sampled value for this counter
66   Value get_value(const Driver &d) const;
67
68   /// Id of the counter
69   int32_t id = -1;
70
71   /// Name of the counter
72   std::string name = "";
73
74   /// ID of the group this counter belongs to
75   int32_t group = -1;
76
77   /// Offset of this counter within GPU counter list
78   /// For derived counters it is negative and remains unused
79   int32_t offset = -1;
80
81   /// Whether it is a derived counter or not
82   bool derived = false;
83
84   /// Returns the value of this counter
85   std::function<Getter> getter;
86
87   /// The unit of the counter
88   Units units;
89};
90
91/// @param get New getter function for this counter
92inline void Counter::set_getter(const std::function<Getter> &get)
93{
94   getter = get;
95}
96
97/// @brief d Driver used to sample performance counters
98/// @return Last sampled value for this counter
99inline Counter::Value Counter::get_value(const Driver &d) const
100{
101   return getter(*this, d);
102}
103
104/// @return The underlying u32 value
105template<typename T> constexpr uint32_t to_u32(T &&elem)
106{
107   return static_cast<uint32_t>(elem);
108}
109
110} // namespace pps
111