ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / amd_performance_monitor / api.c
blobef653cfa1d0eed5b36c19b484d5cac4539283c0b
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 api.c
27 * Basic AMD_performance_monitor infrastructure tests. These test the
28 * mechanism to retrieve counter and group information, string processing,
29 * and various error conditions. They do not actually activate monitoring.
32 #define __STDC_FORMAT_MACROS
33 #include <inttypes.h>
34 #include "piglit-util-gl.h"
36 PIGLIT_GL_TEST_CONFIG_BEGIN
38 config.supports_gl_compat_version = 10;
39 config.window_visual = PIGLIT_GL_VISUAL_RGB;
41 PIGLIT_GL_TEST_CONFIG_END
43 /******************************************************************************/
45 /**
46 * Get a list of group IDs.
48 static void
49 get_groups(unsigned **groups, int *num_groups)
51 glGetPerfMonitorGroupsAMD(num_groups, 0, NULL);
52 *groups = calloc(*num_groups, sizeof(unsigned));
53 glGetPerfMonitorGroupsAMD(NULL, *num_groups, *groups);
56 /**
57 * Get a list of counter IDs in a given group.
59 static void
60 get_counters(unsigned group, unsigned **counters, int *num_counters)
62 glGetPerfMonitorCountersAMD(group, num_counters, NULL, 0, NULL);
63 *counters = calloc(*num_counters, sizeof(unsigned));
64 glGetPerfMonitorCountersAMD(group, NULL, NULL, *num_counters, *counters);
67 /**
68 * Return true if x is in xs.
70 static bool
71 in_list(int x, unsigned *xs, int elts)
73 int i;
74 for (i = 0; i < elts; i++) {
75 if (x == xs[i])
76 return true;
78 return false;
81 /**
82 * Find an invalid group ID.
84 static unsigned
85 find_invalid_group(unsigned *groups, int num_groups)
87 unsigned invalid_group = ~0;
89 /* Most implementations probably use small consecutive integers, so
90 * start at ~0 and work backwards. Hopefully we shouldn't loop.
92 while (in_list(invalid_group, groups, num_groups))
93 --invalid_group;
95 return invalid_group;
98 /**
99 * Find an invalid counter ID.
101 static unsigned
102 find_invalid_counter(unsigned *counters, int num_counters)
104 unsigned invalid_counter = ~0;
106 /* Most implementations probably use small consecutive integers, so
107 * start at ~0 and work backwards. Hopefully we shouldn't loop.
109 while (in_list(invalid_counter, counters, num_counters))
110 --invalid_counter;
112 return invalid_counter;
115 #define report(pass) \
116 do { \
117 piglit_report_subtest_result((pass) ? PIGLIT_PASS : PIGLIT_FAIL, __FUNCTION__); \
118 return; \
119 } while (0)
121 /******************************************************************************/
124 * Call glGetPerfMonitorGroupsAMD() with a NULL numGroups pointer.
126 * Verify that it doesn't attempt to write the number of groups and crash.
128 static void
129 test_number_of_groups_null_num_groups_pointer(void)
131 glGetPerfMonitorGroupsAMD(NULL, 0, NULL);
132 report(piglit_check_gl_error(GL_NO_ERROR));
137 * Call glGetPerfMonitorGroupsAMD() with NULL for groups but non-zero groupSize.
139 * Verify that it returns the number of groups but doesn't try to write any
140 * group IDs and crash.
142 static void
143 test_number_of_groups_null_groups_pointer(void)
145 bool pass = true;
146 int num_groups = -1;
148 glGetPerfMonitorGroupsAMD(&num_groups, 777, NULL);
149 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
150 pass = num_groups >= 0 && pass;
151 report(pass);
155 * Call glGetPerfMonitorGroupsAMD() with zero for groupSize.
157 * Verify that it doesn't write any group IDs.
159 static void
160 test_number_of_groups_zero_size_array(void)
162 bool pass = true;
163 unsigned groups[2] = {0xd0d0d0d0, 0xd1d1d1d1};
164 int num_groups = -1;
166 glGetPerfMonitorGroupsAMD(&num_groups, 0, groups);
167 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
169 /* num_groups must have changed */
170 pass = num_groups >= 0 && pass;
172 /* The groups array should not have changed. */
173 pass = groups[0] == 0xd0d0d0d0 && pass;
174 pass = groups[1] == 0xd1d1d1d1 && pass;
175 report(pass);
179 * Call glGetPerfMonitorGroupsAMD() with a groups array bigger than groupSize.
181 * Verify that it fills the correct number of array slots with group IDs.
183 static void
184 test_number_of_groups_partial_array(void)
186 bool pass = true;
187 unsigned groups[] = {0xdddddddd, 0xdddddddd, 0xdddddddd, 0xdddddddd};
189 /* Artificially low array size */
190 const int groups_array_size = 2;
191 int num_groups = -1;
192 int i;
194 /* This should return the number of groups. It should not attempt to
195 * write any groups since the pointer is NULL.
197 glGetPerfMonitorGroupsAMD(&num_groups, groups_array_size, groups);
198 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
200 /* num_groups must have changed */
201 pass = num_groups >= 0 && pass;
203 /* The first few elements should have changed. */
204 for (i = 0; i < MIN2(num_groups, groups_array_size); i++) {
205 pass = groups[i] != 0xdddddddd && pass;
208 /* Catalyst 13.10 on a Radeon 6870 appears to have a bug where this
209 * returns 3 elements instead of 2. According to the spec,
210 * "The number of entries that will be returned in <groups> is
211 * determined by <groupSize>."
213 * Technically, it does not say that N elements will be returned if
214 * groupSize is N, but that's the only reasonable assumption.
217 /* The rest should remain untouched. */
218 for (; i < ARRAY_SIZE(groups); i++) {
219 pass = groups[i] == 0xdddddddd && pass;
222 report(pass);
225 /******************************************************************************/
228 * Call glGetPerfMonitorCountersAMD() with an invalid group ID.
230 * Verify that it produces INVALID_VALUE.
232 static void
233 test_get_counters_invalid_group(unsigned invalid_group)
235 glGetPerfMonitorCountersAMD(invalid_group, NULL, NULL, 0, NULL);
236 report(piglit_check_gl_error(GL_INVALID_VALUE));
240 * Call glGetPerfMonitorCountersAMD() with a bunch of NULL pointers.
242 * Verify that it doesn't crash attempting to write numCounters,
243 * maxActiveCounters, or the counters list.
245 static void
246 test_get_counters_null_pointers(unsigned valid_group)
248 glGetPerfMonitorCountersAMD(valid_group, NULL, NULL, 0, NULL);
249 report(piglit_check_gl_error(GL_NO_ERROR));
253 * Call glGetPerfMonitorCountersAMD() with NULL for the array but non-zero size.
255 * Verify that it returns the number of groups but doesn't try to write any
256 * group IDs and crash.
258 static void
259 test_get_counters_null_pointer_non_zero_size(unsigned valid_group)
261 glGetPerfMonitorCountersAMD(valid_group, NULL, NULL, 777, NULL);
262 report(piglit_check_gl_error(GL_NO_ERROR));
266 * Call glGetPerfMonitorCountersAMD() with zero for countersSize.
268 * Verify that it doesn't write any IDs, but does return other data.
270 static void
271 test_get_counters_zero_size_array(unsigned valid_group)
273 bool pass = true;
274 unsigned counters[2] = {0xd0d0d0d0, 0xd1d1d1d1};
275 int num_counters = -1;
276 int max_active_counters = -1;
278 glGetPerfMonitorCountersAMD(valid_group, &num_counters,
279 &max_active_counters,
280 0, counters);
281 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
283 /* Expect a positive number of counters. */
284 pass = num_counters >= 0 && pass;
286 /* Expect a positive maximum active counters. */
287 pass = max_active_counters >= 0 && pass;
289 /* The counters array should not have changed. */
290 pass = counters[0] == 0xd0d0d0d0 && pass;
291 pass = counters[1] == 0xd1d1d1d1 && pass;
292 report(pass);
296 * Call glGetPerfMonitorGroupsAMD() with a groups array bigger than groupSize.
298 * Verify that it fills the correct number of array slots with group IDs.
300 static void
301 test_get_counters_partial_array(unsigned valid_group)
303 bool pass = true;
304 unsigned counters[] = {0xdddddddd, 0xdddddddd, 0xdddddddd, 0xdddddddd};
306 /* Artificially low array size */
307 const int counters_array_size = 2;
308 int num_counters = -1;
309 int i;
311 /* This should return the number of groups. It should not attempt to
312 * write any groups since the pointer is NULL.
314 glGetPerfMonitorCountersAMD(valid_group, &num_counters, NULL,
315 counters_array_size, counters);
316 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
318 /* num_counters must have changed */
319 pass = num_counters >= 0 && pass;
321 /* The first few elements should have changed. */
322 for (i = 0; i < MIN2(num_counters, counters_array_size); i++) {
323 pass = counters[i] != 0xdddddddd && pass;
326 /* The rest should remain untouched. */
327 for (; i < ARRAY_SIZE(counters); i++) {
328 pass = counters[i] == 0xdddddddd && pass;
331 report(pass);
334 /******************************************************************************/
337 * Call glGetPerfMonitorGroupStringAMD() with an invalid group ID.
339 * Verify that it produces INVALID_VALUE.
341 static void
342 test_group_string_invalid_group(unsigned invalid_group)
344 glGetPerfMonitorGroupStringAMD(invalid_group, 0, NULL, NULL);
345 report(piglit_check_gl_error(GL_INVALID_VALUE));
349 * Call glGetPerfMonitorGroupStringAMD() with a NULL length pointer.
351 * Verify that it doesn't crash.
353 static void
354 test_group_string_null_length(unsigned valid_group)
356 glGetPerfMonitorGroupStringAMD(valid_group, 0, NULL, NULL);
357 report(piglit_check_gl_error(GL_NO_ERROR));
361 * Call glGetPerfMonitorGroupStringAMD() with a single character buffer.
363 * Verify that length is correct and no buffer overflows occur.
365 static void
366 test_group_string_single_character_buffer(unsigned valid_group)
368 bool pass = true;
369 char name[3] = "```";
370 GLsizei length = 0xd0d0d0d0;
372 glGetPerfMonitorGroupStringAMD(valid_group, 1, &length, name);
373 pass = piglit_check_gl_error(GL_NO_ERROR);
375 /* Verify buffer contents: only the first character should change. */
376 pass = name[0] != '`' && pass;
377 pass = name[1] == '`' && pass;
378 pass = name[2] == '`' && pass;
380 /* length is the number of characters written excluding the null
381 * terminator.
383 if (name[0] == '\0') {
384 pass = length == 0 && pass;
385 } else {
386 /* AMD Catalyst 13.10 (Radeon 6870) does not write a null
387 * terminator. Instead, it writes the first part of the name.
389 pass = length == 1 && pass;
392 report(pass);
396 * Call glGetPerfMonitorGroupStringAMD() with a small buffer.
398 * Verify that a name is returned, length is valid, and no overflows occur.
400 static void
401 test_group_string_small_buffer(unsigned valid_group)
403 bool pass = true;
404 char name[3] = "```";
405 GLsizei length = 0xd0d0d0d0;
406 int i;
408 glGetPerfMonitorGroupStringAMD(valid_group, 3, &length, name);
410 pass = length <= 3 && pass;
412 /* Verify buffer contents: accept no null terminator. */
413 for (i = 0; i < length; i++)
414 pass = name[i] != '`' && pass;
416 if (length < 3) {
417 pass = name[length] == '\0';
418 for (i = length + 1; i < 3; i++)
419 pass = name[i] == '`' && pass;
422 report(pass);
426 * Call glGetPerfMonitorGroupStringAMD() with an appropriately sized buffer.
428 * Verify that a name is returned, length is valid, and no overflows occur.
430 static void
431 test_group_string_normal_buffer(unsigned valid_group)
433 bool pass = true;
434 char *name;
435 GLsizei length = 0xd0d0d0d0;
436 int i;
438 /* Get the length; bail if unwritten to avoid huge allocations. */
439 glGetPerfMonitorGroupStringAMD(valid_group, 0, &length, NULL);
440 pass = pass && piglit_check_gl_error(GL_NO_ERROR);
441 if (length == 0xd0d0d0d0)
442 report(false);
444 name = malloc(length + 1);
445 assert(name != NULL);
447 /* Fill the buffer with a known character (` marks) */
448 memset(name, '`', length + 1);
450 /* Get the name; everything will fit. */
451 glGetPerfMonitorGroupStringAMD(valid_group, length + 1, NULL, name);
452 pass = pass && piglit_check_gl_error(GL_NO_ERROR);
454 /* Indexes in the interval [0, length) must have been written, or
455 * else length is wrong.
457 for (i = 0; i < length; i++)
458 pass = name[i] != '`' && pass;
460 /* The last character must be the null terminator. */
461 pass = name[length] == '\0' && pass;
463 report(pass);
466 /******************************************************************************/
469 * Call glGetPerfMonitorCounterStringAMD() with an invalid group ID.
471 * Verify that it produces INVALID_VALUE.
473 static void
474 test_counter_string_invalid_group(unsigned invalid_group)
476 glGetPerfMonitorCounterStringAMD(invalid_group, 0, 0, NULL, NULL);
477 report(piglit_check_gl_error(GL_INVALID_VALUE));
481 * Call glGetPerfMonitorCounterStringAMD() with an invalid counter ID.
483 * Verify that it produces INVALID_VALUE.
485 static void
486 test_counter_string_invalid_counter(unsigned group, unsigned invalid_counter)
488 glGetPerfMonitorCounterStringAMD(group, invalid_counter, 0, NULL, NULL);
489 report(piglit_check_gl_error(GL_INVALID_VALUE));
493 * Call glGetPerfMonitorCounterStringAMD() with a NULL length pointer.
495 * Verify that it doesn't crash.
497 static void
498 test_counter_string_null_length(unsigned group, unsigned counter)
500 glGetPerfMonitorCounterStringAMD(group, counter, 0, NULL, NULL);
501 report(piglit_check_gl_error(GL_NO_ERROR));
505 * Call glGetPerfMonitorCounterStringAMD() with a single character buffer.
507 * Verify that length is correct and no buffer overflows occur.
509 static void
510 test_counter_string_single_character_buffer(unsigned group, unsigned counter)
512 bool pass = true;
513 char name[3] = "```";
514 GLsizei length = 0xd0d0d0d0;
516 glGetPerfMonitorCounterStringAMD(group, counter, 1, &length, name);
517 pass = piglit_check_gl_error(GL_NO_ERROR);
519 /* Verify buffer contents */
520 pass = name[0] != '`' && pass;
521 pass = name[1] == '`' && pass;
522 pass = name[2] == '`' && pass;
524 /* length is the number of characters written excluding the null
525 * terminator.
527 if (name[0] == '\0') {
528 pass = length == 0 && pass;
529 } else {
530 /* AMD Catalyst 13.10 (Radeon 6870) does not write a null
531 * terminator. Instead, it writes the first part of the name.
533 pass = length == 1 && pass;
536 report(pass);
540 * Call glGetPerfMonitorCounterStringAMD() with a small buffer.
542 * Verify that a name is returned, length is valid, and no overflows occur.
544 static void
545 test_counter_string_small_buffer(unsigned group, unsigned counter)
547 bool pass = true;
548 char name[3] = "```";
549 GLsizei length = 0xd0d0d0d0;
550 int i;
552 glGetPerfMonitorCounterStringAMD(group, counter, 3, &length, name);
554 pass = length <= 3 && pass;
556 /* Verify buffer contents: accept no null terminator. */
557 for (i = 0; i < length; i++)
558 pass = name[i] != '`' && pass;
560 if (length < 3) {
561 pass = name[length] == '\0';
562 for (i = length + 1; i < 3; i++)
563 pass = name[i] == '`' && pass;
566 report(pass);
570 * Call glGetPerfMonitorCounterStringAMD() with an appropriately sized buffer.
572 * Verify that a name is returned, length is valid, and no overflows occur.
574 static void
575 test_counter_string_normal_buffer(unsigned group, unsigned counter)
577 bool pass = true;
578 char *name;
579 GLsizei length = 0xd0d0d0d0;
580 int i;
582 /* Get the length; bail if unwritten to avoid huge allocations. */
583 glGetPerfMonitorCounterStringAMD(group, counter, 0, &length, NULL);
584 pass = pass && piglit_check_gl_error(GL_NO_ERROR);
585 if (length == 0xd0d0d0d0)
586 report(false);
588 name = malloc(length + 1);
589 assert(name != NULL);
591 /* Fill the buffer with a known character (` marks) */
592 memset(name, '`', length + 1);
594 /* Get the name; everything will fit. */
595 glGetPerfMonitorCounterStringAMD(group, counter, length + 1, NULL, name);
596 pass = pass && piglit_check_gl_error(GL_NO_ERROR);
598 /* Indexes in the interval [0, length) must have been written, or
599 * else length is wrong.
601 for (i = 0; i < length; i++)
602 pass = name[i] != '`' && pass;
604 /* The last character must be the null terminator. */
605 pass = name[length] == '\0' && pass;
607 report(pass);
610 /******************************************************************************/
613 * Call glGetPerfMonitorCounterInfoAMD() with an invalid group ID.
615 * Verify that it produces INVALID_VALUE.
617 static void
618 test_counter_info_invalid_group(unsigned invalid_group)
620 GLenum type;
621 glGetPerfMonitorCounterInfoAMD(invalid_group, 0, GL_COUNTER_TYPE_AMD,
622 &type);
623 report(piglit_check_gl_error(GL_INVALID_VALUE));
627 * Call glGetPerfMonitorCounterInfoAMD() with an invalid counter ID.
629 * Verify that it produces INVALID_VALUE.
631 static void
632 test_counter_info_invalid_counter(unsigned group, unsigned invalid_counter)
634 GLenum type;
635 glGetPerfMonitorCounterInfoAMD(group, invalid_counter,
636 GL_COUNTER_TYPE_AMD, &type);
637 report(piglit_check_gl_error(GL_INVALID_VALUE));
641 * Call glGetPerfMonitorCounterInfoAMD() on every group/counter and verify that:
642 * - All counters must have a valid type.
643 * - Percentage counters must have a range of [0.0f, 100.0f]
644 * - Counter ranges should return a minimum strictly less than the maximum.
645 * - The counter range query doesn't return too much data.
647 static void
648 test_counter_info(unsigned *groups, int num_groups)
650 int i;
651 int j;
653 for (i = 0; i < num_groups; i++) {
654 unsigned *counters;
655 int num_counters;
656 get_counters(groups[i], &counters, &num_counters);
658 for (j = 0; j < num_counters; j++) {
659 GLenum type = GL_NONE;
660 uint64_t data[3];
661 uint64_t min_u, max_u;
662 float min_f, max_f;
663 uint32_t unchanged;
664 bool is_unsigned = false;
666 glGetPerfMonitorCounterInfoAMD(groups[i], counters[j],
667 GL_COUNTER_TYPE_AMD,
668 &type);
670 /* Get the range */
671 memset(data, 0xff, sizeof(uint64_t) * 3);
672 glGetPerfMonitorCounterInfoAMD(groups[i], counters[j],
673 GL_COUNTER_RANGE_AMD,
674 data);
676 /* Validate the type and use it to interpret the
677 * minimum/maximum information.
679 switch (type) {
680 case GL_UNSIGNED_INT:
681 min_u = ((uint32_t *) data)[0];
682 max_u = ((uint32_t *) data)[1];
683 unchanged = ((uint32_t *) data)[2];
684 is_unsigned = true;
685 break;
686 case GL_UNSIGNED_INT64_AMD:
687 min_u = data[0];
688 max_u = data[1];
689 unchanged = ((uint32_t *) data)[4];
690 is_unsigned = true;
691 break;
692 case GL_PERCENTAGE_AMD:
693 case GL_FLOAT:
694 min_f = ((float *) data)[0];
695 max_f = ((float *) data)[1];
696 unchanged = ((uint32_t *) data)[2];
697 break;
698 default:
699 printf("Group %u/Counter %u has an invalid type: %x\n", groups[i], counters[j], type);
700 report(false);
703 /* Make sure it didn't write too much data. */
704 if (unchanged != 0xffffffff) {
705 printf("COUNTER_RANGE_AMD query for group %u/Counter %u wrote too much data to the buffer.\n", groups[i], counters[j]);
706 report(false);
709 /* "If type value returned is PERCENTAGE_AMD, then this
710 * describes a float value that is in the range [0.0 ..
711 * 100.0]." So we can check this.
713 if (type == GL_PERCENTAGE_AMD) {
714 if (min_f != 0.0f || max_f != 100.0f) {
715 printf("Group %u/Counter %u's minimum (%f) and maximum (%f) must be 0.0f and 100.0f, respectively.\n", groups[i], counters[j], min_f, max_f);
716 report(false);
718 } else if (is_unsigned) {
719 /* The spec doesn't explicitly state it, but it
720 * makes sense for the minimum to be strictly
721 * less than the maximum. Do a service to
722 * driver authors and validate that.
724 if (min_u >= max_u) {
725 printf("Group %u/Counter %u's minimum (%" PRIu64 ") is >= the maximum (%" PRIu64 ").\n", groups[i], counters[j], min_u, max_u);
726 report(false);
728 } else if (type == GL_FLOAT) {
729 if (min_f >= max_f) {
730 printf("Group %u/Counter %u's minimum (%f) is >= the maximum (%f).\n", groups[i], counters[j], min_f, max_f);
731 report(false);
736 free(counters);
738 report(true);
741 /******************************************************************************/
745 * Call glBeginPerfMonitorAMD() on an invalid monitor ID.
746 * (Should be run before any Gen tests to ensure this ID is invalid.)
748 * XXX: This isn't actually specified, but it seems like it ought to be.
750 void
751 test_begin_invalid_monitor(void)
753 glBeginPerfMonitorAMD(777);
754 report(piglit_check_gl_error(GL_INVALID_VALUE));
758 * Call glEndPerfMonitorAMD() on an invalid monitor ID.
759 * (Should be run before any Gen tests to ensure this ID is invalid.)
761 * XXX: This isn't actually specified, but it seems like it ought to be.
763 * AMD Catalyst 13.10 (Radeon 6870) instead produces INVALID_OPERATION,
764 * presumably because the (invalid) monitor hasn't been started. (See
765 * test_end_without_begin.) So we allow either here.
767 void
768 test_end_invalid_monitor(void)
770 GLenum error;
771 glEndPerfMonitorAMD(777);
772 error = glGetError();
773 report(error == GL_INVALID_VALUE || error == GL_INVALID_OPERATION);
777 * Call glGetPerfMonitorCounterDataAMD() with an invalid monitor ID.
779 * XXX: This isn't actually specified, but it seems like it ought to be.
781 static void
782 test_get_counter_data_invalid_monitor(void)
784 unsigned value;
785 glGetPerfMonitorCounterDataAMD(777, GL_PERFMON_RESULT_AVAILABLE_AMD,
786 0, &value, NULL);
787 report(piglit_check_gl_error(GL_INVALID_VALUE));
791 * Call glSelectPerfMonitorCountersAMD() with an invalid monitor ID.
793 * "If <monitor> is not a valid monitor created by GenPerfMonitorsAMD, then
794 * INVALID_VALUE will be generated."
796 static void
797 test_select_counters_invalid_monitor(void)
799 unsigned junk;
800 glSelectPerfMonitorCountersAMD(777, false, 0, 0, &junk);
801 report(piglit_check_gl_error(GL_INVALID_VALUE));
805 * Call glDeletePerfMonitorsAMD() on an invalid monitor ID.
806 * (Should be run before any Gen tests to ensure this ID is invalid.)
808 * "If a monitor ID in the list <monitors> does not reference a previously
809 * generated performance monitor, an INVALID_VALUE error is generated."
811 * AMD Catalyst 13.10 (Radeon 6870) fails this test, producing NO_ERROR.
813 static void
814 test_delete_monitor_invalid(void)
816 unsigned monitor = 777;
817 glDeletePerfMonitorsAMD(1, &monitor);
818 report(piglit_check_gl_error(GL_INVALID_VALUE));
822 * Mean tests for glGetPerfMonitorCounterDataAMD()'s data return mechanism.
824 * AMD Catalyst 13.10 (Radeon 6870) fails this test. It does not set
825 * bytes_written, yet writes 0 for each of these queries. It apparently
826 * interprets these fields as only relevant to the PERFMON_RESULT_AMD query.
828 static void
829 test_get_counter_data_byte_size(void)
831 bool pass = true;
832 unsigned monitor;
833 unsigned value;
834 GLsizei bytes_written;
836 glGenPerfMonitorsAMD(1, &monitor);
837 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
839 /* "It is an INVALID_OPERATION error far <data> to be NULL." */
840 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AVAILABLE_AMD,
841 0, NULL, NULL);
842 pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
844 /* "The argument <dataSize> specifies the number of bytes available in
845 * the <data> buffer for writing."
847 * It would be easy to accidentally treat this as 4-byte units, so
848 * be mean and try < sizeof(int) sizes.
851 /* dataSize = 0: Nothing should be written. */
852 value = bytes_written = 0xd0d0d0d0;
853 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AVAILABLE_AMD,
854 0, &value, &bytes_written);
855 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
856 pass = value == 0xd0d0d0d0 && pass;
857 pass = bytes_written == 0 && pass;
859 /* dataSize = 1: Unclear. Accept nothing or 1 byte written. */
860 value = bytes_written = 0xd0d0d0d0;
861 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AVAILABLE_AMD,
862 1, &value, &bytes_written);
863 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
864 pass = value == 0xd0d0d0d0 && pass;
865 if (bytes_written == 1) {
866 pass = value == 0xd0d0d000 && pass;
867 } else if (bytes_written == 0) {
868 pass = value == 0xd0d0d0d0 && pass;
869 } else {
870 pass = false;
873 glDeletePerfMonitorsAMD(1, &monitor);
874 report(pass);
877 static void
878 test_gen_initial_state(void)
880 bool pass = true;
881 unsigned monitor;
882 unsigned value;
884 glGenPerfMonitorsAMD(1, &monitor);
885 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
887 /* "The value of the PERFMON_RESULT_AVAILABLE_AMD, PERMON_RESULT_AMD,
888 * and PERFMON_RESULT_SIZE queries will all initially be 0."
890 value = 0xd0d0d0d0;
891 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AVAILABLE_AMD,
892 4, &value, NULL);
893 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
894 pass = value == 0 && pass;
896 /* AMD Catalyst 13.10 (Radeon 6870) actually does write 0 for the
897 * PERFMON_RESULT query even though it isn't available. This
898 * matches the spec, but is strange.
900 value = 0xd0d0d0d0;
901 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AMD,
902 4, &value, NULL);
903 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
904 pass = value == 0 && pass;
906 value = 0xd0d0d0d0;
907 glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_SIZE_AMD,
908 4, &value, NULL);
909 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
910 pass = value == 0 && pass;
912 glDeletePerfMonitorsAMD(1, &monitor);
913 report(pass);
917 * "INVALID_OPERATION error will be generated if EndPerfMonitorAMD is
918 * called when a performance monitor is not currently started."
920 void
921 test_end_without_begin(void)
923 unsigned monitor;
924 glGenPerfMonitorsAMD(1, &monitor);
925 glEndPerfMonitorAMD(monitor);
926 glDeletePerfMonitorsAMD(1, &monitor);
927 report(piglit_check_gl_error(GL_INVALID_OPERATION));
931 * "INVALID_OPERATION error will be generated if BeginPerfMonitorAMD is
932 * called when a performance monitor is already active."
934 void
935 test_double_begin(void)
937 GLenum error;
938 bool pass;
939 unsigned monitor;
940 glGenPerfMonitorsAMD(1, &monitor);
941 glBeginPerfMonitorAMD(monitor);
943 error = glGetError();
944 if (error != GL_NO_ERROR) {
945 glDeletePerfMonitorsAMD(1, &monitor);
946 /* Monitoring couldn't start for some reason; bail. */
947 if (error == GL_INVALID_OPERATION)
948 return;
949 /* We weren't expecting this other error. */
950 report(false);
953 /* Double begin */
954 glBeginPerfMonitorAMD(monitor);
955 pass = piglit_check_gl_error(GL_INVALID_OPERATION);
957 glDeletePerfMonitorsAMD(1, &monitor);
958 report(pass);
961 /******************************************************************************/
964 * Call glSelectPerfMonitorCountersAMD() with an invalid group ID.
966 * "If <group> is not a valid group, the INVALID_VALUE error will be generated."
968 static void
969 test_select_counters_invalid_group(unsigned invalid_group)
971 unsigned monitor;
972 unsigned junk;
973 bool pass;
974 glGenPerfMonitorsAMD(1, &monitor);
975 glSelectPerfMonitorCountersAMD(monitor, false, invalid_group, 0, &junk);
976 pass = piglit_check_gl_error(GL_INVALID_VALUE);
977 glDeletePerfMonitorsAMD(1, &monitor);
978 report(pass);
983 * Call glSelectPerfMonitorCountersAMD() with numCounters < 0.
985 * "If <numCounters> is less than 0, an INVALID_VALUE error will be generated."
987 static void
988 test_select_counters_invalid_num_counters(unsigned group)
990 unsigned monitor;
991 unsigned junk;
992 bool pass;
993 glGenPerfMonitorsAMD(1, &monitor);
994 glSelectPerfMonitorCountersAMD(monitor, false, group, -1, &junk);
995 pass = piglit_check_gl_error(GL_INVALID_VALUE);
996 glDeletePerfMonitorsAMD(1, &monitor);
997 report(pass);
1000 /******************************************************************************/
1002 enum piglit_result
1003 piglit_display(void)
1005 return PIGLIT_FAIL;
1009 * The main test program.
1011 void
1012 piglit_init(int argc, char **argv)
1014 unsigned *groups;
1015 int num_groups;
1016 unsigned *g0_counters;
1017 int num_g0_counters;
1018 unsigned invalid_group;
1019 unsigned invalid_counter;
1021 piglit_require_extension("GL_AMD_performance_monitor");
1023 /* Basic glGetPerfMonitorGroupsAMD() tests */
1024 test_number_of_groups_null_num_groups_pointer();
1025 test_number_of_groups_null_groups_pointer();
1026 test_number_of_groups_zero_size_array();
1027 test_number_of_groups_partial_array();
1029 get_groups(&groups, &num_groups);
1030 invalid_group = find_invalid_group(groups, num_groups);
1032 test_get_counters_invalid_group(invalid_group);
1033 test_group_string_invalid_group(invalid_group);
1034 test_counter_string_invalid_group(invalid_group);
1035 test_counter_info_invalid_group(invalid_group);
1037 test_begin_invalid_monitor();
1038 test_end_invalid_monitor();
1039 test_delete_monitor_invalid();
1040 test_get_counter_data_invalid_monitor();
1041 test_select_counters_invalid_monitor();
1042 test_get_counter_data_byte_size();
1043 test_gen_initial_state();
1044 test_end_without_begin();
1045 test_double_begin();
1047 test_select_counters_invalid_group(invalid_group);
1049 /* If there are no groups, the rest of the tests can't run. Bail. */
1050 if (num_groups == 0)
1051 exit(0);
1053 test_get_counters_null_pointers(groups[0]);
1054 test_get_counters_null_pointer_non_zero_size(groups[0]);
1055 test_get_counters_zero_size_array(groups[0]);
1056 test_get_counters_partial_array(groups[0]);
1057 test_group_string_null_length(groups[0]);
1058 test_group_string_single_character_buffer(groups[0]);
1059 test_group_string_small_buffer(groups[0]);
1060 test_group_string_normal_buffer(groups[0]);
1062 test_counter_info(groups, num_groups);
1064 test_select_counters_invalid_num_counters(groups[0]);
1066 get_counters(groups[0], &g0_counters, &num_g0_counters);
1067 invalid_counter = find_invalid_counter(g0_counters, num_g0_counters);
1069 test_counter_string_invalid_counter(groups[0], invalid_counter);
1070 test_counter_info_invalid_counter(groups[0], invalid_counter);
1072 /* If there are no counters, the rest of the tests can't run. Bail. */
1073 if (num_g0_counters == 0)
1074 exit(0);
1076 test_counter_string_null_length(groups[0], g0_counters[0]);
1077 test_counter_string_single_character_buffer(groups[0], g0_counters[0]);
1078 test_counter_string_small_buffer(groups[0], g0_counters[0]);
1079 test_counter_string_normal_buffer(groups[0], g0_counters[0]);
1081 exit(0);