From patchwork Mon Oct 7 16:10:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824991 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 9ACC0CFB44A for ; Mon, 7 Oct 2024 16:10:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6716510E207; Mon, 7 Oct 2024 16:10:51 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="NiM1IqI7"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1CF9010E0CC for ; Mon, 7 Oct 2024 16:10:48 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id D460E40005; Mon, 7 Oct 2024 16:10:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317447; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nPw90jBWzUneCJNYVnnpD4jiAcd/VX1BxcTgAriuwkw=; b=NiM1IqI7RxHbqJFt5JCm4eivhb0fzFMbT9QAM39HLkaocfp0A0vlbPUfBkVVkVwf3GptRF 2BM6noBNoeoeFURCFxLc4URtnWD/ckfp5mFTau28TM+yD+O0FqIoO+3hZW9gIs81Uf/X8z 6Kv9CXOAVR9p9Tb50DVRQRKzweoHb/ksJR9NmSTt6XHd2w7EeB7PDlcYCgzmfQ2z2L22w7 Md4lX+ggB8bg34y8TEndiszHanFsRwRCwQTQk8JmFmVmnh44rpeAOyhR48qBINBDSj6K3s p6H/RpFpyDNF3ngcVTjXtTIGOl4OAzJDjcY1MO1xIcx2HHqfLdjcm2CjquqAKw== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:35 +0200 Subject: [PATCH v12 01/15] drm/vkms: Code formatting MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-1-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen , =?utf-8?q?Ma=C3=ADra_Canal?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=4941; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=+UNcxZgMXrYbfQ0Wk9GKtPGOAGGqTYaVl8i/PMhH4u4=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAf/1uLz3+1BMZhhmt7HVAzlXd69eo4qn6hdh ZxqO/sdWPuJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQH/wAKCRAgrS7GWxAs 4rKpEACb6enr6SdiL97NNuPWB7Pum3NDTMTOFPLIxYmmZCsnhYpaKzDjU2fgalitB6k0aJSARnw +iLg+eJJ9Kf7SJrj/4BlcVxtvMHa+Vz3anCcFLtysklDME6o2KOYhlS9Q8rA9cqtfZOIheI16u2 FraxfcObxbKkTUF4L7/H5r0hVUn9Bef8NiDchXMUrtaTaSN8tslDM7nOB6f2qDCsRb94K+E95n3 LshWTN4uXx0OZmgwUlbFBYBjxuFEyA4fTe0++RVwgIGN5NYPeL8YXjQgvysyhDPFQNd4MbIBHKU WuzTYy/UNphj5q8Qu/NFjNZaP+etGb34UAWLMKw4/W7cgXJZ5yazdHJCdBH9MQowfsNTEJhA9ic v9l4gKThhFanDArG/tr3gn7WALtQrB283uLFSVA2ImlXVu/0tI4H5MgJ6hrWVDdbRx11rjbjFlt 19c0jCXWTY/Ogsp4B+AW0QCMbt2SmOADI3VMxp5OYT45wL/3k/gzVMe7RGtj8tSvDzQJv2QswVT lTHZyslnP6OeudTo3WC3kwjpMJub9OZ6WC/wGWZuj0JYito0e9Rn6GWTijjjwBZEOdUDHG98jvC 0ME5hMmbAnu/zAxXB2TsVVKm10ADHkW6ZJKjtuNdWtaQqpSZsPMixkLaTLDisFOCqQoME4A/TH2 Ri6YxbWoqalosjg== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Few no-op changes to remove double spaces and fix wrong alignments. Reviewed-by: Pekka Paalanen Reviewed-by: Maíra Canal Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_composer.c | 10 +++++----- drivers/gpu/drm/vkms/vkms_crtc.c | 6 ++---- drivers/gpu/drm/vkms/vkms_drv.c | 3 +-- drivers/gpu/drm/vkms/vkms_plane.c | 8 ++++---- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 57a5769fc994..931e214b225c 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -96,7 +96,7 @@ static u16 lerp_u16(u16 a, u16 b, s64 t) s64 a_fp = drm_int2fixp(a); s64 b_fp = drm_int2fixp(b); - s64 delta = drm_fixp_mul(b_fp - a_fp, t); + s64 delta = drm_fixp_mul(b_fp - a_fp, t); return drm_fixp2int(a_fp + delta); } @@ -309,8 +309,8 @@ static int compose_active_planes(struct vkms_writeback_job *active_wb, void vkms_composer_worker(struct work_struct *work) { struct vkms_crtc_state *crtc_state = container_of(work, - struct vkms_crtc_state, - composer_work); + struct vkms_crtc_state, + composer_work); struct drm_crtc *crtc = crtc_state->base.crtc; struct vkms_writeback_job *active_wb = crtc_state->active_writeback; struct vkms_output *out = drm_crtc_to_vkms_output(crtc); @@ -335,7 +335,7 @@ void vkms_composer_worker(struct work_struct *work) crtc_state->gamma_lut.base = (struct drm_color_lut *)crtc->state->gamma_lut->data; crtc_state->gamma_lut.lut_length = crtc->state->gamma_lut->length / sizeof(struct drm_color_lut); - max_lut_index_fp = drm_int2fixp(crtc_state->gamma_lut.lut_length - 1); + max_lut_index_fp = drm_int2fixp(crtc_state->gamma_lut.lut_length - 1); crtc_state->gamma_lut.channel_value2index_ratio = drm_fixp_div(max_lut_index_fp, u16_max_fp); @@ -374,7 +374,7 @@ void vkms_composer_worker(struct work_struct *work) drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32); } -static const char * const pipe_crc_sources[] = {"auto"}; +static const char *const pipe_crc_sources[] = { "auto" }; const char *const *vkms_get_crc_sources(struct drm_crtc *crtc, size_t *count) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index a40295c18b48..39bf9d4247fa 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -188,8 +188,7 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc, return ret; drm_for_each_plane_mask(plane, crtc->dev, crtc_state->plane_mask) { - plane_state = drm_atomic_get_existing_plane_state(crtc_state->state, - plane); + plane_state = drm_atomic_get_existing_plane_state(crtc_state->state, plane); WARN_ON(!plane_state); if (!plane_state->visible) @@ -205,8 +204,7 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc, i = 0; drm_for_each_plane_mask(plane, crtc->dev, crtc_state->plane_mask) { - plane_state = drm_atomic_get_existing_plane_state(crtc_state->state, - plane); + plane_state = drm_atomic_get_existing_plane_state(crtc_state->state, plane); if (!plane_state->visible) continue; diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 2d1e95cb66e5..19b7322ce49d 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -82,8 +82,7 @@ static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state) drm_atomic_helper_wait_for_flip_done(dev, old_state); for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) { - struct vkms_crtc_state *vkms_state = - to_vkms_crtc_state(old_crtc_state); + struct vkms_crtc_state *vkms_state = to_vkms_crtc_state(old_crtc_state); flush_work(&vkms_state->composer_work); } diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index e5c625ab8e3e..5a8d295e65f2 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -117,10 +117,10 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map)); drm_framebuffer_get(frame_info->fb); frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 | - DRM_MODE_ROTATE_90 | - DRM_MODE_ROTATE_270 | - DRM_MODE_REFLECT_X | - DRM_MODE_REFLECT_Y); + DRM_MODE_ROTATE_90 | + DRM_MODE_ROTATE_270 | + DRM_MODE_REFLECT_X | + DRM_MODE_REFLECT_Y); drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated), drm_rect_height(&frame_info->rotated), frame_info->rotation); From patchwork Mon Oct 7 16:10:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824992 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 83E7BCFB446 for ; Mon, 7 Oct 2024 16:10:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4042F10E3CB; Mon, 7 Oct 2024 16:10:52 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="nIiMDKNS"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7492610E207 for ; Mon, 7 Oct 2024 16:10:50 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 00BD240003; Mon, 7 Oct 2024 16:10:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317449; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2C5hZ/knWBtoOPrBC9CFpCsHQ2ytwSQQLFNkYLaAoVE=; b=nIiMDKNSXPjLENoWFvf7nGWZpNMHYGSKU4MdZx1UcvnVmc2ZmdJ/sax4fvVceE1z7pQ0BQ a/ZR7Yvs7ZaPB82HDxob8h2WA8DWlIK4pR46KmkAhyLfscQWY2f+VR3/LDYQM9LRKErxqx MCILXwPkisR5Ef3s4QrpTA1OtGbySm1jViofeWwMiKmXi9gtTM+wQ9Tr4O95FUGzDr5p4P IWP7uO47MgqZqd1Cub4QfaX1ckJdazHsV6aVOYBlG6HJEHbysodHF3GjKlS8kM02zH1aS+ hCowh9gQ+FScEa0MAVugUZSIx2romL1JuFGa7OSZ+8tOfmxiH1XOJh7R2hkLXg== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:36 +0200 Subject: [PATCH v12 02/15] drm/vkms: Use drm_frame directly MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-2-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen , =?utf-8?q?Ma=C3=ADra_Canal?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=4276; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=2sG3hL92AI5p05ggDfRLdPBFv95vU35OetchXGlRuB8=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgA3AwRhLY5aLn473Sx8ZXdKWRZ8o44y7ObA VYIUsdcFHiJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAAAKCRAgrS7GWxAs 4spvD/9h5T4Grq0Y74dZVWsHrNWA7hfk7B1T1lnbUoQU5Y+qLWKBiCrqW+f9CftJ95Z4Seo2urs u87ShtepIAi7lbCL6cC+N9AsviHEXp8Y78a5aEQShr9wVpSkVf2AlQLGBEFNII12k6m2J/FGr4g iYL2Svn13Tsw8jNd7lU2TJd2IBw7YZ/TwPqTOh7WyrNt4+xniL9UJ5MmJI171qcZxgBDfjlDxfH V+AP4yboMno18tImeUCLvzzE2V3qweAVqXIqRStkPL4V2aZ9aIIzUwSlnZVc5uSWmMM3suYIIOa 85P/r1doUgjos/YLYLagtbu/LS1n1Jv2Fr+5Y+zGNTuo7bcbCOMm4BGQY+bvzfr4d6FWitcF/+1 wgFqRBFUo+GHzdDugBG4l1s7SREsD6nrgRpj0z2Ij4UDfnOPFut4HWaZne/VeyEMa5SbAC/CdDn aArN+XXUYXCX2G4IFo/7j47SxgkRlKxXUe5mLIq9cMR4e5uLdEB/WDxY49SntgD/Ikd8tLyOCuu +d40bQiT5Muwfez+dtO/XRnJc3pSHmeMyoShcN+8XQZ2b2BeMoCSYDp9p+jXauKkbu9+3bcvrfO bfT8urQIdf/Wodju9s7trcdSQWRP7qsWop/XTQPoWCJ2tjMwx2S4mYeB4zbWRZRkvAZqQ0X/m+c BZZlUav74Rdy73g== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Remove intermidiary variables and access the variables directly from drm_frame. These changes should be noop. Signed-off-by: Arthur Grillo Acked-by: Pekka Paalanen Reviewed-by: Maíra Canal Reviewed-by: Louis Chauvet [Louis Chauvet: Applied review from Maíra] Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_drv.h | 3 --- drivers/gpu/drm/vkms/vkms_formats.c | 11 ++++++----- drivers/gpu/drm/vkms/vkms_plane.c | 3 --- drivers/gpu/drm/vkms/vkms_writeback.c | 5 ----- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 672fe191e239..fcb5a5ff7df7 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -42,9 +42,6 @@ struct vkms_frame_info { struct drm_rect rotated; struct iosys_map map[DRM_FORMAT_MAX_PLANES]; unsigned int rotation; - unsigned int offset; - unsigned int pitch; - unsigned int cpp; }; struct pixel_argb_u16 { diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index e8a5cc235ebb..2a0fbe27d8b2 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -23,8 +23,9 @@ */ static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int y) { - return frame_info->offset + (y * frame_info->pitch) - + (x * frame_info->cpp); + struct drm_framebuffer *fb = frame_info->fb; + + return fb->offsets[0] + (y * fb->pitches[0]) + (x * fb->format->cpp[0]); } /** @@ -154,12 +155,12 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state u8 *src_pixels = get_packed_src_addr(frame_info, y); int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels); - for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) { + for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) { int x_pos = get_x_position(frame_info, limit, x); if (drm_rotation_90_or_270(frame_info->rotation)) src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1) - + frame_info->cpp * y; + + frame_info->fb->format->cpp[0] * y; plane->pixel_read(src_pixels, &out_pixels[x_pos]); } @@ -253,7 +254,7 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, struct pixel_argb_u16 *in_pixels = src_buffer->pixels; int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), src_buffer->n_pixels); - for (size_t x = 0; x < x_limit; x++, dst_pixels += frame_info->cpp) + for (size_t x = 0; x < x_limit; x++, dst_pixels += frame_info->fb->format->cpp[0]) wb->pixel_write(dst_pixels, &in_pixels[x]); } diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 5a8d295e65f2..21b5adfb44aa 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -125,9 +125,6 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated), drm_rect_height(&frame_info->rotated), frame_info->rotation); - frame_info->offset = fb->offsets[0]; - frame_info->pitch = fb->pitches[0]; - frame_info->cpp = fb->format->cpp[0]; vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt); } diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c index bc724cbd5e3a..c8582df1f739 100644 --- a/drivers/gpu/drm/vkms/vkms_writeback.c +++ b/drivers/gpu/drm/vkms/vkms_writeback.c @@ -149,11 +149,6 @@ static void vkms_wb_atomic_commit(struct drm_connector *conn, crtc_state->active_writeback = active_wb; crtc_state->wb_pending = true; spin_unlock_irq(&output->composer_lock); - - wb_frame_info->offset = fb->offsets[0]; - wb_frame_info->pitch = fb->pitches[0]; - wb_frame_info->cpp = fb->format->cpp[0]; - drm_writeback_queue_job(wb_conn, connector_state); active_wb->pixel_write = get_pixel_write_function(wb_format); drm_rect_init(&wb_frame_info->src, 0, 0, crtc_width, crtc_height); From patchwork Mon Oct 7 16:10:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824993 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id D3F0CCFB449 for ; Mon, 7 Oct 2024 16:10:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9AB8110E3CC; Mon, 7 Oct 2024 16:10:53 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="pZIUQoC/"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id B088C10E3CB for ; Mon, 7 Oct 2024 16:10:51 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 2EBBE40006; Mon, 7 Oct 2024 16:10:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317450; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/rit4R7BfGzJp+BsDcAO2abNMYF5FXKvgrXhAznsmVw=; b=pZIUQoC/p6bFwSp/i3j9dqSAOzqs6FXKerwJkrR4eGIciYAou//dBzITnfr8DEjWk1+DDO VGhX6iqJOfAFKw0ICeJETUGU8f3ibUZKjHD1NgBPuWMHmzBpIhnZFSSWtQNeGPVDWmELmw 4dvQzRVQRtgJ4UsViiZw3m6f0PfmlwJVH8h/MQ6glhaSTiJxHs7H0b/DNEFMmOK21AZHo7 k1KWO1tGx8bAiX9YRxBmgeJTt1iDVlARoFubmlCloM4hwbECmJnv0lKPtL41wRB/tICnw2 6NGhNPRxUyXsuhbjRBij15hN2wMxkAeBpyEb4iF7hBvagHDuU6Yg/DH4w+mqWw== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:37 +0200 Subject: [PATCH v12 03/15] drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-3-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=13183; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=W6FmTSZbFCzM56Glzlm65mtmYDj+QUzKBDMqD0/Hjw4=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgAp0mBFqkdmvRwZI5BRrmGbLoJUzBtH1gOW bDeqdNiPJaJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAAAKCRAgrS7GWxAs 4tU9D/9miB2ZOfLoY1E20ThfxCsxSJTU8dIfjUVHa6pMX5j7RTOaLKSMeOhFDWPtKPQLb9P8xht TsYwioqQpoZFlHxD1/vV7c/PHidJBHsmn3k5JrcOnms1Uvv2JTtVfFVuWxkVq+MdoxMOqh7JVOV 85DD3O6BWkrv0N+uhiwmGzsy9Z5KCjonTSoW7U0sypStroEEKMEKIZIS6h81zNMuASj2HFK1G2d xFGgSHkX1S43QQ9zW+VWNgLLpWwmY7g+EjoeRXbWaYRLQRuHanmznqIi+zwd+DYoBBX5MIY9qF1 Gm65FkAuOAsxwAWJ1QjrGyNWmJqKvyBXUkC7DE9flqVv07Jz3+f5O9wHGD09cl81+FZGVBe5dNL cUjDkOlJZW/hI9TzdvEcz07yvMyWkxMVkwxVmvnBIQCVGijgdnjD+b+8BwPoDsZSJ6LJRMDDOMI KBkSsmP6kBJ+wCBN3poZ9nuakQatU5SAqvwn0EfvDvJyST9W0yHEbbUYmxcZwQ1RGuDTKRRsnIN aAfmlN2IPc7JWuchSXUCxfp4Fxn2eGSNYKfb5Bi/iV73euCZXqCNhHLNp+yy6/eOQHA0tBH7scD PnA1PQEUCbwjyChHiFrXNulkZrLFxgHRiYsPtMQkISjyqBNwlNsAN0T3fG6AKDqoJzZXtLWHEgf 0xQSYPN/aPgKOuQ== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Introduce two typedefs: pixel_read_t and pixel_write_t. It allows the compiler to check if the passed functions take the correct arguments. Such typedefs will help ensuring consistency across the code base in case of update of these prototypes. Rename input/output variable in a consistent way between read_line and write_line. A warn has been added in get_pixel_*_function to alert when an unsupported pixel format is requested. As those formats are checked before atomic_update callbacks, it should never happen. Document for those typedefs. Reviewed-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_drv.h | 23 ++++++- drivers/gpu/drm/vkms/vkms_formats.c | 124 ++++++++++++++++++++---------------- drivers/gpu/drm/vkms/vkms_formats.h | 4 +- drivers/gpu/drm/vkms/vkms_plane.c | 2 +- 4 files changed, 94 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index fcb5a5ff7df7..e0d46defed83 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -53,12 +53,31 @@ struct line_buffer { struct pixel_argb_u16 *pixels; }; +/** + * typedef pixel_write_t - These functions are used to read a pixel from a + * &struct pixel_argb_u16, convert it in a specific format and write it in the @out_pixel + * buffer. + * + * @out_pixel: destination address to write the pixel + * @in_pixel: pixel to write + */ +typedef void (*pixel_write_t)(u8 *out_pixel, struct pixel_argb_u16 *in_pixel); + struct vkms_writeback_job { struct iosys_map data[DRM_FORMAT_MAX_PLANES]; struct vkms_frame_info wb_frame_info; - void (*pixel_write)(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel); + pixel_write_t pixel_write; }; +/** + * typedef pixel_read_t - These functions are used to read a pixel in the source frame, + * convert it to `struct pixel_argb_u16` and write it to @out_pixel. + * + * @in_pixel: pointer to the pixel to read + * @out_pixel: pointer to write the converted pixel + */ +typedef void (*pixel_read_t)(u8 *in_pixel, struct pixel_argb_u16 *out_pixel); + /** * struct vkms_plane_state - Driver specific plane state * @base: base plane state @@ -69,7 +88,7 @@ struct vkms_writeback_job { struct vkms_plane_state { struct drm_shadow_plane_state base; struct vkms_frame_info *frame_info; - void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel); + pixel_read_t pixel_read; }; struct vkms_plane { diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 2a0fbe27d8b2..b9544e67cd4f 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -75,7 +75,7 @@ static int get_x_position(const struct vkms_frame_info *frame_info, int limit, i * They are used in the vkms_compose_row() function to handle multiple formats. */ -static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) +static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { /* * The 257 is the "conversion ratio". This number is obtained by the @@ -83,48 +83,48 @@ static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixe * the best color value in a pixel format with more possibilities. * A similar idea applies to others RGB color conversions. */ - out_pixel->a = (u16)src_pixels[3] * 257; - out_pixel->r = (u16)src_pixels[2] * 257; - out_pixel->g = (u16)src_pixels[1] * 257; - out_pixel->b = (u16)src_pixels[0] * 257; + out_pixel->a = (u16)in_pixel[3] * 257; + out_pixel->r = (u16)in_pixel[2] * 257; + out_pixel->g = (u16)in_pixel[1] * 257; + out_pixel->b = (u16)in_pixel[0] * 257; } -static void XRGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) +static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { out_pixel->a = (u16)0xffff; - out_pixel->r = (u16)src_pixels[2] * 257; - out_pixel->g = (u16)src_pixels[1] * 257; - out_pixel->b = (u16)src_pixels[0] * 257; + out_pixel->r = (u16)in_pixel[2] * 257; + out_pixel->g = (u16)in_pixel[1] * 257; + out_pixel->b = (u16)in_pixel[0] * 257; } -static void ARGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) +static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { - __le16 *pixels = (__force __le16 *)src_pixels; + __le16 *pixel = (__le16 *)in_pixel; - out_pixel->a = le16_to_cpu(pixels[3]); - out_pixel->r = le16_to_cpu(pixels[2]); - out_pixel->g = le16_to_cpu(pixels[1]); - out_pixel->b = le16_to_cpu(pixels[0]); + out_pixel->a = le16_to_cpu(pixel[3]); + out_pixel->r = le16_to_cpu(pixel[2]); + out_pixel->g = le16_to_cpu(pixel[1]); + out_pixel->b = le16_to_cpu(pixel[0]); } -static void XRGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) +static void XRGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { - __le16 *pixels = (__force __le16 *)src_pixels; + __le16 *pixel = (__le16 *)in_pixel; out_pixel->a = (u16)0xffff; - out_pixel->r = le16_to_cpu(pixels[2]); - out_pixel->g = le16_to_cpu(pixels[1]); - out_pixel->b = le16_to_cpu(pixels[0]); + out_pixel->r = le16_to_cpu(pixel[2]); + out_pixel->g = le16_to_cpu(pixel[1]); + out_pixel->b = le16_to_cpu(pixel[0]); } -static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) +static void RGB565_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { - __le16 *pixels = (__force __le16 *)src_pixels; + __le16 *pixel = (__le16 *)in_pixel; s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31)); s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63)); - u16 rgb_565 = le16_to_cpu(*pixels); + u16 rgb_565 = le16_to_cpu(*pixel); s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f); s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f); s64 fp_b = drm_int2fixp(rgb_565 & 0x1f); @@ -168,12 +168,12 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state /* * The following functions take one &struct pixel_argb_u16 and convert it to a specific format. - * The result is stored in @dst_pixels. + * The result is stored in @out_pixel. * * They are used in vkms_writeback_row() to convert and store a pixel from the src_buffer to * the writeback buffer. */ -static void argb_u16_to_ARGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_ARGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) { /* * This sequence below is important because the format's byte order is @@ -185,43 +185,43 @@ static void argb_u16_to_ARGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel * | Addr + 2 | = Red channel * | Addr + 3 | = Alpha channel */ - dst_pixels[3] = DIV_ROUND_CLOSEST(in_pixel->a, 257); - dst_pixels[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); - dst_pixels[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257); - dst_pixels[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); + out_pixel[3] = DIV_ROUND_CLOSEST(in_pixel->a, 257); + out_pixel[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); + out_pixel[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257); + out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); } -static void argb_u16_to_XRGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_XRGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) { - dst_pixels[3] = 0xff; - dst_pixels[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); - dst_pixels[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257); - dst_pixels[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); + out_pixel[3] = 0xff; + out_pixel[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); + out_pixel[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257); + out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); } -static void argb_u16_to_ARGB16161616(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_ARGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) { - __le16 *pixels = (__force __le16 *)dst_pixels; + __le16 *pixel = (__le16 *)out_pixel; - pixels[3] = cpu_to_le16(in_pixel->a); - pixels[2] = cpu_to_le16(in_pixel->r); - pixels[1] = cpu_to_le16(in_pixel->g); - pixels[0] = cpu_to_le16(in_pixel->b); + pixel[3] = cpu_to_le16(in_pixel->a); + pixel[2] = cpu_to_le16(in_pixel->r); + pixel[1] = cpu_to_le16(in_pixel->g); + pixel[0] = cpu_to_le16(in_pixel->b); } -static void argb_u16_to_XRGB16161616(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_XRGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) { - __le16 *pixels = (__force __le16 *)dst_pixels; + __le16 *pixel = (__le16 *)out_pixel; - pixels[3] = cpu_to_le16(0xffff); - pixels[2] = cpu_to_le16(in_pixel->r); - pixels[1] = cpu_to_le16(in_pixel->g); - pixels[0] = cpu_to_le16(in_pixel->b); + pixel[3] = cpu_to_le16(0xffff); + pixel[2] = cpu_to_le16(in_pixel->r); + pixel[1] = cpu_to_le16(in_pixel->g); + pixel[0] = cpu_to_le16(in_pixel->b); } -static void argb_u16_to_RGB565(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_RGB565(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) { - __le16 *pixels = (__force __le16 *)dst_pixels; + __le16 *pixel = (__le16 *)out_pixel; s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31)); s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63)); @@ -234,7 +234,7 @@ static void argb_u16_to_RGB565(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) u16 g = drm_fixp2int(drm_fixp_div(fp_g, fp_g_ratio)); u16 b = drm_fixp2int(drm_fixp_div(fp_b, fp_rb_ratio)); - *pixels = cpu_to_le16(r << 11 | g << 5 | b); + *pixel = cpu_to_le16(r << 11 | g << 5 | b); } /** @@ -259,13 +259,13 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, } /** - * get_pixel_conversion_function() - Retrieve the correct read_pixel function for a specific + * get_pixel_read_function() - Retrieve the correct read_pixel function for a specific * format. The returned pointer is NULL for unsupported pixel formats. The caller must ensure that * the pointer is valid before using it in a vkms_plane_state. * * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) */ -void *get_pixel_conversion_function(u32 format) +pixel_read_t get_pixel_read_function(u32 format) { switch (format) { case DRM_FORMAT_ARGB8888: @@ -279,7 +279,15 @@ void *get_pixel_conversion_function(u32 format) case DRM_FORMAT_RGB565: return &RGB565_to_argb_u16; default: - return NULL; + /* + * This is a bug in vkms_plane_atomic_check(). All the supported + * format must: + * - Be listed in vkms_formats in vkms_plane.c + * - Have a pixel_read callback defined here + */ + pr_err("Pixel format %p4cc is not supported by VKMS planes. This is a kernel bug, atomic check must forbid this configuration.\n", + &format); + BUG(); } } @@ -290,7 +298,7 @@ void *get_pixel_conversion_function(u32 format) * * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) */ -void *get_pixel_write_function(u32 format) +pixel_write_t get_pixel_write_function(u32 format) { switch (format) { case DRM_FORMAT_ARGB8888: @@ -304,6 +312,14 @@ void *get_pixel_write_function(u32 format) case DRM_FORMAT_RGB565: return &argb_u16_to_RGB565; default: - return NULL; + /* + * This is a bug in vkms_writeback_atomic_check. All the supported + * format must: + * - Be listed in vkms_wb_formats in vkms_writeback.c + * - Have a pixel_write callback defined here + */ + pr_err("Pixel format %p4cc is not supported by VKMS writeback. This is a kernel bug, atomic check must forbid this configuration.\n", + &format); + BUG(); } } diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h index cf59c2ed8e9a..3ecea4563254 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -5,8 +5,8 @@ #include "vkms_drv.h" -void *get_pixel_conversion_function(u32 format); +pixel_read_t get_pixel_read_function(u32 format); -void *get_pixel_write_function(u32 format); +pixel_write_t get_pixel_write_function(u32 format); #endif /* _VKMS_FORMATS_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 21b5adfb44aa..10e9b23dab28 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -125,7 +125,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated), drm_rect_height(&frame_info->rotated), frame_info->rotation); - vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt); + vkms_plane_state->pixel_read = get_pixel_read_function(fmt); } static int vkms_plane_atomic_check(struct drm_plane *plane, From patchwork Mon Oct 7 16:10:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824995 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id EE33ACFB446 for ; Mon, 7 Oct 2024 16:10:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E89F10E3CD; Mon, 7 Oct 2024 16:10:56 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="YIcAuhE+"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id B724610E3CD for ; Mon, 7 Oct 2024 16:10:52 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 5A87740009; Mon, 7 Oct 2024 16:10:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317451; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1SzheK38TqKTamJuQO4NjG5/hQD5MrdB/SoQUKg3juA=; b=YIcAuhE+zX2VAyqUZXMuImPlew5Y7d9R6xD3To2ZSa795Q1L8fcs17TQjTZVQSAFGaWJo0 tIwfrhMO0YS9CqMBSRZeJpyJEP8N9XrPpwMb1+GFbSFEQz796lfHRmA4wtlgvG6ZW8InmO 1VDWHSljw7cNbAE55z+okq5DUJ+M+R6BXJUn9B+YnmLQCii2Ip5dMOtdItkyDFx1DJNBpf H+zu9kQ+G1rg1V4chL21yRGcCVOkT3orNfIb6i7dGFmzc95r6DAX9dh/j6oJp98HbFgtKo 1TOrdAmYJypkn/jgPcgC8a6lV5fHdqahRVL/MT3Bxie2FLdBhNHyA1ToXoz+sw== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:38 +0200 Subject: [PATCH v12 04/15] drm/vkms: Use const for input pointers in pixel_read an pixel_write functions MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-4-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen , =?utf-8?q?Ma=C3=ADra_Canal?= X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=5640; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=NJQ4BIoIQIoJWPyFV3ltFmfTqTQcgWJGwPuIgUylwt4=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgAe8TD05lQD4PpW1nvU6HyZN21mwQ2TaLzi fg1W515Z8KJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAAAKCRAgrS7GWxAs 4sNpEADIeWieX11c2YY9ll/5ExQPtGIsmtlLst8jfct/dl2XsFU9wf3EdTL2FVa9m6ws5QMk8hS V67cDsrDFghVNqe6Y1dQmHCljWIMnW03lZfrBQ/ZC2YAjw1whDpJ+Kb8RX+K0zW5tNgkVElgThF vZWmgRBauqxj67h7Sm5fKIkKVJCzGeABVe0a/UNUNushUdpmUQEJ7gI9vbrFBoks2C+8fY6CMwN cTcO4HaMini06MZv1cA22qna1ade+F7VGOFzeuwXRlTB19y2x6n/1IJM0jpE3a/PDYGZ9EpeNtJ FtsY6syUTkN4joM8ESpWXC+0VTaVHW1yz59AnxyA2DGRq6cRUrLlRVhQbF2zgLL6MpasOzxOxOE tbpuUxRZeCp9q4KM3GuG8kBOiDp6edMfOXwiWiI+6FwY1CWN24OqEDhGSOjtY04Ehkkl7ms1sCi ZRiHo7QGGnqQN/LtMTcv+powRfTvCIRGeSFe8Ndr/fj5ZYYRSxJRX7DHBI4iOeORKOFD8Ui7Z/6 ONMAzCcIWwQynjA8GTtU3U2Fto0BBPd+OgSjxkQb5QJNdyBbk+3537WAWEecGaZ25RZdP9qdo98 vrRaxXNHprvzx/f8u2ExlK8VdHuQFuMQxL5IzAde+qqwnbf150g8W4j9nuIlbXWEL7H13Ngi89s r7HOJB8Nm0hUurA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" As the pixel_read and pixel_write function should never modify the input buffer, mark those pointers const. Reviewed-by: Pekka Paalanen Reviewed-by: Maíra Canal Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_drv.h | 4 ++-- drivers/gpu/drm/vkms/vkms_formats.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index e0d46defed83..3f45290a0c5d 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -61,7 +61,7 @@ struct line_buffer { * @out_pixel: destination address to write the pixel * @in_pixel: pixel to write */ -typedef void (*pixel_write_t)(u8 *out_pixel, struct pixel_argb_u16 *in_pixel); +typedef void (*pixel_write_t)(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel); struct vkms_writeback_job { struct iosys_map data[DRM_FORMAT_MAX_PLANES]; @@ -76,7 +76,7 @@ struct vkms_writeback_job { * @in_pixel: pointer to the pixel to read * @out_pixel: pointer to write the converted pixel */ -typedef void (*pixel_read_t)(u8 *in_pixel, struct pixel_argb_u16 *out_pixel); +typedef void (*pixel_read_t)(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel); /** * struct vkms_plane_state - Driver specific plane state diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index b9544e67cd4f..06aef5162529 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -75,7 +75,7 @@ static int get_x_position(const struct vkms_frame_info *frame_info, int limit, i * They are used in the vkms_compose_row() function to handle multiple formats. */ -static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void ARGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { /* * The 257 is the "conversion ratio". This number is obtained by the @@ -89,7 +89,7 @@ static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) out_pixel->b = (u16)in_pixel[0] * 257; } -static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void XRGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { out_pixel->a = (u16)0xffff; out_pixel->r = (u16)in_pixel[2] * 257; @@ -97,7 +97,7 @@ static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) out_pixel->b = (u16)in_pixel[0] * 257; } -static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void ARGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { __le16 *pixel = (__le16 *)in_pixel; @@ -107,7 +107,7 @@ static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pi out_pixel->b = le16_to_cpu(pixel[0]); } -static void XRGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void XRGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { __le16 *pixel = (__le16 *)in_pixel; @@ -117,7 +117,7 @@ static void XRGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pi out_pixel->b = le16_to_cpu(pixel[0]); } -static void RGB565_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { __le16 *pixel = (__le16 *)in_pixel; @@ -173,7 +173,7 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state * They are used in vkms_writeback_row() to convert and store a pixel from the src_buffer to * the writeback buffer. */ -static void argb_u16_to_ARGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_ARGB8888(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel) { /* * This sequence below is important because the format's byte order is @@ -191,7 +191,7 @@ static void argb_u16_to_ARGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); } -static void argb_u16_to_XRGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_XRGB8888(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel) { out_pixel[3] = 0xff; out_pixel[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); @@ -199,7 +199,7 @@ static void argb_u16_to_XRGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); } -static void argb_u16_to_ARGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_ARGB16161616(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel) { __le16 *pixel = (__le16 *)out_pixel; @@ -209,7 +209,7 @@ static void argb_u16_to_ARGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pi pixel[0] = cpu_to_le16(in_pixel->b); } -static void argb_u16_to_XRGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_XRGB16161616(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel) { __le16 *pixel = (__le16 *)out_pixel; @@ -219,7 +219,7 @@ static void argb_u16_to_XRGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pi pixel[0] = cpu_to_le16(in_pixel->b); } -static void argb_u16_to_RGB565(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel) { __le16 *pixel = (__le16 *)out_pixel; From patchwork Mon Oct 7 16:10:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824994 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id E80F6CFB44A for ; Mon, 7 Oct 2024 16:10:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 57BBB10E3CE; Mon, 7 Oct 2024 16:10:55 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="oVxqhAfP"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id D5A3610E3CD for ; Mon, 7 Oct 2024 16:10:53 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 8A9774000B; Mon, 7 Oct 2024 16:10:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317452; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KPJGKEsxz1PC1IeGIUlzazKnNt9mMdttLIEPvXgoXtI=; b=oVxqhAfPIOCzmFjDdaDrfmmjP5aMK51/YiyaksZxASCYsGQPMr29bB29fOGsSZlcg8bHEU H5KSNJ31/bXygqiySRRAGTFfnPScR+kAMl5W6sgbImbjfQBoIPrkA4yWqlI/N8+6ERszC7 sTIf7F3y3K1DSBsWqR9uLZKNmFdmyL1lXI8f+pF3LYe9fUMb29BDzaRgkB5dX1QhVY1XgZ 9/UlTuCXCoRgb9qF6uM/rzMyz1O6A0Ts13tex/IbfyyScEWVSsXAg/IC2tmvpdc8HzSWti WTG6KO+bIovpYEmHY/43hxLaKja4Zak+XmPgXP4UuOoChEP6T8UojEwUph9NAA== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:39 +0200 Subject: [PATCH v12 05/15] drm/vkms: Update pixels accessor to support packed and multi-plane formats. MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-5-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=8793; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=WSLobhH0HgpInydxPdlo3xquv0fIb51hh/0x7kvEA8g=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgBLripcF+tWUZzOKYA401fce4MkNbijGkkC DyWWG2qu/iJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAQAKCRAgrS7GWxAs 4n+TD/4zdTLElq3vgh03E++B482DDfBaEta5ztE1hlN0XpVhthYw7yDH8OfxkdX0X5PgawybHx3 V2GlY9vdVPrbRf7NiREj2sd0FkzgW6cifKcKgCEtTHMDI/BVOF1N8L6n+Kb2OmjiKHvs1sObJ29 2s9AKLbc+h9V/gq6mcT2tB+fVDZvIJWt3NkFHN7WRfseJ6k5+0zSHI/8x2LaRZppXPrpspM3L0i ZqQ6djDSwoLfYDNm0JyZABpgL7rV0CFWJYMp0JCE3yqCS3GiFrsHycdMcG8+VppBmQTslChu1oh krWP/JGSvKH9R1EMVnf7WXNT5+SSyFCnTlQfoMGxFn1+U/s7XFvbPxvjIgx9vK7lbUe8ADSUn1f ceBoem7eJujUB3ib7Sd0Qpf+Rt2pj+MpjV1h7iBzQKBEwt4hTTBvTfIGKluahxx40/3mMlObENi B8AgK0RqEyKmQHJ3Dcx08E/pjR4VeUDxEqKyPbhSgSms/wtQ6sFyEsa6Kx+ZQ1vTtyYsCIAJ8zm D30dL19RxKt69QZgP2oECoNqtt76T/o22XKw6+pu2wewSiAuomM4lsMPkwq9SriF//TJaoYzfPL /SN4hxYQBfDfUFvu9f+8XAvsJNpVX5tLp/6c2ETfImq6BUYGHY8wvAE+s8Sh5qhhJlAg66wcSNR zVenD89Yolas7sQ== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Introduce the usage of block_h/block_w to compute the offset and the pointer of a pixel. The previous implementation was specialized for planes with block_h == block_w == 1. To avoid confusion and allow easier implementation of tiled formats. It also remove the usage of the deprecated format field `cpp`. Introduce the plane_index parameter to get an offset/pointer on a different plane. Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_formats.c | 114 ++++++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 06aef5162529..7f932d42394d 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -10,22 +10,46 @@ #include "vkms_formats.h" /** - * pixel_offset() - Get the offset of the pixel at coordinates x/y in the first plane + * packed_pixels_offset() - Get the offset of the block containing the pixel at coordinates x/y * * @frame_info: Buffer metadata * @x: The x coordinate of the wanted pixel in the buffer * @y: The y coordinate of the wanted pixel in the buffer + * @plane_index: The index of the plane to use + * @offset: The returned offset inside the buffer of the block + * @rem_x: The returned X coordinate of the requested pixel in the block + * @rem_y: The returned Y coordinate of the requested pixel in the block * - * The caller must ensure that the framebuffer associated with this request uses a pixel format - * where block_h == block_w == 1. - * If this requirement is not fulfilled, the resulting offset can point to an other pixel or - * outside of the buffer. + * As some pixel formats store multiple pixels in a block (DRM_FORMAT_R* for example), some + * pixels are not individually addressable. This function return 3 values: the offset of the + * whole block, and the coordinate of the requested pixel inside this block. + * For example, if the format is DRM_FORMAT_R1 and the requested coordinate is 13,5, the offset + * will point to the byte 5*pitches + 13/8 (second byte of the 5th line), and the rem_x/rem_y + * coordinates will be (13 % 8, 5 % 1) = (5, 0) + * + * With this function, the caller just have to extract the correct pixel from the block. */ -static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int y) +static void packed_pixels_offset(const struct vkms_frame_info *frame_info, int x, int y, + int plane_index, int *offset, int *rem_x, int *rem_y) { struct drm_framebuffer *fb = frame_info->fb; + const struct drm_format_info *format = frame_info->fb->format; + /* Directly using x and y to multiply pitches and format->ccp is not sufficient because + * in some formats a block can represent multiple pixels. + * + * Dividing x and y by the block size allows to extract the correct offset of the block + * containing the pixel. + */ - return fb->offsets[0] + (y * fb->pitches[0]) + (x * fb->format->cpp[0]); + int block_x = x / drm_format_info_block_width(format, plane_index); + int block_y = y / drm_format_info_block_height(format, plane_index); + int block_pitch = fb->pitches[plane_index] * drm_format_info_block_height(format, + plane_index); + *rem_x = x % drm_format_info_block_width(format, plane_index); + *rem_y = y % drm_format_info_block_height(format, plane_index); + *offset = fb->offsets[plane_index] + + block_y * block_pitch + + block_x * format->char_per_block[plane_index]; } /** @@ -35,30 +59,71 @@ static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int * @frame_info: Buffer metadata * @x: The x (width) coordinate inside the plane * @y: The y (height) coordinate inside the plane + * @plane_index: The index of the plane + * @addr: The returned pointer + * @rem_x: The returned X coordinate of the requested pixel in the block + * @rem_y: The returned Y coordinate of the requested pixel in the block * - * Takes the information stored in the frame_info, a pair of coordinates, and - * returns the address of the first color channel. - * This function assumes the channels are packed together, i.e. a color channel - * comes immediately after another in the memory. And therefore, this function - * doesn't work for YUV with chroma subsampling (e.g. YUV420 and NV21). + * Takes the information stored in the frame_info, a pair of coordinates, and returns the address + * of the block containing this pixel and the pixel position inside this block. * - * The caller must ensure that the framebuffer associated with this request uses a pixel format - * where block_h == block_w == 1, otherwise the returned pointer can be outside the buffer. + * See @packed_pixel_offset for details about rem_x/rem_y behavior. */ -static void *packed_pixels_addr(const struct vkms_frame_info *frame_info, - int x, int y) +static void packed_pixels_addr(const struct vkms_frame_info *frame_info, + int x, int y, int plane_index, u8 **addr, int *rem_x, + int *rem_y) { - size_t offset = pixel_offset(frame_info, x, y); + int offset; - return (u8 *)frame_info->map[0].vaddr + offset; + packed_pixels_offset(frame_info, x, y, plane_index, &offset, rem_x, rem_y); + *addr = (u8 *)frame_info->map[0].vaddr + offset; } -static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y) +/** + * packed_pixels_addr_1x1() - Get the pointer to the block containing the pixel at the given + * coordinates + * + * @frame_info: Buffer metadata + * @x: The x (width) coordinate inside the plane + * @y: The y (height) coordinate inside the plane + * @plane_index: The index of the plane + * @addr: The returned pointer + * + * This function can only be used with format where block_h == block_w == 1. + */ +static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info, + int x, int y, int plane_index, u8 **addr) +{ + int offset, rem_x, rem_y; + + WARN_ONCE(drm_format_info_block_width(frame_info->fb->format, + plane_index) != 1, + "%s() only support formats with block_w == 1", __func__); + WARN_ONCE(drm_format_info_block_height(frame_info->fb->format, + plane_index) != 1, + "%s() only support formats with block_h == 1", __func__); + + packed_pixels_offset(frame_info, x, y, plane_index, &offset, &rem_x, + &rem_y); + *addr = (u8 *)frame_info->map[0].vaddr + offset; +} + +static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y, + int plane_index) { int x_src = frame_info->src.x1 >> 16; int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16); + u8 *addr; + int rem_x, rem_y; + + WARN_ONCE(drm_format_info_block_width(frame_info->fb->format, plane_index) != 1, + "%s() only support formats with block_w == 1", __func__); + WARN_ONCE(drm_format_info_block_height(frame_info->fb->format, plane_index) != 1, + "%s() only support formats with block_h == 1", __func__); - return packed_pixels_addr(frame_info, x_src, y_src); + packed_pixels_addr(frame_info, x_src, y_src, plane_index, &addr, &rem_x, &rem_y); + + return addr; } static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x) @@ -152,14 +217,14 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state { struct pixel_argb_u16 *out_pixels = stage_buffer->pixels; struct vkms_frame_info *frame_info = plane->frame_info; - u8 *src_pixels = get_packed_src_addr(frame_info, y); + u8 *src_pixels = get_packed_src_addr(frame_info, y, 0); int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels); for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) { int x_pos = get_x_position(frame_info, limit, x); if (drm_rotation_90_or_270(frame_info->rotation)) - src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1) + src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1, 0) + frame_info->fb->format->cpp[0] * y; plane->pixel_read(src_pixels, &out_pixels[x_pos]); @@ -250,7 +315,10 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, { struct vkms_frame_info *frame_info = &wb->wb_frame_info; int x_dst = frame_info->dst.x1; - u8 *dst_pixels = packed_pixels_addr(frame_info, x_dst, y); + u8 *dst_pixels; + int rem_x, rem_y; + + packed_pixels_addr(frame_info, x_dst, y, 0, &dst_pixels, &rem_x, &rem_y); struct pixel_argb_u16 *in_pixels = src_buffer->pixels; int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), src_buffer->n_pixels); From patchwork Mon Oct 7 16:10:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824997 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id CA9ECCFB449 for ; Mon, 7 Oct 2024 16:11:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 28C2310E3CA; Mon, 7 Oct 2024 16:10:58 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="JVGZINUw"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3AD4210E3CD for ; Mon, 7 Oct 2024 16:10:55 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id B6B4340007; Mon, 7 Oct 2024 16:10:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317453; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4ep0B8W0dWDgOAnvfxKLWEqaGgJI444n/Y1F+rhWVIA=; b=JVGZINUwsUyvq860fyiPERgQV4lptjOi2IlvBKgSx3Fi8gQEuoe63LZkJQyjgrTlYLAZmR 36/Y4ToggUBPRXElK//kdPcIq8jbVmt23MoVtwbwS2vHsLGFDRYXF++KvlSSLN7jAEK6Gy 6/9iK1bYH19lTg85ho2WFA78RMEcf1fsPFKOPwqUwoyfXgiyIliy1HQbPrcypVSPzK6338 ePTKMn/j/AuTgau9gGZucEWmqZvN3n6d/3RLkSQ2l/kFiqP4W2Xb90G7zNwlOttfAkAAo9 gGlRt9YT2OYaiRuSneG1Ma8/0kKNn4oqnXENlhGoMaktdrNNgpxHURUdxXnILw== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:40 +0200 Subject: [PATCH v12 06/15] drm/vkms: Avoid computing blending limits inside pre_mul_alpha_blend MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-6-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=4077; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=JEfqJm+ZjNrd0HRCXf+3IpbuUc2vRJzj0Cqmn8I4SPA=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgBt5AsuMXL2U31rRTzeQdXJBT1uym75lTsK aAwDwVwwJuJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAQAKCRAgrS7GWxAs 4kx+EACOSCCqecOLfDx0E27nI/XSQbAPslmPAOce4kF/oGdGeuvXNXaheZpD3Z7NtwA31N5fgF7 Z5ATWLwb255CZmxEIfbguwmt0623Vb1jv1rb4f+lKWy/4mXKtM6dMaM1R7Hzezf5YdCapcq450i l5MNM8KMcwAa7lh7bC7JQh+yB9SRr16hKmcI3Dme2LdoAR2o+CfVeKELV7pEk3PEwZUR0JDhKel evdyAN5+4qX9dwlytfreDMHxOD2MSY79oARPUPG4QrQMYsoHxRaQd3u6x5Z1eQP3U/wOdJwjAo9 +XD1SCRcmPW2CndM7Hrr+pA9sWTJWICpUdPu/tnss81Q08c2rg2hoBCDUbHID9rjXH9hu4/c6Bf /p7uhVId+Hsv6FqyyAfvCQqmLv9lgIVhTekQS1WgK0gxb4jv5rWIxn8GgC/VnYTVUAVivXOD9e1 e/76UyFHb3/p7RJ+urYtZLc1lwRJbNXpqhB7LtjYJnzkybchk2FJpWTbpeBgLDDql6skP7RkfVf eORGQrXiGU7InWv7vEZyIYgDIe164wsgteVukc/oYVeRU45y3qiHOE7zwqlozIpgsioIj9XDuUN /GooZVr28Y31O8JiV99vJ1YDEY1s1PGYdEHGh0KHyhbFoUgBsqdYk9f+elGSy8vXZQ4udfhkiP7 7ndSMdvjjtLgv6w== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The pre_mul_alpha_blend is dedicated to blending, so to avoid mixing different concepts (coordinate calculation and color management), extract the x_limit and x_dst computation outside of this helper. It also increases the maintainability by grouping the computation related to coordinates in the same place: the loop in `blend`. Reviewed-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_composer.c | 40 +++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 931e214b225c..ecac0bc858a0 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -24,34 +24,30 @@ static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha) /** * pre_mul_alpha_blend - alpha blending equation - * @frame_info: Source framebuffer's metadata * @stage_buffer: The line with the pixels from src_plane * @output_buffer: A line buffer that receives all the blends output + * @x_start: The start offset + * @pixel_count: The number of pixels to blend * - * Using the information from the `frame_info`, this blends only the - * necessary pixels from the `stage_buffer` to the `output_buffer` - * using premultiplied blend formula. + * The pixels [0;@pixel_count) in stage_buffer are blended at [@x_start;@x_start+@pixel_count) in + * output_buffer. * * The current DRM assumption is that pixel color values have been already * pre-multiplied with the alpha channel values. See more * drm_plane_create_blend_mode_property(). Also, this formula assumes a * completely opaque background. */ -static void pre_mul_alpha_blend(struct vkms_frame_info *frame_info, - struct line_buffer *stage_buffer, - struct line_buffer *output_buffer) +static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer, + struct line_buffer *output_buffer, int x_start, int pixel_count) { - int x_dst = frame_info->dst.x1; - struct pixel_argb_u16 *out = output_buffer->pixels + x_dst; - struct pixel_argb_u16 *in = stage_buffer->pixels; - int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), - stage_buffer->n_pixels); - - for (int x = 0; x < x_limit; x++) { - out[x].a = (u16)0xffff; - out[x].r = pre_mul_blend_channel(in[x].r, out[x].r, in[x].a); - out[x].g = pre_mul_blend_channel(in[x].g, out[x].g, in[x].a); - out[x].b = pre_mul_blend_channel(in[x].b, out[x].b, in[x].a); + struct pixel_argb_u16 *out = &output_buffer->pixels[x_start]; + const struct pixel_argb_u16 *in = stage_buffer->pixels; + + for (int i = 0; i < pixel_count; i++) { + out[i].a = (u16)0xffff; + out[i].r = pre_mul_blend_channel(in[i].r, out[i].r, in[i].a); + out[i].g = pre_mul_blend_channel(in[i].g, out[i].g, in[i].a); + out[i].b = pre_mul_blend_channel(in[i].b, out[i].b, in[i].a); } } @@ -183,7 +179,7 @@ static void blend(struct vkms_writeback_job *wb, { struct vkms_plane_state **plane = crtc_state->active_planes; u32 n_active_planes = crtc_state->num_active_planes; - int y_pos; + int y_pos, x_dst, pixel_count; const struct pixel_argb_u16 background_color = { .a = 0xffff }; @@ -201,14 +197,16 @@ static void blend(struct vkms_writeback_job *wb, /* The active planes are composed associatively in z-order. */ for (size_t i = 0; i < n_active_planes; i++) { + x_dst = plane[i]->frame_info->dst.x1; + pixel_count = min_t(int, drm_rect_width(&plane[i]->frame_info->dst), + (int)stage_buffer->n_pixels); y_pos = get_y_pos(plane[i]->frame_info, y); if (!check_limit(plane[i]->frame_info, y_pos)) continue; vkms_compose_row(stage_buffer, plane[i], y_pos); - pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer, - output_buffer); + pre_mul_alpha_blend(stage_buffer, output_buffer, x_dst, pixel_count); } apply_lut(crtc_state, output_buffer); From patchwork Mon Oct 7 16:10:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824996 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id CBBA7CFB44C for ; Mon, 7 Oct 2024 16:10:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 19BB110E3D1; Mon, 7 Oct 2024 16:10:58 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="C1yJQJDI"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7055110E3CA for ; Mon, 7 Oct 2024 16:10:56 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id F13614000A; Mon, 7 Oct 2024 16:10:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317455; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HS73Q9u/CO9V5UFHw6JF8KtX8PR0vVMp8vVwY3wchRg=; b=C1yJQJDImHiieGPxrxMjfi7S9crbuLPn+DA1hXGyq7Ie/ZFOY4jUIoNiBDheuHl2GZF0Dc Okvtik3DoHrcIgb4sEmXntIYnmkTrXAqsyupDC99ke3Puv1B3SxodjqmuV2zng0e6XZnX/ zLfY/9b3wtrGz0fKQ6ujRXKVv8F9rzSsoJBnN68uKQHV0rB7wF7sedNk9MAobsFKo+N+1c RiO40yNygVYbNvu5bLe0hu78yIcZLHu7l2+zdK/7GfVsJ13IBDQ3TP7R0U4/iybeplElDb 7oiCX8pchDAnNc7vt5dF7KrWMPm3+dI6gU8pA0bwBv13remb0qeh3VXNbXHpNA== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:41 +0200 Subject: [PATCH v12 07/15] drm/vkms: Introduce pixel_read_direction enum MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-7-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=5166; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=Vb06RFIRfonrOTvoMJ7RFvbtWNOyLYGq/naTy6kIeM4=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgB4zXCbdOc9WWJjcOJYrxkU90zFOtCJMmcN zX4xAw3mUuJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAQAKCRAgrS7GWxAs 4hRVD/9Kqx86wzBAkLM6sA/l2Rhy1sl2eE/c2KHO4YbNFI3i7dZtnxhkVKdkE2xwM1yAd1PUtnf sJJ1rpaqIvIlElM8JcpEDcrTGKsBqAa2cpzyXVNWB0QZ4NX7bV/veex07QznRCw+z5sTW1WIb+i YAcWIycHDaXO9bD4SmEEnMDgzihNQyspUrshcM9CMd+SreGHY4E4vdgD06dNBbWDcI9ky3y5RjS R+pMpEyrHmPKZvvfladccn6sMb5PVHXUoerPO9YXfsiZdTQUeUBONtZXZLA+Q7JQTSEdo/GzBYp CBPLcz+Ovkz7kC+yZpbpByDT6RlSkABSQ0iAbALdR36wRv8GkuEnCa2V+SefU6gpMfJNeEFGgPh DZCgZNyIZ/nLJtzDMKgzg6K+9P14+P3e3+yk50OcrJp+73ido1zML8V/N7AeMNZ+zmIgrdVtpjN zD0Biw2VntM6Zi/mm6S2TF3aVFcs/11gsU59+GOnkfDURC+mAfRZcX8p83cEaWhr6hkRVrld6Cj LclLralpKDDzPMtgGyHeFzBcjHRHd19ElB9TMnaboUYi0j7fRKNgtZKJnKiFYWXV4qqtPxjwNmc z6lyeTVwlO+XtOjRSqZ3GRmo7VVXKKMzIiQkwhJU5YZA7X+Qobb2UTbHgJmTODsvPeg5aAogRQH KCGbkLrV4stspYw== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The pixel_read_direction enum is useful to describe the reading direction in a plane. It avoids using the rotation property of DRM, which not practical to know the direction of reading. This patch also introduce two helpers, one to compute the pixel_read_direction from the DRM rotation property, and one to compute the step, in byte, between two successive pixel in a specific direction. Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_composer.c | 44 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.h | 11 +++++++++ drivers/gpu/drm/vkms/vkms_formats.c | 32 ++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index ecac0bc858a0..601e33431b45 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -159,6 +159,50 @@ static void apply_lut(const struct vkms_crtc_state *crtc_state, struct line_buff } } +/** + * direction_for_rotation() - Get the correct reading direction for a given rotation + * + * @rotation: Rotation to analyze. It correspond the field @frame_info.rotation. + * + * This function will use the @rotation setting of a source plane to compute the reading + * direction in this plane which correspond to a "left to right writing" in the CRTC. + * For example, if the buffer is reflected on X axis, the pixel must be read from right to left + * to be written from left to right on the CRTC. + */ +static enum pixel_read_direction direction_for_rotation(unsigned int rotation) +{ + struct drm_rect tmp_a, tmp_b; + int x, y; + + /* + * Points A and B are depicted as zero-size rectangles on the CRTC. + * The CRTC writing direction is from A to B. The plane reading direction + * is discovered by inverse-transforming A and B. + * The reading direction is computed by rotating the vector AB (top-left to top-right) in a + * 1x1 square. + */ + + tmp_a = DRM_RECT_INIT(0, 0, 0, 0); + tmp_b = DRM_RECT_INIT(1, 0, 0, 0); + drm_rect_rotate_inv(&tmp_a, 1, 1, rotation); + drm_rect_rotate_inv(&tmp_b, 1, 1, rotation); + + x = tmp_b.x1 - tmp_a.x1; + y = tmp_b.y1 - tmp_a.y1; + + if (x == 1 && y == 0) + return READ_LEFT_TO_RIGHT; + else if (x == -1 && y == 0) + return READ_RIGHT_TO_LEFT; + else if (y == 1 && x == 0) + return READ_TOP_TO_BOTTOM; + else if (y == -1 && x == 0) + return READ_BOTTOM_TO_TOP; + + WARN_ONCE(true, "The inverse of the rotation gives an incorrect direction."); + return READ_LEFT_TO_RIGHT; +} + /** * blend - blend the pixels from all planes and compute crc * @wb: The writeback frame buffer metadata diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 3f45290a0c5d..777b7bd91f27 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -69,6 +69,17 @@ struct vkms_writeback_job { pixel_write_t pixel_write; }; +/** + * enum pixel_read_direction - Enum used internaly by VKMS to represent a reading direction in a + * plane. + */ +enum pixel_read_direction { + READ_BOTTOM_TO_TOP, + READ_TOP_TO_BOTTOM, + READ_RIGHT_TO_LEFT, + READ_LEFT_TO_RIGHT +}; + /** * typedef pixel_read_t - These functions are used to read a pixel in the source frame, * convert it to `struct pixel_argb_u16` and write it to @out_pixel. diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 7f932d42394d..d0e7dfc1f0d3 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -79,6 +79,38 @@ static void packed_pixels_addr(const struct vkms_frame_info *frame_info, *addr = (u8 *)frame_info->map[0].vaddr + offset; } +/** + * get_block_step_bytes() - Common helper to compute the correct step value between each pixel block + * to read in a certain direction. + * + * @fb: Framebuffer to iter on + * @direction: Direction of the reading + * @plane_index: Plane to get the step from + * + * As the returned count is the number of bytes between two consecutive blocks in a direction, + * the caller may have to read multiple pixels before using the next one (for example, to read from + * left to right in a DRM_FORMAT_R1 plane, each block contains 8 pixels, so the step must be used + * only every 8 pixels). + */ +static int get_block_step_bytes(struct drm_framebuffer *fb, enum pixel_read_direction direction, + int plane_index) +{ + switch (direction) { + case READ_LEFT_TO_RIGHT: + return fb->format->char_per_block[plane_index]; + case READ_RIGHT_TO_LEFT: + return -fb->format->char_per_block[plane_index]; + case READ_TOP_TO_BOTTOM: + return (int)fb->pitches[plane_index] * drm_format_info_block_width(fb->format, + plane_index); + case READ_BOTTOM_TO_TOP: + return -(int)fb->pitches[plane_index] * drm_format_info_block_width(fb->format, + plane_index); + } + + return 0; +} + /** * packed_pixels_addr_1x1() - Get the pointer to the block containing the pixel at the given * coordinates From patchwork Mon Oct 7 16:10:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824999 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 8FFB6CFB44B for ; Mon, 7 Oct 2024 16:11:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9539E10E3CF; Mon, 7 Oct 2024 16:10:59 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="FD4ctT9R"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8B1ED10E3CA for ; Mon, 7 Oct 2024 16:10:57 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 2EF364000C; Mon, 7 Oct 2024 16:10:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317456; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6MQnfX9Qj8kXj7/eV4BSo8hbAMVGNYYB5iM9DWW1nkg=; b=FD4ctT9RSrzw/yk4MqMkYguL07TUVqKsDtW10kpVQQxJZBG1HFiaLodrx+22lOvQ6rlq2J NsDtqQfeABO16PMNuceaZHICv5njVIHgtRcR0WBG9cC+h0f9DQwfPGxhKy+uM6vGhafu2e BIf3n06GIxXAKgo9rRkvEPGQK+NNEhngCXqRNKcaW9i/WXhwdV+7xUJN2DgLaBSvHLSGda dXIUy04iCD2/o7d6YGsUnpfBaoWKXm20n+hPFhB1zVhoFQCmfwWZ9X6d/pN51HaoOoS2JJ hpmIBJRhbCeJOF0lY6SCi3rOLNmd9nlrCq78ME1N5dfrfsncrWXkHZ78LwPBLg== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:42 +0200 Subject: [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-8-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=30285; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=/Y9VMlVfq5UJNHiiDgUCeQG11WYbql4tu9XB1HLK2cA=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgCeg6iDRtJ1XF8LPUCLaxgVugQy9Vjxc7wL uhVTVFuC1iJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAgAKCRAgrS7GWxAs 4jpAD/sHN7rgyxVkjP6B6nbL3UZix80qIwCXBMHXBbmdLJTf1rPHi038ANR3L3DaL+z9kjpGUix 3r1mGgRK0fSGIl+J6NPdqH+rhEuUnAhnR5QFpx1WzArT1C9FuQRk3DPC5dClkuXUcgQk7SUJzLK QS6W9hpVsUe95YunpXWWy721iUa4PTu1DoLIdPp9XU2YimRxuE9VfZ+SU5UQUcta4CCPu180vGl 1PN7qtRTErHk466rumYZrskH3TMyFBYhkyc9l0VzGZeF+xrTCja74a1hux60bzBz5NNGH0JftT/ U7/Z4/UI2hH9EqfZp0mrQC9DVvua9Xmnp5nKC0B5GlhvO1xds0PoW9m3o//ZmqbT3TKlK/yUamE lthNZPSm8/rLGnrq0IXcpzsoGC+L8yEHsupvT6fYr5GD2n+3GwnkpPJGAIz3xnU3wn+9bLx3unQ 4fMzGcruCEzisMPQBiIxP61D3naqngaaTgGYzmx5+SJhEer0pV+lUu4ugxeKqzL4Zk1rlOTfJyL ZbhVMuuZizpCI9d7aZHZPKnTmyiA6edSkJcEJ2YYyQyDgCJoV9ew8mLtvyb6Azaasy8Vp1R6Hem 8ok1N8mHt61M1yEVVI/0AqMsD44A1OOjSDVL0dq+ID7vhPyfQAg0+89uTqq1B8+jjkUqgwwg4/4 l976pA045KxFtWg== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Re-introduce a line-by-line composition algorithm for each pixel format. This allows more performance by not requiring an indirection per pixel read. This patch is focused on readability of the code. Line-by-line composition was introduced by [1] but rewritten back to pixel-by-pixel algorithm in [2]. At this time, nobody noticed the impact on performance, and it was merged. This patch is almost a revert of [2], but in addition efforts have been made to increase readability and maintainability of the rotation handling. The blend function is now divided in two parts: - Transformation of coordinates from the output referential to the source referential - Line conversion and blending Most of the complexity of the rotation management is avoided by using drm_rect_* helpers. The remaining complexity is around the clipping, to avoid reading/writing outside source/destination buffers. The pixel conversion is now done line-by-line, so the read_pixel_t was replaced with read_pixel_line_t callback. This way the indirection is only required once per line and per plane, instead of once per pixel and per plane. The read_line_t callbacks are very similar for most pixel format, but it is required to avoid performance impact. Some helpers for color conversion were introduced to avoid code repetition: - *_to_argb_u16: perform colors conversion. They should be inlined by the compiler, and they are used to avoid repetition between multiple variants of the same format (argb/xrgb and maybe in the future for formats like bgr formats). This new algorithm was tested with: - kms_plane (for color conversions) - kms_rotation_crc (for rotations of planes) - kms_cursor_crc (for translations of planes) - kms_rotation (for all rotations and formats combinations) [3] The performance gain was mesured with kms_fb_stress [4] with some modification to fix the writeback format. The performance improvement is around 5 to 10%. [1]: commit 8ba1648567e2 ("drm: vkms: Refactor the plane composer to accept new formats") https://lore.kernel.org/all/20220905190811.25024-7-igormtorrente@gmail.com/ [2]: commit 322d716a3e8a ("drm/vkms: isolate pixel conversion functionality") https://lore.kernel.org/all/20230418130525.128733-2-mcanal@igalia.com/ [3]: https://lore.kernel.org/igt-dev/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com/ [4]: https://lore.kernel.org/all/20240422-kms_fb_stress-dev-v5-0-0c577163dc88@riseup.net/ Signed-off-by: Louis Chauvet Acked-by: Pekka Paalanen # Conflicts: # drivers/gpu/drm/vkms/vkms_composer.c --- drivers/gpu/drm/vkms/vkms_composer.c | 234 ++++++++++++++++++++++++++++------- drivers/gpu/drm/vkms/vkms_drv.h | 28 +++-- drivers/gpu/drm/vkms/vkms_formats.c | 224 ++++++++++++++++++++------------- drivers/gpu/drm/vkms/vkms_formats.h | 2 +- drivers/gpu/drm/vkms/vkms_plane.c | 5 +- 5 files changed, 344 insertions(+), 149 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 601e33431b45..7a3e47b895a7 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -29,8 +29,8 @@ static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha) * @x_start: The start offset * @pixel_count: The number of pixels to blend * - * The pixels [0;@pixel_count) in stage_buffer are blended at [@x_start;@x_start+@pixel_count) in - * output_buffer. + * The pixels [@x_start;@x_start+@pixel_count) in stage_buffer are blended at + * [@x_start;@x_start+@pixel_count) in output_buffer. * * The current DRM assumption is that pixel color values have been already * pre-multiplied with the alpha channel values. See more @@ -41,7 +41,7 @@ static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer, struct line_buffer *output_buffer, int x_start, int pixel_count) { struct pixel_argb_u16 *out = &output_buffer->pixels[x_start]; - const struct pixel_argb_u16 *in = stage_buffer->pixels; + const struct pixel_argb_u16 *in = &stage_buffer->pixels[x_start]; for (int i = 0; i < pixel_count; i++) { out[i].a = (u16)0xffff; @@ -51,33 +51,6 @@ static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer, } } -static int get_y_pos(struct vkms_frame_info *frame_info, int y) -{ - if (frame_info->rotation & DRM_MODE_REFLECT_Y) - return drm_rect_height(&frame_info->rotated) - y - 1; - - switch (frame_info->rotation & DRM_MODE_ROTATE_MASK) { - case DRM_MODE_ROTATE_90: - return frame_info->rotated.x2 - y - 1; - case DRM_MODE_ROTATE_270: - return y + frame_info->rotated.x1; - default: - return y; - } -} - -static bool check_limit(struct vkms_frame_info *frame_info, int pos) -{ - if (drm_rotation_90_or_270(frame_info->rotation)) { - if (pos >= 0 && pos < drm_rect_width(&frame_info->rotated)) - return true; - } else { - if (pos >= frame_info->rotated.y1 && pos < frame_info->rotated.y2) - return true; - } - - return false; -} static void fill_background(const struct pixel_argb_u16 *background_color, struct line_buffer *output_buffer) @@ -203,6 +176,182 @@ static enum pixel_read_direction direction_for_rotation(unsigned int rotation) return READ_LEFT_TO_RIGHT; } +/** + * clamp_line_coordinates() - Compute and clamp the coordinate to read and write during the blend + * process. + * + * @direction: direction of the reading + * @current_plane: current plane blended + * @src_line: source line of the reading. Only the top-left coordinate is used. This rectangle + * must be rotated and have a shape of 1*pixel_count if @direction is vertical and a shape of + * pixel_count*1 if @direction is horizontal. + * @src_x_start: x start coordinate for the line reading + * @src_y_start: y start coordinate for the line reading + * @dst_x_start: x coordinate to blend the read line + * @pixel_count: number of pixels to blend + * + * This function is mainly a safety net to avoid reading outside the source buffer. As the + * userspace should never ask to read outside the source plane, all the cases covered here should + * be dead code. + */ +static void clamp_line_coordinates(enum pixel_read_direction direction, + const struct vkms_plane_state *current_plane, + const struct drm_rect *src_line, int *src_x_start, + int *src_y_start, int *dst_x_start, int *pixel_count) +{ + /* By default the start points are correct */ + *src_x_start = src_line->x1; + *src_y_start = src_line->y1; + *dst_x_start = current_plane->frame_info->dst.x1; + + /* Get the correct number of pixel to blend, it depends of the direction */ + switch (direction) { + case READ_LEFT_TO_RIGHT: + case READ_RIGHT_TO_LEFT: + *pixel_count = drm_rect_width(src_line); + break; + case READ_BOTTOM_TO_TOP: + case READ_TOP_TO_BOTTOM: + *pixel_count = drm_rect_height(src_line); + break; + } + + /* + * Clamp the coordinates to avoid reading outside the buffer + * + * This is mainly a security check to avoid reading outside the buffer, the userspace + * should never request to read outside the source buffer. + */ + switch (direction) { + case READ_LEFT_TO_RIGHT: + case READ_RIGHT_TO_LEFT: + if (*src_x_start < 0) { + *pixel_count += *src_x_start; + *dst_x_start -= *src_x_start; + *src_x_start = 0; + } + if (*src_x_start + *pixel_count > current_plane->frame_info->fb->width) + *pixel_count = max(0, (int)current_plane->frame_info->fb->width - + *src_x_start); + break; + case READ_BOTTOM_TO_TOP: + case READ_TOP_TO_BOTTOM: + if (*src_y_start < 0) { + *pixel_count += *src_y_start; + *dst_x_start -= *src_y_start; + *src_y_start = 0; + } + if (*src_y_start + *pixel_count > current_plane->frame_info->fb->height) + *pixel_count = max(0, (int)current_plane->frame_info->fb->height - + *src_y_start); + break; + } +} + +/** + * blend_line() - Blend a line from a plane to the output buffer + * + * @current_plane: current plane to work on + * @y: line to write in the output buffer + * @crtc_x_limit: width of the output buffer + * @stage_buffer: temporary buffer to convert the pixel line from the source buffer + * @output_buffer: buffer to blend the read line into. + */ +static void blend_line(struct vkms_plane_state *current_plane, int y, + int crtc_x_limit, struct line_buffer *stage_buffer, + struct line_buffer *output_buffer) +{ + int src_x_start, src_y_start, dst_x_start, pixel_count; + struct drm_rect dst_line, tmp_src, src_line; + + /* Avoid rendering useless lines */ + if (y < current_plane->frame_info->dst.y1 || + y >= current_plane->frame_info->dst.y2) + return; + + /* + * dst_line is the line to copy. The initial coordinates are inside the + * destination framebuffer, and then drm_rect_* helpers are used to + * compute the correct position into the source framebuffer. + */ + dst_line = DRM_RECT_INIT(current_plane->frame_info->dst.x1, y, + drm_rect_width(¤t_plane->frame_info->dst), + 1); + + drm_rect_fp_to_int(&tmp_src, ¤t_plane->frame_info->src); + + /* + * [1]: Clamping src_line to the crtc_x_limit to avoid writing outside of + * the destination buffer + */ + dst_line.x1 = max_t(int, dst_line.x1, 0); + dst_line.x2 = min_t(int, dst_line.x2, crtc_x_limit); + /* The destination is completely outside of the crtc. */ + if (dst_line.x2 <= dst_line.x1) + return; + + src_line = dst_line; + + /* + * Transform the coordinate x/y from the crtc to coordinates into + * coordinates for the src buffer. + * + * - Cancel the offset of the dst buffer. + * - Invert the rotation. This assumes that + * dst = drm_rect_rotate(src, rotation) (dst and src have the + * same size, but can be rotated). + * - Apply the offset of the source rectangle to the coordinate. + */ + drm_rect_translate(&src_line, -current_plane->frame_info->dst.x1, + -current_plane->frame_info->dst.y1); + drm_rect_rotate_inv(&src_line, drm_rect_width(&tmp_src), + drm_rect_height(&tmp_src), + current_plane->frame_info->rotation); + drm_rect_translate(&src_line, tmp_src.x1, tmp_src.y1); + + /* Get the correct reading direction in the source buffer. */ + + enum pixel_read_direction direction = + direction_for_rotation(current_plane->frame_info->rotation); + + /* [2]: Compute and clamp the number of pixel to read */ + clamp_line_coordinates(direction, current_plane, &src_line, &src_x_start, &src_y_start, + &dst_x_start, &pixel_count); + + if (pixel_count <= 0) { + /* Nothing to read, so avoid multiple function calls */ + return; + } + + /* + * Modify the starting point to take in account the rotation + * + * src_line is the top-left corner, so when reading READ_RIGHT_TO_LEFT or + * READ_BOTTOM_TO_TOP, it must be changed to the top-right/bottom-left + * corner. + */ + if (direction == READ_RIGHT_TO_LEFT) { + // src_x_start is now the right point + src_x_start += pixel_count - 1; + } else if (direction == READ_BOTTOM_TO_TOP) { + // src_y_start is now the bottom point + src_y_start += pixel_count - 1; + } + + /* + * Perform the conversion and the blending + * + * Here we know that the read line (x_start, y_start, pixel_count) is + * inside the source buffer [2] and we don't write outside the stage + * buffer [1]. + */ + current_plane->pixel_read_line(current_plane, src_x_start, src_y_start, direction, + pixel_count, &stage_buffer->pixels[dst_x_start]); + + pre_mul_alpha_blend(stage_buffer, output_buffer, + dst_x_start, pixel_count); +} + /** * blend - blend the pixels from all planes and compute crc * @wb: The writeback frame buffer metadata @@ -223,34 +372,25 @@ static void blend(struct vkms_writeback_job *wb, { struct vkms_plane_state **plane = crtc_state->active_planes; u32 n_active_planes = crtc_state->num_active_planes; - int y_pos, x_dst, pixel_count; const struct pixel_argb_u16 background_color = { .a = 0xffff }; - size_t crtc_y_limit = crtc_state->base.crtc->mode.vdisplay; + int crtc_y_limit = crtc_state->base.crtc->mode.vdisplay; + int crtc_x_limit = crtc_state->base.crtc->mode.hdisplay; /* * The planes are composed line-by-line to avoid heavy memory usage. It is a necessary * complexity to avoid poor blending performance. * - * The function vkms_compose_row() is used to read a line, pixel-by-pixel, into the staging - * buffer. + * The function pixel_read_line callback is used to read a line, using an efficient + * algorithm for a specific format, into the staging buffer. */ - for (size_t y = 0; y < crtc_y_limit; y++) { + for (int y = 0; y < crtc_y_limit; y++) { fill_background(&background_color, output_buffer); /* The active planes are composed associatively in z-order. */ for (size_t i = 0; i < n_active_planes; i++) { - x_dst = plane[i]->frame_info->dst.x1; - pixel_count = min_t(int, drm_rect_width(&plane[i]->frame_info->dst), - (int)stage_buffer->n_pixels); - y_pos = get_y_pos(plane[i]->frame_info, y); - - if (!check_limit(plane[i]->frame_info, y_pos)) - continue; - - vkms_compose_row(stage_buffer, plane[i], y_pos); - pre_mul_alpha_blend(stage_buffer, output_buffer, x_dst, pixel_count); + blend_line(plane[i], y, crtc_x_limit, stage_buffer, output_buffer); } apply_lut(crtc_state, output_buffer); @@ -258,7 +398,7 @@ static void blend(struct vkms_writeback_job *wb, *crc32 = crc32_le(*crc32, (void *)output_buffer->pixels, row_size); if (wb) - vkms_writeback_row(wb, output_buffer, y_pos); + vkms_writeback_row(wb, output_buffer, y); } } @@ -269,7 +409,7 @@ static int check_format_funcs(struct vkms_crtc_state *crtc_state, u32 n_active_planes = crtc_state->num_active_planes; for (size_t i = 0; i < n_active_planes; i++) - if (!planes[i]->pixel_read) + if (!planes[i]->pixel_read_line) return -1; if (active_wb && !active_wb->pixel_write) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 777b7bd91f27..067a4797f7a0 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -39,7 +39,6 @@ struct vkms_frame_info { struct drm_framebuffer *fb; struct drm_rect src, dst; - struct drm_rect rotated; struct iosys_map map[DRM_FORMAT_MAX_PLANES]; unsigned int rotation; }; @@ -80,26 +79,38 @@ enum pixel_read_direction { READ_LEFT_TO_RIGHT }; +struct vkms_plane_state; + /** - * typedef pixel_read_t - These functions are used to read a pixel in the source frame, + * typedef pixel_read_line_t - These functions are used to read a pixel line in the source frame, * convert it to `struct pixel_argb_u16` and write it to @out_pixel. * - * @in_pixel: pointer to the pixel to read - * @out_pixel: pointer to write the converted pixel + * @plane: plane used as source for the pixel value + * @x_start: X (width) coordinate of the first pixel to copy. The caller must ensure that x_start + * is non-negative and smaller than @plane->frame_info->fb->width. + * @y_start: Y (height) coordinate of the first pixel to copy. The caller must ensure that y_start + * is non-negative and smaller than @plane->frame_info->fb->height. + * @direction: direction to use for the copy, starting at @x_start/@y_start + * @count: number of pixels to copy + * @out_pixel: pointer where to write the pixel values. They will be written from @out_pixel[0] + * (included) to @out_pixel[@count] (excluded). The caller must ensure that out_pixel have a + * length of at least @count. */ -typedef void (*pixel_read_t)(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel); +typedef void (*pixel_read_line_t)(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]); /** * struct vkms_plane_state - Driver specific plane state * @base: base plane state * @frame_info: data required for composing computation - * @pixel_read: function to read a pixel in this plane. The creator of a struct vkms_plane_state - * must ensure that this pointer is valid + * @pixel_read_line: function to read a pixel line in this plane. The creator of a + * struct vkms_plane_state must ensure that this pointer is valid */ struct vkms_plane_state { struct drm_shadow_plane_state base; struct vkms_frame_info *frame_info; - pixel_read_t pixel_read; + pixel_read_line_t pixel_read_line; }; struct vkms_plane { @@ -265,7 +276,6 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name, /* Composer Support */ void vkms_composer_worker(struct work_struct *work); void vkms_set_composer(struct vkms_output *out, bool enabled); -void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y); void vkms_writeback_row(struct vkms_writeback_job *wb, const struct line_buffer *src_buffer, int y); /* Writeback */ diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index d0e7dfc1f0d3..0f6678420a11 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -140,83 +140,51 @@ static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info, *addr = (u8 *)frame_info->map[0].vaddr + offset; } -static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y, - int plane_index) -{ - int x_src = frame_info->src.x1 >> 16; - int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16); - u8 *addr; - int rem_x, rem_y; - - WARN_ONCE(drm_format_info_block_width(frame_info->fb->format, plane_index) != 1, - "%s() only support formats with block_w == 1", __func__); - WARN_ONCE(drm_format_info_block_height(frame_info->fb->format, plane_index) != 1, - "%s() only support formats with block_h == 1", __func__); - - packed_pixels_addr(frame_info, x_src, y_src, plane_index, &addr, &rem_x, &rem_y); - - return addr; -} - -static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x) -{ - if (frame_info->rotation & (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270)) - return limit - x - 1; - return x; -} - /* - * The following functions take pixel data from the buffer and convert them to the format - * ARGB16161616 in @out_pixel. + * The following functions take pixel data (a, r, g, b, pixel, ...) and convert them to + * &struct pixel_argb_u16 * - * They are used in the vkms_compose_row() function to handle multiple formats. + * They are used in the `read_line`s functions to avoid duplicate work for some pixel formats. */ -static void ARGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static struct pixel_argb_u16 argb_u16_from_u8888(u8 a, u8 r, u8 g, u8 b) { + struct pixel_argb_u16 out_pixel; /* * The 257 is the "conversion ratio". This number is obtained by the * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get * the best color value in a pixel format with more possibilities. * A similar idea applies to others RGB color conversions. */ - out_pixel->a = (u16)in_pixel[3] * 257; - out_pixel->r = (u16)in_pixel[2] * 257; - out_pixel->g = (u16)in_pixel[1] * 257; - out_pixel->b = (u16)in_pixel[0] * 257; -} + out_pixel.a = (u16)a * 257; + out_pixel.r = (u16)r * 257; + out_pixel.g = (u16)g * 257; + out_pixel.b = (u16)b * 257; -static void XRGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) -{ - out_pixel->a = (u16)0xffff; - out_pixel->r = (u16)in_pixel[2] * 257; - out_pixel->g = (u16)in_pixel[1] * 257; - out_pixel->b = (u16)in_pixel[0] * 257; + return out_pixel; } -static void ARGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static struct pixel_argb_u16 argb_u16_from_u16161616(u16 a, u16 r, u16 g, u16 b) { - __le16 *pixel = (__le16 *)in_pixel; + struct pixel_argb_u16 out_pixel; + + out_pixel.a = a; + out_pixel.r = r; + out_pixel.g = g; + out_pixel.b = b; - out_pixel->a = le16_to_cpu(pixel[3]); - out_pixel->r = le16_to_cpu(pixel[2]); - out_pixel->g = le16_to_cpu(pixel[1]); - out_pixel->b = le16_to_cpu(pixel[0]); + return out_pixel; } -static void XRGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static struct pixel_argb_u16 argb_u16_from_le16161616(__le16 a, __le16 r, __le16 g, __le16 b) { - __le16 *pixel = (__le16 *)in_pixel; - - out_pixel->a = (u16)0xffff; - out_pixel->r = le16_to_cpu(pixel[2]); - out_pixel->g = le16_to_cpu(pixel[1]); - out_pixel->b = le16_to_cpu(pixel[0]); + return argb_u16_from_u16161616(le16_to_cpu(a), le16_to_cpu(r), le16_to_cpu(g), + le16_to_cpu(b)); } -static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel) { - __le16 *pixel = (__le16 *)in_pixel; + struct pixel_argb_u16 out_pixel; s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31)); s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63)); @@ -226,40 +194,120 @@ static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pi s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f); s64 fp_b = drm_int2fixp(rgb_565 & 0x1f); - out_pixel->a = (u16)0xffff; - out_pixel->r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio)); - out_pixel->g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio)); - out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio)); + out_pixel.a = (u16)0xffff; + out_pixel.r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio)); + out_pixel.g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio)); + out_pixel.b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio)); + + return out_pixel; } -/** - * vkms_compose_row - compose a single row of a plane - * @stage_buffer: output line with the composed pixels - * @plane: state of the plane that is being composed - * @y: y coordinate of the row +/* + * The following functions are read_line function for each pixel format supported by VKMS. + * + * They read a line starting at the point @x_start,@y_start following the @direction. The result + * is stored in @out_pixel and in the format ARGB16161616. + * + * These functions are very repetitive, but the innermost pixel loops must be kept inside these + * functions for performance reasons. Some benchmarking was done in [1] where having the innermost + * loop factored out of these functions showed a slowdown by a factor of three. * - * This function composes a single row of a plane. It gets the source pixels - * through the y coordinate (see get_packed_src_addr()) and goes linearly - * through the source pixel, reading the pixels and converting it to - * ARGB16161616 (see the pixel_read() callback). For rotate-90 and rotate-270, - * the source pixels are not traversed linearly. The source pixels are queried - * on each iteration in order to traverse the pixels vertically. + * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/ */ -void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y) + +static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, + enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) { - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels; - struct vkms_frame_info *frame_info = plane->frame_info; - u8 *src_pixels = get_packed_src_addr(frame_info, y, 0); - int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels); + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); + + while (out_pixel < end) { + u8 *px = (u8 *)src_pixels; + *out_pixel = argb_u16_from_u8888(px[3], px[2], px[1], px[0]); + out_pixel += 1; + src_pixels += step; + } +} + +static void XRGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, + enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); + + while (out_pixel < end) { + u8 *px = (u8 *)src_pixels; + *out_pixel = argb_u16_from_u8888(255, px[2], px[1], px[0]); + out_pixel += 1; + src_pixels += step; + } +} + +static void ARGB16161616_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); + + while (out_pixel < end) { + u16 *px = (u16 *)src_pixels; + *out_pixel = argb_u16_from_u16161616(px[3], px[2], px[1], px[0]); + out_pixel += 1; + src_pixels += step; + } +} + +static void XRGB16161616_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); + + while (out_pixel < end) { + __le16 *px = (__le16 *)src_pixels; + *out_pixel = argb_u16_from_le16161616(cpu_to_le16(0xFFFF), px[2], px[1], px[0]); + out_pixel += 1; + src_pixels += step; + } +} + +static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); - for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) { - int x_pos = get_x_position(frame_info, limit, x); + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); - if (drm_rotation_90_or_270(frame_info->rotation)) - src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1, 0) - + frame_info->fb->format->cpp[0] * y; + while (out_pixel < end) { + __le16 *px = (__le16 *)src_pixels; - plane->pixel_read(src_pixels, &out_pixels[x_pos]); + *out_pixel = argb_u16_from_RGB565(px); + out_pixel += 1; + src_pixels += step; } } @@ -359,25 +407,25 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, } /** - * get_pixel_read_function() - Retrieve the correct read_pixel function for a specific + * get_pixel_read_line_function() - Retrieve the correct read_line function for a specific * format. The returned pointer is NULL for unsupported pixel formats. The caller must ensure that * the pointer is valid before using it in a vkms_plane_state. * * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) */ -pixel_read_t get_pixel_read_function(u32 format) +pixel_read_line_t get_pixel_read_line_function(u32 format) { switch (format) { case DRM_FORMAT_ARGB8888: - return &ARGB8888_to_argb_u16; + return &ARGB8888_read_line; case DRM_FORMAT_XRGB8888: - return &XRGB8888_to_argb_u16; + return &XRGB8888_read_line; case DRM_FORMAT_ARGB16161616: - return &ARGB16161616_to_argb_u16; + return &ARGB16161616_read_line; case DRM_FORMAT_XRGB16161616: - return &XRGB16161616_to_argb_u16; + return &XRGB16161616_read_line; case DRM_FORMAT_RGB565: - return &RGB565_to_argb_u16; + return &RGB565_read_line; default: /* * This is a bug in vkms_plane_atomic_check(). All the supported diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h index 3ecea4563254..8d2bef95ff79 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -5,7 +5,7 @@ #include "vkms_drv.h" -pixel_read_t get_pixel_read_function(u32 format); +pixel_read_line_t get_pixel_read_line_function(u32 format); pixel_write_t get_pixel_write_function(u32 format); diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 10e9b23dab28..8875bed76410 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -112,7 +112,6 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, frame_info = vkms_plane_state->frame_info; memcpy(&frame_info->src, &new_state->src, sizeof(struct drm_rect)); memcpy(&frame_info->dst, &new_state->dst, sizeof(struct drm_rect)); - memcpy(&frame_info->rotated, &new_state->dst, sizeof(struct drm_rect)); frame_info->fb = fb; memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map)); drm_framebuffer_get(frame_info->fb); @@ -122,10 +121,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y); - drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated), - drm_rect_height(&frame_info->rotated), frame_info->rotation); - vkms_plane_state->pixel_read = get_pixel_read_function(fmt); + vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt); } static int vkms_plane_atomic_check(struct drm_plane *plane, From patchwork Mon Oct 7 16:10:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13824998 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 596E8CFB446 for ; Mon, 7 Oct 2024 16:11:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 94A8810E3D0; Mon, 7 Oct 2024 16:11:00 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="SWkhdD1N"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id A567010E3D3 for ; Mon, 7 Oct 2024 16:10:58 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 4DCAA4000F; Mon, 7 Oct 2024 16:10:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317457; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0BsU4INOE1CHTascqSt5xwkugSRCgOxTbOYvghbcOx8=; b=SWkhdD1Noq/TnMpLyGIYwkE1taZTzB1IUEVHF8zOxIMRzch7B17FKcMLoL0FmFGoQEagt4 L84gFLk/Jbu8PjkK3yINXgOkwXu0es9rOMZhvmvfPic9AzPT6ZONdtd/LtKKebJXB+SM4B Dp5v2wBj7h1CrH8n5EIdxZrJB2X4bienUSJ2eKO6L48kmy266umfaxAboP/YCLNAfc4VCG scyGf7BQYJeDuiFcIjSvBYJ2hx6C8LgFZNj/5633c6pfEuaCrQ+bdi05J9b2ox6HvQ36Ym ZQAmU9RKoy/uU+Ohs4x3UfHacciC5iyf9zeCBZL98dCxDZZtcKYAtI5/UfAwjg== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:43 +0200 Subject: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-9-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=1084; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=PFGhswxeEmLZHlnqofeGdDJ2SDZWzjkoeeHK9t5I21Y=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgC3LnWqr3zY/IDAl7m5lcqwe0RZYXrq/YdS TAmMeF+QBOJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAgAKCRAgrS7GWxAs 4ujjD/0RwacmovX0q32XNvaQZ5P5o1CyOaB8ZeyB6TjnnrpD/zUhrWK6ptEmeRgDgiSz4ochFsO 8cyh5k0zscYUIQL0mrU7XR9HfGYjqC/1V1AR+giimaH+MgnplyYwtB9a6ahRcyMc000HxZddbIZ TzXC7Krrpshe4PndqOewj/m8H+wXay70uFXdhKuAu4//eMHeAUnNNY+hVKsYGtn9kgGGFloGWRi EKDMhGd43x/nmeHdJLE33fklHC5lf6iWu9uFbKgIhB3pVCd7FbnNjMbK6cogSzaJoJSeCfrrpvA O5utSjeyBJBl6o9vHNqLhurgZ3lhpFgbVK92xAPzGjEay+CjFVfUNL2kp9ZjBMjF8B6Pow/Ig8Q uP4Le8zdp8On9REU0I3r9R8kr7zkML/J6naibbnRss39rz93xiklY0d5hSndivToKY9Zm7UWQoe NWe5IJBG7BT5Rhs5APBxbfyasFtP+TlGUTVqW3c71on1mZldEMVu6fG5etMS3aq6iuMJmk8YSqZ V0USovd/QMzPphNuy/8+U/dxseVKhMxAHNW7xe3yHTkZijo9hPQIucDaB6MU/RwczkK/3LHlFa9 a7U9zuXwggVv7Ey/m1TnizuVwLZ0H/IPVxwXJfqRygiYITC27zKu7Faf32RnceVCFVU89GEvkEK pX00Uwsg54uB+oA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" As all the rotation are now supported by VKMS, this simplification does not make sense anymore, so remove it. Signed-off-by: Louis Chauvet Acked-by: Maíra Canal --- drivers/gpu/drm/vkms/vkms_plane.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 8875bed76410..5a028ee96c91 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, frame_info->fb = fb; memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map)); drm_framebuffer_get(frame_info->fb); - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 | - DRM_MODE_ROTATE_90 | - DRM_MODE_ROTATE_270 | - DRM_MODE_REFLECT_X | - DRM_MODE_REFLECT_Y); - + frame_info->rotation = new_state->rotation; vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt); } From patchwork Mon Oct 7 16:10:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13825000 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 66FEDCFB449 for ; Mon, 7 Oct 2024 16:11:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A0D2D10E3D3; Mon, 7 Oct 2024 16:11:02 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="RS7UjLzB"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id B0FEE10E3D0 for ; Mon, 7 Oct 2024 16:10:59 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 5E06E4000E; Mon, 7 Oct 2024 16:10:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317458; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E+ewB+o1TUV/MnKxUQS93R8sYNjTnIcPqHEd7HUzzDc=; b=RS7UjLzBFnyv73LUZ9RCr6UOa7Dd1DwLainAAm2FmatvDIMc5vO7YtgdfG3lPnc3gg7/Yj 0/lFi2TyQUVslaRCYB0W8QSXR9GS8gv3kbQ40yf+LJL9On9gjt00AauseFukQalZBMkzML OEsrRiWurMhZvCm+grUQoa5F/C6DIBpfYD/dIkSBj0AAuuyxPn9/2KeWA9qm4JoBaM0/9F MPBO3Z5alM1EyaIHXqg+HbWOHKDdCJUTBXwZD7fT9T+DUlr5Hl8xmfxGGIgl5DWqVKcNQF 9e5OL0lcmFJUZnKEBbnzvtAuU2p8UbqTQsyCW9AXor+w8+JeUifihh91g4o+qQ== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:44 +0200 Subject: [PATCH v12 10/15] drm/vkms: Add YUV support MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-10-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=18658; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=zav+Axt44VBl9P3bilXYbm+zuORh48tSxwBRSlZoU+I=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgCwGMawm6TvFolmMkrX76N6r99CP6WG9LCg 9sf0IMM1ziJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAgAKCRAgrS7GWxAs 4guDEADCi+veR9nCQw8w9dbrzKka2uxXImAEp9iOxH8IjttMuB8MYmuAVtwqsHYTXZTNKGf3hPB gzAhAN8GZFMZDE5arleTfkE/SBD1cMP0WdGiC4Fckq1p5oTgiLNbaI5RuhabbWl2T3ry8hiTVQr +7Xq7sC24cps2E0j4XVHkOcBPkOXVZJODUToetuKKhXusFQ8SbmEnMV0+K2dlwxWw3bxuxFilZD 3R4X/E/BTv6Ju7pn6jMEKRR87O31IvJ27kbRD/ruwL2N5VbB4dqyopZxlUsfOZTqLQ8wCnBIpat 82Q+lRTsIVytPPmCKBxAeSSJyGsuR+gC9+MlsEppWGGgoaAL7Lb9MZrgL53hJip/eCWaHlxwxyO Y5byBIZwPRhT/mO4e49XsZyns/3aAYhuHMRweJOKnkAXRG7F2PRF48PxKgBof0A8jqk3FZSgkND GSxFUdvUTjRZx32D0eocN0ncYWItkFX2TxkZuSB5ohHdwoEICqH9vT8wr/4Px5ZcpF2WRfWPBHz 1qx88q/ezKZVLcnPQRy1njVIxJyY8WwHIpg3L689nG4PAd4mEwKYU+sZo+1E0SS13SJ6I1TxDi0 thvDwpe5voDyXYkd+VrvwrktUmloSqNGVloLOSDmLvGR1bnR9ehhfBeUyGpYIN75TAal1Un9dlS d3G1ApDgJVge2vw== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Add support to the YUV formats bellow: - NV12/NV16/NV24 - NV21/NV61/NV42 - YUV420/YUV422/YUV444 - YVU420/YVU422/YVU444 The conversion from yuv to rgb is done with fixed-point arithmetic, using 32.32 fixed-point numbers and the drm_fixed helpers. To do the conversion, a specific matrix must be used for each color range (DRM_COLOR_*_RANGE) and encoding (DRM_COLOR_*). This matrix is stored in the `conversion_matrix` struct, along with the specific y_offset needed. This matrix is queried only once, in `vkms_plane_atomic_update` and stored in a `vkms_plane_state`. Those conversion matrices of each encoding and range were obtained by rounding the values of the original conversion matrices multiplied by 2^32. This is done to avoid the use of floating point operations. The same reading function is used for YUV and YVU formats. As the only difference between those two category of formats is the order of field, a simple swap in conversion matrix columns allows using the same function. Signed-off-by: Arthur Grillo [Louis Chauvet: - Adapted Arthur's work - Implemented the read_line_t callbacks for yuv - add struct conversion_matrix - store the whole conversion_matrix in the plane state - remove struct pixel_yuv_u8 - update the commit message - Merge the modifications from Arthur] Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_drv.h | 18 ++ drivers/gpu/drm/vkms/vkms_formats.c | 353 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_formats.h | 4 + drivers/gpu/drm/vkms/vkms_plane.c | 16 +- 4 files changed, 390 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 067a4797f7a0..337ca3f39cd2 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -100,17 +100,35 @@ typedef void (*pixel_read_line_t)(const struct vkms_plane_state *plane, int x_st int y_start, enum pixel_read_direction direction, int count, struct pixel_argb_u16 out_pixel[]); +/** + * struct conversion_matrix - Matrix to use for a specific encoding and range + * + * @matrix: Conversion matrix from yuv to rgb. The matrix is stored in a row-major manner and is + * used to compute rgb values from yuv values: + * [[r],[g],[b]] = @matrix * [[y],[u],[v]] + * OR for yvu formats: + * [[r],[g],[b]] = @matrix * [[y],[v],[u]] + * The values of the matrix are signed fixed-point values with 32 bits fractional part. + * @y_offset: Offset to apply on the y value. + */ +struct conversion_matrix { + s64 matrix[3][3]; + int y_offset; +}; + /** * struct vkms_plane_state - Driver specific plane state * @base: base plane state * @frame_info: data required for composing computation * @pixel_read_line: function to read a pixel line in this plane. The creator of a * struct vkms_plane_state must ensure that this pointer is valid + * @conversion_matrix: matrix used for yuv formats to convert to rgb */ struct vkms_plane_state { struct drm_shadow_plane_state base; struct vkms_frame_info *frame_info; pixel_read_line_t pixel_read_line; + struct conversion_matrix conversion_matrix; }; struct vkms_plane { diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 0f6678420a11..adb1228e5201 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -140,6 +140,51 @@ static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info, *addr = (u8 *)frame_info->map[0].vaddr + offset; } +/** + * get_subsampling() - Get the subsampling divisor value on a specific direction + * + * @format: format to extarct the subsampling from + * @direction: direction of the subsampling requested + */ +static int get_subsampling(const struct drm_format_info *format, + enum pixel_read_direction direction) +{ + switch (direction) { + case READ_BOTTOM_TO_TOP: + case READ_TOP_TO_BOTTOM: + return format->vsub; + case READ_RIGHT_TO_LEFT: + case READ_LEFT_TO_RIGHT: + return format->hsub; + } + WARN_ONCE(true, "Invalid direction for pixel reading: %d\n", direction); + return 1; +} + +/** + * get_subsampling_offset() - An offset for keeping the chroma siting consistent regardless of + * x_start and y_start values + * + * @direction: direction of the reading to properly compute this offset + * @x_start: x coordinate of the starting point of the readed line + * @y_start: y coordinate of the starting point of the readed line + */ +static int get_subsampling_offset(enum pixel_read_direction direction, int x_start, int y_start) +{ + switch (direction) { + case READ_BOTTOM_TO_TOP: + return -y_start - 1; + case READ_TOP_TO_BOTTOM: + return y_start; + case READ_RIGHT_TO_LEFT: + return -x_start - 1; + case READ_LEFT_TO_RIGHT: + return x_start; + } + WARN_ONCE(true, "Invalid direction for pixel reading: %d\n", direction); + return 0; +} + /* * The following functions take pixel data (a, r, g, b, pixel, ...) and convert them to * &struct pixel_argb_u16 @@ -202,6 +247,38 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel) return out_pixel; } +static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, + const struct conversion_matrix *matrix) +{ + u16 r, g, b; + s64 fp_y, fp_channel_1, fp_channel_2; + s64 fp_r, fp_g, fp_b; + + fp_y = drm_int2fixp(((int)y - matrix->y_offset) * 257); + fp_channel_1 = drm_int2fixp(((int)channel_1 - 128) * 257); + fp_channel_2 = drm_int2fixp(((int)channel_2 - 128) * 257); + + fp_r = drm_fixp_mul(matrix->matrix[0][0], fp_y) + + drm_fixp_mul(matrix->matrix[0][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[0][2], fp_channel_2); + fp_g = drm_fixp_mul(matrix->matrix[1][0], fp_y) + + drm_fixp_mul(matrix->matrix[1][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[1][2], fp_channel_2); + fp_b = drm_fixp_mul(matrix->matrix[2][0], fp_y) + + drm_fixp_mul(matrix->matrix[2][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[2][2], fp_channel_2); + + fp_r = drm_fixp2int_round(fp_r); + fp_g = drm_fixp2int_round(fp_g); + fp_b = drm_fixp2int_round(fp_b); + + r = clamp(fp_r, 0, 0xffff); + g = clamp(fp_g, 0, 0xffff); + b = clamp(fp_b, 0, 0xffff); + + return argb_u16_from_u16161616(0xffff, r, g, b); +} + /* * The following functions are read_line function for each pixel format supported by VKMS. * @@ -311,6 +388,92 @@ static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start, } } +/* + * This callback can be used for YUV formats where U and V values are + * stored in the same plane (often called semi-planar formats). It will + * correctly handle subsampling as described in the drm_format_info of the plane. + * + * The conversion matrix stored in the @plane is used to: + * - Apply the correct color range and encoding + * - Convert YUV and YVU with the same function (a column swap is needed when setting up + * plane->conversion_matrix) + */ +static void semi_planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + u8 *y_plane; + u8 *uv_plane; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, + &y_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 1, + &uv_plane); + int step_y = get_block_step_bytes(plane->frame_info->fb, direction, 0); + int step_uv = get_block_step_bytes(plane->frame_info->fb, direction, 1); + int subsampling = get_subsampling(plane->frame_info->fb->format, direction); + int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); + const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; + + for (int i = 0; i < count; i++) { + *out_pixel = argb_u16_from_yuv888(y_plane[0], uv_plane[0], uv_plane[1], + conversion_matrix); + out_pixel += 1; + y_plane += step_y; + if ((i + subsampling_offset + 1) % subsampling == 0) + uv_plane += step_uv; + } +} + +/* + * This callback can be used for YUV format where each color component is + * stored in a different plane (often called planar formats). It will + * correctly handle subsampling as described in the drm_format_info of the plane. + * + * The conversion matrix stored in the @plane is used to: + * - Apply the correct color range and encoding + * - Convert YUV and YVU with the same function (a column swap is needed when setting up + * plane->conversion_matrix) + */ +static void planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + u8 *y_plane; + u8 *channel_1_plane; + u8 *channel_2_plane; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, + &y_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 1, + &channel_1_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 2, + &channel_2_plane); + int step_y = get_block_step_bytes(plane->frame_info->fb, direction, 0); + int step_channel_1 = get_block_step_bytes(plane->frame_info->fb, direction, 1); + int step_channel_2 = get_block_step_bytes(plane->frame_info->fb, direction, 2); + int subsampling = get_subsampling(plane->frame_info->fb->format, direction); + int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); + const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; + + for (int i = 0; i < count; i++) { + *out_pixel = argb_u16_from_yuv888(*y_plane, *channel_1_plane, *channel_2_plane, + conversion_matrix); + out_pixel += 1; + y_plane += step_y; + if ((i + subsampling_offset + 1) % subsampling == 0) { + channel_1_plane += step_channel_1; + channel_2_plane += step_channel_2; + } + } +} + /* * The following functions take one &struct pixel_argb_u16 and convert it to a specific format. * The result is stored in @out_pixel. @@ -426,6 +589,20 @@ pixel_read_line_t get_pixel_read_line_function(u32 format) return &XRGB16161616_read_line; case DRM_FORMAT_RGB565: return &RGB565_read_line; + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV24: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV42: + return &semi_planar_yuv_read_line; + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YVU444: + return &planar_yuv_read_line; default: /* * This is a bug in vkms_plane_atomic_check(). All the supported @@ -439,6 +616,182 @@ pixel_read_line_t get_pixel_read_line_function(u32 format) } } +/* + * Those matrices were generated using the colour python framework + * + * Below are the function calls used to generate each matrix, go to + * https://colour.readthedocs.io/en/develop/generated/colour.matrix_YCbCr.html + * for more info: + * + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix no_operation = { + .matrix = { + { 4294967296, 0, 0, }, + { 0, 4294967296, 0, }, + { 0, 0, 4294967296, }, + }, + .y_offset = 0, +}; + +static const struct conversion_matrix yuv_bt601_full = { + .matrix = { + { 4294967296, 0, 6021544149 }, + { 4294967296, -1478054095, -3067191994 }, + { 4294967296, 7610682049, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt601_limited = { + .matrix = { + { 5020601039, 0, 6881764740 }, + { 5020601039, -1689204679, -3505362278 }, + { 5020601039, 8697922339, 0 }, + }, + .y_offset = 16, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt709_full = { + .matrix = { + { 4294967296, 0, 6763714498 }, + { 4294967296, -804551626, -2010578443 }, + { 4294967296, 7969741314, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt709_limited = { + .matrix = { + { 5020601039, 0, 7729959424 }, + { 5020601039, -919487572, -2297803934 }, + { 5020601039, 9108275786, 0 }, + }, + .y_offset = 16, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt2020_full = { + .matrix = { + { 4294967296, 0, 6333358775 }, + { 4294967296, -706750298, -2453942994 }, + { 4294967296, 8080551471, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt2020_limited = { + .matrix = { + { 5020601039, 0, 7238124312 }, + { 5020601039, -807714626, -2804506279 }, + { 5020601039, 9234915964, 0 }, + }, + .y_offset = 16, +}; + +/** + * swap_uv_columns() - Swap u and v column of a given matrix + * + * @matrix: Matrix in which column are swapped + */ +static void swap_uv_columns(struct conversion_matrix *matrix) +{ + swap(matrix->matrix[0][2], matrix->matrix[0][1]); + swap(matrix->matrix[1][2], matrix->matrix[1][1]); + swap(matrix->matrix[2][2], matrix->matrix[2][1]); +} + +/** + * get_conversion_matrix_to_argb_u16() - Retrieve the correct yuv to rgb conversion matrix for a + * given encoding and range. + * + * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) + * @encoding: DRM_COLOR_* value for which to obtain a conversion matrix + * @range: DRM_COLOR_*_RANGE value for which to obtain a conversion matrix + * @matrix: Pointer to store the value into + */ +void get_conversion_matrix_to_argb_u16(u32 format, + enum drm_color_encoding encoding, + enum drm_color_range range, + struct conversion_matrix *matrix) +{ + const struct conversion_matrix *matrix_to_copy; + bool limited_range; + + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + limited_range = true; + break; + case DRM_COLOR_YCBCR_FULL_RANGE: + limited_range = false; + break; + case DRM_COLOR_RANGE_MAX: + limited_range = false; + WARN_ONCE(true, "The requested range is not supported."); + break; + } + + switch (encoding) { + case DRM_COLOR_YCBCR_BT601: + matrix_to_copy = limited_range ? &yuv_bt601_limited : + &yuv_bt601_full; + break; + case DRM_COLOR_YCBCR_BT709: + matrix_to_copy = limited_range ? &yuv_bt709_limited : + &yuv_bt709_full; + break; + case DRM_COLOR_YCBCR_BT2020: + matrix_to_copy = limited_range ? &yuv_bt2020_limited : + &yuv_bt2020_full; + break; + case DRM_COLOR_ENCODING_MAX: + matrix_to_copy = &no_operation; + WARN_ONCE(true, "The requested encoding is not supported."); + break; + } + + memcpy(matrix, matrix_to_copy, sizeof(*matrix_to_copy)); + + switch (format) { + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YVU444: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV42: + swap_uv_columns(matrix); + break; + default: + break; + } +} + /** * get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format. * The returned pointer is NULL for unsupported pixel formats. The caller must ensure that the diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h index 8d2bef95ff79..d583855cb320 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -9,4 +9,8 @@ pixel_read_line_t get_pixel_read_line_function(u32 format); pixel_write_t get_pixel_write_function(u32 format); +void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding, + enum drm_color_range range, + struct conversion_matrix *matrix); + #endif /* _VKMS_FORMATS_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 5a028ee96c91..d4e375913122 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -17,7 +17,19 @@ static const u32 vkms_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, - DRM_FORMAT_RGB565 + DRM_FORMAT_RGB565, + DRM_FORMAT_NV12, + DRM_FORMAT_NV16, + DRM_FORMAT_NV24, + DRM_FORMAT_NV21, + DRM_FORMAT_NV61, + DRM_FORMAT_NV42, + DRM_FORMAT_YUV420, + DRM_FORMAT_YUV422, + DRM_FORMAT_YUV444, + DRM_FORMAT_YVU420, + DRM_FORMAT_YVU422, + DRM_FORMAT_YVU444, }; static struct drm_plane_state * @@ -118,6 +130,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, frame_info->rotation = new_state->rotation; vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt); + get_conversion_matrix_to_argb_u16(fmt, new_state->color_encoding, new_state->color_range, + &vkms_plane_state->conversion_matrix); } static int vkms_plane_atomic_check(struct drm_plane *plane, From patchwork Mon Oct 7 16:10:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13825001 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 7FD3ACFB446 for ; Mon, 7 Oct 2024 16:11:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B0ABD10E3D6; Mon, 7 Oct 2024 16:11:03 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="R9/EeZDD"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id B555D10E3D3 for ; Mon, 7 Oct 2024 16:11:00 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 6E87A40011; Mon, 7 Oct 2024 16:10:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317459; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LZZXCAOt96HKPNadssGl+s0w7QDIgwJlOE/lg2YiDu4=; b=R9/EeZDDkukVZkkpMvN4WzCA52L3uu5TosmVs2Hq9zDio6+YkZ9D3dLXzwas+C7jBLX9vc OI0sApd/5ipfXGRb5L1BKGHeobr5B9VFT5Rgj9cRh5q5WPaFfQPvwBuGnynj8ZOxDA8Ck5 FOgfa9peAVbUzFLcvSRJpij3elKqNMxw6jQ7pqqCyOGe+HzyqbiHkcPgJ+VQVb1UphfhnO fdIEZrzRHMD9MFhMhBjFhZQ5ZTic9tY/yOZXvtVql+j9IPQQ4VK8gAjh/YkwsgAbfmyG6S C+Hz9l0Al2Fyw8vqNZbSwnsiwdnhUwo6jBmltCcKTViR0iuO3j5pkH6xVNfr/g== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:45 +0200 Subject: [PATCH v12 11/15] drm/vkms: Add range and encoding properties to the plane MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-11-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=1253; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=VB/TChUFVIfTCJz1NYTIIebS+nzvAngxAg3Yry+8p1o=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgDePR8EiFnnXUpBJ1MaJbk136pHLXy63awa mjQm8LrWmWJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAwAKCRAgrS7GWxAs 4lOtEADXdMkwzFU6SwIvoYVYrwUpCX5m0QEmypLUJsQNrR/XY1gYIpylS/4ofI2CoaGkFVYJyP6 CMOfZDNBh3xvvECoxYFyctUKoDLj9lYqNMUvjCVuqV6Da0HbRUzHEuDyqZlv2PJXBeaf3GT797c efML4RfFA/7QqXDtbpBHlqrAx1oXWUSxmZUwTkJhlvtP3tLdmA+RogpNVG8Bf5q61218dJ+H5KK bEQgOaOzijWSbSvddUwj9SECa6z6wLmxF8lUQa5NHsK93GFYMJGYD+5IAcXnyuAiPXCO9b6EQ5n H0M7nmsiGeEkuu5PHIC0Z69PEWih7HOrEjDWO6g0NdxMfxWYMh/P2BU1PJXbHKbG6/vv8YK70bb bmxLGLJjhPhrsjCLeQb+FI/lguNSsVEfe11p9jy913dmbnduzejB2j5v1TF+BT3XRfCpA9SEJ+W h+pojaMbh8LbkghWAOGoBYexVBi5YNAgRYX3Xo2VWxK+iEvLz3CtnVMRtLmboptm6FbT1jaOELQ myXs4cHA5Wu7RDESpkCMAUW3IoIXWojzf/gGvI8xXDkQHNl0/bHNaaqm7B19p+hn6gzmUQHdUoX QohiOFSfeywZrBpyQ5xe77+UkSPBIoDP9CcXz2iG15DnfipoSFzFTWnIk6RbWsd9yshOfJzQ6jc y0vwTh7cfj35xPg== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Now that the driver internally handles these quantization ranges and YUV encoding matrices, expose the UAPI for setting them. Signed-off-by: Arthur Grillo [Louis Chauvet: retained only relevant parts, updated the commit message] Acked-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_plane.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index d4e375913122..8f764a108b00 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -218,5 +218,14 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0, DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK); + drm_plane_create_color_properties(&plane->base, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709) | + BIT(DRM_COLOR_YCBCR_BT2020), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_FULL_RANGE); + return plane; } From patchwork Mon Oct 7 16:10:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13825003 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 2610CCFB44B for ; Mon, 7 Oct 2024 16:11:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 468ED10E3D8; Mon, 7 Oct 2024 16:11:05 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="EJG5VeHd"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id E770010E3D3 for ; Mon, 7 Oct 2024 16:11:01 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 9550640008; Mon, 7 Oct 2024 16:10:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317460; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hsQ2CTA2pljllkiENrEWMPdAOoEF3CDQQvjJFAj8G3E=; b=EJG5VeHdqibkfEsHHeUJaCQBZZwB336Y4Yae/96UlN/93JIijpUfk/wwXyvHZhUleAQrHd 6fCTX1D0rMkYm1eLDea0pzM7NzLiqSf1+eD4TsZaSQ/xbxafi2ONvhp8A7UWxNB2GWoOdw XDXVY7dZB7tpSZCefijomhLcuTgIliATaYrME//Oscc7k3Nr0Ck1FLuQNwCIofdvECVcfk Gl/FC8OIpF8ATfzrxuYzh9SRFLFhwLKzyprgOdA0Wsd1zhWqUEDivDRQBRkQuNLf5vBpyV KEFDtqrS3ZygJ8BxTo+yTNXl2yQQDOaZnWsQ1gX/Inyf43raUikMCVoMhyWhpw== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:46 +0200 Subject: [PATCH v12 12/15] drm/vkms: Drop YUV formats TODO MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-12-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=881; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=P2BW0rn/HzAIDwl58Rwi6B7V7fHRrzFFCT1b251G+Ng=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgDBR4uYZGO5txdh3vIJuJ290SkPJaRBtVsM 0SZfu4oxKiJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAwAKCRAgrS7GWxAs 4g0ZD/4l2jUUXLh+lNGvq3/zf1ZIVNEXoElmkH3U0WT66RPA7zwYPQ8oPLsg3AElGByOrNuI/y9 D491sMgq058XAnVkiEYm2jOizTQSFwZNpunbi14DXK2riPrGj0BxUgMwbixvll+EoKTRQNZJ8Nb lRLy9iPKDkDhhAzZVFPeaamDEb79Ea4G8jiBKaf+6+II5D/c+jlaBo6+yb2Fcuvb+YIsdSWyt4K 70zOv/GQL0rGyUlvG75wI/hC/xoCzlTQ65qLj2Bf7jtXPMa6GyeJM0njPKiHKRDwrvZJyaea8eM nl5gLaGANrTj7RDn4Na8WnUFTUoxY6J//jpW1kEBWmeaCPVC3SoIH/8PRB2H/5vfAz6Qgpb0MQ1 qoxZOdQ6hRmXsJ7s5pE70XURz29WXuWN21OxFW0TXGyCVDof/O+cvLolNSMk2ZBTsADcF5oXVEh On4E75gzAn/APqR7GLwya1fTqJHhmFhD/Xn2Q4Q/oAQjZNPMndWIUm/FvD5LTfsUktGGqI7KzmP zYY1GqTid7lBh93L39hLWxbVllYzCdUsTm4OMsAeXCtUHZ9fWaXXO7WWv5xOUGQoemR1JzPVklm MN/DZ9mvzk4/Nan9qL9/C0KIn9/1jliYWvjRoMaxg1cGkS0GQZsX4tGgP0phlcaHvCoPLYt/LrA Tm8OO6tKglleMxA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo VKMS has support for YUV formats now. Remove the task from the TODO list. Signed-off-by: Arthur Grillo Signed-off-by: Louis Chauvet --- Documentation/gpu/vkms.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index ba04ac7c2167..13b866c3617c 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -122,8 +122,7 @@ There's lots of plane features we could add support for: - Scaling. -- Additional buffer formats, especially YUV formats for video like NV12. - Low/high bpp RGB formats would also be interesting. +- Additional buffer formats. Low/high bpp RGB formats would be interesting. - Async updates (currently only possible on cursor plane using the legacy cursor api). From patchwork Mon Oct 7 16:10:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13825004 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id CF311CFB449 for ; Mon, 7 Oct 2024 16:11:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 04EC210E3DA; Mon, 7 Oct 2024 16:11:06 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="YoYnF5Np"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1D5C510E3D8 for ; Mon, 7 Oct 2024 16:11:02 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id A3C2240003; Mon, 7 Oct 2024 16:11:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317461; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iNGCbk5CvGMHOsDGwmLSr2ahX9fjiT+q42SPjgA0nrY=; b=YoYnF5NpiG+73U0/iUSFsL3vlNJpYAJjEH83Tm+hCFTLMyywuPBv5EdZb5W1ClTApcf8na 4+Nst5LSM0EwAj6te4mS8qEImg0bjxe4h0rhy3tlSUkK/GHR41HmxFcsX9noVc44WWrOPg /G6BndfPlHnvTzCvruDBuJMGj40AsludxhWBA1W2sgq0vG6zvKHcUziefeLbV4HRPldehC rBUlAbYIZxRRbY0Zq/Q2l1TNzFGOtzrnJNSZ9CrzxvUK5uiDVENq3lLog0PvBNkU7IdXfK dILID9qk8CbE8uaplNvbHuhDdcROnwALKg67dJ3cZDs8254r5aWbhfUKQMNcaQ== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:47 +0200 Subject: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-13-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=13761; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=uNqEYTopJejl+TyhGF8EeftCxfeA8VlyYahjLwUsBGk=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgD65Hu/daH9Gd77pSJcUcqAv65CdOm3oEjZ g295j14OtCJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIAwAKCRAgrS7GWxAs 4tGhD/9zt6aVpJs1dpwx/qNoseilRe82+6KXv3MqIMJGz3V0H8IOwki5TYQkvN/5SCbSJG/9gmN IHP5AmI4s2vGc8C6jZYYfzh7/smV5orQ7TjbN7UwdnFLjDtIh7c6sRqTMQDcy4PDIPuns3rRqUU dLStMmvY2iO5zNN8JFXTIVjC9wp1CavjJDP70wH0o71nsQ/ydGhYNAU8v2SQyW/g+uPEWtykgtH rNKBTGYGAuD7AyFBfCoxbGvIOL1Rfgl8A1aA9ou7XnUreCH5LEzTUrRtID1Asqz0XraEslAJMkK 9m6W5fAG0aTOvSfVotF+6deggM2Cki/ZFRgsbBld+spMbJd7xPQ2w4oewgMVrsQKSGIZ185tpjd HkOhcwF9PrfT/RTLX+3Hi5djPxqNHSbMW8N+7JN1CtEZ6jmAvFUcXfOwh2PAXXNLYFMQGwReIoU De/V6N/wA7EJhE66Zi/D3+Gurwcp/Hbm1nxjyEufTB+47JbwPzrltYwe7HHatmARN4E10yXRQNw lNbCXQTW6OVLV+0+y6LgNUKM32ALW9wFK1MS+W+lVKlf7zXDghJ5nNoxKiSkh/ZxOQrlS29xCD9 h/rYIHginGNjR4wGnZGnkVs99QE0WgKyUpLnVDoppOBFV6FuXEVXeOA632YSy+2J7V3T2XU9bTp C/ob/M9jVaz1Gmg== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Create KUnit tests to test the conversion between YUV and RGB. Test each conversion and range combination with some common colors. The code used to compute the expected result can be found in comment. [Louis Chauvet: - fix minor formating issues (whitespace, double line) - change expected alpha from 0x0000 to 0xffff - adapt to the new get_conversion_matrix usage - apply the changes from Arthur - move struct pixel_yuv_u8 to the test itself] Signed-off-by: Arthur Grillo Acked-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/Kconfig | 15 ++ drivers/gpu/drm/vkms/Makefile | 1 + drivers/gpu/drm/vkms/tests/.kunitconfig | 4 + drivers/gpu/drm/vkms/tests/Makefile | 3 + drivers/gpu/drm/vkms/tests/vkms_format_test.c | 232 ++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_formats.c | 7 +- drivers/gpu/drm/vkms/vkms_formats.h | 5 + 7 files changed, 265 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig index 9def079f685b..98ecfce929f3 100644 --- a/drivers/gpu/drm/vkms/Kconfig +++ b/drivers/gpu/drm/vkms/Kconfig @@ -14,3 +14,18 @@ config DRM_VKMS a VKMS. If M is selected the module will be called vkms. + +config DRM_VKMS_KUNIT_TESTS + tristate "KUnit tests for VKMS." if !KUNIT_ALL_TESTS + depends on DRM_VKMS=y && KUNIT + default KUNIT_ALL_TESTS + help + This builds unit tests for VKMS. This option is not useful for + distributions or general kernels, but only for kernel + developers working on VKMS. + + For more information on KUnit and unit tests in general, + please refer to the KUnit documentation in + Documentation/dev-tools/kunit/. + + If in doubt, say "N". diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index 1b28a6a32948..8d3e46dde635 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -9,3 +9,4 @@ vkms-y := \ vkms_writeback.o obj-$(CONFIG_DRM_VKMS) += vkms.o +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += tests/ diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig b/drivers/gpu/drm/vkms/tests/.kunitconfig new file mode 100644 index 000000000000..70e378228cbd --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig @@ -0,0 +1,4 @@ +CONFIG_KUNIT=y +CONFIG_DRM=y +CONFIG_DRM_VKMS=y +CONFIG_DRM_VKMS_KUNIT_TESTS=y diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile new file mode 100644 index 000000000000..2d1df668569e --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += vkms_format_test.o diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c b/drivers/gpu/drm/vkms/tests/vkms_format_test.c new file mode 100644 index 000000000000..351409897ca3 --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +#include +#include + +#include "../../drm_crtc_internal.h" + +#include "../vkms_formats.h" + +#define TEST_BUFF_SIZE 50 + +MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); + +struct pixel_yuv_u8 { + u8 y, u, v; +}; + +struct yuv_u8_to_argb_u16_case { + enum drm_color_encoding encoding; + enum drm_color_range range; + size_t n_colors; + struct format_pair { + char *name; + struct pixel_yuv_u8 yuv; + struct pixel_argb_u16 argb; + } colors[TEST_BUFF_SIZE]; +}; + +/* + * The YUV color representation were acquired via the colour python framework. + * Below are the function calls used for generating each case. + * + * For more information got to the docs: + * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html + */ +static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = { + /* + * colour.RGB_to_YCbCr(, + * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], + * in_bits = 16, + * in_legal = False, + * in_int = True, + * out_bits = 8, + * out_legal = False, + * out_int = True) + */ + { + .encoding = DRM_COLOR_YCBCR_BT601, + .range = DRM_COLOR_YCBCR_FULL_RANGE, + .n_colors = 6, + .colors = { + { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, + { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, + { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, + { "red", { 0x4c, 0x55, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, + { "green", { 0x96, 0x2c, 0x15 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, + { "blue", { 0x1d, 0xff, 0x6b }, { 0xffff, 0x0000, 0x0000, 0xffff }}, + }, + }, + /* + * colour.RGB_to_YCbCr(, + * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], + * in_bits = 16, + * in_legal = False, + * in_int = True, + * out_bits = 8, + * out_legal = True, + * out_int = True) + */ + { + .encoding = DRM_COLOR_YCBCR_BT601, + .range = DRM_COLOR_YCBCR_LIMITED_RANGE, + .n_colors = 6, + .colors = { + { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, + { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, + { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, + { "red", { 0x51, 0x5a, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, + { "green", { 0x91, 0x36, 0x22 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, + { "blue", { 0x29, 0xf0, 0x6e }, { 0xffff, 0x0000, 0x0000, 0xffff }}, + }, + }, + /* + * colour.RGB_to_YCbCr(, + * K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], + * in_bits = 16, + * in_legal = False, + * in_int = True, + * out_bits = 8, + * out_legal = False, + * out_int = True) + */ + { + .encoding = DRM_COLOR_YCBCR_BT709, + .range = DRM_COLOR_YCBCR_FULL_RANGE, + .n_colors = 4, + .colors = { + { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, + { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, + { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, + { "red", { 0x36, 0x63, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, + { "green", { 0xb6, 0x1e, 0x0c }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, + { "blue", { 0x12, 0xff, 0x74 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, + }, + }, + /* + * colour.RGB_to_YCbCr(, + * K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], + * in_bits = 16, + * int_legal = False, + * in_int = True, + * out_bits = 8, + * out_legal = True, + * out_int = True) + */ + { + .encoding = DRM_COLOR_YCBCR_BT709, + .range = DRM_COLOR_YCBCR_LIMITED_RANGE, + .n_colors = 4, + .colors = { + { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, + { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, + { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, + { "red", { 0x3f, 0x66, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, + { "green", { 0xad, 0x2a, 0x1a }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, + { "blue", { 0x20, 0xf0, 0x76 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, + }, + }, + /* + * colour.RGB_to_YCbCr(, + * K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"], + * in_bits = 16, + * in_legal = False, + * in_int = True, + * out_bits = 8, + * out_legal = False, + * out_int = True) + */ + { + .encoding = DRM_COLOR_YCBCR_BT2020, + .range = DRM_COLOR_YCBCR_FULL_RANGE, + .n_colors = 4, + .colors = { + { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, + { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, + { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, + { "red", { 0x43, 0x5c, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, + { "green", { 0xad, 0x24, 0x0b }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, + { "blue", { 0x0f, 0xff, 0x76 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, + }, + }, + /* + * colour.RGB_to_YCbCr(, + * K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"], + * in_bits = 16, + * in_legal = False, + * in_int = True, + * out_bits = 8, + * out_legal = True, + * out_int = True) + */ + { + .encoding = DRM_COLOR_YCBCR_BT2020, + .range = DRM_COLOR_YCBCR_LIMITED_RANGE, + .n_colors = 4, + .colors = { + { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, + { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, + { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, + { "red", { 0x4a, 0x61, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, + { "green", { 0xa4, 0x2f, 0x19 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, + { "blue", { 0x1d, 0xf0, 0x77 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, + }, + }, +}; + +static void vkms_format_test_yuv_u8_to_argb_u16(struct kunit *test) +{ + const struct yuv_u8_to_argb_u16_case *param = test->param_value; + struct pixel_argb_u16 argb; + + for (size_t i = 0; i < param->n_colors; i++) { + const struct format_pair *color = ¶m->colors[i]; + struct conversion_matrix matrix; + + get_conversion_matrix_to_argb_u16 + (DRM_FORMAT_NV12, param->encoding, param->range, &matrix); + + argb = argb_u16_from_yuv888(color->yuv.y, color->yuv.u, color->yuv.v, &matrix); + + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.a, color->argb.a), 257, + "On the A channel of the color %s expected 0x%04x, got 0x%04x", + color->name, color->argb.a, argb.a); + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.r, color->argb.r), 257, + "On the R channel of the color %s expected 0x%04x, got 0x%04x", + color->name, color->argb.r, argb.r); + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.g, color->argb.g), 257, + "On the G channel of the color %s expected 0x%04x, got 0x%04x", + color->name, color->argb.g, argb.g); + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.b, color->argb.b), 257, + "On the B channel of the color %s expected 0x%04x, got 0x%04x", + color->name, color->argb.b, argb.b); + } +} + +static void vkms_format_test_yuv_u8_to_argb_u16_case_desc(struct yuv_u8_to_argb_u16_case *t, + char *desc) +{ + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s - %s", + drm_get_color_encoding_name(t->encoding), drm_get_color_range_name(t->range)); +} + +KUNIT_ARRAY_PARAM(yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_cases, + vkms_format_test_yuv_u8_to_argb_u16_case_desc +); + +static struct kunit_case vkms_format_test_cases[] = { + KUNIT_CASE_PARAM(vkms_format_test_yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_gen_params), + {} +}; + +static struct kunit_suite vkms_format_test_suite = { + .name = "vkms-format", + .test_cases = vkms_format_test_cases, +}; + +kunit_test_suite(vkms_format_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Kunit test for vkms format conversion"); diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index adb1228e5201..0b201185eae7 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -7,6 +7,8 @@ #include #include +#include + #include "vkms_formats.h" /** @@ -247,8 +249,8 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel) return out_pixel; } -static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, - const struct conversion_matrix *matrix) +VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, + const struct conversion_matrix *matrix) { u16 r, g, b; s64 fp_y, fp_channel_1, fp_channel_2; @@ -278,6 +280,7 @@ static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel return argb_u16_from_u16161616(0xffff, r, g, b); } +EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888); /* * The following functions are read_line function for each pixel format supported by VKMS. diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h index d583855cb320..b4fe62ab9c65 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -13,4 +13,9 @@ void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encod enum drm_color_range range, struct conversion_matrix *matrix); +#if IS_ENABLED(CONFIG_KUNIT) +struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, + const struct conversion_matrix *matrix); +#endif + #endif /* _VKMS_FORMATS_H_ */ From patchwork Mon Oct 7 16:10:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13825002 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id C12AACFB44A for ; Mon, 7 Oct 2024 16:11:05 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0FB5C10E3D5; Mon, 7 Oct 2024 16:11:05 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="aShXEHrO"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3B09B10E3D8 for ; Mon, 7 Oct 2024 16:11:04 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id CDAB940012; Mon, 7 Oct 2024 16:11:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4dr23WBAY8ZlBbMVkhnAU+t1UPEWAWhnUCz8S7CEndk=; b=aShXEHrONs/7rS4bqP9H684U7ISlZA2wLtsV0tzsWbwENgVR2HGJdl7BHewxUA6Sl+TQZm 1qBPXcSSFDzAalMekNCP/ZCj0axn8AxzMPnvDWwtIm+D2P7EEMZVwxf5X5BQcin6kPzmL3 W1y1/PF+RFIz4WiU6NvmJ0rU0b9ujKOv0soqJyomiEs59vX4mB3HTksaXhEbHX0lyta332 3xmnULcQAMfDLAOPIzJsP9FtibIwdL3Aw6TNEwLeQnfv88vamiwU+K1Pp6KyQ/ZKpfBob/ Do2TwKUDRqQb7y/QEoXJzDFZz93iS7ANpKrlsnkBf3N+hAt6kq2FwK/n3/uepA== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:48 +0200 Subject: [PATCH v12 14/15] drm/vkms: Add how to run the Kunit tests MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-14-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=1115; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=cnp5oJy7nuzGGG9ERF9CFtbtr9GkJcMMWvS4L3S4Vps=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgE40zHTxiatMRHM9aZFY+JrnSZSSetvhWQg MAa321tyr6JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIBAAKCRAgrS7GWxAs 4jOVD/4lmEATNrmbsR/mLiCxSC1E4SFS9kMxbODvJTE+a4khMPPeGL+GDgYGr+SbxdPqM37ZfTv Na8K8IoMXgw371than9uD32L9pq59/m1NiYOtd4ZU+JYQ13LqxVZFgHqzEp+mI4JxBv/eTMm+wM zsaeOBBCEPVw0+lNFi6MQu3RvDjQe7OQk/1FAB6SHhh7hoyRE/CD78rMSnVXydsZP2mm0fNY2VR 1Y1qJ4I/Odkv+WegWzIAb2IqsDSVyi7eswlByNpQi0hTm6j5pdgus9r0rsaKRY47c0mUJpWOQwI afsX99NIaT4svvxUJfn/E96K79kVD1wWLB9oHslWj1qAVY4qcoWdzNSvkxYoJ6hMxey6g87H8hU tGZsmta1tEgdml5kDt2+FzMlAcgn/YmYRKfBSw7k/KVp330kKPSqf5o7pfix6s633fqTMHbxmv+ KtESD9j26sBdf1869xmTaoJ98k1Dzpxm7GjEjW1Nf3RUspbmHfmjs76ewxUupPlLcDd3luS72lq mFigUmd0DitbXR2hF7oBjgAlZAVc2DkevX1UZEt7GBDH/f5r/2nxfAuqW8xE0Qwu/7hcV2qNz1n v86hiQNjFoU/gA8vicnjuyzl+Nj8kt8bXG360Jv/fUvlAHNDZ+v0pPMNPlziTG9bp9WbAbZ5erR /y9N3qU2cBH8RgA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Now that we have KUnit tests, add instructions on how to run them. Signed-off-by: Arthur Grillo Signed-off-by: Louis Chauvet --- Documentation/gpu/vkms.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index 13b866c3617c..5ef5ef2e6a21 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -89,6 +89,17 @@ You can also run subtests if you do not want to run the entire test:: sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device "sys:/sys/devices/platform/vkms" sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip --run-subtest basic-plain-flip +Testing With KUnit +================== + +KUnit (Kernel unit testing framework) provides a common framework for unit tests +within the Linux kernel. +More information in ../dev-tools/kunit/index.rst . + +To run the VKMS KUnit tests:: + + tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/vkms/tests + TODO ==== From patchwork Mon Oct 7 16:10:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13825005 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 1DAC0CFB446 for ; Mon, 7 Oct 2024 16:11:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 92FD310E3D9; Mon, 7 Oct 2024 16:11:09 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="kaCEZXN/"; dkim-atps=neutral Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5054410E3DA for ; Mon, 7 Oct 2024 16:11:05 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id EEFC040005; Mon, 7 Oct 2024 16:11:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1728317464; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bYBVsTbvX0Vvhdgtk3+NNjlF1mcR2qZl1/lxJqF5EiU=; b=kaCEZXN/C1gNE4h9vUUhswWCvZ8DIUXtXsfhjzN2+wq5xP1J6CX5Z182/269JrMktRilYn uIQy2/kxygAklrtH9rmHXzDmz1vD+G1vdJ/rM1q4EUGZNX9Bv74BJEVxbfDD1pYR7Mrkvv 2UL3KXw9yOnAGZi53uN4HmjwrRCKE9gEH6NMqtb5VzEWF+EWbkWVyalotqSP/rMuXtLQXu Ecp3ZcNa4oO4EjUMfgoaUHMHL+tlWuL3vkF9RLljQWVlGc30dWVrKipCxBs9Wfv4bO6Pgt rnmnwOsfWZekZ3GMaMd2PXN7B5Smon6izwMuc3XvMcfdQLUPe5n2rRys8Vv1Dw== From: Louis Chauvet Date: Mon, 07 Oct 2024 18:10:49 +0200 Subject: [PATCH v12 15/15] drm/vkms: Add support for DRM_FORMAT_R* MIME-Version: 1.0 Message-Id: <20241007-yuv-v12-15-01c1ada6fec8@bootlin.com> References: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> In-Reply-To: <20241007-yuv-v12-0-01c1ada6fec8@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Jonathan Corbet , Louis Chauvet , Simona Vetter , rdunlap@infradead.org, arthurgrillo@riseup.net, pekka.paalanen@haloniitty.fi, Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, thomas.petazzoni@bootlin.com, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Pekka Paalanen X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=6383; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=XA5++UHB22P8byetvVhtzmOdqkragW9YoMtVdS2c/kE=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBnBAgEazaRlQ3ZFx7oJX3sXhObAiSzyYJXRKnbG VxczsDxpXOJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZwQIBAAKCRAgrS7GWxAs 4sk6EACYUtgKqtjgVQn/nazxS4GHZP3YDAe5s6Z4wZpYYDmx9fJRKKmwACI6rCgesvXXiCR6zIq m40F5evxk3D/GCwkJLH2qHo+8mecAM4bugoZrbCUewSFjwSm/tOJ92m8pNvC39cT312l9NYJ+kr W11evzi1M8Ypo/3fYKkUfi38YgIovI/z1Fav6ZfA/b+hNk8lNmmL0uuQFs1znEiGA6NoPHMrR2v cDBlWmhAkjqzQ5tOQcEs/DeVXZyqMQAQR8P9YbZ0ywh8Pt07XhLv8YJVnRHk5iv1t6M+9BY5mdj PBuH+UM+DjvWLzBsWNERsBLlio87V2wOL0jYVeOpqwh6HEXoRO/D5DG2pQdgYvrXRLyRAiwFkxy B4GlzMS9QLXqXWvCGU8PYPikCnYAf01tJVhfg4CBsyn1cRKie5xGCF1FQabgP73qY6M88iaRbOE TLN8VktBMcTOBxytv37r+5AeAntxjZCRWE17I1oToB5I2MuW4Uyh0Bir7+ZbxrZSAFMMFN5Ebo3 9iT/BhKPcrovSf5DM7LM9FLYOosopvykjgeOkLK6czpXzQ1HDD6w+jzg+wuzz/cKUTzc85NlPyg IAINIkgde64Ar2lYr/JJX30U8ac+w3pCqYXX54E/ziOxi5gnswryUKXUaBvfP6kXLn2Tyl4Eu5X ZKeoDrJCm+0S+cA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" This add the support for: - R1/R2/R4/R8 R1 format was tested with [1] and [2]. [1]: https://lore.kernel.org/r/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com [2]: https://lore.kernel.org/igt-dev/20240306-b4-kms_tests-v1-0-8fe451efd2ac@bootlin.com/ Reviewed-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_formats.c | 110 +++++++++++++++++++++++++++++++++++- drivers/gpu/drm/vkms/vkms_plane.c | 4 ++ 2 files changed, 113 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 0b201185eae7..f9841b8000c4 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -249,6 +249,16 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel) return out_pixel; } +static struct pixel_argb_u16 argb_u16_from_gray8(u16 gray) +{ + return argb_u16_from_u8888(255, gray, gray, gray); +} + +static struct pixel_argb_u16 argb_u16_from_grayu16(u16 gray) +{ + return argb_u16_from_u16161616(0xFFFF, gray, gray, gray); +} + VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, const struct conversion_matrix *matrix) { @@ -286,7 +296,7 @@ EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888); * The following functions are read_line function for each pixel format supported by VKMS. * * They read a line starting at the point @x_start,@y_start following the @direction. The result - * is stored in @out_pixel and in the format ARGB16161616. + * is stored in @out_pixel and in a 64 bits format, see struct pixel_argb_u16. * * These functions are very repetitive, but the innermost pixel loops must be kept inside these * functions for performance reasons. Some benchmarking was done in [1] where having the innermost @@ -295,6 +305,96 @@ EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888); * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/ */ +static void Rx_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + int bits_per_pixel = drm_format_info_bpp(plane->frame_info->fb->format, 0); + u8 *src_pixels; + int rem_x, rem_y; + + WARN_ONCE(drm_format_info_block_height(plane->frame_info->fb->format, 0) != 1, + "%s() only support formats with block_h == 1", __func__); + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + int bit_offset = (8 - bits_per_pixel) - rem_x * bits_per_pixel; + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); + int mask = (0x1 << bits_per_pixel) - 1; + int lum_per_level = 0xFFFF / mask; + + if (direction == READ_LEFT_TO_RIGHT || direction == READ_RIGHT_TO_LEFT) { + int restart_bit_offset; + int step_bit_offset; + + if (direction == READ_LEFT_TO_RIGHT) { + restart_bit_offset = 8 - bits_per_pixel; + step_bit_offset = -bits_per_pixel; + } else { + restart_bit_offset = 0; + step_bit_offset = bits_per_pixel; + } + + while (out_pixel < end) { + u8 val = ((*src_pixels) >> bit_offset) & mask; + + *out_pixel = argb_u16_from_grayu16((int)val * lum_per_level); + + bit_offset += step_bit_offset; + if (bit_offset < 0 || 8 <= bit_offset) { + bit_offset = restart_bit_offset; + src_pixels += step; + } + out_pixel += 1; + } + } else if (direction == READ_TOP_TO_BOTTOM || direction == READ_BOTTOM_TO_TOP) { + while (out_pixel < end) { + u8 val = (*src_pixels >> bit_offset) & mask; + *out_pixel = argb_u16_from_grayu16((int)val * lum_per_level); + src_pixels += step; + out_pixel += 1; + } + } +} + +static void R1_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + Rx_read_line(plane, x_start, y_start, direction, count, out_pixel); +} + +static void R2_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + Rx_read_line(plane, x_start, y_start, direction, count, out_pixel); +} + +static void R4_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + Rx_read_line(plane, x_start, y_start, direction, count, out_pixel); +} + +static void R8_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + while (out_pixel < end) { + *out_pixel = argb_u16_from_gray8(*src_pixels); + src_pixels += step; + out_pixel += 1; + } +} + static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, enum pixel_read_direction direction, int count, struct pixel_argb_u16 out_pixel[]) @@ -606,6 +706,14 @@ pixel_read_line_t get_pixel_read_line_function(u32 format) case DRM_FORMAT_YVU422: case DRM_FORMAT_YVU444: return &planar_yuv_read_line; + case DRM_FORMAT_R1: + return &R1_read_line; + case DRM_FORMAT_R2: + return &R2_read_line; + case DRM_FORMAT_R4: + return &R4_read_line; + case DRM_FORMAT_R8: + return &R8_read_line; default: /* * This is a bug in vkms_plane_atomic_check(). All the supported diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 8f764a108b00..67f891e7ac58 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -30,6 +30,10 @@ static const u32 vkms_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU422, DRM_FORMAT_YVU444, + DRM_FORMAT_R1, + DRM_FORMAT_R2, + DRM_FORMAT_R4, + DRM_FORMAT_R8, }; static struct drm_plane_state *