~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/nouveau/nv50/nv50_query_hw_metric.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2015 Samuel Pitoiset
3
 
 *
4
 
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 
 * copy of this software and associated documentation files (the "Software"),
6
 
 * to deal in the Software without restriction, including without limitation
7
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 
 * and/or sell copies of the Software, and to permit persons to whom the
9
 
 * Software is furnished to do so, subject to the following conditions:
10
 
 *
11
 
 * The above copyright notice and this permission notice shall be included in
12
 
 * all copies or substantial portions of the Software.
13
 
 *
14
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
 
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
 
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
 
 * OTHER DEALINGS IN THE SOFTWARE.
21
 
 */
22
 
 
23
 
#include "nv50/nv50_context.h"
24
 
#include "nv50/nv50_query_hw_metric.h"
25
 
#include "nv50/nv50_query_hw_sm.h"
26
 
 
27
 
/* === PERFORMANCE MONITORING METRICS for NV84+ === */
28
 
static const char *nv50_hw_metric_names[] =
29
 
{
30
 
   "metric-branch_efficiency",
31
 
};
32
 
 
33
 
struct nv50_hw_metric_query_cfg {
34
 
   uint32_t queries[4];
35
 
   uint32_t num_queries;
36
 
};
37
 
 
38
 
#define _SM(n) NV50_HW_SM_QUERY(NV50_HW_SM_QUERY_ ##n)
39
 
#define _M(n, c) [NV50_HW_METRIC_QUERY_##n] = c
40
 
 
41
 
/* ==== Compute capability 1.1 (G84+) ==== */
42
 
static const struct nv50_hw_metric_query_cfg
43
 
sm11_branch_efficiency =
44
 
{
45
 
   .queries[0]  = _SM(BRANCH),
46
 
   .queries[1]  = _SM(DIVERGENT_BRANCH),
47
 
   .num_queries = 2,
48
 
};
49
 
 
50
 
static const struct nv50_hw_metric_query_cfg *sm11_hw_metric_queries[] =
51
 
{
52
 
   _M(BRANCH_EFFICIENCY, &sm11_branch_efficiency),
53
 
};
54
 
 
55
 
#undef _SM
56
 
#undef _M
57
 
 
58
 
static const struct nv50_hw_metric_query_cfg *
59
 
nv50_hw_metric_query_get_cfg(struct nv50_context *nv50,
60
 
                             struct nv50_hw_query *hq)
61
 
{
62
 
   struct nv50_query *q = &hq->base;
63
 
   return sm11_hw_metric_queries[q->type - NV50_HW_METRIC_QUERY(0)];
64
 
}
65
 
 
66
 
static void
67
 
nv50_hw_metric_destroy_query(struct nv50_context *nv50,
68
 
                             struct nv50_hw_query *hq)
69
 
{
70
 
   struct nv50_hw_metric_query *hmq = nv50_hw_metric_query(hq);
71
 
   unsigned i;
72
 
 
73
 
   for (i = 0; i < hmq->num_queries; i++)
74
 
      if (hmq->queries[i]->funcs->destroy_query)
75
 
         hmq->queries[i]->funcs->destroy_query(nv50, hmq->queries[i]);
76
 
   FREE(hmq);
77
 
}
78
 
 
79
 
static bool
80
 
nv50_hw_metric_begin_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
81
 
{
82
 
   struct nv50_hw_metric_query *hmq = nv50_hw_metric_query(hq);
83
 
   bool ret = false;
84
 
   unsigned i;
85
 
 
86
 
   for (i = 0; i < hmq->num_queries; i++) {
87
 
      ret = hmq->queries[i]->funcs->begin_query(nv50, hmq->queries[i]);
88
 
      if (!ret)
89
 
         return ret;
90
 
   }
91
 
   return ret;
92
 
}
93
 
 
94
 
static void
95
 
nv50_hw_metric_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
96
 
{
97
 
   struct nv50_hw_metric_query *hmq = nv50_hw_metric_query(hq);
98
 
   unsigned i;
99
 
 
100
 
   for (i = 0; i < hmq->num_queries; i++)
101
 
      hmq->queries[i]->funcs->end_query(nv50, hmq->queries[i]);
102
 
}
103
 
 
104
 
static uint64_t
105
 
sm11_hw_metric_calc_result(struct nv50_hw_query *hq, uint64_t res64[4])
106
 
