2 * Copyright 2015 Samuel Pitoiset
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
23 #include "nvc0/nvc0_context.h"
24 #include "nvc0/nvc0_query_hw_metric.h"
25 #include "nvc0/nvc0_query_hw_sm.h"
27 #define _Q(i,n,t,d) { NVC0_HW_METRIC_QUERY_##i, n, PIPE_DRIVER_QUERY_TYPE_##t, d }
28 static const struct nvc0_hw_metric_cfg
{
31 enum pipe_driver_query_type type
;
33 } nvc0_hw_metric_queries
[] = {
34 _Q(ACHIEVED_OCCUPANCY
,
35 "metric-achieved_occupancy",
37 "Ratio of the average active warps per active cycle to the maximum "
38 "number of warps supported on a multiprocessor"),
41 "metric-branch_efficiency",
43 "Ratio of non-divergent branches to total branches"),
48 "The number of instructions issued"),
51 "metric-inst_per_wrap",
53 "Average number of instructions executed by each warp"),
55 _Q(INST_REPLAY_OVERHEAD
,
56 "metric-inst_replay_overhead",
58 "Average number of replays for each instruction executed"),
63 "Instructions issued per cycle"),
68 "The number of issue slots used"),
70 _Q(ISSUE_SLOT_UTILIZATION
,
71 "metric-issue_slot_utilization",
73 "Percentage of issue slots that issued at least one instruction, "
74 "averaged across all cycles"),
79 "Instructions executed per cycle"),
81 _Q(SHARED_REPLAY_OVERHEAD
,
82 "metric-shared_replay_overhead",
84 "Average number of replays due to shared memory conflicts for each "
85 "instruction executed"),
87 _Q(WARP_EXECUTION_EFFICIENCY
,
88 "metric-warp_execution_efficiency",
90 "Ratio of the average active threads per warp to the maximum number of "
91 "threads per warp supported on a multiprocessor"),
96 static inline const struct nvc0_hw_metric_cfg
*
97 nvc0_hw_metric_get_cfg(unsigned metric_id
)
101 for (i
= 0; i
< ARRAY_SIZE(nvc0_hw_metric_queries
); i
++) {
102 if (nvc0_hw_metric_queries
[i
].id
== metric_id
)
103 return &nvc0_hw_metric_queries
[i
];
109 struct nvc0_hw_metric_query_cfg
{
112 uint32_t num_queries
;
115 #define _SM(n) NVC0_HW_SM_QUERY(NVC0_HW_SM_QUERY_ ##n)
117 /* ==== Compute capability 2.0 (GF100/GF110) ==== */
118 static const struct nvc0_hw_metric_query_cfg
119 sm20_achieved_occupancy
=
121 .type
= NVC0_HW_METRIC_QUERY_ACHIEVED_OCCUPANCY
,
122 .queries
[0] = _SM(ACTIVE_WARPS
),
123 .queries
[1] = _SM(ACTIVE_CYCLES
),
127 static const struct nvc0_hw_metric_query_cfg
128 sm20_branch_efficiency
=
130 .type
= NVC0_HW_METRIC_QUERY_BRANCH_EFFICIENCY
,
131 .queries
[0] = _SM(BRANCH
),
132 .queries
[1] = _SM(DIVERGENT_BRANCH
),
136 static const struct nvc0_hw_metric_query_cfg
139 .type
= NVC0_HW_METRIC_QUERY_INST_PER_WRAP
,
140 .queries
[0] = _SM(INST_EXECUTED
),
141 .queries
[1] = _SM(WARPS_LAUNCHED
),
145 static const struct nvc0_hw_metric_query_cfg
146 sm20_inst_replay_overhead
=
148 .type
= NVC0_HW_METRIC_QUERY_INST_REPLAY_OVERHEAD
,
149 .queries
[0] = _SM(INST_ISSUED
),
150 .queries
[1] = _SM(INST_EXECUTED
),
154 static const struct nvc0_hw_metric_query_cfg
157 .type
= NVC0_HW_METRIC_QUERY_ISSUED_IPC
,
158 .queries
[0] = _SM(INST_ISSUED
),
159 .queries
[1] = _SM(ACTIVE_CYCLES
),
163 static const struct nvc0_hw_metric_query_cfg
164 sm20_issue_slot_utilization
=
166 .type
= NVC0_HW_METRIC_QUERY_ISSUE_SLOT_UTILIZATION
,
167 .queries
[0] = _SM(INST_ISSUED
),
168 .queries
[1] = _SM(ACTIVE_CYCLES
),
172 static const struct nvc0_hw_metric_query_cfg
175 .type
= NVC0_HW_METRIC_QUERY_IPC
,
176 .queries
[0] = _SM(INST_EXECUTED
),
177 .queries
[1] = _SM(ACTIVE_CYCLES
),
181 static const struct nvc0_hw_metric_query_cfg
*sm20_hw_metric_queries
[] =
183 &sm20_achieved_occupancy
,
184 &sm20_branch_efficiency
,
186 &sm20_inst_replay_overhead
,
189 &sm20_issue_slot_utilization
,
192 /* ==== Compute capability 2.1 (GF108+ except GF110) ==== */
193 static const struct nvc0_hw_metric_query_cfg
196 .type
= NVC0_HW_METRIC_QUERY_INST_ISSUED
,
197 .queries
[0] = _SM(INST_ISSUED1_0
),
198 .queries
[1] = _SM(INST_ISSUED1_1
),
199 .queries
[2] = _SM(INST_ISSUED2_0
),
200 .queries
[3] = _SM(INST_ISSUED2_1
),
204 static const struct nvc0_hw_metric_query_cfg
205 sm21_inst_replay_overhead
=
207 .type
= NVC0_HW_METRIC_QUERY_INST_REPLAY_OVERHEAD
,
208 .queries
[0] = _SM(INST_ISSUED1_0
),
209 .queries
[1] = _SM(INST_ISSUED1_1
),
210 .queries
[2] = _SM(INST_ISSUED2_0
),
211 .queries
[3] = _SM(INST_ISSUED2_1
),
212 .queries
[4] = _SM(INST_EXECUTED
),
216 static const struct nvc0_hw_metric_query_cfg
219 .type
= NVC0_HW_METRIC_QUERY_ISSUED_IPC
,
220 .queries
[0] = _SM(INST_ISSUED1_0
),
221 .queries
[1] = _SM(INST_ISSUED1_1
),
222 .queries
[2] = _SM(INST_ISSUED2_0
),
223 .queries
[3] = _SM(INST_ISSUED2_1
),
224 .queries
[4] = _SM(ACTIVE_CYCLES
),
228 static const struct nvc0_hw_metric_query_cfg
231 .type
= NVC0_HW_METRIC_QUERY_ISSUE_SLOTS
,
232 .queries
[0] = _SM(INST_ISSUED1_0
),
233 .queries
[1] = _SM(INST_ISSUED1_1
),
234 .queries
[2] = _SM(INST_ISSUED2_0
),
235 .queries
[3] = _SM(INST_ISSUED2_1
),
239 static const struct nvc0_hw_metric_query_cfg
240 sm21_issue_slot_utilization
=
242 .type
= NVC0_HW_METRIC_QUERY_ISSUE_SLOT_UTILIZATION
,
243 .queries
[0] = _SM(INST_ISSUED1_0
),
244 .queries
[1] = _SM(INST_ISSUED1_1
),
245 .queries
[2] = _SM(INST_ISSUED2_0
),
246 .queries
[3] = _SM(INST_ISSUED2_1
),
247 .queries
[4] = _SM(ACTIVE_CYCLES
),
251 static const struct nvc0_hw_metric_query_cfg
*sm21_hw_metric_queries
[] =
253 &sm20_achieved_occupancy
,
254 &sm20_branch_efficiency
,
257 &sm21_inst_replay_overhead
,
261 &sm21_issue_slot_utilization
,
264 /* ==== Compute capability 3.0 (GK104/GK106/GK107) ==== */
265 static const struct nvc0_hw_metric_query_cfg
268 .type
= NVC0_HW_METRIC_QUERY_INST_ISSUED
,
269 .queries
[0] = _SM(INST_ISSUED1
),
270 .queries
[1] = _SM(INST_ISSUED2
),
274 static const struct nvc0_hw_metric_query_cfg
275 sm30_inst_replay_overhead
=
277 .type
= NVC0_HW_METRIC_QUERY_INST_REPLAY_OVERHEAD
,
278 .queries
[0] = _SM(INST_ISSUED1
),
279 .queries
[1] = _SM(INST_ISSUED2
),
280 .queries
[2] = _SM(INST_EXECUTED
),
284 static const struct nvc0_hw_metric_query_cfg
287 .type
= NVC0_HW_METRIC_QUERY_ISSUED_IPC
,
288 .queries
[0] = _SM(INST_ISSUED1
),
289 .queries
[1] = _SM(INST_ISSUED2
),
290 .queries
[2] = _SM(ACTIVE_CYCLES
),
294 static const struct nvc0_hw_metric_query_cfg
297 .type
= NVC0_HW_METRIC_QUERY_ISSUE_SLOTS
,
298 .queries
[0] = _SM(INST_ISSUED1
),
299 .queries
[1] = _SM(INST_ISSUED2
),
303 static const struct nvc0_hw_metric_query_cfg
304 sm30_issue_slot_utilization
=
306 .type
= NVC0_HW_METRIC_QUERY_ISSUE_SLOT_UTILIZATION
,
307 .queries
[0] = _SM(INST_ISSUED1
),
308 .queries
[1] = _SM(INST_ISSUED2
),
309 .queries
[2] = _SM(ACTIVE_CYCLES
),
313 static const struct nvc0_hw_metric_query_cfg
314 sm30_shared_replay_overhead
=
316 .type
= NVC0_HW_METRIC_QUERY_SHARED_REPLAY_OVERHEAD
,
317 .queries
[0] = _SM(SHARED_LD_REPLAY
),
318 .queries
[1] = _SM(SHARED_ST_REPLAY
),
319 .queries
[2] = _SM(INST_EXECUTED
),
323 static const struct nvc0_hw_metric_query_cfg
324 sm30_warp_execution_efficiency
=
326 .type
= NVC0_HW_METRIC_QUERY_WARP_EXECUTION_EFFICIENCY
,
327 .queries
[0] = _SM(INST_EXECUTED
),
328 .queries
[1] = _SM(TH_INST_EXECUTED
),
332 static const struct nvc0_hw_metric_query_cfg
*sm30_hw_metric_queries
[] =
334 &sm20_achieved_occupancy
,
335 &sm20_branch_efficiency
,
338 &sm30_inst_replay_overhead
,
342 &sm30_issue_slot_utilization
,
343 &sm30_shared_replay_overhead
,
344 &sm30_warp_execution_efficiency
,
347 /* ==== Compute capability 3.5 (GK110) ==== */
348 static const struct nvc0_hw_metric_query_cfg
*sm35_hw_metric_queries
[] =
350 &sm20_achieved_occupancy
,
353 &sm30_inst_replay_overhead
,
357 &sm30_issue_slot_utilization
,
358 &sm30_shared_replay_overhead
,
359 &sm30_warp_execution_efficiency
,
364 static inline const struct nvc0_hw_metric_query_cfg
**
365 nvc0_hw_metric_get_queries(struct nvc0_screen
*screen
)
367 struct nouveau_device
*dev
= screen
->base
.device
;
369 switch (screen
->base
.class_3d
) {
371 return sm35_hw_metric_queries
;
373 return sm30_hw_metric_queries
;
375 if (dev
->chipset
== 0xc0 || dev
->chipset
== 0xc8)
376 return sm20_hw_metric_queries
;
377 return sm21_hw_metric_queries
;
384 nvc0_hw_metric_get_num_queries(struct nvc0_screen
*screen
)
386 struct nouveau_device
*dev
= screen
->base
.device
;
388 switch (screen
->base
.class_3d
) {
390 return ARRAY_SIZE(sm35_hw_metric_queries
);
392 return ARRAY_SIZE(sm30_hw_metric_queries
);
394 if (dev
->chipset
== 0xc0 || dev
->chipset
== 0xc8)
395 return ARRAY_SIZE(sm20_hw_metric_queries
);
396 return ARRAY_SIZE(sm21_hw_metric_queries
);
401 static const struct nvc0_hw_metric_query_cfg
*
402 nvc0_hw_metric_query_get_cfg(struct nvc0_context
*nvc0
, struct nvc0_hw_query
*hq
)
404 const struct nvc0_hw_metric_query_cfg
**queries
;
405 struct nvc0_screen
*screen
= nvc0
->screen
;
406 struct nvc0_query
*q
= &hq
->base
;
407 unsigned num_queries
;
410 num_queries
= nvc0_hw_metric_get_num_queries(screen
);
411 queries
= nvc0_hw_metric_get_queries(screen
);
413 for (i
= 0; i
< num_queries
; i
++) {
414 if (NVC0_HW_METRIC_QUERY(queries
[i
]->type
) == q
->type
)
422 nvc0_hw_metric_destroy_query(struct nvc0_context
*nvc0
,
423 struct nvc0_hw_query
*hq
)
425 struct nvc0_hw_metric_query
*hmq
= nvc0_hw_metric_query(hq
);
428 for (i
= 0; i
< hmq
->num_queries
; i
++)
429 if (hmq
->queries
[i
]->funcs
->destroy_query
)
430 hmq
->queries
[i
]->funcs
->destroy_query(nvc0
, hmq
->queries
[i
]);
435 nvc0_hw_metric_begin_query(struct nvc0_context
*nvc0
, struct nvc0_hw_query
*hq
)
437 struct nvc0_hw_metric_query
*hmq
= nvc0_hw_metric_query(hq
);
441 for (i
= 0; i
< hmq
->num_queries
; i
++) {
442 ret
= hmq
->queries
[i
]->funcs
->begin_query(nvc0
, hmq
->queries
[i
]);
450 nvc0_hw_metric_end_query(struct nvc0_context
*nvc0
, struct nvc0_hw_query
*hq
)
452 struct nvc0_hw_metric_query
*hmq
= nvc0_hw_metric_query(hq
);
455 for (i
= 0; i
< hmq
->num_queries
; i
++)
456 hmq
->queries
[i
]->funcs
->end_query(nvc0
, hmq
->queries
[i
]);
460 sm20_hw_metric_calc_result(struct nvc0_hw_query
*hq
, uint64_t res64
[8])
462 switch (hq
->base
.type
- NVC0_HW_METRIC_QUERY(0)) {
463 case NVC0_HW_METRIC_QUERY_ACHIEVED_OCCUPANCY
:
464 /* ((active_warps / active_cycles) / max. number of warps on a MP) * 100 */
466 return ((res64
[0] / (double)res64
[1]) / 48) * 100;
468 case NVC0_HW_METRIC_QUERY_BRANCH_EFFICIENCY
:
469 /* (branch / (branch + divergent_branch)) * 100 */
470 if (res64
[0] + res64
[1])
471 return (res64
[0] / (double)(res64
[0] + res64
[1])) * 100;
473 case NVC0_HW_METRIC_QUERY_INST_PER_WRAP
:
474 /* inst_executed / warps_launched */
476 return res64
[0] / (double)res64
[1];
478 case NVC0_HW_METRIC_QUERY_INST_REPLAY_OVERHEAD
:
479 /* (inst_issued - inst_executed) / inst_executed */
481 return (res64
[0] - res64
[1]) / (double)res64
[1];
483 case NVC0_HW_METRIC_QUERY_ISSUED_IPC
:
484 /* inst_issued / active_cycles */
486 return res64
[0] / (double)res64
[1];
488 case NVC0_HW_METRIC_QUERY_ISSUE_SLOT_UTILIZATION
:
489 /* ((inst_issued / 2) / active_cycles) * 100 */
491 return ((res64
[0] / 2) / (double)res64
[1]) * 100;
493 case NVC0_HW_METRIC_QUERY_IPC
:
494 /* inst_executed / active_cycles */
496 return res64
[0] / (double)res64
[1];
499 debug_printf("invalid metric type: %d\n",
500 hq
->base
.type
- NVC0_HW_METRIC_QUERY(0));
507 sm21_hw_metric_calc_result(struct nvc0_hw_query
*hq
, uint64_t res64
[8])
509 switch (hq
->base
.type
- NVC0_HW_METRIC_QUERY(0)) {
510 case NVC0_HW_METRIC_QUERY_ACHIEVED_OCCUPANCY
:
511 return sm20_hw_metric_calc_result(hq
, res64
);
512 case NVC0_HW_METRIC_QUERY_BRANCH_EFFICIENCY
:
513 return sm20_hw_metric_calc_result(hq
, res64
);
514 case NVC0_HW_METRIC_QUERY_INST_ISSUED
:
515 /* issued1_0 + issued1_1 + (issued2_0 + issued2_1) * 2 */
516 return res64
[0] + res64
[1] + (res64
[2] + res64
[3]) * 2;
518 case NVC0_HW_METRIC_QUERY_INST_PER_WRAP
:
519 return sm20_hw_metric_calc_result(hq
, res64
);
520 case NVC0_HW_METRIC_QUERY_INST_REPLAY_OVERHEAD
:
521 /* (metric-inst_issued - inst_executed) / inst_executed */
523 return (((res64
[0] + res64
[1] + (res64
[2] + res64
[3]) * 2) -
524 res64
[4]) / (double)res64
[4]);
526 case NVC0_HW_METRIC_QUERY_ISSUED_IPC
:
527 /* metric-inst_issued / active_cycles */
529 return (res64
[0] + res64
[1] + (res64
[2] + res64
[3]) * 2) /
532 case NVC0_HW_METRIC_QUERY_ISSUE_SLOTS
:
533 /* issued1_0 + issued1_1 + issued2_0 + issued2_1 */
534 return res64
[0] + res64
[1] + res64
[2] + res64
[3];
536 case NVC0_HW_METRIC_QUERY_ISSUE_SLOT_UTILIZATION
:
537 /* ((metric-issue_slots / 2) / active_cycles) * 100 */
539 return (((res64
[0] + res64
[1] + res64
[2] + res64
[3]) / 2) /
540 (double)res64
[4]) * 100;
542 case NVC0_HW_METRIC_QUERY_IPC
:
543 return sm20_hw_metric_calc_result(hq
, res64
);
545 debug_printf("invalid metric type: %d\n",
546 hq
->base
.type
- NVC0_HW_METRIC_QUERY(0));
553 sm30_hw_metric_calc_result(struct nvc0_hw_query
*hq
, uint64_t res64
[8])
555 switch (hq
->base
.type
- NVC0_HW_METRIC_QUERY(0)) {
556 case NVC0_HW_METRIC_QUERY_ACHIEVED_OCCUPANCY
:
557 /* ((active_warps / active_cycles) / max. number of warps on a MP) * 100 */
559 return ((res64
[0] / (double)res64
[1]) / 64) * 100;
561 case NVC0_HW_METRIC_QUERY_BRANCH_EFFICIENCY
:
562 return sm20_hw_metric_calc_result(hq
, res64
);
563 case NVC0_HW_METRIC_QUERY_INST_ISSUED
:
564 /* inst_issued1 + inst_issued2 * 2 */
565 return res64
[0] + res64
[1] * 2;
566 case NVC0_HW_METRIC_QUERY_INST_PER_WRAP
:
567 return sm20_hw_metric_calc_result(hq
, res64
);
568 case NVC0_HW_METRIC_QUERY_INST_REPLAY_OVERHEAD
:
569 /* (metric-inst_issued - inst_executed) / inst_executed */
571 return (((res64
[0] + res64
[1] * 2) - res64
[2]) / (double)res64
[2]);
573 case NVC0_HW_METRIC_QUERY_ISSUED_IPC
:
574 /* metric-inst_issued / active_cycles */
576 return (res64
[0] + res64
[1] * 2) / (double)res64
[2];
578 case NVC0_HW_METRIC_QUERY_ISSUE_SLOTS
:
579 /* inst_issued1 + inst_issued2 */
580 return res64
[0] + res64
[1];
581 case NVC0_HW_METRIC_QUERY_ISSUE_SLOT_UTILIZATION
:
582 /* ((metric-issue_slots / 2) / active_cycles) * 100 */
584 return (((res64
[0] + res64
[1]) / 2) / (double)res64
[2]) * 100;
586 case NVC0_HW_METRIC_QUERY_IPC
:
587 return sm20_hw_metric_calc_result(hq
, res64
);
588 case NVC0_HW_METRIC_QUERY_SHARED_REPLAY_OVERHEAD
:
589 /* (shared_load_replay + shared_store_replay) / inst_executed */
591 return (res64
[0] + res64
[1]) / (double)res64
[2];
593 case NVC0_HW_METRIC_QUERY_WARP_EXECUTION_EFFICIENCY
:
594 /* thread_inst_executed / (inst_executed * max. number of threads per
597 return (res64
[1] / ((double)res64
[0] * 32)) * 100;
600 debug_printf("invalid metric type: %d\n",
601 hq
->base
.type
- NVC0_HW_METRIC_QUERY(0));
608 nvc0_hw_metric_get_query_result(struct nvc0_context
*nvc0
,
609 struct nvc0_hw_query
*hq
, boolean wait
,
610 union pipe_query_result
*result
)
612 struct nvc0_hw_metric_query
*hmq
= nvc0_hw_metric_query(hq
);
613 struct nvc0_screen
*screen
= nvc0
->screen
;
614 struct nouveau_device
*dev
= screen
->base
.device
;
615 union pipe_query_result results
[8] = {};
616 uint64_t res64
[8] = {};
621 for (i
= 0; i
< hmq
->num_queries
; i
++) {
622 ret
= hmq
->queries
[i
]->funcs
->get_query_result(nvc0
, hmq
->queries
[i
],
626 res64
[i
] = *(uint64_t *)&results
[i
];
629 switch (screen
->base
.class_3d
) {
632 value
= sm30_hw_metric_calc_result(hq
, res64
);
635 if (dev
->chipset
== 0xc0 || dev
->chipset
== 0xc8)
636 value
= sm20_hw_metric_calc_result(hq
, res64
);
638 value
= sm21_hw_metric_calc_result(hq
, res64
);
642 *(uint64_t *)result
= value
;
646 static const struct nvc0_hw_query_funcs hw_metric_query_funcs
= {
647 .destroy_query
= nvc0_hw_metric_destroy_query
,
648 .begin_query
= nvc0_hw_metric_begin_query
,
649 .end_query
= nvc0_hw_metric_end_query
,
650 .get_query_result
= nvc0_hw_metric_get_query_result
,
653 struct nvc0_hw_query
*
654 nvc0_hw_metric_create_query(struct nvc0_context
*nvc0
, unsigned type
)
656 const struct nvc0_hw_metric_query_cfg
*cfg
;
657 struct nvc0_hw_metric_query
*hmq
;
658 struct nvc0_hw_query
*hq
;
661 if (type
< NVC0_HW_METRIC_QUERY(0) || type
> NVC0_HW_METRIC_QUERY_LAST
)
664 hmq
= CALLOC_STRUCT(nvc0_hw_metric_query
);
669 hq
->funcs
= &hw_metric_query_funcs
;
670 hq
->base
.type
= type
;
672 cfg
= nvc0_hw_metric_query_get_cfg(nvc0
, hq
);
674 for (i
= 0; i
< cfg
->num_queries
; i
++) {
675 hmq
->queries
[i
] = nvc0_hw_sm_create_query(nvc0
, cfg
->queries
[i
]);
676 if (!hmq
->queries
[i
]) {
677 nvc0_hw_metric_destroy_query(nvc0
, hq
);
687 nvc0_hw_metric_get_driver_query_info(struct nvc0_screen
*screen
, unsigned id
,
688 struct pipe_driver_query_info
*info
)
692 if (screen
->base
.drm
->version
>= 0x01000101) {
694 count
= nvc0_hw_metric_get_num_queries(screen
);
701 if (screen
->compute
) {
702 if (screen
->base
.class_3d
<= NVF0_3D_CLASS
) {
703 const struct nvc0_hw_metric_query_cfg
**queries
=
704 nvc0_hw_metric_get_queries(screen
);
705 const struct nvc0_hw_metric_cfg
*cfg
=
706 nvc0_hw_metric_get_cfg(queries
[id
]->type
);
708 info
->name
= cfg
->name
;
709 info
->query_type
= NVC0_HW_METRIC_QUERY(queries
[id
]->type
);
710 info
->type
= cfg
->type
;
711 info
->group_id
= NVC0_HW_METRIC_QUERY_GROUP
;