From patchwork Wed Apr 29 12:24:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 6295761 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 A62809F1C2 for ; Wed, 29 Apr 2015 12:24:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6FF7A201B4 for ; Wed, 29 Apr 2015 12:24:44 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 06FE22012D for ; Wed, 29 Apr 2015 12:24:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 88F466E6B4; Wed, 29 Apr 2015 05:24:42 -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 48D7D6E6AB for ; Wed, 29 Apr 2015 05:24:40 -0700 (PDT) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP; 29 Apr 2015 05:24:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,670,1422950400"; d="scan'208";a="487155441" Received: from tursulin-linux.isw.intel.com ([10.102.226.59]) by FMSMGA003.fm.intel.com with ESMTP; 29 Apr 2015 05:24:38 -0700 From: Tvrtko Ursulin To: Intel-gfx@lists.freedesktop.org Date: Wed, 29 Apr 2015 13:24:35 +0100 Message-Id: <1430310275-15075-2-git-send-email-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.3.5 In-Reply-To: <1430310275-15075-1-git-send-email-tvrtko.ursulin@linux.intel.com> References: <1430310275-15075-1-git-send-email-tvrtko.ursulin@linux.intel.com> Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH i-g-t 2/2] 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 Cc: 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 {