From patchwork Fri May 16 06:34:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Sun X-Patchwork-Id: 4187721 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 3E2C0BFF02 for ; Fri, 16 May 2014 06:35:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 27277202E9 for ; Fri, 16 May 2014 06:35:47 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id B5385202E6 for ; Fri, 16 May 2014 06:35:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 31B356E873; Thu, 15 May 2014 23:35:45 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id DBF916E873 for ; Thu, 15 May 2014 23:35:43 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 15 May 2014 23:35:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="4.97,1065,1389772800"; d="scan'208"; a="540066935" Received: from sunyi-pc.sh.intel.com ([10.239.36.179]) by fmsmga002.fm.intel.com with ESMTP; 15 May 2014 23:35:41 -0700 From: Yi Sun To: intel-gfx@lists.freedesktop.org Date: Fri, 16 May 2014 14:34:47 +0800 Message-Id: <1400222087-25357-1-git-send-email-yi.sun@intel.com> X-Mailer: git-send-email 1.7.6.4 Cc: Lei Liu , gordon.jin@intel.com Subject: [Intel-gfx] [I-G-T][PATCH] Add panning test for primary plane. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 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=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 Get CRCs of a full red and a full blue surface as reference. Create a big framebuffer that is twice width and twice height as the current display mode. Fill the top left quarter with red, bottom right quarter with blue Check the scanned out image with the CRTC at position (0, 0) of the framebuffer and it should be the same CRC as the full red fb Check the scanned out image with the CRTC at position (hdisplay, vdisplay) and it should be the same CRC as the full blue fb Signed-off-by: Lei Liu Signed-off-by: Yi Sun diff --git a/lib/igt_kms.c b/lib/igt_kms.c index fffad9f..5cdc48b 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -532,6 +532,13 @@ void igt_display_init(igt_display_t *display, int drm_fd) display->outputs = calloc(display->n_outputs, sizeof(igt_output_t)); igt_assert(display->outputs); + /* + * Be default display can scan out from the original position of the frame buffer. + * But we can change this position making display scan out with a offset. + */ + display->buffer_x = 0; + display->buffer_y = 0; + for (i = 0; i < display->n_outputs; i++) { igt_output_t *output = &display->outputs[i]; @@ -830,13 +837,13 @@ static int igt_output_commit(igt_output_t *output) igt_output_name(output), pipe_name(output->config.pipe), fb_id, - 0, 0, + display->buffer_x, display->buffer_y, mode->hdisplay, mode->vdisplay); ret = drmModeSetCrtc(display->drm_fd, crtc_id, fb_id, - 0, 0, /* x, y */ + display->buffer_x, display->buffer_y, /* x, y */ &output->id, 1, mode); @@ -849,7 +856,7 @@ static int igt_output_commit(igt_output_t *output) ret = drmModeSetCrtc(display->drm_fd, crtc_id, fb_id, - 0, 0, /* x, y */ + display->buffer_x, display->buffer_y, /* x, y */ NULL, /* connectors */ 0, /* n_connectors */ NULL /* mode */); @@ -987,6 +994,26 @@ void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb) plane->fb_changed = true; } +void igt_plane_set_fb_offset(igt_plane_t *plane, struct igt_fb *fb, int x, int y) +{ + igt_pipe_t *pipe = plane->pipe; + igt_display_t *display = pipe->display; + + (*display).buffer_x = x; + (*display).buffer_y = y; + + LOG(display, "%c.%d: plane_set_fb(%d)\n", pipe_name(pipe->pipe), + plane->index, fb ? fb->fb_id : 0); + + plane->fb = fb; + + if (plane->is_primary) + pipe->need_set_crtc = true; + else if (plane->is_cursor) + pipe->need_set_cursor = true; + + plane->fb_changed = true; +} void igt_plane_set_position(igt_plane_t *plane, int x, int y) { igt_pipe_t *pipe = plane->pipe; diff --git a/lib/igt_kms.h b/lib/igt_kms.h index 439a634..cb9370e 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -139,6 +139,8 @@ struct igt_display { int log_shift; int n_pipes; int n_outputs; + int buffer_x; + int buffer_y; unsigned long pipes_in_use; igt_output_t *outputs; igt_pipe_t pipes[I915_MAX_PIPES]; diff --git a/tests/kms_plane.c b/tests/kms_plane.c index 6bdbca3..6fcdadb 100644 --- a/tests/kms_plane.c +++ b/tests/kms_plane.c @@ -34,6 +34,12 @@ #include "igt_kms.h" typedef struct { + float red; + float green; + float blue; +} colour_t; + +typedef struct { int drm_fd; igt_display_t display; } data_t; @@ -55,12 +61,19 @@ typedef struct { igt_crc_t reference_crc; } test_position_t; +//colour_t colour; + +enum { + TEST_POSITION_FULLY_COVERED = 1 << 0, + TEST_POSITION_BUFFER_ORIGINAL, +}; + /* * create a green fb with a black rectangle at (rect_x,rect_y) and of size * (rect_w,rect_h) */ static void -create_fb_for_mode__position(data_t *data, drmModeModeInfo *mode, +create_fb_for_mode_position(data_t *data, drmModeModeInfo *mode, double rect_x, double rect_y, double rect_w, double rect_h, struct igt_fb *fb /* out */) @@ -84,13 +97,44 @@ create_fb_for_mode__position(data_t *data, drmModeModeInfo *mode, } static void -test_position_init(test_position_t *test, igt_output_t *output, enum pipe pipe) +create_fb_for_mode_panning(data_t *data, drmModeModeInfo *mode, + double rect_x, double rect_y, + double rect_w, double rect_h, + struct igt_fb *fb /* out */) +{ + unsigned int fb_id; + cairo_t *cr; + + fb_id = igt_create_fb(data->drm_fd, + mode->hdisplay * 2, mode->vdisplay * 2, + DRM_FORMAT_XRGB8888, + false /* tiling */, + fb); + igt_assert(fb_id); + + cr = igt_get_cairo_ctx(data->drm_fd, fb); + + igt_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay, + 1.0, 0.0, 0.0); + + igt_paint_color(cr, rect_x, rect_y, rect_w, rect_h, + 0.0, 0.0, 1.0); + + igt_assert(cairo_status(cr) == 0); + cairo_destroy(cr); +} + +static void +test_position_init(test_position_t *test, igt_output_t *output, enum pipe pipe, colour_t colour_fb) { data_t *data = test->data; struct igt_fb green_fb; drmModeModeInfo *mode; igt_plane_t *primary; + data->display.buffer_x = 0; + data->display.buffer_y = 0; + test->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); igt_output_set_pipe(output, pipe); @@ -100,7 +144,7 @@ test_position_init(test_position_t *test, igt_output_t *output, enum pipe pipe) igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, false, /* tiled */ - 0.0, 1.0, 0.0, + colour_fb.red, colour_fb.green, colour_fb.blue, &green_fb); igt_plane_set_fb(primary, &green_fb); @@ -115,6 +159,44 @@ test_position_init(test_position_t *test, igt_output_t *output, enum pipe pipe) } static void +test_panning_init(test_position_t *test, igt_output_t *output, + enum pipe pipe, unsigned int flags) +{ + data_t *data = test->data; + struct igt_fb panning_fb; + drmModeModeInfo *mode; + igt_plane_t *primary; + colour_t colour; + + data->display.buffer_x=0; + data->display.buffer_y=0; + + test->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); + + igt_output_set_pipe(output, pipe); + primary = igt_output_get_plane(output, 0); + + if (flags & TEST_POSITION_BUFFER_ORIGINAL) + colour = (colour_t){ .red = 1.0, .green = 0.0, .blue = 0.0 }; + else + colour = (colour_t){ .red = 0.0, .green = 0.0, .blue = 1.0 }; + + mode = igt_output_get_mode(output); + igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, + DRM_FORMAT_XRGB8888, + false, /* tiled */ + colour.red, colour.green, colour.blue, + &panning_fb); + igt_plane_set_fb(primary, &panning_fb); + + igt_display_commit(&data->display); + + igt_pipe_crc_collect_crc(test->pipe_crc, &test->reference_crc); + + igt_remove_fb(data->drm_fd, &panning_fb); +} + +static void test_position_fini(test_position_t *test, igt_output_t *output) { igt_pipe_crc_free(test->pipe_crc); @@ -123,10 +205,6 @@ test_position_fini(test_position_t *test, igt_output_t *output) igt_display_commit(&test->data->display); } -enum { - TEST_POSITION_FULLY_COVERED = 1 << 0, -}; - static void test_plane_position_with_output(data_t *data, enum pipe pipe, @@ -139,18 +217,19 @@ test_plane_position_with_output(data_t *data, struct igt_fb primary_fb, sprite_fb; drmModeModeInfo *mode; igt_crc_t crc; + colour_t color_green = { .red = 0, .green = 1.0, .blue = 0.0 }; fprintf(stdout, "Testing connector %s using pipe %c plane %d\n", igt_output_name(output), pipe_name(pipe), plane); - test_position_init(&test, output, pipe); + test_position_init(&test, output, pipe, color_green); mode = igt_output_get_mode(output); primary = igt_output_get_plane(output, 0); sprite = igt_output_get_plane(output, plane); - create_fb_for_mode__position(data, mode, 100, 100, 64, 64, - &primary_fb); + create_fb_for_mode_position(data, mode, 100, 100, 64, 64, + &primary_fb); igt_plane_set_fb(primary, &primary_fb); igt_create_color_fb(data->drm_fd, @@ -182,6 +261,59 @@ test_plane_position_with_output(data_t *data, } static void +test_plane_panning_with_output(data_t *data, + enum pipe pipe, + enum igt_plane plane, + igt_output_t *output, + unsigned int flags) +{ + test_position_t test = { .data = data }; + igt_plane_t *primary; + struct igt_fb primary_fb; + drmModeModeInfo *mode; + igt_crc_t crc; + colour_t colour; + + fprintf(stdout, "Testing connector %s using pipe %c plane %d\n", + igt_output_name(output), pipe_name(pipe), plane); + + if (flags & TEST_POSITION_BUFFER_ORIGINAL) + colour = (colour_t){ .red = 1.0, .green = 0.0, .blue = 0.0 }; + else + colour = (colour_t){ .red = 0.0, .green = 0.0, .blue = 1.0 }; + + test_position_init(&test, output, pipe, colour); + + mode = igt_output_get_mode(output); + primary = igt_output_get_plane(output, 0); + + create_fb_for_mode_panning(data, + mode, mode->hdisplay, mode->vdisplay, + mode->hdisplay, mode->vdisplay, + &primary_fb); + + if (flags & TEST_POSITION_BUFFER_ORIGINAL) + igt_plane_set_fb_offset(primary, &primary_fb, 0, 0); + else + igt_plane_set_fb_offset(primary, &primary_fb, mode->hdisplay, mode->vdisplay); + + igt_plane_set_position(primary, 0, 0); + + igt_display_commit(&data->display); + + igt_pipe_crc_collect_crc(test.pipe_crc, &crc); + + igt_plane_set_fb(primary, NULL); + + test_position_fini(&test, output); + + if (flags & TEST_POSITION_BUFFER_ORIGINAL) + igt_assert(igt_crc_equal(&test.reference_crc, &crc)); + else + igt_assert(igt_crc_equal(&test.reference_crc, &crc)); +} + +static void test_plane_position(data_t *data, enum pipe pipe, enum igt_plane plane, unsigned int flags) { @@ -196,16 +328,40 @@ test_plane_position(data_t *data, enum pipe pipe, enum igt_plane plane, } static void +test_plane_panning(data_t *data, enum pipe pipe, enum igt_plane plane, + unsigned int flags) +{ + igt_output_t *output; + + igt_skip_on(pipe >= data->display.n_pipes); + igt_skip_on(plane >= data->display.pipes[pipe].n_planes); + + for_each_connected_output(&data->display, output) + test_plane_panning_with_output(data, pipe, plane, output, + flags); +} + +static void run_tests_for_pipe_plane(data_t *data, enum pipe pipe, enum igt_plane plane) { igt_subtest_f("plane-position-covered-pipe-%c-plane-%d", - pipe_name(pipe), plane) + pipe_name(pipe), plane) test_plane_position(data, pipe, plane, - TEST_POSITION_FULLY_COVERED); + TEST_POSITION_FULLY_COVERED); igt_subtest_f("plane-position-hole-pipe-%c-plane-%d", - pipe_name(pipe), plane) + pipe_name(pipe), plane) test_plane_position(data, pipe, plane, 0); + + igt_subtest_f("plane-panning-buffer-position-original-%c-plane-%d", + pipe_name(pipe), plane) + test_plane_panning(data, pipe, plane, + TEST_POSITION_BUFFER_ORIGINAL); + + igt_subtest_f("plane-panning-set-position-pipe-%c-plane-%d", + pipe_name(pipe), plane) + test_plane_panning(data, pipe, plane, 0); + } static void