etnaviv: Fix memory leak on error path.
[mesa.git] / src / gallium / drivers / etnaviv / etnaviv_perfmon.c
1 /*
2 * Copyright (c) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Christian Gmeiner <christian.gmeiner@gmail.com>
26 */
27
28 #include "etnaviv_context.h"
29 #include "etnaviv_perfmon.h"
30 #include "etnaviv_screen.h"
31
32 static const char *group_names[] = {
33 [ETNA_QUERY_HI_GROUP_ID] = "HI",
34 [ETNA_QUERY_PE_GROUP_ID] = "PE",
35 [ETNA_QUERY_SH_GROUP_ID] = "SH",
36 [ETNA_QUERY_PA_GROUP_ID] = "PA",
37 [ETNA_QUERY_SE_GROUP_ID] = "SE",
38 [ETNA_QUERY_RA_GROUP_ID] = "RA",
39 [ETNA_QUERY_TX_GROUP_ID] = "TX",
40 [ETNA_QUERY_MC_GROUP_ID] = "MC",
41 };
42
43 static const struct etna_perfmon_config query_config[] = {
44 {
45 .name = "hi-total-cycles",
46 .type = ETNA_QUERY_HI_TOTAL_CYCLES,
47 .group_id = ETNA_QUERY_HI_GROUP_ID,
48 .source = (const struct etna_perfmon_source[]) {
49 { "HI", "TOTAL_CYCLES" }
50 }
51 },
52 {
53 .name = "hi-idle-cycles",
54 .type = ETNA_QUERY_HI_IDLE_CYCLES,
55 .group_id = ETNA_QUERY_HI_GROUP_ID,
56 .source = (const struct etna_perfmon_source[]) {
57 { "HI", "IDLE_CYCLES" }
58 }
59 },
60 {
61 .name = "hi-axi-cycles-read-request-stalled",
62 .type = ETNA_QUERY_HI_AXI_CYCLES_READ_REQUEST_STALLED,
63 .group_id = ETNA_QUERY_HI_GROUP_ID,
64 .source = (const struct etna_perfmon_source[]) {
65 { "HI", "AXI_CYCLES_READ_REQUEST_STALLED" }
66 }
67 },
68 {
69 .name = "hi-axi-cycles-write-request-stalled",
70 .type = ETNA_QUERY_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,
71 .group_id = ETNA_QUERY_HI_GROUP_ID,
72 .source = (const struct etna_perfmon_source[]) {
73 { "HI", "AXI_CYCLES_WRITE_REQUEST_STALLED" }
74 }
75 },
76 {
77 .name = "hi-axi-cycles-write-data-stalled",
78 .type = ETNA_QUERY_HI_AXI_CYCLES_WRITE_DATA_STALLED,
79 .group_id = ETNA_QUERY_HI_GROUP_ID,
80 .source = (const struct etna_perfmon_source[]) {
81 { "HI", "AXI_CYCLES_WRITE_DATA_STALLED" }
82 }
83 },
84 {
85 .name = "pe-pixel-count-killed-by-color-pipe",
86 .type = ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE,
87 .group_id = ETNA_QUERY_PE_GROUP_ID,
88 .source = (const struct etna_perfmon_source[]) {
89 { "PE", "PIXEL_COUNT_KILLED_BY_COLOR_PIPE" }
90 }
91 },
92 {
93 .name = "pe-pixel-count-killed-by-depth-pipe",
94 .type = ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE,
95 .group_id = ETNA_QUERY_PE_GROUP_ID,
96 .source = (const struct etna_perfmon_source[]) {
97 { "PE", "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE" }
98 }
99 },
100 {
101 .name = "pe-pixel-count-drawn-by-color-pipe",
102 .type = ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE,
103 .group_id = ETNA_QUERY_PE_GROUP_ID,
104 .source = (const struct etna_perfmon_source[]) {
105 { "PE", "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE" }
106 }
107 },
108 {
109 .name = "pe-pixel-count-drawn-by-depth-pipe",
110 .type = ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE,
111 .group_id = ETNA_QUERY_PE_GROUP_ID,
112 .source = (const struct etna_perfmon_source[]) {
113 { "PE", "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE" }
114 }
115 },
116 {
117 .name = "sh-shader-cycles",
118 .type = ETNA_QUERY_SH_SHADER_CYCLES,
119 .group_id = ETNA_QUERY_SH_GROUP_ID,
120 .source = (const struct etna_perfmon_source[]) {
121 { "SH", "SHADER_CYCLES" }
122 }
123 },
124 {
125 .name = "sh-ps-inst-counter",
126 .type = ETNA_QUERY_SH_PS_INST_COUNTER,
127 .group_id = ETNA_QUERY_SH_GROUP_ID,
128 .source = (const struct etna_perfmon_source[]) {
129 { "SH", "PS_INST_COUNTER" }
130 }
131 },
132 {
133 .name = "sh-rendered-pixel-counter",
134 .type = ETNA_QUERY_SH_RENDERED_PIXEL_COUNTER,
135 .group_id = ETNA_QUERY_SH_GROUP_ID,
136 .source = (const struct etna_perfmon_source[]) {
137 { "SH", "RENDERED_PIXEL_COUNTER" }
138 }
139 },
140 {
141 .name = "sh-vs-inst-counter",
142 .type = ETNA_QUERY_SH_VS_INST_COUNTER,
143 .group_id = ETNA_QUERY_SH_GROUP_ID,
144 .source = (const struct etna_perfmon_source[]) {
145 { "SH", "VS_INST_COUNTER" }
146 }
147 },
148 {
149 .name = "sh-rendered-vertice-counter",
150 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
151 .group_id = ETNA_QUERY_SH_GROUP_ID,
152 .source = (const struct etna_perfmon_source[]) {
153 { "SH", "RENDERED_VERTICE_COUNTER" }
154 }
155 },
156 {
157 .name = "sh-vtx-branch-inst-counter",
158 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
159 .group_id = ETNA_QUERY_SH_GROUP_ID,
160 .source = (const struct etna_perfmon_source[]) {
161 { "SH", "VTX_BRANCH_INST_COUNTER" }
162 }
163 },
164 {
165 .name = "sh-vtx-texld-inst-counter",
166 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
167 .group_id = ETNA_QUERY_SH_GROUP_ID,
168 .source = (const struct etna_perfmon_source[]) {
169 { "SH", "VTX_TEXLD_INST_COUNTER" }
170 }
171 },
172 {
173 .name = "sh-plx-branch-inst-counter",
174 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
175 .group_id = ETNA_QUERY_SH_GROUP_ID,
176 .source = (const struct etna_perfmon_source[]) {
177 { "SH", "PXL_BRANCH_INST_COUNTER" }
178 }
179 },
180 {
181 .name = "sh-plx-texld-inst-counter",
182 .type = ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER,
183 .group_id = ETNA_QUERY_SH_GROUP_ID,
184 .source = (const struct etna_perfmon_source[]) {
185 { "SH", "PXL_TEXLD_INST_COUNTER" }
186 }
187 },
188 {
189 .name = "pa-input-vtx-counter",
190 .type = ETNA_QUERY_PA_INPUT_VTX_COUNTER,
191 .group_id = ETNA_QUERY_PA_GROUP_ID,
192 .source = (const struct etna_perfmon_source[]) {
193 { "PA", "INPUT_VTX_COUNTER" }
194 }
195 },
196 {
197 .name = "pa-input-prim-counter",
198 .type = ETNA_QUERY_PA_INPUT_PRIM_COUNTER,
199 .group_id = ETNA_QUERY_PA_GROUP_ID,
200 .source = (const struct etna_perfmon_source[]) {
201 { "PA", "INPUT_PRIM_COUNTER" }
202 }
203 },
204 {
205 .name = "pa-output-prim-counter",
206 .type = ETNA_QUERY_PA_OUTPUT_PRIM_COUNTER,
207 .group_id = ETNA_QUERY_PA_GROUP_ID,
208 .source = (const struct etna_perfmon_source[]) {
209 { "PA", "OUTPUT_PRIM_COUNTER" }
210 }
211 },
212 {
213 .name = "pa-depth-clipped-counter",
214 .type = ETNA_QUERY_PA_DEPTH_CLIPPED_COUNTER,
215 .group_id = ETNA_QUERY_PA_GROUP_ID,
216 .source = (const struct etna_perfmon_source[]) {
217 { "PA", "DEPTH_CLIPPED_COUNTER" }
218 }
219 },
220 {
221 .name = "pa-trivial-rejected-counter",
222 .type = ETNA_QUERY_PA_TRIVIAL_REJECTED_COUNTER,
223 .group_id = ETNA_QUERY_PA_GROUP_ID,
224 .source = (const struct etna_perfmon_source[]) {
225 { "PA", "TRIVIAL_REJECTED_COUNTER" }
226 }
227 },
228 {
229 .name = "pa-culled-counter",
230 .type = ETNA_QUERY_PA_CULLED_COUNTER,
231 .group_id = ETNA_QUERY_PA_GROUP_ID,
232 .source = (const struct etna_perfmon_source[]) {
233 { "PA", "CULLED_COUNTER" }
234 }
235 },
236 {
237 .name = "se-culled-triangle-count",
238 .type = ETNA_QUERY_SE_CULLED_TRIANGLE_COUNT,
239 .group_id = ETNA_QUERY_SE_GROUP_ID,
240 .source = (const struct etna_perfmon_source[]) {
241 { "SE", "CULLED_TRIANGLE_COUNT" }
242 }
243 },
244 {
245 .name = "se-culled-lines-count",
246 .type = ETNA_QUERY_SE_CULLED_LINES_COUNT,
247 .group_id = ETNA_QUERY_SE_GROUP_ID,
248 .source = (const struct etna_perfmon_source[]) {
249 { "SE", "CULLED_LINES_COUNT" }
250 }
251 },
252 {
253 .name = "ra-valid-pixel-count",
254 .type = ETNA_QUERY_RA_VALID_PIXEL_COUNT,
255 .group_id = ETNA_QUERY_RA_GROUP_ID,
256 .source = (const struct etna_perfmon_source[]) {
257 { "RA", "VALID_PIXEL_COUNT" }
258 }
259 },
260 {
261 .name = "ra-total-quad-count",
262 .type = ETNA_QUERY_RA_TOTAL_QUAD_COUNT,
263 .group_id = ETNA_QUERY_RA_GROUP_ID,
264 .source = (const struct etna_perfmon_source[]) {
265 { "RA", "TOTAL_QUAD_COUNT" }
266 }
267 },
268 {
269 .name = "ra-valid-quad-count-after-early-z",
270 .type = ETNA_QUERY_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z,
271 .group_id = ETNA_QUERY_RA_GROUP_ID,
272 .source = (const struct etna_perfmon_source[]) {
273 { "RA", "VALID_QUAD_COUNT_AFTER_EARLY_Z" }
274 }
275 },
276 {
277 .name = "ra-total-primitive-count",
278 .type = ETNA_QUERY_RA_TOTAL_PRIMITIVE_COUNT,
279 .group_id = ETNA_QUERY_RA_GROUP_ID,
280 .source = (const struct etna_perfmon_source[]) {
281 { "RA", "TOTAL_PRIMITIVE_COUNT" }
282 }
283 },
284 {
285 .name = "ra-pipe-cache-miss-counter",
286 .type = ETNA_QUERY_RA_PIPE_CACHE_MISS_COUNTER,
287 .group_id = ETNA_QUERY_RA_GROUP_ID,
288 .source = (const struct etna_perfmon_source[]) {
289 { "RA", "PIPE_CACHE_MISS_COUNTER" }
290 }
291 },
292 {
293 .name = "ra-prefetch-cache-miss-counter",
294 .type = ETNA_QUERY_RA_PREFETCH_CACHE_MISS_COUNTER,
295 .group_id = ETNA_QUERY_RA_GROUP_ID,
296 .source = (const struct etna_perfmon_source[]) {
297 { "RA", "PREFETCH_CACHE_MISS_COUNTER" }
298 }
299 },
300 {
301 .name = "ra-pculled-quad-count",
302 .type = ETNA_QUERY_RA_CULLED_QUAD_COUNT,
303 .group_id = ETNA_QUERY_RA_GROUP_ID,
304 .source = (const struct etna_perfmon_source[]) {
305 { "RA", "CULLED_QUAD_COUNT" }
306 }
307 },
308 {
309 .name = "tx-total-bilinear-requests",
310 .type = ETNA_QUERY_TX_TOTAL_BILINEAR_REQUESTS,
311 .group_id = ETNA_QUERY_TX_GROUP_ID,
312 .source = (const struct etna_perfmon_source[]) {
313 { "TX", "TOTAL_BILINEAR_REQUESTS" }
314 }
315 },
316 {
317 .name = "tx-total-trilinear-requests",
318 .type = ETNA_QUERY_TX_TOTAL_TRILINEAR_REQUESTS,
319 .group_id = ETNA_QUERY_TX_GROUP_ID,
320 .source = (const struct etna_perfmon_source[]) {
321 { "TX", "TOTAL_TRILINEAR_REQUESTS" }
322 }
323 },
324 {
325 .name = "tx-total-discarded-texture-requests",
326 .type = ETNA_QUERY_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS,
327 .group_id = ETNA_QUERY_TX_GROUP_ID,
328 .source = (const struct etna_perfmon_source[]) {
329 { "TX", "TOTAL_DISCARDED_TEXTURE_REQUESTS" }
330 }
331 },
332 {
333 .name = "tx-total-texture-requests",
334 .type = ETNA_QUERY_TX_TOTAL_TEXTURE_REQUESTS,
335 .group_id = ETNA_QUERY_TX_GROUP_ID,
336 .source = (const struct etna_perfmon_source[]) {
337 { "TX", "TOTAL_TEXTURE_REQUESTS" }
338 }
339 },
340 {
341 .name = "tx-mem-read-count",
342 .type = ETNA_QUERY_TX_MEM_READ_COUNT,
343 .group_id = ETNA_QUERY_TX_GROUP_ID,
344 .source = (const struct etna_perfmon_source[]) {
345 { "TX", "MEM_READ_COUNT" }
346 }
347 },
348 {
349 .name = "tx-mem-read-in-8b-count",
350 .type = ETNA_QUERY_TX_MEM_READ_IN_8B_COUNT,
351 .group_id = ETNA_QUERY_TX_GROUP_ID,
352 .source = (const struct etna_perfmon_source[]) {
353 { "TX", "MEM_READ_IN_8B_COUNT" }
354 }
355 },
356 {
357 .name = "tx-cache-miss-count",
358 .type = ETNA_QUERY_TX_CACHE_MISS_COUNT,
359 .group_id = ETNA_QUERY_TX_GROUP_ID,
360 .source = (const struct etna_perfmon_source[]) {
361 { "TX", "CACHE_MISS_COUNT" }
362 }
363 },
364 {
365 .name = "tx-cache-hit-texel-count",
366 .type = ETNA_QUERY_TX_CACHE_HIT_TEXEL_COUNT,
367 .group_id = ETNA_QUERY_TX_GROUP_ID,
368 .source = (const struct etna_perfmon_source[]) {
369 { "TX", "CACHE_HIT_TEXEL_COUNT" }
370 }
371 },
372 {
373 .name = "tx-cache-miss-texel-count",
374 .type = ETNA_QUERY_TX_CACHE_MISS_TEXEL_COUNT,
375 .group_id = ETNA_QUERY_TX_GROUP_ID,
376 .source = (const struct etna_perfmon_source[]) {
377 { "TX", "CACHE_MISS_TEXEL_COUNT" }
378 }
379 },
380 {
381 .name = "mc-total-read-req-8b-from-pipeline",
382 .type = ETNA_QUERY_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE,
383 .group_id = ETNA_QUERY_MC_GROUP_ID,
384 .source = (const struct etna_perfmon_source[]) {
385 { "MC", "TOTAL_READ_REQ_8B_FROM_PIPELINE" }
386 }
387 },
388 {
389 .name = "mc-total-read-req-8b-from-ip",
390 .type = ETNA_QUERY_MC_TOTAL_READ_REQ_8B_FROM_IP,
391 .group_id = ETNA_QUERY_MC_GROUP_ID,
392 .source = (const struct etna_perfmon_source[]) {
393 { "MC", "TOTAL_READ_REQ_8B_FROM_IP" }
394 }
395 },
396 {
397 .name = "mc-total-write-req-8b-from-pipeline",
398 .type = ETNA_QUERY_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE,
399 .group_id = ETNA_QUERY_MC_GROUP_ID,
400 .source = (const struct etna_perfmon_source[]) {
401 { "MC", "TOTAL_WRITE_REQ_8B_FROM_PIPELINE" }
402 }
403 }
404 };
405
406 struct etna_perfmon_signal *
407 etna_pm_query_signal(struct etna_perfmon *perfmon,
408 const struct etna_perfmon_source *source)
409 {
410 struct etna_perfmon_domain *domain;
411
412 domain = etna_perfmon_get_dom_by_name(perfmon, source->domain);
413 if (!domain)
414 return NULL;
415
416 return etna_perfmon_get_sig_by_name(domain, source->signal);
417 }
418
419 void
420 etna_pm_query_setup(struct etna_screen *screen)
421 {
422 screen->perfmon = etna_perfmon_create(screen->pipe);
423
424 if (!screen->perfmon)
425 return;
426
427 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++) {
428 const struct etna_perfmon_config *cfg = &query_config[i];
429
430 if (!etna_pm_cfg_supported(screen->perfmon, cfg))
431 continue;
432
433 util_dynarray_append(&screen->supported_pm_queries, unsigned, i);
434 }
435 }
436
437 const struct etna_perfmon_config *
438 etna_pm_query_config(unsigned type)
439 {
440 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++)
441 if (query_config[i].type == type)
442 return &query_config[i];
443
444 return NULL;
445 }
446
447 int
448 etna_pm_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
449 struct pipe_driver_query_info *info)
450 {
451 const struct etna_screen *screen = etna_screen(pscreen);
452 const unsigned num = screen->supported_pm_queries.size / sizeof(unsigned);
453 unsigned i;
454
455 if (!info)
456 return num;
457
458 if (index >= num)
459 return 0;
460
461 i = *util_dynarray_element(&screen->supported_pm_queries, unsigned, index);
462 assert(i < ARRAY_SIZE(query_config));
463
464 info->name = query_config[i].name;
465 info->query_type = query_config[i].type;
466 info->group_id = query_config[i].group_id;
467
468 return 1;
469 }
470
471 static
472 unsigned query_count(unsigned group)
473 {
474 unsigned count = 0;
475
476 for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++)
477 if (query_config[i].group_id == group)
478 count++;
479
480 assert(count);
481
482 return count;
483 }
484
485 int
486 etna_pm_get_driver_query_group_info(struct pipe_screen *pscreen,
487 unsigned index,
488 struct pipe_driver_query_group_info *info)
489 {
490 if (!info)
491 return ARRAY_SIZE(group_names);
492
493 if (index >= ARRAY_SIZE(group_names))
494 return 0;
495
496 unsigned count = query_count(index);
497
498 info->name = group_names[index];
499 info->max_active_queries = count;
500 info->num_queries = count;
501
502 return 1;
503 }