]> git.cworth.org Git - fips/blob - metrics-info.c
Make definition of context_t private to context.c
[fips] / metrics-info.c
1 /* Copyright © 2013, Intel Corporation
2  *
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:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
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
19  * THE SOFTWARE.
20  */
21
22 #include "metrics-info.h"
23
24 #include "xmalloc.h"
25
26 static void
27 metrics_group_info_init (metrics_group_info_t *group, GLuint id)
28 {
29         GLsizei length;
30         unsigned i;
31
32         group->id = id;
33
34         /* Get name */
35         glGetPerfMonitorGroupStringAMD (id, 0, &length, NULL);
36
37         group->name = xmalloc (length + 1);
38
39         glGetPerfMonitorGroupStringAMD (id, length + 1, NULL, group->name);
40
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,
47                                      0, NULL);
48
49         /* Get counter numbers */
50         group->counter_ids = xmalloc (group->num_counters * sizeof (GLuint));
51
52         glGetPerfMonitorCountersAMD (group->id, NULL, NULL,
53                                      group->num_counters,
54                                      group->counter_ids);
55
56         /* Get counter names */
57         group->counter_names = xmalloc (group->num_counters * sizeof (char *));
58         group->counter_types = xmalloc (group->num_counters * sizeof (GLuint));
59
60         for (i = 0; i < group->num_counters; i++) {
61                 glGetPerfMonitorCounterInfoAMD (group->id,
62                                                 group->counter_ids[i],
63                                                 GL_COUNTER_TYPE_AMD,
64                                                 &group->counter_types[i]);
65
66                 glGetPerfMonitorCounterStringAMD (group->id,
67                                                   group->counter_ids[i],
68                                                   0, &length, NULL);
69
70                 group->counter_names[i] = xmalloc (length + 1);
71
72                 glGetPerfMonitorCounterStringAMD (group->id,
73                                                   group->counter_ids[i],
74                                                   length + 1, NULL,
75                                                   group->counter_names[i]);
76         }
77 }
78
79 static void
80 metrics_group_info_fini (metrics_group_info_t *group)
81 {
82         unsigned i;
83
84         for (i = 0; i < group->num_counters; i++)
85                 free (group->counter_names[i]);
86
87         free (group->counter_types);
88         free (group->counter_names);
89         free (group->counter_ids);
90
91         free (group->name);
92 }
93
94 /* A helper function, part of metrics_info_init below. */
95
96 typedef enum {
97         SHADER_ACTIVE,
98         SHADER_STALL
99 } shader_phase_t;
100
101 static void
102 _add_shader_stage (metrics_info_t *info, const char *name,
103                    GLuint group_index, GLuint counter_index,
104                    shader_phase_t phase)
105 {
106         shader_stage_info_t *stage;
107         char *stage_name, *space;
108         unsigned i;
109
110         stage_name = xstrdup (name);
111
112         /* Terminate the stage name at the first space.
113          *
114          * This is valid for counter names such as:
115          *
116          *      "Vertex Shader Active Time"
117          * or
118          *      "Vertex Shader Stall Time - Core Stall"
119          */
120         space = strchr (stage_name, ' ');
121         if (space)
122                 *space = '\0';
123
124         /* Look for an existing stage of the given name. */
125         stage = NULL;
126
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];
130                         break;
131                 }
132         }
133
134         if (stage == NULL) {
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;
145         }
146
147         if (phase == SHADER_ACTIVE) {
148                 stage->active_group_index = group_index;
149                 stage->active_counter_index = counter_index;
150         } else {
151                 stage->stall_group_index = group_index;
152                 stage->stall_counter_index = counter_index;
153         }
154
155         free (stage_name);
156 }
157
158 void
159 metrics_info_init (metrics_info_t *info)
160 {
161         unsigned i, j;
162         GLuint *group_ids;
163
164         glGetPerfMonitorGroupsAMD ((int *) &info->num_groups, 0, NULL);
165
166         group_ids = xmalloc (info->num_groups * sizeof (GLuint));
167
168         glGetPerfMonitorGroupsAMD (NULL, info->num_groups, group_ids);
169
170         info->groups = xmalloc (info->num_groups * sizeof (metrics_group_info_t));
171
172         for (i = 0; i < info->num_groups; i++)
173                 metrics_group_info_init (&info->groups[i], group_ids[i]);
174
175         free (group_ids);
176
177         /* Identify each shader stage (by looking at
178          * performance-counter names for specific patterns) and
179          * initialize structures referring to the corresponding
180          * counter numbers for each stage. */
181         info->num_shader_stages = 0;
182         info->stages = NULL;
183
184         for (i = 0; i < info->num_groups; i++) {
185                 metrics_group_info_t *group = &info->groups[i];
186                 for (j = 0; j < group->num_counters; j++) {
187                         char *name = group->counter_names[j];
188                         if (strstr (name, "Shader Active Time")) {
189                                 _add_shader_stage (info, name, i, j,
190                                                    SHADER_ACTIVE);
191                         }
192                         if (strstr (name, "Shader Stall Time")) {
193                                 _add_shader_stage (info, name, i, j,
194                                                    SHADER_STALL);
195                         }
196                 }
197         }
198
199         info->initialized = 1;
200 }
201
202 void
203 metrics_info_fini (metrics_info_t *info)
204 {
205         unsigned i;
206         if (! info->initialized)
207                 return;
208
209         for (i = 0; i < info->num_groups; i++)
210                 metrics_group_info_fini (&info->groups[i]);
211
212         free (info->groups);
213         info->groups = NULL;
214
215         for (i = 0; i < info->num_shader_stages; i++)
216                 free (info->stages[i].name);
217
218         free (info->stages);
219         info->stages = NULL;
220
221         info->initialized = 0;
222 }