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