From patchwork Wed Dec 16 17:48:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Souza, Jose" X-Patchwork-Id: 11978177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9CF73C4361B for ; Wed, 16 Dec 2020 17:48:52 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5B96E24E06 for ; Wed, 16 Dec 2020 17:48:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5B96E24E06 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 39674899D4; Wed, 16 Dec 2020 17:48:48 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 42FCD899B7 for ; Wed, 16 Dec 2020 17:48:44 +0000 (UTC) IronPort-SDR: ryWClZxMkvyJzOK+aSBiu6mBqu7EhrZSRKKNQ3urQJz0mPHq47AvAx1A9Q/21cUy5dOXGBgav0 ApmldEginV9Q== X-IronPort-AV: E=McAfee;i="6000,8403,9837"; a="162156868" X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="162156868" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Dec 2020 09:48:44 -0800 IronPort-SDR: DJSfdkVpINfhWdSKex/mNGHh6vvZxWhh28/mNeX2HwwURThcPu7dLTPRV+4ia6cBa2LQdlERgC 092wmUBVyCEg== X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="488613669" Received: from mhlabrec-mobl1.amr.corp.intel.com (HELO josouza-mobl2.intel.com) ([10.255.69.154]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Dec 2020 09:48:42 -0800 From: =?utf-8?q?Jos=C3=A9_Roberto_de_Souza?= To: intel-gfx@lists.freedesktop.org Date: Wed, 16 Dec 2020 09:48:57 -0800 Message-Id: <20201216174900.185178-2-jose.souza@intel.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201216174900.185178-1-jose.souza@intel.com> References: <20201216174900.185178-1-jose.souza@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v7 2/5] drm/i915/display/psr: Use plane damage clips to calculate damaged area X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Now using plane damage clips property to calcualte the damaged area. Selective fetch only supports one region to be fetched so software needs to calculate a bounding box around all damage clips. Now that we are not complete fetching each plane, there is another loop needed as all the plane areas that intersect with the pipe damaged area needs to be fetched from memory so the complete blending of all planes can happen. v2: - do not shifthing new_plane_state->uapi.dst only src is in 16.16 format v4: - setting plane selective fetch area using the whole pipe damage area - mark the whole plane area damaged if plane visibility or alpha changed v5: - taking in consideration src.y1 in the damage coordinates - adding to the pipe damaged area planes that were visible but are invisible in the new state v6: - consider old state plane coordinates when visibility changes or it moved to calculate damaged area - remove from damaged area the portion not in src clip v7: - intersec every damage clip with src to minimize damaged area Cc: Ville Syrjälä Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza --- drivers/gpu/drm/i915/display/intel_psr.c | 101 ++++++++++++++++++++--- 1 file changed, 89 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index d9a395c486d3..4bed18422c8a 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1269,8 +1269,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); + struct drm_rect pipe_clip = { .x1 = 0, .y1 = -1, .x2 = INT_MAX, .y2 = -1 }; struct intel_plane_state *new_plane_state, *old_plane_state; - struct drm_rect pipe_clip = { .y1 = -1 }; struct intel_plane *plane; bool full_update = false; int i, ret; @@ -1282,9 +1282,17 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, if (ret) return ret; + /* + * Calculate minimal selective fetch area of each plane and calculate + * the pipe damaged area. + * In the next loop the plane selective fetch area will actually be set + * using whole pipe damaged area. + */ for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { - struct drm_rect *sel_fetch_area, temp; + struct drm_rect src, damaged_area = { .y1 = -1 }; + struct drm_mode_rect *damaged_clips; + u32 num_clips, j; if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc) continue; @@ -1300,23 +1308,92 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, break; } - if (!new_plane_state->uapi.visible) - continue; + drm_rect_fp_to_int(&src, &new_plane_state->uapi.src); + damaged_clips = drm_plane_get_damage_clips(&new_plane_state->uapi); + num_clips = drm_plane_get_damage_clips_count(&new_plane_state->uapi); /* - * For now doing a selective fetch in the whole plane area, - * optimizations will come in the future. + * If visibility or plane moved, mark the whole plane area as + * damaged as it needs to be complete redraw in the new and old + * position. */ + if (new_plane_state->uapi.visible != old_plane_state->uapi.visible || + !drm_rect_equals(&new_plane_state->uapi.dst, + &old_plane_state->uapi.dst)) { + damaged_area.y1 = old_plane_state->uapi.src.y1 >> 16; + damaged_area.y1 = old_plane_state->uapi.src.y2 >> 16; + damaged_area.y1 += old_plane_state->uapi.dst.y1; + damaged_area.y2 += old_plane_state->uapi.dst.y1; + clip_area_update(&pipe_clip, &damaged_area); + + num_clips = 0; + damaged_area.y1 = src.y1; + damaged_area.y2 = src.y2; + } else if (new_plane_state->uapi.alpha != old_plane_state->uapi.alpha) { + num_clips = 0; + damaged_area.y1 = src.y1; + damaged_area.y2 = src.y2; + } else if (!num_clips && + new_plane_state->uapi.fb != old_plane_state->uapi.fb) { + /* + * If the plane don't have damage areas but the + * framebuffer changed, mark the whole plane area as + * damaged. + */ + damaged_area.y1 = src.y1; + damaged_area.y2 = src.y2; + } + + for (j = 0; j < num_clips; j++) { + struct drm_rect clip; + + clip.x1 = damaged_clips[j].x1; + clip.y1 = damaged_clips[j].y1; + clip.x2 = damaged_clips[j].x2; + clip.y2 = damaged_clips[j].y2; + if (drm_rect_intersect(&clip, &src)) + clip_area_update(&damaged_area, &clip); + } + + if (damaged_area.y1 == -1) + continue; + + damaged_area.y1 += new_plane_state->uapi.dst.y1; + damaged_area.y2 += new_plane_state->uapi.dst.y1; + clip_area_update(&pipe_clip, &damaged_area); + } + + if (full_update) + goto skip_sel_fetch_set_loop; + + /* + * Now that we have the pipe damaged area check if it intersect with + * every plane, if it does set the plane selective fetch area. + */ + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, + new_plane_state, i) { + struct drm_rect *sel_fetch_area, inter, src; + + if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc || + !new_plane_state->uapi.visible) + continue; + + inter = pipe_clip; + if (!drm_rect_intersect(&inter, &new_plane_state->uapi.dst)) + continue; + + drm_rect_fp_to_int(&src, &new_plane_state->uapi.src); + sel_fetch_area = &new_plane_state->psr2_sel_fetch_area; - sel_fetch_area->y1 = new_plane_state->uapi.src.y1 >> 16; - sel_fetch_area->y2 = new_plane_state->uapi.src.y2 >> 16; + sel_fetch_area->y1 = inter.y1 - new_plane_state->uapi.dst.y1; + sel_fetch_area->y2 = inter.y2 - new_plane_state->uapi.dst.y1; + sel_fetch_area->x1 = src.x1; + sel_fetch_area->x2 = src.x2; - temp = *sel_fetch_area; - temp.y1 += new_plane_state->uapi.dst.y1; - temp.y2 += new_plane_state->uapi.dst.y2; - clip_area_update(&pipe_clip, &temp); + drm_rect_intersect(sel_fetch_area, &src); } +skip_sel_fetch_set_loop: psr2_man_trk_ctl_calc(crtc_state, &pipe_clip, full_update); return 0; }