17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2020 Collabora, Ltd.
37ec681f3Smrg * Author: Antonio Caggiano <antonio.caggiano@collabora.com>
47ec681f3Smrg * Author: Rohan Garg <rohan.garg@collabora.com>
57ec681f3Smrg * Author: Robert Beckett <bob.beckett@collabora.com>
67ec681f3Smrg *
77ec681f3Smrg * SPDX-License-Identifier: MIT
87ec681f3Smrg */
97ec681f3Smrg
107ec681f3Smrg#pragma once
117ec681f3Smrg
127ec681f3Smrg#include <functional>
137ec681f3Smrg#include <string>
147ec681f3Smrg#include <variant>
157ec681f3Smrg#include <vector>
167ec681f3Smrg
177ec681f3Smrgnamespace pps
187ec681f3Smrg{
197ec681f3Smrgstruct CounterGroup {
207ec681f3Smrg   std::string name;
217ec681f3Smrg
227ec681f3Smrg   uint32_t id;
237ec681f3Smrg
247ec681f3Smrg   /// List of counters ID belonging to this group
257ec681f3Smrg   std::vector<int32_t> counters;
267ec681f3Smrg
277ec681f3Smrg   std::vector<CounterGroup> subgroups;
287ec681f3Smrg};
297ec681f3Smrg
307ec681f3Smrgclass Driver;
317ec681f3Smrg
327ec681f3Smrgclass Counter
337ec681f3Smrg{
347ec681f3Smrg   public:
357ec681f3Smrg   /// @brief A counter value can be of different types depending on what it represents:
367ec681f3Smrg   /// cycles, cycles-per-instruction, percentages, bytes, and so on.
377ec681f3Smrg   enum class Units {
387ec681f3Smrg      Percent,
397ec681f3Smrg      Byte,
407ec681f3Smrg      Hertz,
417ec681f3Smrg      None,
427ec681f3Smrg   };
437ec681f3Smrg
447ec681f3Smrg   using Value = std::variant<int64_t, double>;
457ec681f3Smrg
467ec681f3Smrg   /// @param c Counter which we want to retrieve a value
477ec681f3Smrg   /// @param d Driver used to sample performance counters
487ec681f3Smrg   /// @return The value of the counter
497ec681f3Smrg   using Getter = Value(const Counter &c, const Driver &d);
507ec681f3Smrg
517ec681f3Smrg   Counter() = default;
527ec681f3Smrg   virtual ~Counter() = default;
537ec681f3Smrg
547ec681f3Smrg   /// @param id ID of the counter
557ec681f3Smrg   /// @param name Name of the counter
567ec681f3Smrg   /// @param group Group ID this counter belongs to
577ec681f3Smrg   Counter(int32_t id, const std::string &name, int32_t group);
587ec681f3Smrg
597ec681f3Smrg   bool operator==(const Counter &c) const;
607ec681f3Smrg
617ec681f3Smrg   /// @param get New getter function for this counter
627ec681f3Smrg   void set_getter(const std::function<Getter> &get);
637ec681f3Smrg
647ec681f3Smrg   /// @brief d Driver used to sample performance counters
657ec681f3Smrg   /// @return Last sampled value for this counter
667ec681f3Smrg   Value get_value(const Driver &d) const;
677ec681f3Smrg
687ec681f3Smrg   /// Id of the counter
697ec681f3Smrg   int32_t id = -1;
707ec681f3Smrg
717ec681f3Smrg   /// Name of the counter
727ec681f3Smrg   std::string name = "";
737ec681f3Smrg
747ec681f3Smrg   /// ID of the group this counter belongs to
757ec681f3Smrg   int32_t group = -1;
767ec681f3Smrg
777ec681f3Smrg   /// Offset of this counter within GPU counter list
787ec681f3Smrg   /// For derived counters it is negative and remains unused
797ec681f3Smrg   int32_t offset = -1;
807ec681f3Smrg
817ec681f3Smrg   /// Whether it is a derived counter or not
827ec681f3Smrg   bool derived = false;
837ec681f3Smrg
847ec681f3Smrg   /// Returns the value of this counter
857ec681f3Smrg   std::function<Getter> getter;
867ec681f3Smrg
877ec681f3Smrg   /// The unit of the counter
887ec681f3Smrg   Units units;
897ec681f3Smrg};
907ec681f3Smrg
917ec681f3Smrg/// @param get New getter function for this counter
927ec681f3Smrginline void Counter::set_getter(const std::function<Getter> &get)
937ec681f3Smrg{
947ec681f3Smrg   getter = get;
957ec681f3Smrg}
967ec681f3Smrg
977ec681f3Smrg/// @brief d Driver used to sample performance counters
987ec681f3Smrg/// @return Last sampled value for this counter
997ec681f3Smrginline Counter::Value Counter::get_value(const Driver &d) const
1007ec681f3Smrg{
1017ec681f3Smrg   return getter(*this, d);
1027ec681f3Smrg}
1037ec681f3Smrg
1047ec681f3Smrg/// @return The underlying u32 value
1057ec681f3Smrgtemplate<typename T> constexpr uint32_t to_u32(T &&elem)
1067ec681f3Smrg{
1077ec681f3Smrg   return static_cast<uint32_t>(elem);
1087ec681f3Smrg}
1097ec681f3Smrg
1107ec681f3Smrg} // namespace pps
111