xref: /aosp_15_r20/external/mesa3d/src/intel/ds/intel_pps_perf.cc (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2021 Collabora, Ltd.
3  * Author: Antonio Caggiano <[email protected]>
4  *
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "intel_pps_perf.h"
9 
10 #include <math.h>
11 #include <sys/ioctl.h>
12 #include <util/ralloc.h>
13 #include <utility>
14 
15 #include <pps/pps.h>
16 #include <pps/pps_device.h>
17 
18 namespace pps
19 {
IntelPerf(const int drm_fd)20 IntelPerf::IntelPerf(const int drm_fd)
21    : drm_fd {drm_fd}
22    , cfg {intel_perf_new(NULL)}
23 {
24    assert(drm_fd >= 0 && "DRM fd is not valid");
25 
26    if (!intel_get_device_info_from_fd(drm_fd, &devinfo, -1, -1)) {
27       PPS_LOG_FATAL("Failed to get devinfo");
28    }
29 
30    intel_perf_init_metrics(cfg,
31       &devinfo,
32       drm_fd,
33       false, // no pipeline statistics
34       false  // no register snapshots
35    );
36 }
37 
~IntelPerf()38 IntelPerf::~IntelPerf()
39 {
40    close();
41 
42    intel_perf_free(cfg);
43 }
44 
get_queries() const45 std::vector<struct intel_perf_query_info *> IntelPerf::get_queries() const
46 {
47    assert(cfg && "Intel perf config should be valid");
48    assert(cfg->n_queries && "Intel perf queries not initialized");
49 
50    std::vector<struct intel_perf_query_info *> queries = {};
51 
52    for (int i = 0; i < cfg->n_queries; ++i) {
53       struct intel_perf_query_info *query = &cfg->queries[i];
54       // Skip invalid queries
55       if (query && query->symbol_name) {
56          queries.push_back(query);
57       }
58    }
59 
60    return queries;
61 }
62 
63 // The period_exponent gives a sampling period as follows:
64 // sample_period = timestamp_period * 2^(period_exponent + 1)
65 // where timestamp_period is 80ns for Haswell+
get_oa_exponent(const intel_device_info * devinfo,const uint64_t sampling_period_ns)66 static uint32_t get_oa_exponent(const intel_device_info *devinfo, const uint64_t sampling_period_ns)
67 {
68    return static_cast<uint32_t>(log2(sampling_period_ns * devinfo->timestamp_frequency / 1000000000ull)) - 1;
69 }
70 
open(const uint64_t sampling_period_ns,struct intel_perf_query_info * query)71 bool IntelPerf::open(const uint64_t sampling_period_ns,
72                      struct intel_perf_query_info *query)
73 {
74    assert(!ctx && "Perf context should not be initialized at this point");
75 
76    ctx = intel_perf_new_context(NULL);
77    intel_perf_init_context(ctx, cfg, nullptr, nullptr, nullptr, &devinfo, 0, drm_fd);
78 
79    auto oa_exponent = get_oa_exponent(&devinfo, sampling_period_ns);
80 
81    return intel_perf_open(ctx,
82       query->oa_metrics_set_id,
83       query->oa_format,
84       oa_exponent,
85       drm_fd,
86       INTEL_PERF_INVALID_CTX_ID,
87       true /* enable stream immediately */);
88 }
89 
close()90 void IntelPerf::close()
91 {
92    if (ctx) {
93       intel_perf_close(ctx, nullptr);
94       intel_perf_free_context(ctx);
95       ctx = nullptr;
96    }
97 }
98 
oa_stream_ready() const99 bool IntelPerf::oa_stream_ready() const
100 {
101    assert(ctx && "Perf context was not open");
102    return intel_perf_oa_stream_ready(ctx);
103 }
104 
read_oa_stream(void * buf,size_t bytes) const105 ssize_t IntelPerf::read_oa_stream(void *buf, size_t bytes) const
106 {
107    assert(ctx && "Perf context was not open");
108    return intel_perf_read_oa_stream(ctx, buf, bytes);
109 }
110 
111 } // namespace pps
112