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
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
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
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 /******************************************************************************/
46 * Get a list of group IDs.
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
);
57 * Get a list of counter IDs in a given group.
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
);
68 * Return true if x is in xs.
71 in_list(int x
, unsigned *xs
, int elts
)
74 for (i
= 0; i
< elts
; i
++) {
82 * Find an invalid group ID.
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
))
99 * Find an invalid counter ID.
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
))
112 return invalid_counter
;
115 #define report(pass) \
117 piglit_report_subtest_result((pass) ? PIGLIT_PASS : PIGLIT_FAIL, __FUNCTION__); \
121 /******************************************************************************/
124 * Call glGetPerfMonitorGroupsAMD() with a NULL numGroups pointer.
126 * Verify that it doesn't attempt to write the number of groups and crash.
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.
143 test_number_of_groups_null_groups_pointer(void)
148 glGetPerfMonitorGroupsAMD(&num_groups
, 777, NULL
);
149 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
150 pass
= num_groups
>= 0 && pass
;
155 * Call glGetPerfMonitorGroupsAMD() with zero for groupSize.
157 * Verify that it doesn't write any group IDs.
160 test_number_of_groups_zero_size_array(void)
163 unsigned groups
[2] = {0xd0d0d0d0, 0xd1d1d1d1};
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
;
179 * Call glGetPerfMonitorGroupsAMD() with a groups array bigger than groupSize.
181 * Verify that it fills the correct number of array slots with group IDs.
184 test_number_of_groups_partial_array(void)
187 unsigned groups
[] = {0xdddddddd, 0xdddddddd, 0xdddddddd, 0xdddddddd};
189 /* Artificially low array size */
190 const int groups_array_size
= 2;
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
;
225 /******************************************************************************/
228 * Call glGetPerfMonitorCountersAMD() with an invalid group ID.
230 * Verify that it produces INVALID_VALUE.
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.
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.
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.
271 test_get_counters_zero_size_array(unsigned valid_group
)
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
,
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
;
296 * Call glGetPerfMonitorGroupsAMD() with a groups array bigger than groupSize.
298 * Verify that it fills the correct number of array slots with group IDs.
301 test_get_counters_partial_array(unsigned valid_group
)
304 unsigned counters
[] = {0xdddddddd, 0xdddddddd, 0xdddddddd, 0xdddddddd};
306 /* Artificially low array size */
307 const int counters_array_size
= 2;
308 int num_counters
= -1;
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
;
334 /******************************************************************************/
337 * Call glGetPerfMonitorGroupStringAMD() with an invalid group ID.
339 * Verify that it produces INVALID_VALUE.
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.
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.
366 test_group_string_single_character_buffer(unsigned valid_group
)
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
383 if (name
[0] == '\0') {
384 pass
= length
== 0 && pass
;
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
;
396 * Call glGetPerfMonitorGroupStringAMD() with a small buffer.
398 * Verify that a name is returned, length is valid, and no overflows occur.
401 test_group_string_small_buffer(unsigned valid_group
)
404 char name
[3] = "```";
405 GLsizei length
= 0xd0d0d0d0;
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
;
417 pass
= name
[length
] == '\0';
418 for (i
= length
+ 1; i
< 3; i
++)
419 pass
= name
[i
] == '`' && pass
;
426 * Call glGetPerfMonitorGroupStringAMD() with an appropriately sized buffer.
428 * Verify that a name is returned, length is valid, and no overflows occur.
431 test_group_string_normal_buffer(unsigned valid_group
)
435 GLsizei length
= 0xd0d0d0d0;
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)
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
;
466 /******************************************************************************/
469 * Call glGetPerfMonitorCounterStringAMD() with an invalid group ID.
471 * Verify that it produces INVALID_VALUE.
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.
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.
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.
510 test_counter_string_single_character_buffer(unsigned group
, unsigned counter
)
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
527 if (name
[0] == '\0') {
528 pass
= length
== 0 && pass
;
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
;
540 * Call glGetPerfMonitorCounterStringAMD() with a small buffer.
542 * Verify that a name is returned, length is valid, and no overflows occur.
545 test_counter_string_small_buffer(unsigned group
, unsigned counter
)
548 char name
[3] = "```";
549 GLsizei length
= 0xd0d0d0d0;
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
;
561 pass
= name
[length
] == '\0';
562 for (i
= length
+ 1; i
< 3; i
++)
563 pass
= name
[i
] == '`' && pass
;
570 * Call glGetPerfMonitorCounterStringAMD() with an appropriately sized buffer.
572 * Verify that a name is returned, length is valid, and no overflows occur.
575 test_counter_string_normal_buffer(unsigned group
, unsigned counter
)
579 GLsizei length
= 0xd0d0d0d0;
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)
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
;
610 /******************************************************************************/
613 * Call glGetPerfMonitorCounterInfoAMD() with an invalid group ID.
615 * Verify that it produces INVALID_VALUE.
618 test_counter_info_invalid_group(unsigned invalid_group
)
621 glGetPerfMonitorCounterInfoAMD(invalid_group
, 0, GL_COUNTER_TYPE_AMD
,
623 report(piglit_check_gl_error(GL_INVALID_VALUE
));
627 * Call glGetPerfMonitorCounterInfoAMD() with an invalid counter ID.
629 * Verify that it produces INVALID_VALUE.
632 test_counter_info_invalid_counter(unsigned group
, unsigned invalid_counter
)
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.
648 test_counter_info(unsigned *groups
, int num_groups
)
653 for (i
= 0; i
< num_groups
; i
++) {
656 get_counters(groups
[i
], &counters
, &num_counters
);
658 for (j
= 0; j
< num_counters
; j
++) {
659 GLenum type
= GL_NONE
;
661 uint64_t min_u
, max_u
;
664 bool is_unsigned
= false;
666 glGetPerfMonitorCounterInfoAMD(groups
[i
], counters
[j
],
671 memset(data
, 0xff, sizeof(uint64_t) * 3);
672 glGetPerfMonitorCounterInfoAMD(groups
[i
], counters
[j
],
673 GL_COUNTER_RANGE_AMD
,
676 /* Validate the type and use it to interpret the
677 * minimum/maximum information.
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];
686 case GL_UNSIGNED_INT64_AMD
:
689 unchanged
= ((uint32_t *) data
)[4];
692 case GL_PERCENTAGE_AMD
:
694 min_f
= ((float *) data
)[0];
695 max_f
= ((float *) data
)[1];
696 unchanged
= ((uint32_t *) data
)[2];
699 printf("Group %u/Counter %u has an invalid type: %x\n", groups
[i
], counters
[j
], type
);
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
]);
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
);
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
);
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
);
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.
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.
768 test_end_invalid_monitor(void)
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.
782 test_get_counter_data_invalid_monitor(void)
785 glGetPerfMonitorCounterDataAMD(777, GL_PERFMON_RESULT_AVAILABLE_AMD
,
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."
797 test_select_counters_invalid_monitor(void)
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.
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.
829 test_get_counter_data_byte_size(void)
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
,
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
;
873 glDeletePerfMonitorsAMD(1, &monitor
);
878 test_gen_initial_state(void)
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."
891 glGetPerfMonitorCounterDataAMD(monitor
, GL_PERFMON_RESULT_AVAILABLE_AMD
,
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.
901 glGetPerfMonitorCounterDataAMD(monitor
, GL_PERFMON_RESULT_AMD
,
903 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
904 pass
= value
== 0 && pass
;
907 glGetPerfMonitorCounterDataAMD(monitor
, GL_PERFMON_RESULT_SIZE_AMD
,
909 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
910 pass
= value
== 0 && pass
;
912 glDeletePerfMonitorsAMD(1, &monitor
);
917 * "INVALID_OPERATION error will be generated if EndPerfMonitorAMD is
918 * called when a performance monitor is not currently started."
921 test_end_without_begin(void)
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."
935 test_double_begin(void)
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
)
949 /* We weren't expecting this other error. */
954 glBeginPerfMonitorAMD(monitor
);
955 pass
= piglit_check_gl_error(GL_INVALID_OPERATION
);
957 glDeletePerfMonitorsAMD(1, &monitor
);
961 /******************************************************************************/
964 * Call glSelectPerfMonitorCountersAMD() with an invalid group ID.
966 * "If <group> is not a valid group, the INVALID_VALUE error will be generated."
969 test_select_counters_invalid_group(unsigned invalid_group
)
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
);
983 * Call glSelectPerfMonitorCountersAMD() with numCounters < 0.
985 * "If <numCounters> is less than 0, an INVALID_VALUE error will be generated."
988 test_select_counters_invalid_num_counters(unsigned group
)
993 glGenPerfMonitorsAMD(1, &monitor
);
994 glSelectPerfMonitorCountersAMD(monitor
, false, group
, -1, &junk
);
995 pass
= piglit_check_gl_error(GL_INVALID_VALUE
);
996 glDeletePerfMonitorsAMD(1, &monitor
);
1000 /******************************************************************************/
1003 piglit_display(void)
1009 * The main test program.
1012 piglit_init(int argc
, char **argv
)
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)
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)
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]);