{
107
 
   switch (hq->base.type - NV50_HW_METRIC_QUERY(0)) {
108
 
   case NV50_HW_METRIC_QUERY_BRANCH_EFFICIENCY:
109
 
      /* (branch / (branch + divergent_branch)) * 100 */
110
 
      if (res64[0] + res64[1])
111
 
         return (res64[0] / (double)(res64[0] + res64[1])) * 100;
112
 
      break;
113
 
   default:
114
 
      debug_printf("invalid metric type: %d\n",
115
 
                   hq->base.type - NV50_HW_METRIC_QUERY(0));
116
 
      break;
117
 
   }
118
 
   return 0;
119
 
}
120
 
 
121
 
static bool
122
 
nv50_hw_metric_get_query_result(struct nv50_context *nv50,
123
 
                                struct nv50_hw_query *hq, bool wait,
124
 
                                union pipe_query_result *result)
125
 
{
126
 
   struct nv50_hw_metric_query *hmq = nv50_hw_metric_query(hq);
127
 
   union pipe_query_result results[4] = {};
128
 
   uint64_t res64[4] = {};
129
 
   bool ret = false;
130
 
   unsigned i;
131
 
 
132
 
   for (i = 0; i < hmq->num_queries; i++) {
133
 
      ret = hmq->queries[i]->funcs->get_query_result(nv50, hmq->queries[i],
134
 
                                                     wait, &results[i]);
135
 
      if (!ret)
136
 
         return ret;
137
 
      res64[i] = *(uint64_t *)&results[i];
138
 
   }
139
 
 
140
 
   *(uint64_t *)result = sm11_hw_metric_calc_result(hq, res64);
141
 
   return ret;
142
 
}
143
 
 
144
 
static const struct nv50_hw_query_funcs hw_metric_query_funcs = {
145
 
   .destroy_query = nv50_hw_metric_destroy_query,
146
 
   .begin_query = nv50_hw_metric_begin_query,
147
 
   .end_query = nv50_hw_metric_end_query,
148
 
   .get_query_result = nv50_hw_metric_get_query_result,
149
 
};
150
 
 
151
 
struct nv50_hw_query *
152
 
nv50_hw_metric_create_query(struct nv50_context *nv50, unsigned type)
153
 
{
154
 
   const struct nv50_hw_metric_query_cfg *cfg;
155
 
   struct nv50_hw_metric_query *hmq;
156
 
   struct nv50_hw_query *hq;
157
 
   unsigned i;
158
 
 
159
 
   if (type < NV50_HW_METRIC_QUERY(0) || type > NV50_HW_METRIC_QUERY_LAST)
160
 
      return NULL;
161
 
 
162
 
   hmq = CALLOC_STRUCT(nv50_hw_metric_query);
163
 
   if (!hmq)
164
 
      return NULL;
165
 
 
166
 
   hq = &hmq->base;
167
 
   hq->funcs = &hw_metric_query_funcs;
168
 
   hq->base.type = type;
169
 
 
170
 
   cfg = nv50_hw_metric_query_get_cfg(nv50, hq);
171
 
 
172
 
   for (i = 0; i < cfg->num_queries; i++) {
173
 
      hmq->queries[i] = nv50_hw_sm_create_query(nv50, cfg->queries[i]);
174
 
      if (!hmq->queries[i]) {
175
 
         nv50_hw_metric_destroy_query(nv50, hq);
176
 
         return NULL;
177
 
      }
178
 
      hmq->num_queries++;
179
 
   }
180
 
 
181
 
   return hq;
182
 
}
183
 
 
184
 
int
185
 
nv50_hw_metric_get_driver_query_info(struct nv50_screen *screen, unsigned id,
186
 
                                     struct pipe_driver_query_info *info)
187
 
{
188
 
   int count = 0;
189
 
 
190
 
   if (screen->compute)
191
 
      if (screen->base.class_3d >= NV84_3D_CLASS)
192
 
         count += NV50_HW_METRIC_QUERY_COUNT;
193
 
 
194
 
   if (!info)
195
 
      return count;
196
 
 
197
 
   if (id < count) {
198
 
      if (screen->compute) {
199
 
         if (screen->base.class_3d >= NV84_3D_CLASS) {
200
 
            info->name = nv50_hw_metric_names[id];
201
 
            info->query_type = NV50_HW_METRIC_QUERY(id);
202
 
            info->group_id = NV50_HW_METRIC_QUERY_GROUP;
203
 
            return 1;
204
 
         }
205
 
      }
206
 
   }
207
 
   return 0;
208
 
}