From: Boris Brezillon <boris.brezil...@free-electrons.com> This adds a specific test for the VC4 GPU. Right now, it only checks that FEP-valid-quads and QPU-total-clk-cycles-waiting-TMU are consistent after executing well know operations (draw a rectangle or a texture).
More tests will be added over time. Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com> --- .../spec/amd_performance_monitor/CMakeLists.gl.txt | 1 + tests/spec/amd_performance_monitor/vc4.c | 309 +++++++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 tests/spec/amd_performance_monitor/vc4.c diff --git a/tests/spec/amd_performance_monitor/CMakeLists.gl.txt b/tests/spec/amd_performance_monitor/CMakeLists.gl.txt index ac29de782f45..73dad38e9973 100644 --- a/tests/spec/amd_performance_monitor/CMakeLists.gl.txt +++ b/tests/spec/amd_performance_monitor/CMakeLists.gl.txt @@ -10,3 +10,4 @@ link_libraries ( piglit_add_executable (amd_performance_monitor_api api.c) piglit_add_executable (amd_performance_monitor_measure measure.c) +piglit_add_executable (amd_performance_monitor_vc4 vc4.c) diff --git a/tests/spec/amd_performance_monitor/vc4.c b/tests/spec/amd_performance_monitor/vc4.c new file mode 100644 index 000000000000..40f9a0b93a52 --- /dev/null +++ b/tests/spec/amd_performance_monitor/vc4.c @@ -0,0 +1,309 @@ +/* + * Copyright © 2018 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * \file vc4.c + * + * Check consistency of some of the VC4 perf counters. + */ + +#define __STDC_FORMAT_MACROS +#include <inttypes.h> +#include "piglit-util-gl.h" + +PIGLIT_GL_TEST_CONFIG_BEGIN + + config.supports_gl_compat_version = 20; + config.window_visual = PIGLIT_GL_VISUAL_RGB; + +PIGLIT_GL_TEST_CONFIG_END + +#define verify(x) \ + if (!(x)) { \ + printf("%s:%i\n", __func__, __LINE__); \ + piglit_report_subtest_result(PIGLIT_FAIL, "%s", test->name); \ + return; \ + } + +/******************************************************************************/ + +struct perfcounter_id { + unsigned groupid; + unsigned counterid; +}; + +struct perfmon_counter { + const char *name; + unsigned id; + GLenum type; +}; + +struct perfmon_group { + const char *name; + unsigned id; + int num_counters; + int max_active_counters; + struct perfmon_counter *counters; +}; + +struct perfmon_info { + int num_groups; + struct perfmon_group *groups; +}; + +static void +get_group_info(struct perfmon_group *group) +{ + unsigned *counterids; + GLsizei length; + char *name; + int i; + + glGetPerfMonitorGroupStringAMD(group->id, 0, &length, NULL); + name = calloc(length + 1, sizeof(char)); + group->name = name; + glGetPerfMonitorGroupStringAMD(group->id, length + 1, NULL, name); + + glGetPerfMonitorCountersAMD(group->id, &group->num_counters, + NULL, 0, NULL); + group->counters = calloc(group->num_counters, sizeof(*group->counters)); + counterids = calloc(group->num_counters, sizeof(*counterids)); + glGetPerfMonitorCountersAMD(group->id, NULL, + &group->max_active_counters, + group->num_counters, counterids); + + for (i = 0; i < group->num_counters; i++) { + group->counters[i].id = counterids[i]; + glGetPerfMonitorCounterStringAMD(group->id, counterids[i], 0, + &length, NULL); + name = calloc(length + 1, sizeof(char)); + group->counters[i].name = name; + glGetPerfMonitorCounterStringAMD(group->id, counterids[i], + length + 1, NULL, name); + glGetPerfMonitorCounterInfoAMD(group->id, counterids[i], + GL_COUNTER_TYPE_AMD, + &group->counters[i].type); + } + + free(counterids); +} + +static void +get_perfmon_info(struct perfmon_info *info) +{ + unsigned *groupids; + int i; + + glGetPerfMonitorGroupsAMD(&info->num_groups, 0, NULL); + info->groups = calloc(info->num_groups, sizeof(*info->groups)); + groupids = calloc(info->num_groups, sizeof(*groupids)); + + glGetPerfMonitorGroupsAMD(NULL, info->num_groups, groupids); + + for (i = 0; i < info->num_groups; i++) { + info->groups[i].id = groupids[i]; + get_group_info(&info->groups[i]); + } + + free(groupids); +} + +static bool +find_perfcounter(const struct perfmon_info *info, const char *group_name, + const char *counter_name, struct perfcounter_id *id) +{ + int i, j; + + for (i = 0; i < info->num_groups; i++) { + struct perfmon_group *group = &info->groups[i]; + + if (strcmp(group->name, group_name)) + continue; + + for (j = 0; j < group->num_counters; j++) { + struct perfmon_counter *counter = &group->counters[j]; + + if (strcmp(counter->name, counter_name)) + continue; + + id->groupid = i; + id->counterid = j; + return true; + } + } + + return false; +} + +/******************************************************************************/ + +enum piglit_result +piglit_display(void) +{ + return PIGLIT_FAIL; +} + +struct counter_res { + unsigned group; + unsigned counter; + uint64_t val; +}; + +struct perfmon_test { + const char *name; + const char *group; + const char *counter; + void (*job)(const struct perfmon_test *test); + bool (*check_res)(uint64_t res); +}; + +static void +do_perfmon_test(const struct perfmon_info *info, + const struct perfmon_test *test) +{ + struct perfcounter_id counterid; + unsigned perfmon, counter; + struct counter_res res = { }; + unsigned avail = 0; + int written = 0; + + if (!find_perfcounter(info, test->group, test->counter, + &counterid)) + piglit_report_subtest_result(PIGLIT_SKIP, "%s", test->name); + + glGenPerfMonitorsAMD(1, &perfmon); + verify(piglit_check_gl_error(GL_NO_ERROR)); + + counter = counterid.counterid; + glSelectPerfMonitorCountersAMD(perfmon, true, counterid.groupid, 1, + &counter); + + /* Start monitoring. */ + glBeginPerfMonitorAMD(perfmon); + verify(piglit_check_gl_error(GL_NO_ERROR)); + + test->job(test); + + /* Stop monitoring. */ + glEndPerfMonitorAMD(perfmon); + verify(piglit_check_gl_error(GL_NO_ERROR)); + + while (!avail) { + glGetPerfMonitorCounterDataAMD(perfmon, + GL_PERFMON_RESULT_AVAILABLE_AMD, + sizeof(avail), &avail, + &written); + verify(piglit_check_gl_error(GL_NO_ERROR)); + verify(written == sizeof(avail)); + } + + glGetPerfMonitorCounterDataAMD(perfmon, GL_PERFMON_RESULT_AMD, + sizeof(res), (GLuint *)&res, + &written); + verify(piglit_check_gl_error(GL_NO_ERROR)); + verify(written == sizeof(res)); + verify(res.group == 0 && res.counter == counter); + verify(test->check_res(res.val)); + + piglit_report_subtest_result(PIGLIT_PASS, "%s", test->name); +} + +#define FEP_VALID_QUADS_REF_VAL 6440 + +static void draw_rect(const struct perfmon_test *test) +{ + piglit_draw_rect(-1, -1, 3, 3); +} + +static void draw_tex(const struct perfmon_test *test) +{ + GLuint tex; + + tex = piglit_rgbw_texture(GL_RGBA, 64, 64, false, true, + GL_UNSIGNED_BYTE); + verify(piglit_check_gl_error(GL_NO_ERROR)); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex); + piglit_draw_rect_tex(-1, -1, 2, 2, 0, 0, 1, 1); + glDisable(GL_TEXTURE_2D); + glDeleteTextures(1, &tex); +} + +static bool fep_valid_quads_check_res(uint64_t res) +{ + return res == FEP_VALID_QUADS_REF_VAL; +} + +static bool is_zero(uint64_t res) +{ + return !res; +} + +static bool not_zero(uint64_t res) +{ + return res; +} + +static const struct perfmon_test tests[] = { + { + .name = "fep-valid-quads", + .group = "V3D counters", + .counter = "FEP-valid-quads", + .job = draw_rect, + .check_res = fep_valid_quads_check_res, + }, + { + .name = "no-tex-qpu-wait-tmu-zero", + .group = "V3D counters", + .counter = "QPU-total-clk-cycles-waiting-TMU", + .job = draw_rect, + .check_res = is_zero, + }, + { + .name = "tex-qpu-wait-tmu-not-zero", + .group = "V3D counters", + .counter = "QPU-total-clk-cycles-waiting-TMU", + .job = draw_tex, + .check_res = not_zero, + }, +}; + +/** + * The main test program. + */ +void +piglit_init(int argc, char **argv) +{ + struct perfmon_info info; + int i; + + piglit_require_extension("GL_AMD_performance_monitor"); + + get_perfmon_info(&info); + + for (i = 0; i < ARRAY_SIZE(tests); i++) + do_perfmon_test(&info, &tests[i]); + + exit(0); +} -- 2.14.1 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit