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
45 const struct etna_perfmon_source
*source
;
48 static const struct etna_perfmon_config query_config
[] = {
50 .name
= "hi-total-cyles",
51 .type
= ETNA_QUERY_HI_TOTAL_CYCLES
,
52 .source
= (const struct etna_perfmon_source
[]) {
53 { "HI", "TOTAL_CYCLES" }
57 .name
= "hi-idle-cyles",
58 .type
= ETNA_QUERY_HI_IDLE_CYCLES
,
59 .source
= (const struct etna_perfmon_source
[]) {
60 { "HI", "IDLE_CYCLES" }
64 .name
= "hi-axi-cycles-read-request-stalled",
65 .type
= ETNA_QUERY_HI_AXI_CYCLES_READ_REQUEST_STALLED
,
66 .source
= (const struct etna_perfmon_source
[]) {
67 { "HI", "AXI_CYCLES_READ_REQUEST_STALLED" }
71 .name
= "hi-axi-cycles-write-request-stalled",
72 .type
= ETNA_QUERY_HI_AXI_CYCLES_WRITE_REQUEST_STALLED
,
73 .source
= (const struct etna_perfmon_source
[]) {
74 { "HI", "AXI_CYCLES_WRITE_REQUEST_STALLED" }
78 .name
= "hi-axi-cycles-write-data-stalled",
79 .type
= ETNA_QUERY_HI_AXI_CYCLES_WRITE_DATA_STALLED
,
80 .source
= (const struct etna_perfmon_source
[]) {
81 { "HI", "AXI_CYCLES_WRITE_DATA_STALLED" }
85 .name
= "pe-pixel-count-killed-by-color-pipe",
86 .type
= ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE
,
87 .source
= (const struct etna_perfmon_source
[]) {
88 { "PE", "PIXEL_COUNT_KILLED_BY_COLOR_PIPE" }
92 .name
= "pe-pixel-count-killed-by-depth-pipe",
93 .type
= ETNA_QUERY_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE
,
94 .source
= (const struct etna_perfmon_source
[]) {
95 { "PE", "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE" }
99 .name
= "pe-pixel-count-drawn-by-color-pipe",
100 .type
= ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE
,
101 .source
= (const struct etna_perfmon_source
[]) {
102 { "PE", "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE" }
106 .name
= "pe-pixel-count-drawn-by-depth-pipe",
107 .type
= ETNA_QUERY_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE
,
108 .source
= (const struct etna_perfmon_source
[]) {
109 { "PE", "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE" }
113 .name
= "sh-shader-cycles",
114 .type
= ETNA_QUERY_SH_SHADER_CYCLES
,
115 .source
= (const struct etna_perfmon_source
[]) {
116 { "SH", "SHADER_CYCLES" }
120 .name
= "sh-ps-inst-counter",
121 .type
= ETNA_QUERY_SH_PS_INST_COUNTER
,
122 .source
= (const struct etna_perfmon_source
[]) {
123 { "SH", "PS_INST_COUNTER" }
127 .name
= "sh-rendered-pixel-counter",
128 .type
= ETNA_QUERY_SH_RENDERED_PIXEL_COUNTER
,
129 .source
= (const struct etna_perfmon_source
[]) {
130 { "SH", "RENDERED_PIXEL_COUNTER" }
134 .name
= "sh-vs-inst-counter",
135 .type
= ETNA_QUERY_SH_VS_INST_COUNTER
,
136 .source
= (const struct etna_perfmon_source
[]) {
137 { "SH", "VS_INST_COUNTER" }
141 .name
= "sh-rendered-vertice-counter",
142 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
143 .source
= (const struct etna_perfmon_source
[]) {
144 { "SH", "RENDERED_VERTICE_COUNTER" }
148 .name
= "sh-vtx-branch-inst-counter",
149 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
150 .source
= (const struct etna_perfmon_source
[]) {
151 { "SH", "VTX_BRANCH_INST_COUNTER" }
155 .name
= "sh-vtx-texld-inst-counter",
156 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
157 .source
= (const struct etna_perfmon_source
[]) {
158 { "SH", "VTX_TEXLD_INST_COUNTER" }
162 .name
= "sh-plx-branch-inst-counter",
163 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
164 .source
= (const struct etna_perfmon_source
[]) {
165 { "SH", "PXL_BRANCH_INST_COUNTER" }
169 .name
= "sh-plx-texld-inst-counter",
170 .type
= ETNA_QUERY_SH_RENDERED_VERTICE_COUNTER
,
171 .source
= (const struct etna_perfmon_source
[]) {
172 { "SH", "PXL_TEXLD_INST_COUNTER" }
176 .name
= "pa-input-vtx-counter",
177 .type
= ETNA_QUERY_PA_INPUT_VTX_COUNTER
,
178 .source
= (const struct etna_perfmon_source
[]) {
179 { "PA", "INPUT_VTX_COUNTER" }
183 .name
= "pa-input-prim-counter",
184 .type
= ETNA_QUERY_PA_INPUT_PRIM_COUNTER
,
185 .source
= (const struct etna_perfmon_source
[]) {
186 { "PA", "INPUT_PRIM_COUNTER" }
190 .name
= "pa-output-prim-counter",
191 .type
= ETNA_QUERY_PA_OUTPUT_PRIM_COUNTER
,
192 .source
= (const struct etna_perfmon_source
[]) {
193 { "PA", "OUTPUT_PRIM_COUNTER" }
197 .name
= "pa-depth-clipped-counter",
198 .type
= ETNA_QUERY_PA_DEPTH_CLIPPED_COUNTER
,
199 .source
= (const struct etna_perfmon_source
[]) {
200 { "PA", "DEPTH_CLIPPED_COUNTER" }
204 .name
= "pa-trivial-rejected-counter",
205 .type
= ETNA_QUERY_PA_TRIVIAL_REJECTED_COUNTER
,
206 .source
= (const struct etna_perfmon_source
[]) {
207 { "PA", "TRIVIAL_REJECTED_COUNTER" }
211 .name
= "pa-culled-counter",
212 .type
= ETNA_QUERY_PA_CULLED_COUNTER
,
213 .source
= (const struct etna_perfmon_source
[]) {
214 { "PA", "CULLED_COUNTER" }
218 .name
= "se-culled-triangle-count",
219 .type
= ETNA_QUERY_SE_CULLED_TRIANGLE_COUNT
,
220 .source
= (const struct etna_perfmon_source
[]) {
221 { "SE", "CULLED_TRIANGLE_COUNT" }
225 .name
= "se-culled-lines-count",
226 .type
= ETNA_QUERY_SE_CULLED_LINES_COUNT
,
227 .source
= (const struct etna_perfmon_source
[]) {
228 { "SE", "CULLED_LINES_COUNT" }
233 static const struct etna_perfmon_config
*
234 etna_pm_query_config(unsigned type
)
236 for (unsigned i
= 0; i
< ARRAY_SIZE(query_config
); i
++)
237 if (query_config
[i
].type
== type
)
238 return &query_config
[i
];
243 static struct etna_perfmon_signal
*
244 etna_pm_query_signal(struct etna_perfmon
*perfmon
,
245 const struct etna_perfmon_source
*source
)
247 struct etna_perfmon_domain
*domain
;
249 domain
= etna_perfmon_get_dom_by_name(perfmon
, source
->domain
);
253 return etna_perfmon_get_sig_by_name(domain
, source
->signal
);
257 etna_pm_cfg_supported(struct etna_perfmon
*perfmon
,
258 const struct etna_perfmon_config
*cfg
)
260 struct etna_perfmon_signal
*signal
= etna_pm_query_signal(perfmon
, cfg
->source
);
266 etna_pm_add_signal(struct etna_pm_query
*pq
, struct etna_perfmon
*perfmon
,
267 const struct etna_perfmon_config
*cfg
)
269 struct etna_perfmon_signal
*signal
= etna_pm_query_signal(perfmon
, cfg
->source
);
275 realloc_query_bo(struct etna_context
*ctx
, struct etna_pm_query
*pq
)
280 pq
->bo
= etna_bo_new(ctx
->screen
->dev
, 64, DRM_ETNA_GEM_CACHE_WC
);
281 if (unlikely(!pq
->bo
))
284 pq
->data
= etna_bo_map(pq
->bo
);
290 etna_pm_query_get(struct etna_cmd_stream
*stream
, struct etna_query
*q
,
293 struct etna_pm_query
*pq
= etna_pm_query(q
);
297 if (flags
== ETNA_PM_PROCESS_PRE
)
302 struct etna_perf p
= {
304 .sequence
= pq
->sequence
,
306 .signal
= pq
->signal
,
310 etna_cmd_stream_perf(stream
, &p
);
314 etna_pm_query_update(struct etna_query
*q
)
316 struct etna_pm_query
*pq
= etna_pm_query(q
);
318 if (pq
->data
[0] == pq
->sequence
)
323 etna_pm_destroy_query(struct etna_context
*ctx
, struct etna_query
*q
)
325 struct etna_pm_query
*pq
= etna_pm_query(q
);
332 etna_pm_begin_query(struct etna_context
*ctx
, struct etna_query
*q
)
334 struct etna_pm_query
*pq
= etna_pm_query(q
);
339 etna_pm_query_get(ctx
->stream
, q
, ETNA_PM_PROCESS_PRE
);
345 etna_pm_end_query(struct etna_context
*ctx
, struct etna_query
*q
)
347 etna_pm_query_get(ctx
->stream
, q
, ETNA_PM_PROCESS_POST
);
351 etna_pm_get_query_result(struct etna_context
*ctx
, struct etna_query
*q
,
352 boolean wait
, union pipe_query_result
*result
)
354 struct etna_pm_query
*pq
= etna_pm_query(q
);
356 etna_pm_query_update(q
);
362 if (!etna_bo_cpu_prep(pq
->bo
, DRM_ETNA_PREP_READ
))
366 etna_bo_cpu_fini(pq
->bo
);
369 result
->u32
= pq
->data
[2] - pq
->data
[1];
374 static const struct etna_query_funcs hw_query_funcs
= {
375 .destroy_query
= etna_pm_destroy_query
,
376 .begin_query
= etna_pm_begin_query
,
377 .end_query
= etna_pm_end_query
,
378 .get_query_result
= etna_pm_get_query_result
,
382 etna_pm_create_query(struct etna_context
*ctx
, unsigned query_type
)
384 struct etna_perfmon
*perfmon
= ctx
->screen
->perfmon
;
385 const struct etna_perfmon_config
*cfg
;
386 struct etna_pm_query
*pq
;
387 struct etna_query
*q
;
389 cfg
= etna_pm_query_config(query_type
);
393 if (!etna_pm_cfg_supported(perfmon
, cfg
))
396 pq
= CALLOC_STRUCT(etna_pm_query
);
400 if (!realloc_query_bo(ctx
, pq
)) {
406 q
->funcs
= &hw_query_funcs
;
407 q
->type
= query_type
;
409 etna_pm_add_signal(pq
, perfmon
, cfg
);
415 etna_pm_query_setup(struct etna_screen
*screen
)
417 screen
->perfmon
= etna_perfmon_create(screen
->pipe
);
419 if (!screen
->perfmon
)
422 for (unsigned i
= 0; i
< ARRAY_SIZE(query_config
); i
++) {
423 const struct etna_perfmon_config
*cfg
= &query_config
[i
];
425 if (!etna_pm_cfg_supported(screen
->perfmon
, cfg
))
428 util_dynarray_append(&screen
->supported_pm_queries
, unsigned, i
);
433 etna_pm_get_driver_query_info(struct pipe_screen
*pscreen
, unsigned index
,
434 struct pipe_driver_query_info
*info
)
436 const struct etna_screen
*screen
= etna_screen(pscreen
);
437 const unsigned num
= screen
->supported_pm_queries
.size
/ sizeof(unsigned);
446 i
= *util_dynarray_element(&screen
->supported_pm_queries
, unsigned, index
);
447 assert(i
< ARRAY_SIZE(query_config
));
449 info
->name
= query_config
[i
].name
;
450 info
->query_type
= query_config
[i
].type
;