From patchwork Fri Jan 15 09:06:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marius Vlad X-Patchwork-Id: 8039281 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 225E79F6FA for ; Fri, 15 Jan 2016 09:05:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CB6CF20459 for ; Fri, 15 Jan 2016 09:05:15 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 6B483203E1 for ; Fri, 15 Jan 2016 09:05:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9915F6E160; Fri, 15 Jan 2016 01:05:13 -0800 (PST) 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 ESMTP id A99A36E160 for ; Fri, 15 Jan 2016 01:05:11 -0800 (PST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga101.jf.intel.com with ESMTP; 15 Jan 2016 01:05:12 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,298,1449561600"; d="scan'208";a="29812309" Received: from mcvlad-wk.rb.intel.com ([10.237.105.57]) by fmsmga004.fm.intel.com with ESMTP; 15 Jan 2016 01:05:10 -0800 From: Marius Vlad To: intel-gfx@lists.freedesktop.org Date: Fri, 15 Jan 2016 11:06:24 +0200 Message-Id: <1452848784-7970-1-git-send-email-marius.c.vlad@intel.com> X-Mailer: git-send-email 2.6.4 Subject: [Intel-gfx] [PATCH i-g-t] lib/igt_kms: Add COMIT_ATOMIC to igt_display_commit2() 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=-4.2 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 So far, we had only COMMIT_UNIVERSAL and COMMIT_LEGACY, using drmModeSetPlane()/drmSetCrtc(). This patch adds COMMIT_ATOMIC to igt_display_commit2() that makes use of drmModeAtomicCommit(). Signed-off-by: Marius Vlad --- lib/igt_kms.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- lib/igt_kms.h | 33 +++++++++- 2 files changed, 221 insertions(+), 2 deletions(-) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 497118a..61f7a39 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -1306,6 +1306,191 @@ static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane) igt_assert(r == 0); \ } +static const char *igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = { + "SRC_X", + "SRC_Y", + "SRC_W", + "SRC_H", + "CRTC_X", + "CRTC_Y", + "CRTC_W", + "CRTC_H", + "FB_ID", + "CRTC_ID", + "type" +}; + +/* + * Retrieve all the properies specified in props_name and store them into + * plane->atomic_props_plane. + */ +static void +igt_atomic_fill_plane_props(igt_display_t *display, igt_plane_t *plane, + int type, int num_props, const char **prop_names) +{ + drmModeObjectPropertiesPtr props; + int i, j, fd; + + fd = display->drm_fd; + + props = drmModeObjectGetProperties(fd, plane->drm_plane->plane_id, type); + igt_assert(props); + + for (i = 0; i < props->count_props; i++) { + drmModePropertyPtr prop = + drmModeGetProperty(fd, props->props[i]); + + for (j = 0; j < num_props; j++) { + if (strcmp(prop->name, prop_names[j]) != 0) + continue; + plane->atomic_props_plane[j] = props->props[i]; + break; + } + + drmModeFreeProperty(prop); + } + + drmModeFreeObjectProperties(props); +} + +/* + * Commit position and fb changes to a DRM plane via the AtomicCommit() + * ioctl; if the DRM call to program the plane fails, we'll either fail + * immediately (for tests that expect the commit to succeed) or return the + * failure code (for tests that expect a specific error code). + */ +static int +igt_atomic_plane_commit(igt_plane_t *plane, igt_output_t *output, + bool fail_on_error) +{ + igt_display_t *display = output->display; + + uint32_t fb_id, crtc_id; + int ret; + uint32_t src_x; + uint32_t src_y; + uint32_t src_w; + uint32_t src_h; + int32_t crtc_x; + int32_t crtc_y; + uint32_t crtc_w; + uint32_t crtc_h; + drmModeAtomicReq *req; + + igt_assert(plane->drm_plane); + + do_or_die(drmSetClientCap(display->drm_fd, DRM_CLIENT_CAP_ATOMIC, 1)); + + /* it's an error to try an unsupported feature */ + igt_assert(igt_plane_supports_rotation(plane) || + !plane->rotation_changed); + + fb_id = igt_plane_get_fb_id(plane); + crtc_id = output->config.crtc->crtc_id; + + if ((plane->fb_changed || plane->size_changed) && fb_id == 0) { + + LOG(display, + "%s: drmModeAtomicCommit pipe %s, plane %d, disabling\n", + igt_output_name(output), + kmstest_pipe_name(output->config.pipe), + plane->index); + + req = drmModeAtomicAlloc(); + igt_atomic_fill_plane_props(display, plane, + DRM_MODE_OBJECT_PLANE, + IGT_NUM_PLANE_PROPS, + igt_plane_prop_names); + + drmModeAtomicSetCursor(req, 0); + + /* populate plane req */ + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_ID, crtc_id); + + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_X, IGT_FIXED(0, 0)); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_Y, IGT_FIXED(0, 0)); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_W, IGT_FIXED(0, 0)); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_H, IGT_FIXED(0, 0)); + + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_X, 0); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_Y, 0); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_W, 0); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_H, 0); + + ret = drmModeAtomicCommit(display->drm_fd, req, 0, NULL); + drmModeAtomicFree(req); + + CHECK_RETURN(ret, fail_on_error); + + } else if (plane->fb_changed || plane->position_changed || + plane->size_changed) { + + src_x = IGT_FIXED(plane->fb->src_x,0); /* src_x */ + src_y = IGT_FIXED(plane->fb->src_y,0); /* src_y */ + src_w = IGT_FIXED(plane->fb->src_w,0); /* src_w */ + src_h = IGT_FIXED(plane->fb->src_h,0); /* src_h */ + crtc_x = plane->crtc_x; + crtc_y = plane->crtc_y; + crtc_w = plane->crtc_w; + crtc_h = plane->crtc_h; + + LOG(display, + "%s: drmModeAtomicCommit %s.%d, fb %u, src = (%d, %d) " + "%ux%u dst = (%u, %u) %ux%u\n", + igt_output_name(output), + kmstest_pipe_name(output->config.pipe), + plane->index, + fb_id, + src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16, + crtc_x, crtc_y, crtc_w, crtc_h); + + + req = drmModeAtomicAlloc(); + igt_atomic_fill_plane_props(display, plane, + DRM_MODE_OBJECT_PLANE, + IGT_NUM_PLANE_PROPS, + igt_plane_prop_names); + + drmModeAtomicSetCursor(req, 0); + + /* populate plane req */ + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_ID, crtc_id); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_FB_ID, fb_id); + + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_X, src_x); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_Y, src_y); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_W, src_w); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_H, src_h); + + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_X, crtc_x); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_Y, crtc_y); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_W, crtc_w); + igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_H, crtc_h); + + ret = drmModeAtomicCommit(display->drm_fd, req, 0, NULL); + drmModeAtomicFree(req); + + CHECK_RETURN(ret, fail_on_error); + } + + plane->fb_changed = false; + plane->position_changed = false; + plane->size_changed = false; + + + if (plane->rotation_changed) { + ret = igt_plane_set_property(plane, plane->rotation_property, + plane->rotation); + + plane->rotation_changed = false; + CHECK_RETURN(ret, fail_on_error); + } + + return 0; +} + + + /* * Commit position and fb changes to a DRM plane via the SetPlane ioctl; if the * DRM call to program the plane fails, we'll either fail immediately (for @@ -1558,7 +1743,10 @@ static int igt_plane_commit(igt_plane_t *plane, return igt_primary_plane_commit_legacy(plane, output, fail_on_error); } else { - return igt_drm_plane_commit(plane, output, fail_on_error); + if (s == COMMIT_ATOMIC) + return igt_atomic_plane_commit(plane, output, fail_on_error); + else + return igt_drm_plane_commit(plane, output, fail_on_error); } } diff --git a/lib/igt_kms.h b/lib/igt_kms.h index 94f315f..81d8dd7 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -156,9 +156,27 @@ void kmstest_unset_all_crtcs(int drm_fd, drmModeResPtr resources); enum igt_commit_style { COMMIT_LEGACY = 0, COMMIT_UNIVERSAL, - /* We'll add atomic here eventually. */ + COMMIT_ATOMIC, }; +enum igt_atomic_plane_properties { + IGT_PLANE_SRC_X = 0, + IGT_PLANE_SRC_Y, + IGT_PLANE_SRC_W, + IGT_PLANE_SRC_H, + + IGT_PLANE_CRTC_X, + IGT_PLANE_CRTC_Y, + IGT_PLANE_CRTC_W, + IGT_PLANE_CRTC_H, + + IGT_PLANE_FB_ID, + IGT_PLANE_CRTC_ID, + IGT_PLANE_TYPE, + IGT_NUM_PLANE_PROPS +}; + + typedef struct igt_display igt_display_t; typedef struct igt_pipe igt_pipe_t; typedef uint32_t igt_fixed_t; /* 16.16 fixed point */ @@ -200,6 +218,7 @@ typedef struct { /* panning offset within the fb */ unsigned int pan_x, pan_y; igt_rotation_t rotation; + uint32_t atomic_props_plane[IGT_NUM_PLANE_PROPS]; } igt_plane_t; struct igt_pipe { @@ -281,6 +300,18 @@ void igt_wait_for_vblank(int drm_fd, enum pipe pipe); #define IGT_FIXED(i,f) ((i) << 16 | (f)) +/** + * igt_atomic_populate_plane_req: + * @req: A pointer to drmModeAtomicReq + * @plane: A pointer igt_plane_t + * @prop: one of igt_atomic_plane_properties + * @value: the value to add + */ +#define igt_atomic_populate_plane_req(req, plane, prop, value) \ + igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->drm_plane->plane_id,\ + plane->atomic_props_plane[prop], value)) + + void igt_enable_connectors(void); void igt_reset_connectors(void);