From patchwork Fri Nov 22 17:56:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 11258221 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0AACA14E5 for ; Fri, 22 Nov 2019 17:56:35 +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 E6ADB20674 for ; Fri, 22 Nov 2019 17:56:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E6ADB20674 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.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 6FBA76E46B; Fri, 22 Nov 2019 17:56:32 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9C0CB6E46B; Fri, 22 Nov 2019 17:56:31 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Nov 2019 09:56:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,230,1571727600"; d="scan'208";a="290714835" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga001.jf.intel.com with SMTP; 22 Nov 2019 09:56:27 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 22 Nov 2019 19:56:27 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Date: Fri, 22 Nov 2019 19:56:20 +0200 Message-Id: <20191122175623.13565-2-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191122175623.13565-1-ville.syrjala@linux.intel.com> References: <20191122175623.13565-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 1/4] drm/rect: Avoid division by zero X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, Benjamin Gaignard , stable@vger.kernel.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Ville Syrjälä Check for zero width/height destination rectangle in drm_rect_clip_scaled() to avoid a division by zero. Cc: stable@vger.kernel.org Fixes: f96bdf564f3e ("drm/rect: Handle rounding errors in drm_rect_clip_scaled, v3.") Cc: Maarten Lankhorst Cc: Benjamin Gaignard Cc: Daniel Vetter Testcase: igt/kms_selftest/drm_rect_clip_scaled_div_by_zero Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_rect.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c index b8363aaa9032..818738e83d06 100644 --- a/drivers/gpu/drm/drm_rect.c +++ b/drivers/gpu/drm/drm_rect.c @@ -54,7 +54,12 @@ EXPORT_SYMBOL(drm_rect_intersect); static u32 clip_scaled(u32 src, u32 dst, u32 clip) { - u64 tmp = mul_u32_u32(src, dst - clip); + u64 tmp; + + if (dst == 0) + return 0; + + tmp = mul_u32_u32(src, dst - clip); /* * Round toward 1.0 when clipping so that we don't accidentally From patchwork Fri Nov 22 17:56:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 11258225 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7E2C91871 for ; Fri, 22 Nov 2019 17:56:38 +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 660D520674 for ; Fri, 22 Nov 2019 17:56:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 660D520674 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.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 008B86E46D; Fri, 22 Nov 2019 17:56:37 +0000 (UTC) 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 ESMTPS id 7D1CF6E46D; Fri, 22 Nov 2019 17:56:35 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Nov 2019 09:56:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,230,1571727600"; d="scan'208";a="210490435" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga006.jf.intel.com with SMTP; 22 Nov 2019 09:56:32 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 22 Nov 2019 19:56:31 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Date: Fri, 22 Nov 2019 19:56:21 +0200 Message-Id: <20191122175623.13565-3-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191122175623.13565-1-ville.syrjala@linux.intel.com> References: <20191122175623.13565-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 2/4] drm/rect: Keep the scaled clip bounded X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, Benjamin Gaignard Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Ville Syrjälä Limit the scaled clip to only clip at most dst_w/h pixels. This avoids the problem with clip_scaled() not being able to return negative values. Since new_src_w/h is now properly bounded we can remove the clamp()s. Cc: Benjamin Gaignard Cc: Maarten Lankhorst Cc: Daniel Vetter Testcase: igt/kms_selftest/drm_rect_clip_scaled_signed_vs_unsigned Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_rect.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c index 818738e83d06..a9c7f90836f3 100644 --- a/drivers/gpu/drm/drm_rect.c +++ b/drivers/gpu/drm/drm_rect.c @@ -59,6 +59,9 @@ static u32 clip_scaled(u32 src, u32 dst, u32 clip) if (dst == 0) return 0; + /* Only clip what we have. Keeps the result bounded. */ + clip = min(clip, dst); + tmp = mul_u32_u32(src, dst - clip); /* @@ -94,7 +97,7 @@ bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, u32 new_src_w = clip_scaled(drm_rect_width(src), drm_rect_width(dst), diff); - src->x1 = clamp_t(int64_t, src->x2 - new_src_w, INT_MIN, INT_MAX); + src->x1 = src->x2 - new_src_w; dst->x1 = clip->x1; } diff = clip->y1 - dst->y1; @@ -102,7 +105,7 @@ bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, u32 new_src_h = clip_scaled(drm_rect_height(src), drm_rect_height(dst), diff); - src->y1 = clamp_t(int64_t, src->y2 - new_src_h, INT_MIN, INT_MAX); + src->y1 = src->y2 - new_src_h; dst->y1 = clip->y1; } diff = dst->x2 - clip->x2; @@ -110,7 +113,7 @@ bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, u32 new_src_w = clip_scaled(drm_rect_width(src), drm_rect_width(dst), diff); - src->x2 = clamp_t(int64_t, src->x1 + new_src_w, INT_MIN, INT_MAX); + src->x2 = src->x1 + new_src_w; dst->x2 = clip->x2; } diff = dst->y2 - clip->y2; @@ -118,7 +121,7 @@ bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, u32 new_src_h = clip_scaled(drm_rect_height(src), drm_rect_height(dst), diff); - src->y2 = clamp_t(int64_t, src->y1 + new_src_h, INT_MIN, INT_MAX); + src->y2 = src->y1 + new_src_h; dst->y2 = clip->y2; } From patchwork Fri Nov 22 17:56:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 11258231 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 130621871 for ; Fri, 22 Nov 2019 17:56:44 +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 EF82520674 for ; Fri, 22 Nov 2019 17:56:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EF82520674 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.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 2CB726E48E; Fri, 22 Nov 2019 17:56:43 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9D0516E46E; Fri, 22 Nov 2019 17:56:41 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Nov 2019 09:56:38 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,230,1571727600"; d="scan'208";a="238687946" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga002.fm.intel.com with SMTP; 22 Nov 2019 09:56:35 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 22 Nov 2019 19:56:35 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Date: Fri, 22 Nov 2019 19:56:22 +0200 Message-Id: <20191122175623.13565-4-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191122175623.13565-1-ville.syrjala@linux.intel.com> References: <20191122175623.13565-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 3/4] drm/rect: Keep the clipped dst rectangle in place X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, Benjamin Gaignard Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Ville Syrjälä Now that we've constrained the clipped source rectangle such that it can't have negative dimensions doing the same for the dst rectangle seems appropriate. Should at least result in the clipped src and dst rectangles being a bit more consistent with each other. Cc: Benjamin Gaignard Cc: Maarten Lankhorst Cc: Daniel Vetter Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_rect.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c index a9c7f90836f3..1e1e2101007a 100644 --- a/drivers/gpu/drm/drm_rect.c +++ b/drivers/gpu/drm/drm_rect.c @@ -52,7 +52,7 @@ bool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2) } EXPORT_SYMBOL(drm_rect_intersect); -static u32 clip_scaled(u32 src, u32 dst, u32 clip) +static u32 clip_scaled(int src, int dst, int *clip) { u64 tmp; @@ -60,9 +60,9 @@ static u32 clip_scaled(u32 src, u32 dst, u32 clip) return 0; /* Only clip what we have. Keeps the result bounded. */ - clip = min(clip, dst); + *clip = min(*clip, dst); - tmp = mul_u32_u32(src, dst - clip); + tmp = mul_u32_u32(src, dst - *clip); /* * Round toward 1.0 when clipping so that we don't accidentally @@ -95,34 +95,34 @@ bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, diff = clip->x1 - dst->x1; if (diff > 0) { u32 new_src_w = clip_scaled(drm_rect_width(src), - drm_rect_width(dst), diff); + drm_rect_width(dst), &diff); src->x1 = src->x2 - new_src_w; - dst->x1 = clip->x1; + dst->x1 += diff; } diff = clip->y1 - dst->y1; if (diff > 0) { u32 new_src_h = clip_scaled(drm_rect_height(src), - drm_rect_height(dst), diff); + drm_rect_height(dst), &diff); src->y1 = src->y2 - new_src_h; - dst->y1 = clip->y1; + dst->y1 += diff; } diff = dst->x2 - clip->x2; if (diff > 0) { u32 new_src_w = clip_scaled(drm_rect_width(src), - drm_rect_width(dst), diff); + drm_rect_width(dst), &diff); src->x2 = src->x1 + new_src_w; - dst->x2 = clip->x2; + dst->x2 -= diff; } diff = dst->y2 - clip->y2; if (diff > 0) { u32 new_src_h = clip_scaled(drm_rect_height(src), - drm_rect_height(dst), diff); + drm_rect_height(dst), &diff); src->y2 = src->y1 + new_src_h; - dst->y2 = clip->y2; + dst->y2 -= diff; } return drm_rect_visible(dst); From patchwork Fri Nov 22 17:56:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 11258229 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DD8591593 for ; Fri, 22 Nov 2019 17:56:43 +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 C5D7D20715 for ; Fri, 22 Nov 2019 17:56:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C5D7D20715 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.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 261BC6E46E; Fri, 22 Nov 2019 17:56:43 +0000 (UTC) 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 ESMTPS id D814A6E48E; Fri, 22 Nov 2019 17:56:41 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Nov 2019 09:56:41 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,230,1571727600"; d="scan'208";a="201602747" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga008.jf.intel.com with SMTP; 22 Nov 2019 09:56:39 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 22 Nov 2019 19:56:38 +0200 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Date: Fri, 22 Nov 2019 19:56:23 +0200 Message-Id: <20191122175623.13565-5-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191122175623.13565-1-ville.syrjala@linux.intel.com> References: <20191122175623.13565-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 4/4] drm/selftests: Add drm_rect selftests X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Ville Syrjälä Add selftests for drm_rect. A few basic ones for clipped and unclipped cases, and a few special ones for specific bugs we had in the code. I'm too lazy to think of more corner cases to check at this time. Maybe later. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/selftests/Makefile | 3 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 4 + .../drm/selftests/test-drm_modeset_common.h | 7 + drivers/gpu/drm/selftests/test-drm_rect.c | 223 ++++++++++++++++++ include/drm/drm_rect.h | 2 + 5 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/selftests/test-drm_rect.c diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index d2137342b371..0856e4b12f70 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ - test-drm_damage_helper.o test-drm_dp_mst_helper.o + test-drm_damage_helper.o test-drm_dp_mst_helper.o \ + test-drm_rect.o obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o test-drm_cmdline_parser.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 1898de0b4a4d..782e285ca383 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -6,6 +6,10 @@ * * Tests are executed in order by igt/drm_selftests_helper */ +selftest(drm_rect_clip_scaled_div_by_zero, igt_drm_rect_clip_scaled_div_by_zero) +selftest(drm_rect_clip_scaled_not_clipped, igt_drm_rect_clip_scaled_not_clipped) +selftest(drm_rect_clip_scaled_clipped, igt_drm_rect_clip_scaled_clipped) +selftest(drm_rect_clip_scaled_signed_vs_unsigned, igt_drm_rect_clip_scaled_signed_vs_unsigned) selftest(check_plane_state, igt_check_plane_state) selftest(check_drm_format_block_width, igt_check_drm_format_block_width) selftest(check_drm_format_block_height, igt_check_drm_format_block_height) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index 0fcb8bbc6a1b..cfb51d8da2bc 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -3,6 +3,9 @@ #ifndef __TEST_DRM_MODESET_COMMON_H__ #define __TEST_DRM_MODESET_COMMON_H__ +#include +#include + #define FAIL(test, msg, ...) \ do { \ if (test) { \ @@ -13,6 +16,10 @@ #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") +int igt_drm_rect_clip_scaled_div_by_zero(void *ignored); +int igt_drm_rect_clip_scaled_not_clipped(void *ignored); +int igt_drm_rect_clip_scaled_clipped(void *ignored); +int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored); int igt_check_plane_state(void *ignored); int igt_check_drm_format_block_width(void *ignored); int igt_check_drm_format_block_height(void *ignored); diff --git a/drivers/gpu/drm/selftests/test-drm_rect.c b/drivers/gpu/drm/selftests/test-drm_rect.c new file mode 100644 index 000000000000..3a5ff38321f4 --- /dev/null +++ b/drivers/gpu/drm/selftests/test-drm_rect.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test cases for the drm_rect functions + */ + +#define pr_fmt(fmt) "drm_rect: " fmt + +#include + +#include + +#include "test-drm_modeset_common.h" + +int igt_drm_rect_clip_scaled_div_by_zero(void *ignored) +{ + struct drm_rect src, dst, clip; + bool visible; + + /* + * Make sure we don't divide by zero when dst + * width/height is zero and dst and clip do not intersect. + */ + drm_rect_init(&src, 0, 0, 0, 0); + drm_rect_init(&dst, 0, 0, 0, 0); + drm_rect_init(&clip, 1, 1, 1, 1); + visible = drm_rect_clip_scaled(&src, &dst, &clip); + FAIL(visible, "Destination not be visible\n"); + FAIL(drm_rect_visible(&src), "Source should not be visible\n"); + + drm_rect_init(&src, 0, 0, 0, 0); + drm_rect_init(&dst, 3, 3, 0, 0); + drm_rect_init(&clip, 1, 1, 1, 1); + visible = drm_rect_clip_scaled(&src, &dst, &clip); + FAIL(visible, "Destination not be visible\n"); + FAIL(drm_rect_visible(&src), "Source should not be visible\n"); + + return 0; +} + +int igt_drm_rect_clip_scaled_not_clipped(void *ignored) +{ + struct drm_rect src, dst, clip; + bool visible; + + /* 1:1 scaling */ + drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); + drm_rect_init(&dst, 0, 0, 1, 1); + drm_rect_init(&clip, 0, 0, 1, 1); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 0 || src.x2 != 1 << 16 || + src.y1 != 0 || src.y2 != 1 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 0 || dst.x2 != 1 || + dst.y1 != 0 || dst.y2 != 1, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + /* 2:1 scaling */ + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); + drm_rect_init(&dst, 0, 0, 1, 1); + drm_rect_init(&clip, 0, 0, 1, 1); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 0 || src.x2 != 2 << 16 || + src.y1 != 0 || src.y2 != 2 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 0 || dst.x2 != 1 || + dst.y1 != 0 || dst.y2 != 1, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + /* 1:2 scaling */ + drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); + drm_rect_init(&dst, 0, 0, 2, 2); + drm_rect_init(&clip, 0, 0, 2, 2); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 0 || src.x2 != 1 << 16 || + src.y1 != 0 || src.y2 != 1 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 0 || dst.x2 != 2 || + dst.y1 != 0 || dst.y2 != 2, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + return 0; +} + +int igt_drm_rect_clip_scaled_clipped(void *ignored) +{ + struct drm_rect src, dst, clip; + bool visible; + + /* 1:1 scaling top/left clip */ + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); + drm_rect_init(&dst, 0, 0, 2, 2); + drm_rect_init(&clip, 0, 0, 1, 1); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 0 || src.x2 != 1 << 16 || + src.y1 != 0 || src.y2 != 1 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 0 || dst.x2 != 1 || + dst.y1 != 0 || dst.y2 != 1, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + /* 1:1 scaling bottom/right clip */ + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); + drm_rect_init(&dst, 0, 0, 2, 2); + drm_rect_init(&clip, 1, 1, 1, 1); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 1 << 16 || src.x2 != 2 << 16 || + src.y1 != 1 << 16 || src.y2 != 2 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 1 || dst.x2 != 2 || + dst.y1 != 1 || dst.y2 != 2, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + /* 2:1 scaling top/left clip */ + drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); + drm_rect_init(&dst, 0, 0, 2, 2); + drm_rect_init(&clip, 0, 0, 1, 1); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 0 || src.x2 != 2 << 16 || + src.y1 != 0 || src.y2 != 2 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 0 || dst.x2 != 1 || + dst.y1 != 0 || dst.y2 != 1, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + /* 2:1 scaling bottom/right clip */ + drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); + drm_rect_init(&dst, 0, 0, 2, 2); + drm_rect_init(&clip, 1, 1, 1, 1); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 2 << 16 || src.x2 != 4 << 16 || + src.y1 != 2 << 16 || src.y2 != 4 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 1 || dst.x2 != 2 || + dst.y1 != 1 || dst.y2 != 2, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + /* 1:2 scaling top/left clip */ + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); + drm_rect_init(&dst, 0, 0, 4, 4); + drm_rect_init(&clip, 0, 0, 2, 2); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 0 || src.x2 != 1 << 16 || + src.y1 != 0 || src.y2 != 1 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 0 || dst.x2 != 2 || + dst.y1 != 0 || dst.y2 != 2, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + /* 1:2 scaling bottom/right clip */ + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); + drm_rect_init(&dst, 0, 0, 4, 4); + drm_rect_init(&clip, 2, 2, 2, 2); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(src.x1 != 1 << 16 || src.x2 != 2 << 16 || + src.y1 != 1 << 16 || src.y2 != 2 << 16, + "Source badly clipped\n"); + FAIL(dst.x1 != 2 || dst.x2 != 4 || + dst.y1 != 2 || dst.y2 != 4, + "Destination badly clipped\n"); + FAIL(!visible, "Destination should be visible\n"); + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + + return 0; +} + +int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored) +{ + struct drm_rect src, dst, clip; + bool visible; + + /* + * 'clip.x2 - dst.x1 >= dst width' could result a negative + * src rectangle width which is no longer expected by the + * code as it's using unsigned types. This could lead to + * the clipped source rectangle appering visible when it + * should have been fully clipped. Make sure both rectangles + * end up invisible. + */ + drm_rect_init(&src, 0, 0, INT_MAX, INT_MAX); + drm_rect_init(&dst, 0, 0, 2, 2); + drm_rect_init(&clip, 3, 3, 1, 1); + + visible = drm_rect_clip_scaled(&src, &dst, &clip); + + FAIL(visible, "Destination should not be visible\n"); + FAIL(drm_rect_visible(&src), "Source should not be visible\n"); + + return 0; +} diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h index cd0106135b6a..57a3be9e53e4 100644 --- a/include/drm/drm_rect.h +++ b/include/drm/drm_rect.h @@ -24,6 +24,8 @@ #ifndef DRM_RECT_H #define DRM_RECT_H +#include + /** * DOC: rect utils *