1 /* Copyright © 2013, Intel Corporation
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 #include "metrics-info.h"
27 metrics_group_info_init (metrics_group_info_t *group, GLuint id)
35 glGetPerfMonitorGroupStringAMD (id, 0, &length, NULL);
37 group->name = xmalloc (length + 1);
39 glGetPerfMonitorGroupStringAMD (id, length + 1, NULL, group->name);
41 /* Get number of counters */
42 group->num_counters = 0;
43 group->max_active_counters = 0;
44 glGetPerfMonitorCountersAMD (group->id,
45 (int *) &group->num_counters,
46 (int *) &group->max_active_counters,
49 /* Get counter numbers */
50 group->counter_ids = xmalloc (group->num_counters * sizeof (GLuint));
52 glGetPerfMonitorCountersAMD (group->id, NULL, NULL,
56 /* Get counter names */
57 group->counter_names = xmalloc (group->num_counters * sizeof (char *));
58 group->counter_types = xmalloc (group->num_counters * sizeof (GLuint));
60 for (i = 0; i < group->num_counters; i++) {
61 glGetPerfMonitorCounterInfoAMD (group->id,
62 group->counter_ids[i],
64 &group->counter_types[i]);
66 glGetPerfMonitorCounterStringAMD (group->id,
67 group->counter_ids[i],
70 group->counter_names[i] = xmalloc (length + 1);
72 glGetPerfMonitorCounterStringAMD (group->id,
73 group->counter_ids[i],
75 group->counter_names[i]);
80 metrics_group_info_fini (metrics_group_info_t *group)
84 for (i = 0; i < group->num_counters; i++)
85 free (group->counter_names[i]);
87 free (group->counter_types);
88 free (group->counter_names);
89 free (group->counter_ids);
94 /* A helper function, part of metrics_info_init below. */
102 _add_shader_stage (metrics_info_t *info, const char *name,
103 GLuint group_index, GLuint counter_index,
104 shader_phase_t phase)
106 shader_stage_info_t *stage;
107 char *stage_name, *space;
110 stage_name = xstrdup (name);
112 /* Terminate the stage name at the first space.
114 * This is valid for counter names such as:
116 * "Vertex Shader Active Time"
118 * "Vertex Shader Stall Time - Core Stall"
120 space = strchr (stage_name, ' ');
124 /* Look for an existing stage of the given name. */
127 for (i = 0; i < info->num_shader_stages; i++) {
128 if (strcmp (info->stages[i].name, stage_name) == 0) {
129 stage = &info->stages[i];
135 info->num_shader_stages++;
136 info->stages = xrealloc (info->stages,
137 info->num_shader_stages *
138 sizeof (shader_stage_info_t));
139 stage = &info->stages[info->num_shader_stages - 1];
140 stage->name = xstrdup (stage_name);
141 stage->active_group_index = 0;
142 stage->active_counter_index = 0;
143 stage->stall_group_index = 0;
144 stage->stall_counter_index = 0;
147 if (phase == SHADER_ACTIVE) {
148 stage->active_group_index = group_index;
149 stage->active_counter_index = counter_index;
151 stage->stall_group_index = group_index;
152 stage->stall_counter_index = counter_index;
159 metrics_info_init (metrics_info_t *info, bool have_perfmon)
164 info->have_perfmon = have_perfmon;
166 if (! have_perfmon) {
168 info->num_groups = 0;
169 info->num_shader_stages = 0;
171 info->initialized = 1;
176 glGetPerfMonitorGroupsAMD ((int *) &info->num_groups, 0, NULL);
178 group_ids = xmalloc (info->num_groups * sizeof (GLuint));
180 glGetPerfMonitorGroupsAMD (NULL, info->num_groups, group_ids);
182 info->groups = xmalloc (info->num_groups * sizeof (metrics_group_info_t));
184 for (i = 0; i < info->num_groups; i++)
185 metrics_group_info_init (&info->groups[i], group_ids[i]);
189 /* Identify each shader stage (by looking at
190 * performance-counter names for specific patterns) and
191 * initialize structures referring to the corresponding
192 * counter numbers for each stage. */
193 info->num_shader_stages = 0;
196 for (i = 0; i < info->num_groups; i++) {
197 metrics_group_info_t *group = &info->groups[i];
198 for (j = 0; j < group->num_counters; j++) {
199 char *name = group->counter_names[j];
200 if (strstr (name, "Shader Active Time")) {
201 _add_shader_stage (info, name, i, j,
204 if (strstr (name, "Shader Stall Time")) {
205 _add_shader_stage (info, name, i, j,
211 info->initialized = 1;
215 metrics_info_fini (metrics_info_t *info)
218 if (! info->initialized)
221 for (i = 0; i < info->num_groups; i++)
222 metrics_group_info_fini (&info->groups[i]);
227 for (i = 0; i < info->num_shader_stages; i++)
228 free (info->stages[i].name);
233 info->initialized = 0;