From patchwork Wed Jul 5 08:04:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowki X-Patchwork-Id: 9826087 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C52CD60317 for ; Wed, 5 Jul 2017 08:04:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BC27826247 for ; Wed, 5 Jul 2017 08:04:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AD93126E55; Wed, 5 Jul 2017 08:04:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2221D27813 for ; Wed, 5 Jul 2017 08:04:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 55F756E390; Wed, 5 Jul 2017 08:04:47 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 374FD6E390 for ; Wed, 5 Jul 2017 08:04:46 +0000 (UTC) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jul 2017 01:04:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,310,1496127600"; d="scan'208";a="122427798" Received: from linux.intel.com ([10.54.29.200]) by fmsmga005.fm.intel.com with ESMTP; 05 Jul 2017 01:04:45 -0700 Received: from workstation.fi.intel.com (workstation.fi.intel.com [10.237.68.144]) by linux.intel.com (Postfix) with ESMTP id 32AE95801CF; Wed, 5 Jul 2017 01:04:43 -0700 (PDT) From: Paul Kocialkowski To: intel-gfx@lists.freedesktop.org Date: Wed, 5 Jul 2017 11:04:35 +0300 Message-Id: <20170705080435.26789-4-paul.kocialkowski@linux.intel.com> X-Mailer: git-send-email 2.13.2 In-Reply-To: <20170705080435.26789-1-paul.kocialkowski@linux.intel.com> References: <20170705080435.26789-1-paul.kocialkowski@linux.intel.com> Cc: Lyude Subject: [Intel-gfx] [PATCH i-g-t v3 4/4] chamelium: Dump obtained and reference frames to png on crc error X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP When a CRC comparison error occurs, it is quite useful to get a dump of both the frame obtained from the chamelium and the reference in order to compare them. This implements the frame dump, with a configurable path that enables the use of this feature. Signed-off-by: Paul Kocialkowski --- lib/igt_chamelium.c | 21 +++++++++++ lib/igt_chamelium.h | 1 + lib/igt_debugfs.c | 20 ++++++++++ lib/igt_debugfs.h | 1 + tests/chamelium.c | 104 ++++++++++++++++++++-------------------------------- 5 files changed, 82 insertions(+), 65 deletions(-) diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c index ef51ef68..9aca6842 100644 --- a/lib/igt_chamelium.c +++ b/lib/igt_chamelium.c @@ -57,6 +57,7 @@ * |[ * [Chamelium] * URL=http://chameleon:9992 # The URL used for connecting to the Chamelium's RPC server + * FrameDumpPath=/tmp # The path to dump frames that fail comparison checks * * # The rest of the sections are used for defining connector mappings. * # This is required so any tests using the Chamelium know which connector @@ -115,11 +116,26 @@ struct chamelium { struct chamelium_edid *edids; struct chamelium_port *ports; int port_count; + + char *frame_dump_path; }; static struct chamelium *cleanup_instance; /** + * chamelium_get_frame_dump_path: + * @chamelium: The Chamelium instance to use + * + * Retrieves the path to dump frames to. + * + * Returns: a string with the frame dump path + */ +char *chamelium_get_frame_dump_path(struct chamelium *chamelium) +{ + return chamelium->frame_dump_path; +} + +/** * chamelium_get_ports: * @chamelium: The Chamelium instance to use * @count: Where to store the number of ports @@ -1338,6 +1354,11 @@ static bool chamelium_read_config(struct chamelium *chamelium, int drm_fd) return false; } + chamelium->frame_dump_path = g_key_file_get_string(igt_key_file, + "Chamelium", + "FrameDumpPath", + &error); + return chamelium_read_port_mappings(chamelium, drm_fd); } diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h index 908e03d1..aa881971 100644 --- a/lib/igt_chamelium.h +++ b/lib/igt_chamelium.h @@ -42,6 +42,7 @@ struct chamelium *chamelium_init(int drm_fd); void chamelium_deinit(struct chamelium *chamelium); void chamelium_reset(struct chamelium *chamelium); +char *chamelium_get_frame_dump_path(struct chamelium *chamelium); struct chamelium_port **chamelium_get_ports(struct chamelium *chamelium, int *count); unsigned int chamelium_port_get_type(const struct chamelium_port *port); diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c index 80f25c61..dcb4e0a7 100644 --- a/lib/igt_debugfs.c +++ b/lib/igt_debugfs.c @@ -282,6 +282,26 @@ bool igt_debugfs_search(int device, const char *filename, const char *substring) */ /** + * igt_check_crc_equal: + * @a: first pipe CRC value + * @b: second pipe CRC value + * + * Compares two CRC values and return whether they match. + * + * Returns: A boolean indicating whether the CRC values match + */ +bool igt_check_crc_equal(const igt_crc_t *a, const igt_crc_t *b) +{ + int i; + + for (i = 0; i < a->n_words; i++) + if (a->crc[i] != b->crc[i]) + return false; + + return true; +} + +/** * igt_assert_crc_equal: * @a: first pipe CRC value * @b: second pipe CRC value diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h index 7b846a83..2695cbda 100644 --- a/lib/igt_debugfs.h +++ b/lib/igt_debugfs.h @@ -113,6 +113,7 @@ enum intel_pipe_crc_source { INTEL_PIPE_CRC_SOURCE_MAX, }; +bool igt_check_crc_equal(const igt_crc_t *a, const igt_crc_t *b); void igt_assert_crc_equal(const igt_crc_t *a, const igt_crc_t *b); char *igt_crc_to_string(igt_crc_t *crc); diff --git a/tests/chamelium.c b/tests/chamelium.c index 5cf8b3af..3d95c05c 100644 --- a/tests/chamelium.c +++ b/tests/chamelium.c @@ -381,7 +381,7 @@ disable_output(data_t *data, } static void -test_display_crc_single(data_t *data, struct chamelium_port *port) +test_display_crc(data_t *data, struct chamelium_port *port, int count) { igt_display_t display; igt_output_t *output; @@ -390,9 +390,14 @@ test_display_crc_single(data_t *data, struct chamelium_port *port) igt_crc_t *expected_crc; struct chamelium_fb_crc *fb_crc; struct igt_fb fb; + struct chamelium_frame_dump *frame; drmModeModeInfo *mode; drmModeConnector *connector; - int fb_id, i; + int fb_id, i, j, captured_frame_count; + const char *connector_name; + char *frame_dump_path; + char path[PATH_MAX]; + bool eq; reset_state(data, port); @@ -401,6 +406,9 @@ test_display_crc_single(data_t *data, struct chamelium_port *port) primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); igt_assert(primary); + connector_name = kmstest_connector_type_str(connector->connector_type); + frame_dump_path = chamelium_get_frame_dump_path(data->chamelium); + for (i = 0; i < connector->count_modes; i++) { mode = &connector->modes[i]; fb_id = igt_create_color_pattern_fb(data->drm_fd, @@ -415,74 +423,40 @@ test_display_crc_single(data_t *data, struct chamelium_port *port) enable_output(data, port, output, mode, &fb); - igt_debug("Testing single CRC fetch\n"); - - crc = chamelium_get_crc_for_area(data->chamelium, port, - 0, 0, 0, 0); - - expected_crc = chamelium_calculate_fb_crc_result(fb_crc); - - igt_assert_crc_equal(crc, expected_crc); - free(expected_crc); - free(crc); - - disable_output(data, port, output); - igt_remove_fb(data->drm_fd, &fb); - } - - drmModeFreeConnector(connector); - igt_display_fini(&display); -} - -static void -test_display_crc_multiple(data_t *data, struct chamelium_port *port) -{ - igt_display_t display; - igt_output_t *output; - igt_plane_t *primary; - igt_crc_t *crc; - igt_crc_t *expected_crc; - struct chamelium_fb_crc *fb_crc; - struct igt_fb fb; - drmModeModeInfo *mode; - drmModeConnector *connector; - int fb_id, i, j, captured_frame_count; + chamelium_capture(data->chamelium, port, 0, 0, 0, 0, count); + crc = chamelium_read_captured_crcs(data->chamelium, + &captured_frame_count); - reset_state(data, port); + igt_assert(captured_frame_count == count); - output = prepare_output(data, &display, port); - connector = chamelium_port_get_connector(data->chamelium, port, false); - primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); - igt_assert(primary); + igt_debug("Captured %d frames\n", captured_frame_count); - for (i = 0; i < connector->count_modes; i++) { - mode = &connector->modes[i]; - fb_id = igt_create_color_pattern_fb(data->drm_fd, - mode->hdisplay, - mode->vdisplay, - DRM_FORMAT_XRGB8888, - LOCAL_DRM_FORMAT_MOD_NONE, - 0, 0, 0, &fb); - igt_assert(fb_id > 0); + expected_crc = chamelium_calculate_fb_crc_result(fb_crc); - fb_crc = chamelium_calculate_fb_crc_launch(data->drm_fd, &fb); + for (j = 0; j < captured_frame_count; j++) { + eq = igt_check_crc_equal(&crc[j], expected_crc); + if (!eq && frame_dump_path) { + frame = chamelium_read_captured_frame(data->chamelium, + j); - enable_output(data, port, output, mode, &fb); + igt_debug("Dumping reference and chamelium frames to %s...\n", + frame_dump_path); - /* We want to keep the display running for a little bit, since - * there's always the potential the driver isn't able to keep - * the display running properly for very long - */ - chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 3); - crc = chamelium_read_captured_crcs(data->chamelium, - &captured_frame_count); + snprintf(path, PATH_MAX, "%s/frame-reference-%s.png", + frame_dump_path, connector_name); + igt_write_fb_to_png(data->drm_fd, &fb, path); - igt_debug("Captured %d frames\n", captured_frame_count); + snprintf(path, PATH_MAX, "%s/frame-chamelium-%s.png", + frame_dump_path, connector_name); + chamelium_write_frame_to_png(data->chamelium, + frame, path); - expected_crc = chamelium_calculate_fb_crc_result(fb_crc); + chamelium_destroy_frame_dump(frame); + } - for (j = 0; j < captured_frame_count; j++) - igt_assert_crc_equal(&crc[j], expected_crc); + igt_fail_on_f(!eq, + "Chamelium frame CRC mismatch with reference\n"); + } free(expected_crc); free(crc); @@ -644,10 +618,10 @@ igt_main edid_id, alt_edid_id); connector_subtest("dp-crc-single", DisplayPort) - test_display_crc_single(&data, port); + test_display_crc(&data, port, 1); connector_subtest("dp-crc-multiple", DisplayPort) - test_display_crc_multiple(&data, port); + test_display_crc(&data, port, 3); } igt_subtest_group { @@ -698,10 +672,10 @@ igt_main edid_id, alt_edid_id); connector_subtest("hdmi-crc-single", HDMIA) - test_display_crc_single(&data, port); + test_display_crc(&data, port, 1); connector_subtest("hdmi-crc-multiple", HDMIA) - test_display_crc_multiple(&data, port); + test_display_crc(&data, port, 3); } igt_subtest_group {