ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / amd_performance_monitor / measure.c
blobace287944d880da8571e32a75b8e3c08864d0355
1 /*
2 * Copyright © 2013 Intel Corporation
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 (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 /**
25 * \file measure.c
27 * Some AMD_performance_monitor tests that actually measure things.
30 #define __STDC_FORMAT_MACROS
31 #include <inttypes.h>
32 #include "piglit-util-gl.h"
34 PIGLIT_GL_TEST_CONFIG_BEGIN
36 config.supports_gl_compat_version = 10;
37 config.window_visual = PIGLIT_GL_VISUAL_RGB;
39 PIGLIT_GL_TEST_CONFIG_END
41 /******************************************************************************/
43 /**
44 * Get a list of group IDs.
46 static void
47 get_groups(unsigned **groups, int *num_groups)
49 glGetPerfMonitorGroupsAMD(num_groups, 0, NULL);
50 *groups = calloc(*num_groups, sizeof(unsigned));
51 glGetPerfMonitorGroupsAMD(NULL, *num_groups, *groups);
54 /**
55 * Get a list of counter IDs in a given group.
57 static void
58 get_counters(unsigned group, unsigned **counters, int *num_counters,
59 int *max_active_counters)
61 glGetPerfMonitorCountersAMD(group, num_counters, NULL, 0, NULL);
62 *counters = calloc(*num_counters, sizeof(unsigned));
63 glGetPerfMonitorCountersAMD(group, NULL, max_active_counters,
64 *num_counters, *counters);
67 #define verify(x) \
68 if (!(x)) { \
69 piglit_report_subtest_result(PIGLIT_FAIL, "%s", test_name); \
70 return; \
73 /******************************************************************************/
75 /**
76 * Poll until PERFMON_RESULT_AVAILABLE returns 1; glFinish() on each iteration.
78 * Only loop for 5 times to guard against implementations that never finish.
80 static bool
81 wait_until_available(unsigned monitor)
83 int i;
84 unsigned available = 0;
85 for (i = 0; !available && i < 5; i++) {
86 glFinish();
87 glGetPerfMonitorCounterDataAMD(monitor,
88 GL_PERFMON_RESULT_AVAILABLE_AMD,
89 sizeof(unsigned), &available,
90 NULL);
92 return available;
95 /**
96 * Basic functional test: enable all the counters in the first group
97 * (up to the maximum that can be active at a time), begin monitoring,
98 * end monitoring, make sure results are available, sanity check the
99 * result size, and get the results.
101 static void
102 test_basic_measurement(unsigned group)
104 unsigned monitor;
105 unsigned *counters;
106 int num_counters;
107 int max_active_counters;
108 unsigned usable_counters;
109 unsigned result_size = 0;
110 GLsizei bytes_written = 0;
111 unsigned *data;
113 uint32_t *p;
114 unsigned value;
116 const char *test_name;
119 * Test #1: Basic Measurement.
121 * Enable all the counters in the first group (up to the maximum that
122 * can be active at a time), begin monitoring, end monitoring, make
123 * sure results are available, sanity check the result size, and get
124 * the results.
126 test_name = "basic measurement";
128 get_counters(group, &counters, &num_counters,
129 &max_active_counters);
130 verify(max_active_counters >= 0);
131 verify(piglit_check_gl_error(GL_NO_ERROR));
133 usable_counters = MIN2(num_counters, max_active_counters);
135 glGenPerfMonitorsAMD(1, &monitor);
136 verify(piglit_check_gl_error(GL_NO_ERROR));
138 /* Enable counters 0 .. usable_counters from the list. */
139 glSelectPerfMonitorCountersAMD(monitor, true, group, usable_counters,
140 counters);
141 verify(piglit_check_gl_error(GL_NO_ERROR));
143 /* Start monitoring */
144 glBeginPerfMonitorAMD(monitor);
145 verify(piglit_check_gl_error(GL_NO_ERROR));
147 /* Drawing...meh */
148 glFinish();
150 /* End monitoring */
151 glEndPerfMonitorAMD(monitor);
152 verify(piglit_check_gl_error(GL_NO_ERROR));
154 /* Wait for the result to be available. */
155 verify(wait_until_available(monitor));
156 verify(piglit_check_gl_error(GL_NO_ERROR));
158 /* Get the result size. */
159 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_SIZE_AMD,
160 sizeof(unsigned), &result_size, NULL);
161 verify(piglit_check_gl_error(GL_NO_ERROR));
163 /* Make sure the size is in bytes. */
164 verify(result_size % sizeof(unsigned) == 0);
166 /* The format is <Group ID, Group, Value>. The first two are
167 * uint32_ts. Value is either a float, uint32_t, or uint64_t.
168 * As a sanity check, make sure the result size is within
169 * reasonable limits. Don't bother checking the actual types
170 * since that's a bunch of work.
172 verify(result_size >= 3 * sizeof(uint32_t) * usable_counters)
173 verify(result_size <=
174 (2 * sizeof(uint32_t) + sizeof(uint64_t)) * usable_counters);
176 /* Get the results. */
177 data = calloc(1, result_size);
178 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AMD,
179 result_size, data, &bytes_written);
181 verify(bytes_written == result_size);
183 piglit_report_subtest_result(PIGLIT_PASS, "%s", test_name);
186 * Test #2: Verify counter results against specified range.
188 test_name = "counters in range";
189 p = data;
190 while ((char *) p < ((char *) data) + bytes_written) {
191 uint32_t group_id = p[0];
192 uint32_t counter_id = p[1];
194 /* Counter values */
195 uint32_t u32 = p[2];
196 float f = ((float *) p)[2];
198 /* Query results */
199 GLenum counter_type = GL_NONE;
200 uint64_t range[2];
202 /* There's only one group, so it better match */
203 verify(group_id == group);
205 /* Getting the counter data also validates the counter ID
206 * without having to walk through the whole list of counters.
208 glGetPerfMonitorCounterInfoAMD(group_id, counter_id,
209 GL_COUNTER_TYPE_AMD,
210 &counter_type);
211 verify(piglit_check_gl_error(GL_NO_ERROR));
213 glGetPerfMonitorCounterInfoAMD(group_id, counter_id,
214 GL_COUNTER_RANGE_AMD,
215 range);
216 verify(piglit_check_gl_error(GL_NO_ERROR));
218 /* Make sure it falls within the proper range */
219 switch (counter_type) {
220 case GL_UNSIGNED_INT: {
221 uint32_t min = ((uint32_t *) range)[0];
222 uint32_t max = ((uint32_t *) range)[1];
223 verify(u32 >= min);
224 verify(u32 <= max);
225 break;
227 case GL_UNSIGNED_INT64_AMD: {
228 uint64_t u64 = ((uint64_t *) p)[1];
229 verify(u64 >= range[0]);
230 verify(u64 <= range[1]);
231 break;
233 case GL_PERCENTAGE_AMD:
234 case GL_FLOAT: {
235 float min = ((float *) range)[0];
236 float max = ((float *) range)[1];
237 verify(f >= min);
238 verify(f <= max);
239 break;
243 p += (counter_type == GL_UNSIGNED_INT64_AMD) ? 4 : 3;
245 verify(result_size == ((char *) p - (char *) data));
247 piglit_report_subtest_result(PIGLIT_PASS, "%s", test_name);
249 free(data);
252 * Test #3: Changing the set of active counters resets queries.
254 * "When SelectPerfMonitorCountersAMD is called on a monitor, any
255 * outstanding results for that monitor become invalidated and the
256 * result queries PERFMON_RESULT_SIZE_AMD and
257 * PERFMON_RESULT_AVAILABLE_AMD are reset to 0."
259 test_name = "selecting counters resets queries";
261 /* Turn off the first counter. */
262 glSelectPerfMonitorCountersAMD(monitor, false, group, 1, counters);
263 verify(piglit_check_gl_error(GL_NO_ERROR));
265 /* Results should no longer be available. All queries should
266 * return 0.
268 value = 0xd0d0d0d0;
269 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AVAILABLE_AMD,
270 sizeof(unsigned), &value, NULL);
271 verify(piglit_check_gl_error(GL_NO_ERROR));
272 verify(value == 0);
274 value = 0xd0d0d0d0;
275 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_SIZE_AMD,
276 sizeof(unsigned), &value, NULL);
277 verify(piglit_check_gl_error(GL_NO_ERROR));
278 verify(value == 0);
280 piglit_report_subtest_result(PIGLIT_PASS, "%s", test_name);
282 glDeletePerfMonitorsAMD(1, &monitor);
287 * Make sure that calling SelectPerfMonitorCountersAMD on an active monitor
288 * is possible, resets active queries, and restarts monitoring (so it remains
289 * active).
291 * This is not actually specified, but matches the behavior of AMD's driver.
292 * Being an AMD extension, other implementations should probably match theirs.
294 static void
295 test_change_counters_while_active(unsigned group)
297 unsigned monitor;
298 unsigned *counters;
299 int num_counters;
300 int max_active_counters;
301 unsigned usable_counters;
302 unsigned data;
303 const char *test_name = "change counters while active";
305 get_counters(group, &counters, &num_counters,
306 &max_active_counters);
307 verify(max_active_counters >= 0);
308 verify(piglit_check_gl_error(GL_NO_ERROR));
310 usable_counters = MIN2(num_counters, max_active_counters);
312 if (usable_counters == 0)
313 return; /* skip */
315 glGenPerfMonitorsAMD(1, &monitor);
316 verify(piglit_check_gl_error(GL_NO_ERROR));
318 /* Enable counters 0 .. usable_counters from the list. */
319 glSelectPerfMonitorCountersAMD(monitor, true, group, usable_counters,
320 counters);
321 verify(piglit_check_gl_error(GL_NO_ERROR));
323 /* Start monitoring */
324 glBeginPerfMonitorAMD(monitor);
325 verify(piglit_check_gl_error(GL_NO_ERROR));
327 /* Turn off the first counter. The specification is unclear whether
328 * or not this should be allowed while monitoring is active, but it
329 * apparently is (Catalyst 12.06 on a Radeon 3650).
331 glSelectPerfMonitorCountersAMD(monitor, false, group, 1, counters);
332 verify(piglit_check_gl_error(GL_NO_ERROR));
334 /* Verify that all queries have been reset to 0 */
335 data = 0xd0d0d0d0;
336 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AVAILABLE_AMD,
337 sizeof(unsigned), &data, NULL);
338 verify(piglit_check_gl_error(GL_NO_ERROR));
339 verify(data == 0);
341 data = 0xd0d0d0d0;
342 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_SIZE_AMD,
343 sizeof(unsigned), &data, NULL);
344 verify(piglit_check_gl_error(GL_NO_ERROR));
345 verify(data == 0);
347 /* The spec doesn't explicitly mention whether or not monitoring
348 * is still active, but apparently it is.
350 glEndPerfMonitorAMD(monitor);
351 verify(piglit_check_gl_error(GL_NO_ERROR));
353 glDeletePerfMonitorsAMD(1, &monitor);
354 verify(piglit_check_gl_error(GL_NO_ERROR));
356 piglit_report_subtest_result(PIGLIT_PASS, "%s", test_name);
360 /******************************************************************************/
362 enum piglit_result
363 piglit_display(void)
365 return PIGLIT_FAIL;
369 * The main test program.
371 void
372 piglit_init(int argc, char **argv)
374 unsigned *groups;
375 int num_groups;
377 piglit_require_extension("GL_AMD_performance_monitor");
379 /* Basic glGetPerfMonitorGroupsAMD() tests */
380 get_groups(&groups, &num_groups);
382 /* If there are no groups, the rest of the tests can't run. Bail. */
383 if (num_groups == 0)
384 exit(0);
386 test_basic_measurement(groups[0]);
387 test_change_counters_while_active(groups[0]);
389 exit(0);