1 /* 2 * Copyright © 2021 Google, Inc. 3 * 4 * SPDX-License-Identifier: MIT 5 */ 6 7 #pragma once 8 9 #include "pps/pps_driver.h" 10 11 #include "common/freedreno_dev_info.h" 12 #include "drm/freedreno_drmif.h" 13 #include "drm/freedreno_ringbuffer.h" 14 #include "perfcntrs/freedreno_dt.h" 15 #include "perfcntrs/freedreno_perfcntr.h" 16 17 namespace pps 18 { 19 20 class FreedrenoDriver : public Driver 21 { 22 public: 23 uint64_t get_min_sampling_period_ns() override; 24 bool init_perfcnt() override; 25 void enable_counter(uint32_t counter_id) override; 26 void enable_all_counters() override; 27 void enable_perfcnt(uint64_t sampling_period_ns) override; 28 void disable_perfcnt() override; 29 bool dump_perfcnt() override; 30 uint64_t next() override; 31 uint32_t gpu_clock_id() const override; 32 uint64_t gpu_timestamp() const override; 33 34 private: 35 struct fd_device *dev; 36 struct fd_pipe *pipe; 37 const struct fd_dev_id *dev_id; 38 uint32_t max_freq; 39 uint32_t next_counter_id; 40 uint32_t next_countable_id; 41 uint64_t last_dump_ts = 0; 42 uint64_t last_capture_ts; 43 44 bool has_suspend_count; 45 uint32_t suspend_count; 46 47 const struct fd_dev_info *info; 48 49 /** 50 * The memory mapped i/o space for counter readback: 51 */ 52 void *io; 53 54 const struct fd_perfcntr_group *perfcntrs; 55 unsigned num_perfcntrs; 56 57 /** 58 * The number of counters assigned per perfcntr group, the index 59 * into this matches the index into perfcntrs 60 */ 61 std::vector<int> assigned_counters; 62 63 /* 64 * Values that can be used by derived counters evaluation 65 */ 66 float time; /* time since last sample in fraction of second */ 67 // uint32_t cycles; /* the number of clock cycles since last sample */ 68 69 void setup_a6xx_counters(); 70 71 void configure_counters(bool reset, bool wait); 72 void collect_countables(); 73 74 /** 75 * Split out countable mutable state from the class so that copy- 76 * constructor does something sane when lambda derive function 77 * tries to get the countable value. 78 */ 79 struct CountableState { 80 uint64_t last_value, value; 81 const struct fd_perfcntr_countable *countable; 82 const struct fd_perfcntr_counter *counter; 83 }; 84 85 std::vector<struct CountableState> state; 86 87 /** 88 * Performance counters on adreno consist of sets of counters in various 89 * blocks of the GPU, where each counter can be can be muxed to collect 90 * one of a set of countables. 91 * 92 * But the countables tend to be too low level to be directly useful to 93 * visualize. Instead various combinations of countables are combined 94 * with various formulas to derive the high level "Counter" value exposed 95 * via gfx-pps. 96 * 97 * This class serves to decouple the logic of those formulas from the 98 * details of collecting countable values. 99 */ 100 class Countable { 101 public: 102 Countable(FreedrenoDriver *d, std::string name); 103 int64_t()104 operator int64_t() const { return get_value(); }; 105 106 void configure(struct fd_ringbuffer *ring, bool reset); 107 void collect(); 108 void resolve(); 109 110 private: 111 112 uint64_t get_value() const; 113 114 uint32_t id; 115 FreedrenoDriver *d; 116 std::string name; 117 }; 118 119 Countable countable(std::string name); 120 121 std::vector<Countable> countables; 122 123 /** 124 * A derived "Counter" (from pps's perspective) 125 */ 126 class DerivedCounter : public Counter { 127 public: 128 DerivedCounter(FreedrenoDriver *d, std::string name, Counter::Units units, 129 std::function<int64_t()> derive); 130 }; 131 132 DerivedCounter counter(std::string name, Counter::Units units, 133 std::function<int64_t()> derive); 134 }; 135 136 } // namespace pps 137