From: Simon Ser <simon.ser@intel.com>
To: igt-dev@lists.freedesktop.org
Subject: [igt-dev] [PATCH i-g-t] tests/kms_chamelium: add a latency test
Date: Fri, 6 Sep 2019 14:46:00 +0300 [thread overview]
Message-ID: <20190906114600.9817-1-simon.ser@intel.com> (raw)
This new test creates a red and a green framebuffer, then alternatively shows
one and the other for a while. We check that we correctly capture the
alternating pattern with Chamelium.
We do our best to capture the pattern, which is tricky because of
synchronization issues. We first show the red FB, start the capture, then
play the alternating pattern, and stop the capture. We capture more frames than
there are in the pattern to make sure the delay after starting the capture
doesn't make us completely miss the pattern.
Signed-off-by: Simon Ser <simon.ser@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Martin Peres <martin.peres@linux.intel.com>
---
tests/kms_chamelium.c | 163 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 163 insertions(+)
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 6b6292497cd7..ba9f8acb600c 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -2522,6 +2522,161 @@ test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width)
igt_hpd_storm_reset(data->drm_fd);
}
+static void latency_page_flip_handler(int fd, unsigned seq, unsigned tv_sec,
+ unsigned tv_usec, void *data)
+{
+ int64_t *seq_ptr = data;
+
+ igt_debug("Got page-flip event (seq=%u)\n", seq);
+ *seq_ptr = seq;
+}
+
+#define TEST_LATENCY_PLAYBACK_FRAMES 20
+#define TEST_LATENCY_CAPTURE_FRAMES (TEST_LATENCY_PLAYBACK_FRAMES + 10)
+
+static const char test_display_latency_desc[] =
+ "Alternate between two different buffers at each page-flip, "
+ "check there is no latency or tearing";
+static void
+test_display_latency(data_t *data, struct chamelium_port *port)
+{
+ igt_output_t *output;
+ igt_plane_t *primary;
+ struct igt_fb fbs[2];
+ unsigned int fb_ids[2];
+ struct chamelium_fb_crc_async_data *fb_crcs[2];
+ drmModeModeInfo mode;
+ drmModeConnector *connector;
+ struct pollfd pfd = {0};
+ drmEventContext drm_event = {0};
+ int i, j, ret, captured_frames_count, start, end;
+ int64_t prev_seq, seq;
+ igt_crc_t *crcs, *expected_crcs[2];
+
+ reset_state(data, port);
+
+ output = prepare_output(data, port, TEST_EDID_BASE);
+ connector = chamelium_port_get_connector(data->chamelium, port, false);
+ primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+ igt_assert(primary);
+
+ igt_assert(connector->count_modes > 0);
+ mode = connector->modes[0];
+
+ drmModeFreeConnector(connector);
+
+ fb_ids[0] = igt_create_color_pattern_fb(data->drm_fd,
+ mode.hdisplay, mode.vdisplay,
+ DRM_FORMAT_XRGB8888,
+ LOCAL_DRM_FORMAT_MOD_NONE,
+ 1, 0, 0, &fbs[0]);
+ igt_assert(fb_ids[0] > 0);
+ fb_ids[1] = igt_create_color_pattern_fb(data->drm_fd,
+ mode.hdisplay, mode.vdisplay,
+ DRM_FORMAT_XRGB8888,
+ LOCAL_DRM_FORMAT_MOD_NONE,
+ 0, 1, 0, &fbs[1]);
+ igt_assert(fb_ids[1] > 0);
+
+ fb_crcs[0] = chamelium_calculate_fb_crc_async_start(data->drm_fd,
+ &fbs[0]);
+ fb_crcs[1] = chamelium_calculate_fb_crc_async_start(data->drm_fd,
+ &fbs[1]);
+
+ igt_plane_set_fb(primary, &fbs[0]);
+ igt_plane_set_size(primary, mode.hdisplay, mode.vdisplay);
+ igt_output_override_mode(output, &mode);
+ igt_display_commit2(&data->display, COMMIT_ATOMIC);
+
+ chamelium_start_capture(data->chamelium, port, 0, 0, 0, 0);
+
+ pfd.fd = data->drm_fd;
+ pfd.events = POLLIN;
+
+ drm_event.version = 2;
+ drm_event.page_flip_handler = latency_page_flip_handler;
+
+ /* Make sure we stop the alternating pattern with fb[1] */
+ assert(TEST_LATENCY_PLAYBACK_FRAMES % 2 == 0);
+
+ prev_seq = -1;
+ for (i = 0; i < TEST_LATENCY_PLAYBACK_FRAMES; i++) {
+ igt_plane_set_fb(primary, &fbs[i % 2]);
+
+ igt_display_commit_atomic(&data->display,
+ DRM_MODE_ATOMIC_NONBLOCK |
+ DRM_MODE_PAGE_FLIP_EVENT,
+ &seq);
+
+ ret = poll(&pfd, 1, 1000);
+ igt_assert_f(ret == 1, "poll returned %d, expected 1\n", ret);
+ seq = -1;
+ drmHandleEvent(data->drm_fd, &drm_event);
+ igt_assert(seq >= 0);
+
+ if (prev_seq >= 0) {
+ igt_assert((unsigned) (prev_seq + 1) == (unsigned) seq);
+ }
+ prev_seq = seq;
+ }
+
+ /* Capture more frames than necessary, because we don't want to miss
+ * our alternating pattern. */
+ chamelium_stop_capture(data->chamelium, TEST_LATENCY_CAPTURE_FRAMES);
+ crcs = chamelium_read_captured_crcs(data->chamelium,
+ &captured_frames_count);
+ igt_assert(captured_frames_count == TEST_LATENCY_CAPTURE_FRAMES);
+
+ igt_debug("Captured %d frames\n", captured_frames_count);
+
+ expected_crcs[0] = chamelium_calculate_fb_crc_async_finish(fb_crcs[0]);
+ expected_crcs[1] = chamelium_calculate_fb_crc_async_finish(fb_crcs[1]);
+
+ /* Assuming reference CRCs A and B, the captured CRCs should look like:
+ * A A A A A B A B A B A B A B A B A B … A B A B B B B B B B
+ * ^ ^
+ * playback starts playback ends
+ */
+ igt_debug("Reference CRC #0: %s\n", igt_crc_to_string(expected_crcs[0]));
+ igt_debug("Reference CRC #1: %s\n", igt_crc_to_string(expected_crcs[1]));
+ for (i = 0; i < captured_frames_count; i++) {
+ igt_debug("Captured CRC #%d: %s\n", i,
+ igt_crc_to_string(&crcs[i]));
+ }
+
+ igt_debug("Searching start and end of alternating pattern...\n");
+ for (start = 0; start < captured_frames_count; start++) {
+ if (!igt_check_crc_equal(expected_crcs[0], &crcs[start]))
+ break;
+ }
+ for (end = captured_frames_count - 1; end >= 0; end--) {
+ if (!igt_check_crc_equal(expected_crcs[1], &crcs[end]))
+ break;
+ }
+ igt_debug("Alternating pattern starts at frame #%d and ends at "
+ "frame #%d\n", start, end);
+ /* Make sure we captured a big enough chunk of the pattern */
+ igt_assert_f(end - start > TEST_LATENCY_PLAYBACK_FRAMES / 2,
+ "Captured only %d frames of the alternating pattern, "
+ "that's not enough (expected more than %d)\n",
+ end - start, TEST_LATENCY_PLAYBACK_FRAMES / 2);
+
+ j = 1; /* crcs[start] should match expected_crcs[1] */
+ for (i = start; i <= end; i++) {
+ igt_assert_f(igt_check_crc_equal(expected_crcs[j % 2], &crcs[i]),
+ "Captured CRC #%d mismatches reference CRC #%d\n",
+ i, j % 2);
+ j++;
+ }
+
+ free(expected_crcs[0]);
+ free(expected_crcs[1]);
+ free(crcs);
+
+ igt_remove_fb(data->drm_fd, &fbs[0]);
+ igt_remove_fb(data->drm_fd, &fbs[1]);
+}
+
static const struct edid *get_edid(enum test_edid edid)
{
switch (edid) {
@@ -2659,6 +2814,10 @@ igt_main
connector_subtest("dp-audio-edid", DisplayPort)
test_display_audio_edid(&data, port,
TEST_EDID_DP_AUDIO);
+
+ igt_describe(test_display_latency_desc);
+ connector_subtest("dp-latency", DisplayPort)
+ test_display_latency(&data, port);
}
igt_subtest_group {
@@ -2820,6 +2979,10 @@ igt_main
connector_subtest("hdmi-aspect-ratio", HDMIA)
test_display_aspect_ratio(&data, port);
+
+ igt_describe(test_display_latency_desc);
+ connector_subtest("hdmi-latency", HDMIA)
+ test_display_latency(&data, port);
}
igt_subtest_group {
--
2.23.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
next reply other threads:[~2019-09-06 11:45 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-06 11:46 Simon Ser [this message]
2019-09-06 11:56 ` [igt-dev] [PATCH i-g-t] tests/kms_chamelium: add a latency test Ser, Simon
2019-09-06 12:28 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
2019-09-06 14:09 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190906114600.9817-1-simon.ser@intel.com \
--to=simon.ser@intel.com \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox