From patchwork Tue May 12 10:06:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 6387081 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id AEBA79F1C2 for ; Tue, 12 May 2015 10:07:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BF54C203FB for ; Tue, 12 May 2015 10:07:00 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D173E203DF for ; Tue, 12 May 2015 10:06:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 867B86E5BE; Tue, 12 May 2015 03:06:57 -0700 (PDT) X-Original-To: Intel-gfx@lists.freedesktop.org Delivered-To: Intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id A2AA66E2EF for ; Tue, 12 May 2015 03:06:55 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP; 12 May 2015 03:06:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,414,1427785200"; d="scan'208";a="727787857" Received: from tursulin-linux.isw.intel.com ([10.102.226.59]) by orsmga002.jf.intel.com with ESMTP; 12 May 2015 03:06:54 -0700 From: Tvrtko Ursulin To: Intel-gfx@lists.freedesktop.org Date: Tue, 12 May 2015 11:06:34 +0100 Message-Id: <1431425197-29991-1-git-send-email-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.4.0 Cc: Daniel Vetter , Thomas Wood Subject: [Intel-gfx] [PATCH 1/4] kms_flip_tiling: New tiling tests, including Y/Yf 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-Spam-Status: No, score=-3.2 required=5.0 tests=BAYES_00,HK_RANDOM_FROM, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Tvrtko Ursulin New subtests to excercise flips from tiled to tiled and from linear to tiled frame buffers. These will catch display programming issues like not preserving the tiling mode in page flips or not re-programming the watermarks. v2: Cleanup crc object after failing subtests. v3: * Wait for page flip completion instead of vblank. (Chris Wilson) * Added linear->tiled flip tests to catch watermark programming issues. v4: * Refactored for less code. * Check crc after page flip to ensure it happened. (Chris Wilson) * Skip rather than fail when flip fails. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Cc: Daniel Vetter --- tests/kms_flip_tiling.c | 230 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 184 insertions(+), 46 deletions(-) diff --git a/tests/kms_flip_tiling.c b/tests/kms_flip_tiling.c index 8345505..c7fd4de 100644 --- a/tests/kms_flip_tiling.c +++ b/tests/kms_flip_tiling.c @@ -35,8 +35,7 @@ #include "ioctl_wrappers.h" #include "intel_chipset.h" -IGT_TEST_DESCRIPTION("Test that a page flip from a tiled buffer to a linear" - " one works correctly."); +IGT_TEST_DESCRIPTION("Test page flips and tiling scenarios"); typedef struct { int drm_fd; @@ -44,16 +43,8 @@ typedef struct { int gen; } data_t; -/* - * Test that a page flip from a tiled buffer to a linear one works - * correctly. First, it sets the crtc with the linear buffer and generate - * a reference crc for the pipe. Then, the crtc is set with the tiled one - * and page flip to the linear one issued. A new crc is generated and - * compared to the rerence one. - */ - static void -fill_linear_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode) +fill_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode) { cairo_t *cr; @@ -62,67 +53,124 @@ fill_linear_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode) cairo_destroy(cr); } +static igt_pipe_crc_t *_pipe_crc; + +static igt_pipe_crc_t *pipe_crc_new(int pipe) +{ + if (_pipe_crc) { + igt_pipe_crc_free(_pipe_crc); + _pipe_crc = NULL; + } + + _pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); + igt_assert(_pipe_crc); + + return _pipe_crc; +} + +static void pipe_crc_free(void) +{ + if (_pipe_crc) { + igt_pipe_crc_free(_pipe_crc); + _pipe_crc = NULL; + } +} + +static void wait_for_pageflip(int fd) +{ + drmEventContext evctx = { .version = DRM_EVENT_CONTEXT_VERSION }; + struct timeval timeout = { .tv_sec = 0, .tv_usec = 32000 }; + fd_set fds; + int ret; + + /* Wait for pageflip completion, then consume event on fd */ + FD_ZERO(&fds); + FD_SET(fd, &fds); + do { + ret = select(fd + 1, &fds, NULL, NULL, &timeout); + } while (ret < 0 && errno == EINTR); + igt_assert_eq(ret, 1); + igt_assert(drmHandleEvent(fd, &evctx) == 0); +} + static void -test_flip_changes_tiling(data_t *data, igt_output_t *output, uint64_t tiling) +test_flip_tiling(data_t *data, igt_output_t *output, uint64_t tiling[2]) { - struct igt_fb linear, tiled; drmModeModeInfo *mode; igt_plane_t *primary; + struct igt_fb fb[2]; igt_pipe_crc_t *pipe_crc; igt_crc_t reference_crc, crc; int fb_id, pipe, ret, width; pipe = output->config.pipe; - pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); + pipe_crc = pipe_crc_new(pipe); igt_output_set_pipe(output, pipe); mode = igt_output_get_mode(output); primary = igt_output_get_plane(output, 0); - /* Allocate a linear buffer. Since a page flip to a buffer with - * different stride doesn't work, choose width so that the stride of - * both buffers is the same. */ - width = 512; - while (width < mode->hdisplay) - width *= 2; + width = mode->hdisplay; + + if (tiling[0] != tiling[1] && + (tiling[0] != LOCAL_DRM_FORMAT_MOD_NONE || + tiling[1] != LOCAL_DRM_FORMAT_MOD_NONE)) { + /* + * Since a page flip to a buffer with different stride + * doesn't work, choose width so that the stride of both + * buffers is the same. + */ + width = 512; + while (width < mode->hdisplay) + width *= 2; + } + fb_id = igt_create_fb(data->drm_fd, width, mode->vdisplay, - DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE, - &linear); + DRM_FORMAT_XRGB8888, tiling[0], + &fb[0]); + igt_assert(fb_id); + + /* Second fb has different background so CRC does not match. */ + fb_id = igt_create_color_fb(data->drm_fd, width, mode->vdisplay, + DRM_FORMAT_XRGB8888, tiling[1], + 0.5, 0.5, 0.5, &fb[1]); + igt_assert(fb_id); - /* fill it with a pattern that will look wrong if tiling is wrong */ - fill_linear_fb(&linear, data, mode); + fill_fb(&fb[0], data, mode); + fill_fb(&fb[1], data, mode); - /* set the crtc and generate a reference crc */ - igt_plane_set_fb(primary, &linear); + /* Set the crtc and generate a reference CRC. */ + igt_plane_set_fb(primary, &fb[1]); igt_display_commit(&data->display); igt_pipe_crc_collect_crc(pipe_crc, &reference_crc); - /* allocate a tiled buffer and set the crtc with it */ - igt_create_color_fb(data->drm_fd, width, mode->vdisplay, - DRM_FORMAT_XRGB8888, tiling, - 0.0, 0.0, 0.0, &tiled); - igt_plane_set_fb(primary, &tiled); + /* Commit the first fb. */ + igt_plane_set_fb(primary, &fb[0]); igt_display_commit(&data->display); - /* flip to the linear buffer */ + /* Flip to the second fb. */ ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id, - fb_id, 0, NULL); - igt_assert_eq(ret, 0); + fb[1].fb_id, DRM_MODE_PAGE_FLIP_EVENT, NULL); + /* + * Page flip should work but some transitions may be temporarily + * on some kernels. + */ + igt_require(ret == 0); - igt_wait_for_vblank(data->drm_fd, pipe); + wait_for_pageflip(data->drm_fd); - /* get a crc and compare with the reference */ + /* Get a crc and compare with the reference. */ igt_pipe_crc_collect_crc(pipe_crc, &crc); igt_assert_crc_equal(&reference_crc, &crc); - /* clean up */ + /* Clean up. */ igt_plane_set_fb(primary, NULL); - igt_pipe_crc_free(pipe_crc); + pipe_crc_free(); igt_output_set_pipe(output, PIPE_ANY); igt_display_commit(&data->display); - igt_remove_fb(data->drm_fd, &tiled); - igt_remove_fb(data->drm_fd, &linear); + igt_remove_fb(data->drm_fd, &fb[0]); + igt_remove_fb(data->drm_fd, &fb[1]); } static data_t data; @@ -142,28 +190,118 @@ igt_main igt_display_init(&data.display, data.drm_fd); } + /* + * Test that a page flip from a tiled buffer to a linear one works + * correctly. First, it sets the crtc with the linear buffer and + * generates a reference crc for the pipe. Then, the crtc is set with + * the tiled one and page flip to the linear one issued. A new crc is + * generated and compared to the reference one. + */ + igt_subtest_f("flip-changes-tiling") { + uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_X_TILED, + LOCAL_DRM_FORMAT_MOD_NONE }; + for_each_connected_output(&data.display, output) - test_flip_changes_tiling(&data, output, - LOCAL_I915_FORMAT_MOD_X_TILED); + test_flip_tiling(&data, output, tiling); } igt_subtest_f("flip-changes-tiling-Y") { + uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Y_TILED, + LOCAL_DRM_FORMAT_MOD_NONE }; + igt_require_fb_modifiers(data.drm_fd); igt_require(data.gen >= 9); for_each_connected_output(&data.display, output) - test_flip_changes_tiling(&data, output, - LOCAL_I915_FORMAT_MOD_Y_TILED); + test_flip_tiling(&data, output, tiling); } igt_subtest_f("flip-changes-tiling-Yf") { + uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Yf_TILED, + LOCAL_DRM_FORMAT_MOD_NONE }; + + igt_require_fb_modifiers(data.drm_fd); + igt_require(data.gen >= 9); + + for_each_connected_output(&data.display, output) + test_flip_tiling(&data, output, tiling); + } + + /* + * Test that a page flip from a tiled buffer to another tiled one works + * correctly. First, it sets the crtc with the tiled buffer and + * generates a reference crc for the pipe. Then a page flip to second + * tiled buffer is issued. A new crc is generated and compared to the + * reference one. + */ + + igt_subtest_f("flip-X-tiled") { + uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_X_TILED, + LOCAL_I915_FORMAT_MOD_X_TILED }; + + for_each_connected_output(&data.display, output) + test_flip_tiling(&data, output, tiling); + } + + igt_subtest_f("flip-Y-tiled") { + uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Y_TILED, + LOCAL_I915_FORMAT_MOD_Y_TILED }; + + igt_require_fb_modifiers(data.drm_fd); + igt_require(data.gen >= 9); + + for_each_connected_output(&data.display, output) + test_flip_tiling(&data, output, tiling); + } + + igt_subtest_f("flip-Yf-tiled") { + uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Yf_TILED, + LOCAL_I915_FORMAT_MOD_Yf_TILED }; + + igt_require_fb_modifiers(data.drm_fd); + igt_require(data.gen >= 9); + + for_each_connected_output(&data.display, output) + test_flip_tiling(&data, output, tiling); + } + + /* + * Test that a page flip from a linear buffer to a tiled one works + * correctly. First, it sets the crtc with the linear buffer and + * generates a reference crc for the pipe. Then a page flip to a tiled + * buffer is issued. A new crc is generated and compared to the + * reference one. + */ + + igt_subtest_f("flip-to-X-tiled") { + uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE, + LOCAL_I915_FORMAT_MOD_X_TILED }; + + for_each_connected_output(&data.display, output) + test_flip_tiling(&data, output, tiling); + } + + igt_subtest_f("flip-to-Y-tiled") { + uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE, + LOCAL_I915_FORMAT_MOD_Y_TILED }; + + igt_require_fb_modifiers(data.drm_fd); + igt_require(data.gen >= 9); + + for_each_connected_output(&data.display, output) + test_flip_tiling(&data, output, tiling); + } + + igt_subtest_f("flip-to-Yf-tiled") { + uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE, + LOCAL_I915_FORMAT_MOD_Yf_TILED }; + igt_require_fb_modifiers(data.drm_fd); igt_require(data.gen >= 9); for_each_connected_output(&data.display, output) - test_flip_changes_tiling(&data, output, - LOCAL_I915_FORMAT_MOD_Yf_TILED); + test_flip_tiling(&data, output, tiling); } igt_fixture {