2 * Copyright (c) 2017 Etnaviv Project
3 * Copyright (C) 2017 Zodiac Inflight Innovations
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
25 * Christian Gmeiner <christian.gmeiner@gmail.com>
28 #include "util/u_inlines.h"
29 #include "util/u_memory.h"
31 #include "etnaviv_context.h"
32 #include "etnaviv_query_pm.h"
33 #include "etnaviv_screen.h"
35 struct etna_perfmon_source
41 struct etna_perfmon_config
46 const struct etna_perfmon_source
*source
;
49 static const struct etna_perfmon_config query_config
[] = {
51 .name
= "hi-total-cyles",
52 .type
= ETNA_QUERY_HI_TOTAL_CYCLES
,
53 .group_id
= ETNA_QUERY_HI_GROUP_ID
,
54 .source
= (const struct etna_perfmon_source
[]) {
55 { "HI", "TOTAL_CYCLES" }
59 .name
= "hi-idle-cyles",
60 .type
= ETNA_QUERY_HI_IDLE_CYCLES
,
61 .group_id
= ETNA_QUERY_HI_GROUP_ID
,
62 .source
= (const struct etna_perfmon_source
[]) {
63 { "HI", "IDLE_CYCLES" }
67 .name
= "hi-axi-cycles-read-request-stalled",
68 .type
= ETNA_QUERY_HI_AXI_CYCLES_READ_REQUEST_STALLED
,
69 .group_id
= ETNA_QUERY_HI_GROUP_ID
,
70 .source
= (const struct etna_perfmon_source
[]) {
71 { "HI", "AXI_CYCLES_READ_REQUEST_STALLED" }
75 .name
= "hi-axi-cycles-write-request-stalled",
76 .type
= ETNA_QUERY_HI_AXI_CYCLES_WRITE_REQUEST_STALLED
,
77 .group_id
= ETNA_QUERY_HI_GROUP_ID
,
78 .source
= (const struct etna_perfmon_source
[]) {
79 { "HI", "AXI_CYCLES_WRITE_REQUEST_STALLED" }
83 .name
= "hi-axi-cycles-write-data-stalled",
84 .type
= ETNA_QUERY_HI_AXI_CYCLES_WRITE_DATA_STALLED
,
85 .group_id
= ETNA_QUERY_HI_GROUP_ID
,
86 .source
= (const struct etna_perfmon_source
[]) {
87 { "HI", "AXI_CYCLES_WRITE_DATA_STALLED" }
91 .name
= "pe-pixel-count-killed-by-color-pipe",
92 .type
= ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE
,
93 .group_id
= ETNA_QUERY_PE_GROUP_ID
,
94 .source
= (const struct etna_perfmon_source
[]) {
95 { "PE", "PIXEL_COUNT_KILLED_BY_COLOR_PIPE" }
99 .name
= "pe-pixel-count-killed-by-depth-pipe",
100 .type
= ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE
,
101 .group_id
= ETNA_QUERY_PE_GROUP_ID
,
102 .source
= (const struct etna_perfmon_source
[]) {
103 { "PE", "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE" }
107 .name
= "pe-pixel-count-drawn-by-color-pipe",
108 .type
= ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE
,
109 .group_id
= ETNA_QUERY_PE_GROUP_ID
,
110 .source
= (const struct etna_perfmon_source
[]) {
111 { "PE", "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE" }
115 .name
= "pe-pixel-count-drawn-by-depth-pipe",
116 .type
= ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE
,
117 .group_id
= ETNA_QUERY_PE_GROUP_ID
,
118 .source
= (const struct etna_perfmon_source
[]) {
119 { "PE", "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE" }
123 .name
= "sh-shader-cycles",
124 .type
= ETNA_QUERY_SH_SHADER_CYCLES
,
125 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
126 .source
= (const struct etna_perfmon_source
[]) {
127 { "SH", "SHADER_CYCLES" }
131 .name
= "sh-ps-inst-counter",
132 .type
= ETNA_QUERY_SH_PS_INST_COUNTER
,
133 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
134 .source
= (const struct etna_perfmon_source
[]) {
135 { "SH", "PS_INST_COUNTER" }
139 .name
= "sh-rendered-pixel-counter",
140 .type
= ETNA_QUERY_SH_RENDERED_PIXEL_COUNTER
,
141 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
142 .source
= (const struct etna_perfmon_source
[]) {
143 { "SH", "RENDERED_PIXEL_COUNTER" }
147 .name
= "sh-vs-inst-counter",
148 .type
= ETNA_QUERY_SH_VS_INST_COUNTER
,
149 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
150 .source
= (const struct etna_perfmon_source
[]) {
151 { "SH", "VS_INST_COUNTER" }
155 .name
= "sh-rendered-vertice-counter",
156 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
157 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
158 .source
= (const struct etna_perfmon_source
[]) {
159 { "SH", "RENDERED_VERTICE_COUNTER" }
163 .name
= "sh-vtx-branch-inst-counter",
164 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
165 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
166 .source
= (const struct etna_perfmon_source
[]) {
167 { "SH", "VTX_BRANCH_INST_COUNTER" }
171 .name
= "sh-vtx-texld-inst-counter",
172 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
173 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
174 .source
= (const struct etna_perfmon_source
[]) {
175 { "SH", "VTX_TEXLD_INST_COUNTER" }
179 .name
= "sh-plx-branch-inst-counter",
180 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
181 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
182 .source
= (const struct etna_perfmon_source
[]) {
183 { "SH", "PXL_BRANCH_INST_COUNTER" }
187 .name
= "sh-plx-texld-inst-counter",
188 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
189 .group_id
= ETNA_QUERY_SH_GROUP_ID
,
190 .source
= (const struct etna_perfmon_source
[]) {
191 { "SH", "PXL_TEXLD_INST_COUNTER" }
195 .name
= "pa-input-vtx-counter",
196 .type
= ETNA_QUERY_PA_INPUT_VTX_COUNTER
,
197 .group_id
= ETNA_QUERY_PA_GROUP_ID
,
198 .source
= (const struct etna_perfmon_source
[]) {
199 { "PA", "INPUT_VTX_COUNTER" }
203 .name
= "pa-input-prim-counter",
204 .type
= ETNA_QUERY_PA_INPUT_PRIM_COUNTER
,
205 .group_id
= ETNA_QUERY_PA_GROUP_ID
,
206 .source
= (const struct etna_perfmon_source
[]) {
207 { "PA", "INPUT_PRIM_COUNTER" }
211 .name
= "pa-output-prim-counter",
212 .type
= ETNA_QUERY_PA_OUTPUT_PRIM_COUNTER
,
213 .group_id
= ETNA_QUERY_PA_GROUP_ID
,
214 .source
= (const struct etna_perfmon_source
[]) {
215 { "PA", "OUTPUT_PRIM_COUNTER" }
219 .name
= "pa-depth-clipped-counter",
220 .type
= ETNA_QUERY_PA_DEPTH_CLIPPED_COUNTER
,
221 .group_id
= ETNA_QUERY_PA_GROUP_ID
,
222 .source
= (const struct etna_perfmon_source
[]) {
223 { "PA", "DEPTH_CLIPPED_COUNTER" }
227 .name
= "pa-trivial-rejected-counter",
228 .type
= ETNA_QUERY_PA_TRIVIAL_REJECTED_COUNTER
,
229 .group_id
= ETNA_QUERY_PA_GROUP_ID
,
230 .source
= (const struct etna_perfmon_source
[]) {
231 { "PA", "TRIVIAL_REJECTED_COUNTER" }
235 .name
= "pa-culled-counter",
236 .type
= ETNA_QUERY_PA_CULLED_COUNTER
,
237 .group_id
= ETNA_QUERY_PA_GROUP_ID
,
238 .source
= (const struct etna_perfmon_source
[]) {
239 { "PA", "CULLED_COUNTER" }
243 .name
= "se-culled-triangle-count",
244 .type
= ETNA_QUERY_SE_CULLED_TRIANGLE_COUNT
,
245 .group_id
= ETNA_QUERY_SE_GROUP_ID
,
246 .source
= (const struct etna_perfmon_source
[]) {
247 { "SE", "CULLED_TRIANGLE_COUNT" }
251 .name
= "se-culled-lines-count",
252 .type
= ETNA_QUERY_SE_CULLED_LINES_COUNT
,
253 .group_id
= ETNA_QUERY_SE_GROUP_ID
,
254 .source
= (const struct etna_perfmon_source
[]) {
255 { "SE", "CULLED_LINES_COUNT" }
259 .name
= "ra-valid-pixel-count",
260 .type
= ETNA_QUERY_RA_VALID_PIXEL_COUNT
,
261 .group_id
= ETNA_QUERY_RA_GROUP_ID
,
262 .source
= (const struct etna_perfmon_source
[]) {
263 { "RA", "VALID_PIXEL_COUNT" }
267 .name
= "ra-total-quad-count",
268 .type
= ETNA_QUERY_RA_TOTAL_QUAD_COUNT
,
269 .group_id
= ETNA_QUERY_RA_GROUP_ID
,
270 .source
= (const struct etna_perfmon_source
[]) {
271 { "RA", "TOTAL_QUAD_COUNT" }
275 .name
= "ra-valid-quad-count-after-early-z",
276 .type
= ETNA_QUERY_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z
,
277 .group_id
= ETNA_QUERY_RA_GROUP_ID
,
278 .source
= (const struct etna_perfmon_source
[]) {
279 { "RA", "VALID_QUAD_COUNT_AFTER_EARLY_Z" }
283 .name
= "ra-total-primitive-count",
284 .type
= ETNA_QUERY_RA_TOTAL_PRIMITIVE_COUNT
,
285 .group_id
= ETNA_QUERY_RA_GROUP_ID
,
286 .source
= (const struct etna_perfmon_source
[]) {
287 { "RA", "TOTAL_PRIMITIVE_COUNT" }
291 .name
= "ra-pipe-cache-miss-counter",
292 .type
= ETNA_QUERY_RA_PIPE_CACHE_MISS_COUNTER
,
293 .group_id
= ETNA_QUERY_RA_GROUP_ID
,
294 .source
= (const struct etna_perfmon_source
[]) {
295 { "RA", "PIPE_CACHE_MISS_COUNTER" }
299 .name
= "ra-prefetch-cache-miss-counter",
300 .type
= ETNA_QUERY_RA_PREFETCH_CACHE_MISS_COUNTER
,
301 .group_id
= ETNA_QUERY_RA_GROUP_ID
,
302 .source
= (const struct etna_perfmon_source
[]) {
303 { "RA", "PREFETCH_CACHE_MISS_COUNTER" }
307 .name
= "ra-pculled-quad-count",
308 .type
= ETNA_QUERY_RA_CULLED_QUAD_COUNT
,
309 .group_id
= ETNA_QUERY_RA_GROUP_ID
,
310 .source
= (const struct etna_perfmon_source
[]) {
311 { "RA", "CULLED_QUAD_COUNT" }
315 .name
= "tx-total-bilinear-requests",
316 .type
= ETNA_QUERY_TX_TOTAL_BILINEAR_REQUESTS
,
317 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
318 .source
= (const struct etna_perfmon_source
[]) {
319 { "TX", "TOTAL_BILINEAR_REQUESTS" }
323 .name
= "tx-total-trilinear-requests",
324 .type
= ETNA_QUERY_TX_TOTAL_TRILINEAR_REQUESTS
,
325 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
326 .source
= (const struct etna_perfmon_source
[]) {
327 { "TX", "TOTAL_TRILINEAR_REQUESTS" }
331 .name
= "tx-total-discarded-texture-requests",
332 .type
= ETNA_QUERY_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS
,
333 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
334 .source
= (const struct etna_perfmon_source
[]) {
335 { "TX", "TOTAL_DISCARDED_TEXTURE_REQUESTS" }
339 .name
= "tx-total-texture-requests",
340 .type
= ETNA_QUERY_TX_TOTAL_TEXTURE_REQUESTS
,
341 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
342 .source
= (const struct etna_perfmon_source
[]) {
343 { "TX", "TOTAL_TEXTURE_REQUESTS" }
347 .name
= "tx-mem-read-count",
348 .type
= ETNA_QUERY_TX_MEM_READ_COUNT
,
349 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
350 .source
= (const struct etna_perfmon_source
[]) {
351 { "TX", "MEM_READ_COUNT" }
355 .name
= "tx-mem-read-in-8b-count",
356 .type
= ETNA_QUERY_TX_MEM_READ_IN_8B_COUNT
,
357 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
358 .source
= (const struct etna_perfmon_source
[]) {
359 { "TX", "MEM_READ_IN_8B_COUNT" }
363 .name
= "tx-cache-miss-count",
364 .type
= ETNA_QUERY_TX_CACHE_MISS_COUNT
,
365 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
366 .source
= (const struct etna_perfmon_source
[]) {
367 { "TX", "CACHE_MISS_COUNT" }
371 .name
= "tx-cache-hit-texel-count",
372 .type
= ETNA_QUERY_TX_CACHE_HIT_TEXEL_COUNT
,
373 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
374 .source
= (const struct etna_perfmon_source
[]) {
375 { "TX", "CACHE_HIT_TEXEL_COUNT" }
379 .name
= "tx-cache-miss-texel-count",
380 .type
= ETNA_QUERY_TX_CACHE_MISS_TEXEL_COUNT
,
381 .group_id
= ETNA_QUERY_TX_GROUP_ID
,
382 .source
= (const struct etna_perfmon_source
[]) {
383 { "TX", "CACHE_MISS_TEXEL_COUNT" }
387 .name
= "mc-total-read-req-8b-from-pipeline",
388 .type
= ETNA_QUERY_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE
,
389 .group_id
= ETNA_QUERY_MC_GROUP_ID
,
390 .source
= (const struct etna_perfmon_source
[]) {
391 { "MC", "TOTAL_READ_REQ_8B_FROM_PIPELINE" }
395 .name
= "mc-total-read-req-8b-from-ip",
396 .type
= ETNA_QUERY_MC_TOTAL_READ_REQ_8B_FROM_IP
,
397 .group_id
= ETNA_QUERY_MC_GROUP_ID
,
398 .source
= (const struct etna_perfmon_source
[]) {
399 { "MC", "TOTAL_READ_REQ_8B_FROM_IP" }
403 .name
= "mc-total-write-req-8b-from-pipeline",
404 .type
= ETNA_QUERY_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE
,
405 .group_id
= ETNA_QUERY_MC_GROUP_ID
,
406 .source
= (const struct etna_perfmon_source
[]) {
407 { "MC", "TOTAL_WRITE_REQ_8B_FROM_PIPELINE" }
412 static const struct etna_perfmon_config
*
413 etna_pm_query_config(unsigned type
)
415 for (unsigned i
= 0; i
< ARRAY_SIZE(query_config
); i
++)
416 if (query_config
[i
].type
== type
)
417 return &query_config
[i
];
422 static struct etna_perfmon_signal
*
423 etna_pm_query_signal(struct etna_perfmon
*perfmon
,
424 const struct etna_perfmon_source
*source
)
426 struct etna_perfmon_domain
*domain
;
428 domain
= etna_perfmon_get_dom_by_name(perfmon
, source
->domain
);
432 return etna_perfmon_get_sig_by_name(domain
, source
->signal
);
436 etna_pm_cfg_supported(struct etna_perfmon
*perfmon
,
437 const struct etna_perfmon_config
*cfg
)
439 struct etna_perfmon_signal
*signal
= etna_pm_query_signal(perfmon
, cfg
->source
);
445 etna_pm_add_signal(struct etna_pm_query
*pq
, struct etna_perfmon
*perfmon
,
446 const struct etna_perfmon_config
*cfg
)
448 struct etna_perfmon_signal
*signal
= etna_pm_query_signal(perfmon
, cfg
->source
);
454 realloc_query_bo(struct etna_context
*ctx
, struct etna_pm_query
*pq
)
459 pq
->bo
= etna_bo_new(ctx
->screen
->dev
, 64, DRM_ETNA_GEM_CACHE_WC
);
460 if (unlikely(!pq
->bo
))
463 pq
->data
= etna_bo_map(pq
->bo
);
469 etna_pm_query_get(struct etna_cmd_stream
*stream
, struct etna_query
*q
,
472 struct etna_pm_query
*pq
= etna_pm_query(q
);
476 if (flags
== ETNA_PM_PROCESS_PRE
)
481 struct etna_perf p
= {
483 .sequence
= pq
->sequence
,
485 .signal
= pq
->signal
,
489 etna_cmd_stream_perf(stream
, &p
);
493 etna_pm_query_update(struct etna_query
*q
)
495 struct etna_pm_query
*pq
= etna_pm_query(q
);
497 if (pq
->data
[0] == pq
->sequence
)
502 etna_pm_destroy_query(struct etna_context
*ctx
, struct etna_query
*q
)
504 struct etna_pm_query
*pq
= etna_pm_query(q
);
511 etna_pm_begin_query(struct etna_context
*ctx
, struct etna_query
*q
)
513 struct etna_pm_query
*pq
= etna_pm_query(q
);
518 etna_pm_query_get(ctx
->stream
, q
, ETNA_PM_PROCESS_PRE
);
524 etna_pm_end_query(struct etna_context
*ctx
, struct etna_query
*q
)
526 etna_pm_query_get(ctx
->stream
, q
, ETNA_PM_PROCESS_POST
);
530 etna_pm_get_query_result(struct etna_context
*ctx
, struct etna_query
*q
,
531 boolean wait
, union pipe_query_result
*result
)
533 struct etna_pm_query
*pq
= etna_pm_query(q
);
535 etna_pm_query_update(q
);
541 if (!etna_bo_cpu_prep(pq
->bo
, DRM_ETNA_PREP_READ
))
545 etna_bo_cpu_fini(pq
->bo
);
548 result
->u32
= pq
->data
[2] - pq
->data
[1];
553 static const struct etna_query_funcs hw_query_funcs
= {
554 .destroy_query
= etna_pm_destroy_query
,
555 .begin_query
= etna_pm_begin_query
,
556 .end_query
= etna_pm_end_query
,
557 .get_query_result
= etna_pm_get_query_result
,
561 etna_pm_create_query(struct etna_context
*ctx
, unsigned query_type
)
563 struct etna_perfmon
*perfmon
= ctx
->screen
->perfmon
;
564 const struct etna_perfmon_config
*cfg
;
565 struct etna_pm_query
*pq
;
566 struct etna_query
*q
;
568 cfg
= etna_pm_query_config(query_type
);
572 if (!etna_pm_cfg_supported(perfmon
, cfg
))
575 pq
= CALLOC_STRUCT(etna_pm_query
);
579 if (!realloc_query_bo(ctx
, pq
)) {
585 q
->funcs
= &hw_query_funcs
;
586 q
->type
= query_type
;
588 etna_pm_add_signal(pq
, perfmon
, cfg
);
594 etna_pm_query_setup(struct etna_screen
*screen
)
596 screen
->perfmon
= etna_perfmon_create(screen
->pipe
);
598 if (!screen
->perfmon
)
601 for (unsigned i
= 0; i
< ARRAY_SIZE(query_config
); i
++) {
602 const struct etna_perfmon_config
*cfg
= &query_config
[i
];
604 if (!etna_pm_cfg_supported(screen
->perfmon
, cfg
))
607 util_dynarray_append(&screen
->supported_pm_queries
, unsigned, i
);
612 etna_pm_get_driver_query_info(struct pipe_screen
*pscreen
, unsigned index
,
613 struct pipe_driver_query_info
*info
)
615 const struct etna_screen
*screen
= etna_screen(pscreen
);
616 const unsigned num
= screen
->supported_pm_queries
.size
/ sizeof(unsigned);
625 i
= *util_dynarray_element(&screen
->supported_pm_queries
, unsigned, index
);
626 assert(i
< ARRAY_SIZE(query_config
));
628 info
->name
= query_config
[i
].name
;
629 info
->query_type
= query_config
[i
].type
;
630 info
->group_id
= query_config
[i
].group_id
;