From patchwork Wed Mar 13 17:44:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591663 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 E4C26C54791 for ; Wed, 13 Mar 2024 17:45:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2BEE310F697; Wed, 13 Mar 2024 17:45:31 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="RzvU2j9e"; 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 0D05610F697 for ; Wed, 13 Mar 2024 17:45:29 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id D227B40006; Wed, 13 Mar 2024 17:45:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351928; 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=hht86WDYBmmd5HJ0kBTByD9xXyq+2Qqfx093Hdq4g/E=; b=RzvU2j9ednDvi05rgHjzsJqaAuVItoKYmuA3s5iUHB0uH8j0tdwfpVQC8PFfwBfJloIHMj t7e1jdeV3JSOWespI/46pzDcKn7YBvuI7vKBfoGsWdSwfp8IAeMCNNNsREYlVMEoMu/Ruw HWqzQ70IrlI67DFcn14chPcTpPBYdu3Ggzo8fgkjFsxM0+tAGMVtcRzvJ7JjYvuWFcecnl 50Z8Ix92JKo3RN24zKomQolYFY49UbXa0RjbvQoBWuyTK0Pf+hELtPhPwQKkKKCA2OE7LV L36POivdLM6cyAujZ0PWvquYB+XN9lIKoZfc2Jqn9DhXOY+ohPab/ND+IfjBuA== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:44:55 +0100 Subject: [PATCH v5 01/16] drm/vkms: Code formatting MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-1-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4834; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=jQLWVvGHX0RwVHU0wEm+ZMMYBxMzOtg605EU0kzKs58=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eYySTdGDiGsC4TKrC39rnaeps9U2aZvyemtyyJ9 PcfpYymJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmMgAKCRAgrS7GWxAs4nSYEA CrP5hBlCAjtLqxs7yD1pwcwqDUzuT5hW3csVlGRQK1bDO6YSdgHwytECLDNTjBgPoPAJiPlH2N0pZq 8JsyJ5bmpaCnnGiVuwyBiAz/NOi99C5IHXB5NAWkU64AopcactmBc+qPyCHzFffTmg/ct5zUSXA3ou VX0cXn8vI4CTdIw/0095THcibqISo63Gp1DN3WQdoxXy01w3ihJEPIg/zgNKmR5FxW0q5b1sCfoA1e xSwKf9JMTQD/+LadNSOKfSmsSsVSfqrj68z9pCsqUo+/gjyyHRKgVd56HY1HPIDhO7Q/kCAqv/0WfX bX2G5xLWcrU7ynb0kgBJrX+1mfsr1FJhZo/muh7wj9NKjcYH0buvbRDQD/8dUU//eo3yYp+7NuT2Sn EXDBDAkRs7rmTb7xYg/Hh9SLylHU+BC3L5BDSs01H3YUmYIUtOXDtDMbxsu+ca/FAurmlITgvUYpR1 qxWmGXPn+FF6x4qyZdobbnFirSCmD/wTRM7SWNnqH1+dZyxJ6gCkQD8lwr5hjdBm3y8IiVpHsEc7at L2syLfuUFTCU9+qaG5VdqcJX681DiQlrZ77dR70GLQ3UXuLFiBnP16o7qOIpEBKnzE75jXN/ycMHBF 46deNfHZ/5smVwB//BdBJRchTBelHhyjvTVN+T6DmpY+vZ8lGiBsHSJG5niw== 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. Signed-off-by: Louis Chauvet Reviewed-by: Pekka Paalanen Reviewed-by: Maíra Canal --- 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 e7441b227b3c..c6d9b4a65809 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); } @@ -302,8 +302,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); @@ -328,7 +328,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); @@ -367,7 +367,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 61e500b8c9da..7586ae2e1dd3 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -191,8 +191,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) @@ -208,8 +207,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 dd0af086e7fa..83e6c9b9ff46 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -81,8 +81,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 Wed Mar 13 17:44:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591665 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 4805DC54E66 for ; Wed, 13 Mar 2024 17:45:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B8F7F10F70E; Wed, 13 Mar 2024 17:45:34 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="Ky2Wirqz"; 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 2BADD10F68A for ; Wed, 13 Mar 2024 17:45:31 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id C528B40009; Wed, 13 Mar 2024 17:45:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351929; 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=jiFoWvvgAV8DiexHt8SOwI23FzpgbcJPyIxwHbI/8Nc=; b=Ky2WirqzXeIoJNa/WIFP3+Exy5REnzJ1Z7sr+vUwTBWE5nW5AVcLT824dSlSQ2LlqiZyOU wdMBGM2qKnzIVDuB3vhRiXuJXs9vwMgchsUmAGW0qbZK8nBacxuE0csBP/RUkNLtHFoUnU KCRbXOCzsNrUx0PeIU82Mj4Zhx/fOKmjdxD7jgmyaVOoYj2CcZvMlMqj2Tp1vYY7iGFwRf gX/C46k+Kbi34tHjjcbXrJMfHp2OTtblG5UNvFJBlnZ1mgws32Hzek23DSS5qts9FL2lqb nu3k5PVjmJDrqs9PPTBmfCNlx4mweZKLkT7I6CpKRkTeROOoWy6G2ZEFHwQWRA== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:44:56 +0100 Subject: [PATCH v5 02/16] drm/vkms: Use drm_frame directly MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-2-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4080; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=N7pM5FLs21FNL8hsQWxNphWYncmcUeuWyWea5GV/zSA=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eYySjdIDO0IEapq4icOYEIqSrn1vtEEN6kMxiNo OzMxKl+JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmMgAKCRAgrS7GWxAs4gO5D/ 9KYM+FUJvh7eqVuT1QqqYkzCvJ9iAbKtPiLOSqwI9ObI8kaq1fr41xD6UR9Pxt+dbHcVDVd0rO1Fq+ WDi3iGFO6uv/G7Mqajg66IgHn4T2VXtfFW9aiKXcJuofm+5H380R7fdSSY2f3wDbezTANBCkJym7SP +qrF0zY4/g9OO3Us/MkzDRWuWT23RKQ53+aB7MXPpuWzmA9BhCAvVEkRzTC9lQRY7bxDkw0cySZlHQ QsQ/9bG8KFX0MWFifOwQM8QUYzlmfhPrOsfscsWKBCR2OeTf29DQvgI8KnuBR14huhJ2kNUnMDU5Q8 X4Qhzv2J53PbVCJk60vGK3UZmjZgTIMo3/DfdRItF/TULeYtguXFCzjxBBG8S31/cF88hZeGNYPi8E BLQOcM/Xi6QS9szKpGH8eK/hPqvejUBo0Sk4Z5XcGxfXotEK+GHibz8KFnYxPJf1SnuVCwpTOEJ8+k nJmxLTX3vInfn9eaekM1BYmJVTjalbQwcSkVRkIqSnHFU1tChvImIAPwqxgmrgvNKNC71qMogbnhZ2 vIC7E5pYMA3KV/45vIYsR6vxd7u+3dq+dM3O6cZtVPCyxVq2B15/gncZfjtvkycMynSfr18WZJVF9a jpIAHjo3v7CxixqumT5h8eQcEL6qb67vNLj3U57mL274X0Db6/6qO28txt4Q== 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 Signed-off-by: Louis Chauvet Acked-by: Pekka Paalanen Reviewed-by: Maíra Canal --- drivers/gpu/drm/vkms/vkms_drv.h | 3 --- drivers/gpu/drm/vkms/vkms_formats.c | 12 +++++++----- drivers/gpu/drm/vkms/vkms_plane.c | 3 --- drivers/gpu/drm/vkms/vkms_writeback.c | 5 ----- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 8f5710debb1e..b4b357447292 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -31,9 +31,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 36046b12f296..172830a3936a 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -11,8 +11,10 @@ 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]); } /* @@ -131,12 +133,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]); } @@ -223,7 +225,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 Wed Mar 13 17:44:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591669 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 90E29C54E66 for ; Wed, 13 Mar 2024 17:45:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A7F7F10F803; Wed, 13 Mar 2024 17:45:40 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="eVzik8fQ"; 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 D8A1210F68A for ; Wed, 13 Mar 2024 17:45:31 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id B77414000E; Wed, 13 Mar 2024 17:45:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351930; 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=UoEJVitgQdwqzYit9x2fRkuhzwqFW+P/Z98aACWVEW8=; b=eVzik8fQzGYjawRO9Sn1n9s5VuViJ9xpzeYO3sPFUshXW8W8nh3N0irSYQa/Ro+RKW0c43 IuYQfuvaOmXoU7o6QaO+uPpoA8y2uNWEvIaKpoAYsPzwwn/KeagBfK6VvE34NBb2ezSfQo XGVo92iJyYw+ytHy9rnixtNYP8kfVfgBrGLL1duOX1LCNvQ/Cv88+g6uD9uYx1LDhwSLAs Yuk5ZWYL9bk5OND1S+3T7laZ80/QiHXC6IFQADDgFfPILbNnnbRkflGmqKpvtbyaRqRSnW oaLJinTX+N20fI6oXnbae2Bn98HkSlip84mA2A8DeTyGMZaE736pe4FOAcOkUg== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:44:57 +0100 Subject: [PATCH v5 03/16] drm/vkms: write/update the documentation for pixel conversion and pixel write functions MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-3-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7282; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=rAa69AVNvXwStTD/zFUG8N7xq95vym8ycf+nNk+Pqpg=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eYyB27ZkpYgLBf21H0iKy6EBIryIehZr58AzJeb V7KqS4GJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmMgAKCRAgrS7GWxAs4lzMEA CxE4OiYkGOSeLG6XXWBHZsX7a7hIGBAN7TUS3URfZfwWwF0OtCz76VyXrCF/DpYhuPhYw+xEp8uIpk pGsJ4SO7/BGHz35rfvB7MnpNi6MmQadszHizMyAmwSAqA+fn3Q8G4VFWNPydI4nuPQOD6lbS2YBOkj sYVI8XjX8u98PFrVanNQI91dUAtKK4LiIxHR0PztbopCja6UgEVb4vRgQZwdJ8vk/53+zAmlBEGnr2 ymQD9Jgam4SmAJfxtI4O6mnKEG8Up48oqRgQ4GqmHsHw3OjuAoAEMFkjuYNGllKqQSU1J/ssQGOwfd O9RZiOXfPr2sBzNqEkhh3i6ZNld0Rf3Wp8FhKVSYUXao/viRO0DUBkpgiUefXqxWJIwc6AU/AwrQVe 9H9AIfSg7o0VafbdrH4sdajxj/e9E7S99EyH0PQi16iMw9ocd7ZhWoUu9icf7QFrec4BJjSdB0iGW3 lrJgfB1X9l5cg+K4fY4OeivspK4YJi+7FzhwfccKdDiKLtmXYpfFMq/M5d30Fwt2+SWz4qBSPl5XxO qzeFoZi+as/1RxClV06mtuL8X5FSWb0OysCEMC/vtpfRtg5M3lq6L2T0zTpZITT+/MFb5Q/3+8rFoS a1DDNzBnkBHc3Qcu1DGTtS7LbpZiI7QWZxyPMblLHjAUBiaOjC9ah8VIx5Ig== 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" Add some documentation on pixel conversion functions. Update of outdated comments for pixel_write functions. Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_composer.c | 7 ++++ drivers/gpu/drm/vkms/vkms_drv.h | 13 ++++++++ drivers/gpu/drm/vkms/vkms_formats.c | 62 ++++++++++++++++++++++++++++++------ 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index c6d9b4a65809..da0651a94c9b 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -189,6 +189,13 @@ static void blend(struct vkms_writeback_job *wb, size_t crtc_y_limit = crtc_state->base.crtc->mode.vdisplay; + /* + * 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. + */ for (size_t y = 0; y < crtc_y_limit; y++) { fill_background(&background_color, output_buffer); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index b4b357447292..18086423a3a7 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -25,6 +25,17 @@ #define VKMS_LUT_SIZE 256 +/** + * struct vkms_frame_info - structure to store the state of a frame + * + * @fb: backing drm framebuffer + * @src: source rectangle of this frame in the source framebuffer + * @dst: destination rectangle in the crtc buffer + * @map: see drm_shadow_plane_state@data + * @rotation: rotation applied to the source. + * + * @src and @dst should have the same size modulo the rotation. + */ struct vkms_frame_info { struct drm_framebuffer *fb; struct drm_rect src, dst; @@ -52,6 +63,8 @@ struct vkms_writeback_job { * 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 vkms_plane_state must + * ensure that this pointer is valid */ struct vkms_plane_state { struct drm_shadow_plane_state base; diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 172830a3936a..6e3dc8682ff9 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -9,6 +9,18 @@ #include "vkms_formats.h" +/** + * pixel_offset() - Get the offset of the pixel at coordinates x/y in the first plane + * + * @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 + * + * 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. + */ static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int y) { struct drm_framebuffer *fb = frame_info->fb; @@ -17,18 +29,22 @@ static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int + (x * fb->format->cpp[0]); } -/* - * packed_pixels_addr - Get the pointer to pixel of a given pair of coordinates +/** + * packed_pixels_addr() - Get the pointer to the block containing the pixel at the given + * coordinates * * @frame_info: Buffer metadata - * @x: The x(width) coordinate of the 2D buffer - * @y: The y(Heigth) coordinate of the 2D buffer + * @x: The x(width) coordinate inside the plane + * @y: The y(height) coordinate inside the plane * * 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). + * + * 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. */ static void *packed_pixels_addr(const struct vkms_frame_info *frame_info, int x, int y) @@ -53,6 +69,13 @@ static int get_x_position(const struct vkms_frame_info *frame_info, int limit, i return x; } +/* + * The following functions take pixel data from the buffer and convert them to the format + * ARGB16161616 in out_pixel. + * + * 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) { /* @@ -145,12 +168,11 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state } /* - * The following functions take an line of argb_u16 pixels from the - * src_buffer, convert them to a specific format, and store them in the - * destination. + * The following functions take one argb_u16 pixel and convert it to a specific format. The + * result is stored in @dst_pixels. * - * They are used in the `compose_active_planes` to convert and store a line - * from the src_buffer to the writeback buffer. + * They are used in the `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) { @@ -216,6 +238,14 @@ static void argb_u16_to_RGB565(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) *pixels = cpu_to_le16(r << 11 | g << 5 | b); } +/** + * Generic loop for all supported writeback format. It is executed just after the blending to + * write a line in the writeback buffer. + * + * @wb: Job where to insert the final image + * @src_buffer: Line to write + * @y: Row to write in the writeback buffer + */ void vkms_writeback_row(struct vkms_writeback_job *wb, const struct line_buffer *src_buffer, int y) { @@ -229,6 +259,13 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, wb->pixel_write(dst_pixels, &in_pixels[x]); } +/** + * 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) { switch (format) { @@ -247,6 +284,13 @@ void *get_pixel_conversion_function(u32 format) } } +/** + * 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 + * pointer is valid before using it in a vkms_writeback_job. + * + * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) + */ void *get_pixel_write_function(u32 format) { switch (format) { From patchwork Wed Mar 13 17:44:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591668 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 DA19BC54791 for ; Wed, 13 Mar 2024 17:45:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 75B2E10F6C2; Wed, 13 Mar 2024 17:45:40 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="bTGmTw1O"; 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 0666110F68A for ; Wed, 13 Mar 2024 17:45:32 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id A9B204000A; Wed, 13 Mar 2024 17:45:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351931; 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=vORBOa/fDKBS0WtbVxYBEScDcO9uHc+OoySd4rAWJLg=; b=bTGmTw1Ok3Sd0gMHXQaEErs9hwAXtj2lTLJBDrF9ECtwoiyuQ4LppgS8lXdlzHyq0NP7xO 3moY08avjM215PlJHc5J3YMokqHlz5e0Qi9pE2ag27sjHtMxJ3qxAs9mqcitV8WaaeJPZG qIZxyY2GwM/KnTKCoKefJ7B9y67oTGUxdyFdeWTfiTyBVaw4EJTz11l9LbzAI5C2MhbMOK IPXxtQNgN2BCjuiAzS3GNFel+QMsp+ckHhHmxVjG2cuEAHBVGaiv8Cb9Uc9cqHbYDHoJ2X 1hgPU565HF3S+VqtjkQOmum9KDVAlzdhsVuTvcXeF5OhPF1hKxiURfaiQ7eGTg== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:44:58 +0100 Subject: [PATCH v5 04/16] drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-4-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=12661; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=dDvKDmwpWlMF3/Em7Xq7bMNZ5mUHFg8sV7wJ4MAkcB8=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eYynkZrVvzJcZCITuR+vmJqz050BBamBPC36CN6 KSuoLGSJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmMgAKCRAgrS7GWxAs4vmAD/ 9cc8liu62K9sXNVb/v+qYRK6gBvZma7dvtXJJM6DfohYJLEKwAnv31ltTnq335fErOdGNyvj3LI7zz 3KMGHlzGtPkA8wXX0A5C4hSW8MSW+5AmQR3Vk+LX9b8YyjJ9esfj/iRykrxlHeHURfKxiMWZuA68M6 GJaZ4NykaPAIeUAZIe+iHkrVKwvv/iZb/5NfkSjJ1qR7CfumpDdOPNwF7mLKPb3aifuaTZ8LgkDCVP D3fo4KNsjvk6Wjaq1OtEGIge7Kvv/N263HQ1xMECuJqedTGdP+yLSE/eWVTKH8S/+NSNbzV5+v/qdr JQ1VThMClixmagS3kq5rGWTiT747r2qmdiXhFFymafpPA0FkSPOtvCxrw6I7ztG896lFfa1leNcpEa pFVvX3v3EGtotSAJt46sJvx8EYUmnTcvX1R46erGHUwB3QjbrU34cX+jLZfB3lPPfKBW66vLbUcdlO 6CdV+Tdvzlu4DxoZpLhdXa591myZOavjPq2wIoHjQoaXx7+IEO/TNC0aUoBYeeaajwEmFbb0wO/2yx DVdi+U+oAprDA/KxSyF098Ko3P7PtifV82WEvk4cy0HefGEw5cJuQBd3uBfYIMzmdgdDVtvsn37i47 orYZO+rIHJqSrpAWrdP4xTs49U+qfP9Vf0PW8x8xqwPoEwVUrxMt1ma6xfHA== 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 append. Document for those typedefs. Signed-off-by: Louis Chauvet Reviewed-by: Pekka Paalanen --- 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, 95 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 18086423a3a7..4bfc62d26f08 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 @dst_pixels + * 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); + /** * 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 6e3dc8682ff9..55a4365d21a4 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -76,7 +76,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 @@ -84,48 +84,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) { - u16 *pixels = (u16 *)src_pixels; + u16 *pixel = (u16 *)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) { - u16 *pixels = (u16 *)src_pixels; + u16 *pixel = (u16 *)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) { - u16 *pixels = (u16 *)src_pixels; + u16 *pixel = (u16 *)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); @@ -169,12 +169,12 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state /* * The following functions take one argb_u16 pixel and convert it to a specific format. The - * result is stored in @dst_pixels. + * result is stored in @out_pixel. * * They are used in the `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 @@ -186,43 +186,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) { - u16 *pixels = (u16 *)dst_pixels; + u16 *pixel = (u16 *)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) { - u16 *pixels = (u16 *)dst_pixels; + u16 *pixel = (u16 *)out_pixel; - pixels[3] = 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] = 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) { - u16 *pixels = (u16 *)dst_pixels; + u16 *pixel = (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)); @@ -235,7 +235,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); } /** @@ -266,7 +266,7 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, * * @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: @@ -280,7 +280,16 @@ 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 + */ + WARN(true, + "Pixel format %p4cc is not supported by VKMS planes. This is a kernel bug, atomic check must forbid this configuration.\n", + &format); + return (pixel_read_t)NULL; } } @@ -291,7 +300,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: @@ -305,6 +314,15 @@ 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 + */ + WARN(true, + "Pixel format %p4cc is not supported by VKMS writeback. This is a kernel bug, atomic check must forbid this configuration.\n", + &format); + return (pixel_write_t)NULL; } } 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 Wed Mar 13 17:44:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591666 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 692FFC54E66 for ; Wed, 13 Mar 2024 17:45:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4B94010F7F4; Wed, 13 Mar 2024 17:45:37 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="Q/r2VPAG"; 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 BDD2810F6C2 for ; Wed, 13 Mar 2024 17:45:33 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id A0C374000B; Wed, 13 Mar 2024 17:45:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351932; 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=esYVbqoyMnTYaHzvOF2VUzx2RJ3x/zSrqTrYmwfzZkk=; b=Q/r2VPAG4xEkAiWkAN6692uB5lWbLgVsBG3SjSVWzqlw6DUHSENwvYcXCFk60hJHcrdKBO W8lfUOdZvFsRH6jKjLni4ituBFE233ptL26gu3SN4g6wFJ4/WsSlwQpoROHQ0JbYtSqGaP bkyQ23LO7va4k9zb+HjAR5ZfYmEKWCVSkZaKyQpFFl6slS93DmBip7jYZf87fbS/SUFzER bEujqMPB4FEY4QlIeQlpfs/2aqhwzbhfvEGFiOlXz2OSbB9NqDCaTZ9+DveYXsVY3Dpax7 NuPIdQg0rNljirKC2lnIY9usrRE6nYTIfjccGnKPeir8qXeUnbCRPO8dSsxdmQ== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:44:59 +0100 Subject: [PATCH v5 05/16] drm/vkms: Add dummy pixel_read/pixel_write callbacks to avoid NULL pointers MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-5-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4481; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=9ZPVdGk0pJtVP26SrBX+ZVjo7p8EmT2b/86RbmQI15E=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eYzPoa6AEW5znaZfmxscs9WwpZyPGBNTulbz13P +8PTSPOJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmMwAKCRAgrS7GWxAs4nwWD/ 49STSyWsA+XEAckzZNYZbCS1v6PcmX4ZF5KKo4mb+81k4luTqJmRR6fvlF39DsQWsD+7c5KrRdMWdf bekTyltqqXtmZ9IOvX/4cKoyKdMfBHgDY0NRceCjvLUxUf5tg1noea4c2UsyHa0J6Ns4FTa9UMVx4u fh+rdnO+NE88wS2101f/HaRjbjIdSAami4xdxtFz00QKrwF/ZFHiD3cqYxsYzZLE5mCLOsc01YD5De xIYKZ9vOP0BgF7+/RL7FN63k2Mkb1YVY+/LyjXPCmq58CaPMjGUvOFt0zZZUIPZj0IxyxrcG1cRtIu D9wbMbRYXMpLnIGtmUaVNQUL2fx8vGrsFu+tliFIBXwVGV6RWYNJNjg7ec23AFLCtnNHzY/h/76RTm j0RdxXSSnd/Dnzu25NxgGZTnesqqH5e+j/OC1Vd9m+SGo7IFcmxfZsoC6sRm3qq+2IR7arZpmFdcOU StYSaw5E8BYvSkJKDT3NNWXav1O+jQxCo7xAg3GbtijpFM6TMeB/TUXgs6a+UkyGiqaOSQp40FGtC1 7YDxHH33He8wx5tkW8VPmjjm00UKAwKi+x9pvMBRCAJ8tPn6v/hyeUPG9EGy5CIoNvDijs6IwiT0YP W8I2dmfLYCfYGW8UjfdMmH4FZiCY7qTSbjnyulrAIlRfz6mxHaWQFBTbCtGA== 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 callbacks which does nothing. They are used in replacement of NULL and it avoid kernel OOPS if this NULL is called. If those callback are used, it means that there is a mismatch between what formats are announced by atomic_check and what is realy supported by atomic_update. Signed-off-by: Louis Chauvet Acked-by: Pekka Paalanen --- drivers/gpu/drm/vkms/vkms_formats.c | 43 +++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 55a4365d21a4..b57d85b8b935 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -136,6 +136,21 @@ static void RGB565_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio)); } +/** + * black_to_argb_u16() - pixel_read callback which always read black + * + * This callback is used when an invalid format is requested for plane reading. + * It is used to avoid null pointer to be used as a function. In theory, this function should + * never be called, except if you found a bug in the driver/DRM core. + */ +static void black_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +{ + out_pixel->a = (u16)0xFFFF; + out_pixel->r = 0; + out_pixel->g = 0; + out_pixel->b = 0; +} + /** * vkms_compose_row - compose a single row of a plane * @stage_buffer: output line with the composed pixels @@ -238,6 +253,16 @@ static void argb_u16_to_RGB565(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) *pixel = cpu_to_le16(r << 11 | g << 5 | b); } +/** + * argb_u16_to_nothing() - pixel_write callback with no effect + * + * This callback is used when an invalid format is requested for writeback. + * It is used to avoid null pointer to be used as a function. In theory, this should never + * happen, except if there is a bug in the driver + */ +static void argb_u16_to_nothing(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) +{} + /** * Generic loop for all supported writeback format. It is executed just after the blending to * write a line in the writeback buffer. @@ -261,8 +286,8 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, /** * 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. + * If the format is not supported by VKMS a warn is emitted and a dummy "always read black" + * function is returned. * * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) */ @@ -285,18 +310,21 @@ pixel_read_t get_pixel_read_function(u32 format) * format must: * - Be listed in vkms_formats in vkms_plane.c * - Have a pixel_read callback defined here + * + * To avoid kernel crash, a dummy "always read black" function is used. It means + * that during the composition, this plane will always be black. */ WARN(true, "Pixel format %p4cc is not supported by VKMS planes. This is a kernel bug, atomic check must forbid this configuration.\n", &format); - return (pixel_read_t)NULL; + return &black_to_argb_u16; } } /** * 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 - * pointer is valid before using it in a vkms_writeback_job. + * If the format is not supported by VKMS a warn is emitted and a dummy "don't do anything" + * function is returned. * * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) */ @@ -319,10 +347,13 @@ pixel_write_t get_pixel_write_function(u32 format) * format must: * - Be listed in vkms_wb_formats in vkms_writeback.c * - Have a pixel_write callback defined here + * + * To avoid kernel crash, a dummy "don't do anything" function is used. It means + * that the resulting writeback buffer is not composed and can contains any values. */ WARN(true, "Pixel format %p4cc is not supported by VKMS writeback. This is a kernel bug, atomic check must forbid this configuration.\n", &format); - return (pixel_write_t)NULL; + return &argb_u16_to_nothing; } } From patchwork Wed Mar 13 17:45:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591667 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 D1993C54E67 for ; Wed, 13 Mar 2024 17:45:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 816EB10F738; Wed, 13 Mar 2024 17:45:37 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="FW86Axai"; 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 AE66210F6C2 for ; Wed, 13 Mar 2024 17:45:34 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 91CA14000F; Wed, 13 Mar 2024 17:45:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351933; 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=J5eNM0DhAMIgKT/kkCgWrA9s8H4fNzBpCgQ7okrYfr0=; b=FW86Axai64pv208U0YOs8bwxLfeRvCLXuYQaGc+0j4vcP5PYIi1LnxQW5mLQ/lhIUgY4ZF jZBCgpE/xUmgf/477wgcoiPYgbKmbpgp00ntlhoFZqVJaV5pqjRbjUC5PvfuCjlcUZNEOH Uqbq8S5dpWKojQeMtTAQBS2+IdbOYvEFyHQR7JZ24NiKkMEuf+Xmh1x5GDADFFL3I22HFA zOQ9mA9k6JGGSeK1j7zUORm+uZLa2Q9UcS7QUFUK7X/ipN7Py1l6dB3J1iLIB8AA1fvSY4 VsECNzRZEPGOG0mcxRgXGCztUoW9IEMRBf9AuiM4foFFnprUFRgxv97OFTNdEg== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:00 +0100 Subject: [PATCH v5 06/16] drm/vkms: Use const for input pointers in pixel_read an pixel_write functions MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-6-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6429; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=CsX4Bl/EEHcmw+Z+z88jdKEOU/WdC0wYmGUUTNJHiO0=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eYzJmuhbk5UOvwem9mRZcBZgFRuaMALqEd0DVpz 5Z9d8nuJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmMwAKCRAgrS7GWxAs4iUmEA CgpBgN8y/k8gzSXSZkY1+CFawep75UCzYQn52KNnsmIoh8Cxu0cvdis6uPF46OLUqtqZUlA4+DGVuw sA8KfaDlCW7ahC/ZhcpOlkegV3V4ou17c1ERlnfywGkO1mgULKuiwEnRxmBmmKsjS9iolckuKias1y fhE2kAVksA244hboNeeyAmB0EvEWNcJhLjL6f+98Rm7UdGws9jG/VsDHqjfp9GIgNUly33v5R59Cl2 steGyfvy1Wca8I7IgKhKO8GsAX6hbqmKEW7euYwi7GGK5Y3ej3LzK8FDCYwBna7pU7O/JK7IU//hmu 3Ufvcu56MYJ96Klk1HwJ8806V+G/QB+OFhKqQhYJtfpTqYZ+9f+CHB1XMB69Qh1f500AYh0/AUZycA 5v4lrJEVMQnnSUu4FtBLWsJlUwhkelqwN3i1163U3rgBG1z2d8sbfDTQKe/JipKILNIPKz1zPYXMXv 8msXGST8+O6FA3GXW6o+XH5+FNiTxronLuEzF9W8Xn1L7HGCUVbzNB6wNcPiRNbQuWy727JvhuybSH I74FWUOPpXlpDRBD0xT6VbFWwN136mpCQFW+/w3qNi9r0v0GjCWFSN2IYYrLbEamDcwn4v2GLNsdLs r41SWd+Ma8tX9hHBberB5lRWSbterkLFcl/ZPU/r5iaixtBfmUVbh7ZAp8uA== 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. Signed-off-by: Louis Chauvet Reviewed-by: Pekka Paalanen Reviewed-by: Maíra Canal --- drivers/gpu/drm/vkms/vkms_drv.h | 4 ++-- drivers/gpu/drm/vkms/vkms_formats.c | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 4bfc62d26f08..3ead8b39af4a 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); /** * 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 b57d85b8b935..b2f8dfc26c35 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -76,7 +76,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 @@ -90,7 +90,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; @@ -98,7 +98,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) { u16 *pixel = (u16 *)in_pixel; @@ -108,7 +108,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) { u16 *pixel = (u16 *)in_pixel; @@ -118,7 +118,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) { u16 *pixel = (u16 *)in_pixel; @@ -143,7 +143,7 @@ static void RGB565_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) * It is used to avoid null pointer to be used as a function. In theory, this function should * never be called, except if you found a bug in the driver/DRM core. */ -static void black_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void black_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { out_pixel->a = (u16)0xFFFF; out_pixel->r = 0; @@ -189,7 +189,7 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state * They are used in the `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 @@ -207,7 +207,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); @@ -215,7 +215,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) { u16 *pixel = (u16 *)out_pixel; @@ -225,7 +225,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) { u16 *pixel = (u16 *)out_pixel; @@ -235,7 +235,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) { u16 *pixel = (u16 *)out_pixel; @@ -260,7 +260,7 @@ static void argb_u16_to_RGB565(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) * It is used to avoid null pointer to be used as a function. In theory, this should never * happen, except if there is a bug in the driver */ -static void argb_u16_to_nothing(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_nothing(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel) {} /** From patchwork Wed Mar 13 17:45:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591671 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 0A177C54E67 for ; Wed, 13 Mar 2024 17:45:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2B6E810F815; Wed, 13 Mar 2024 17:45:41 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="SY2r2Hz9"; 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 A767210F6C2 for ; Wed, 13 Mar 2024 17:45:35 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 8404140010; Wed, 13 Mar 2024 17:45:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351934; 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=topb8prnlkO3hDZ+MWbWhdCxAg3fNHcFeHR+nVEh9+s=; b=SY2r2Hz9Fpc4yctZW8H2HFx6jYGVYRfJ7cCSJZSOBPqOHiGa2mSNDzVculX017Zkm4U5Uz 17TgvwfxAeukZUfQhDTBmGnRK9paQaEEkXIzI8k970c6lAJ/EcFsFukAMKWB17g/A6u/P4 U2UZx+FDGKoT88h1wNSAj8u02jIE676jAzdvnklL0oOz00BdKLZ0jOYzjZFqxTzzW0IZ8L rWrbqpZXxQHMaNd58juxsJ/BBHmOuEsKMIBhZkO1V+jsfvskRQMfBYWElXrUfbR2/runKU 2EYPy9b2hrSQRHWxXK1D/S1UcolvLFmN/PXh+c94mFdGcYgA04oZXnoejg7OJA== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:01 +0100 Subject: [PATCH v5 07/16] drm/vkms: Update pixels accessor to support packed and multi-plane formats. MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-7-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7195; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=SrBB5KXz1QL9eQ48nY2Dv3KvNWc0/mA4SAe3dTkfyww=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eYzeUgriFWBkcLj5STyEQDIjjz88wtpaeuxDI5s RTMuI7eJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmMwAKCRAgrS7GWxAs4taeD/ 95UOPYi6+vsQL5qaU93DnNr4j0t5/JVU7/tsZaiHaYlSNDu2yQtLinxqCdJi2sKxTYVsl8jLvczkCH u7fyTqVfCQ3B0PNRK9fhOzvbPaJQ6ZQnzhSa8OoSVK73fx4I5VnLfxayg0cj8cCJhbonbKjSQP40Bv yLYDO0N2/3xJQqMTGLrRViCwunfH/Ad0J1M6rVE3Vt1B2Vz6PYzTmG96QaIT4ie6WgsovBnUmqdduO oyZSNo7oNhT++9O9KeD4FP+RVfbcwtr0BRdJiXndCVqYIsu7WmirP0zx3ff65SEq1Pt3ZcC6XeCy7q WfJ+YczDlytylSG5kPRMo2cyUUnpob8f23skVGLyX86HvRyh8IGgYiXcL40dSzv63BkRY0QZhxhBZL qbt5f4pwfsdojRR8TEf7X28CYYhmbvrP3O93GKLRCTb8Tl6mpmK6LawpfqUzM/1PM9a83vfm8M3d+c kkdDfhnYaUg+tqa7bK9QpTz/e724gxJVrchU40nufbwz6T8xyoemnhzA1otzXeSP4vlF673zcOZSRW V0598GUD2R6CpOY61ubP52CwZ76shhynqQpPKNExDnK8ex7HDOkdg5hpZ/IDPCO8bi6x8J3lgrgs0R j9OfnyMY245cWwCnXVkIH6PF2S6G8/ueLqhurlL4COnh9gUezYJ1MpgluouQ== 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 | 76 +++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index b2f8dfc26c35..649d75d05b1f 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -10,23 +10,43 @@ #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,@rem_y: The returned 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); + *rem_x = x % drm_format_info_block_width(format, plane_index); + *rem_y = x % drm_format_info_block_height(format, plane_index); + *offset = fb->offsets[plane_index] + + block_y * fb->pitches[plane_index] + + block_x * format->char_per_block[plane_index]; } /** @@ -36,30 +56,35 @@ 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,@rem_y: The returned 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) +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; - 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) @@ -168,14 +193,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]); @@ -276,7 +301,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 Wed Mar 13 17:45:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591670 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 D872CC54791 for ; Wed, 13 Mar 2024 17:45:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C2A7210F80C; Wed, 13 Mar 2024 17:45:40 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="C9KMtrT1"; 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 BCDDB10F738 for ; Wed, 13 Mar 2024 17:45:36 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 7D7FD40008; Wed, 13 Mar 2024 17:45:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351935; 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=qMstdhDPz4vxVLkbs1vWT/dPmbE9XkubESTK+znot4g=; b=C9KMtrT1eyc93j8aSzRoeI+Anfo6BTjh8CtgsnrQ4qI945aV8Q7X22IrmF0kSLrcepkKlw i5fffyH3Mzd+nR9oWfDMG0n7ihjqXmGW8wWaAxDTi/W6gLCWA1M0IMX7o37s++P5c1VxUt pBwsztlBcWDDBtC+pX1mtw9vxM5YI+1WErSn66P144YVanc1bWAY2kau8MPHjwlWdCk19t jLm5kS97ZCi+Iip0mXDkuKCUu4L1Z2B63TGyX1Vq0Hhl7KEM/WsFNZVEVPeAEJ/9C1UaiV UOqTtjuKIdDLsRqKfr49qe6q3tHFXc6jVqTW/97LUawfSQXqnDsGxiSfvF2DbA== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:02 +0100 Subject: [PATCH v5 08/16] drm/vkms: Avoid computing blending limits inside pre_mul_alpha_blend MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-8-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4008; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=LN600J/FnLEqSMjYXKqVPbLYRqj27Lwqilp/WDPlSs4=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eYz9hf3F9w8htumYUb6KlKrtqpbmCKe8R5pvJ+o 4vwifwaJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmMwAKCRAgrS7GWxAs4gxJEA Cu7eY95oSNOqvf2k4uAo1LXtF3mJ7ntDFPjgsHg6Ii38d/o9UsDDlznI3IglIqYlm8vMQ3M3itfgjP JiY4cvCkjEuI+NCiF4TU9f0dBvNYGWS+YqnUi+9YAhq822Ucjd7xR6SkHCr5KiqRJuTZ20WXQLphfC QtNJwbFdMaQEsWtq/YGnguc8C0sJ4E5RZY7M6XWlt30foyGH8gwfSj4wvyqRA5AZy//H0hzdqy02FD +83HSAmVpn+CeUG70MdP0cdF2avbi/E3reUT2RGR1OPIRk27LT5Wec7Ofw9OZf1w5hLgR8Jayfug49 6rPJhrWvamqc3EeCZ6GLdJWPZn8wRVcVIo8L2QuCFup0uGPvZj4Z1wfabwiI/CWxtGRvVbIKv8eWVT EYcSZO2/dnk7dP604BXSX4LyZv5C5PIvIM9/M2sP995Qh2P9J9MHg2cykjm+TOuDdpq1wrXP5MZydR iR+2eQnGd2+hvIp+QPb6Jlnukq+ja9yNlplS73kK1KYyaQft7YNzA6rUWFLGsRJlZqu5HKnvU1iZWQ Cpj8kQWtyk3ikdaZEft2dVdDVSWvyrTaUNa5RdnNLDjKNXmEfTf2KLikJFIeytx8IAfIBvAgjlKxoJ fTnjopTJbccwWzppmiOtBSFt5GquwRuTT8qMFiRPr/WRcPnpV+IhuQpVOsbA== 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`. 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 da0651a94c9b..9254086f23ff 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 to avoid useless copy + * @count: The number of byte to copy * - * 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. + * Using @x_start and @count information, only few pixel can be blended instead of the whole line + * each time. * * 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, x_limit; 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; + x_limit = min_t(size_t, drm_rect_width(&plane[i]->frame_info->dst), + 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, x_limit); } apply_lut(crtc_state, output_buffer); From patchwork Wed Mar 13 17:45:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591679 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 D352AC54791 for ; Wed, 13 Mar 2024 17:46:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9BC0F10F827; Wed, 13 Mar 2024 17:46:08 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="LFweQlQA"; 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 845A110F7F7 for ; Wed, 13 Mar 2024 17:45:37 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 6C46A4000D; Wed, 13 Mar 2024 17:45:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351936; 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=fvpHRvoA+r8MzKnJomCYkfJhC+FGJMS1P3vzAB0//K4=; b=LFweQlQAF4K+c7LHmf8/B53B4G5O9T0xlfIwbSQFQ36QMkuAULBLSnpWvdefiE6rIU11CL 7hbt27JA27k6pJ10KcIvfxQah/NMEhdIuUoufRwRUT+I2NiBcLkFAAL1gbY6HHbb7LPlVI dHoLqPgNG9iweMMyjzfY4YAH3/P0OBFmSYpAX/0wLkccYQmJ4HaE4Jiy9ENPJdR9xvpy7v KMlpmg39itJJxtzE5kITWe6pZUxglsJ8NkYGHpS7vRAnPknIV61Xu5vt7tAcuV/Rf8+B5d tNQHaxwLK+kSNRyIqG+0n9Rfg+XlgFnWFTFyb9akHtHkZP5EZ6ooo+1vpVUvgQ== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:03 +0100 Subject: [PATCH v5 09/16] drm/vkms: Introduce pixel_read_direction enum MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-9-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4725; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=iIicmQla2LEzH8GgecY5rPqd6iTEX/DNAL/60xWRQwE=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eY0heQDZLj05nsF2/TlGqiprIBuyb8l2ca87FfG kaGUsQ+JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmNAAKCRAgrS7GWxAs4mkSEA CSwvsGnjmGlmwjnOYjROX2sIyNbOyjRKh8odmY5lqGL1bgskhTwgX3dawxInPK3GRSHCgH5WjgDGKA kJzSb8m6qEaYyLoH2wg+v0dOtOj+Wh1Y+zULx0U8LW6DoEjrYoKLyB+3xMNVTXEJ82BBObdtX2jXCi G8bZONkUdq/86G/l4sBl13vPsi1gr/CskWQ3dD2pRJQtZgtLIE9suSVUgATsMHKrsPqyw59nkAyCRN PDM8K+ua6I1ajYGSqDFwpKalGH0T1f7NkF03TKzxOWNrcgvax9aYHnzZEp25D2ppr4e3Zr03GPNNjx NYquf8Yec+/3CX/SUh3491DdMlIa9rciTcd1E1KzJDNtBcAidUxHwWTrEfbe79bmCZNcrrqyznHwYK FoHcSdiO36Fg2tfcSICycicdzM40rIZBuG5sWQmqL3+WNFZ1DeeZUn6UX5DfmoTrBZpt2KVwu4Uqtd 4SmlcMGWVplzDRepqxJLjGG7Rq5eI0ievf0QIKQgoiz7abK7NhJ9nCRjBEDXtSO7TW+r4tE6b04yAW WsOiSBtQXDW33HkzN03YEsph8H/HQejWGYdMhLHxSXk+n106eGBfiOflglmE2/iKjDLDlaw8WVrXi2 1BKLdbJs+zEaGBSwWGENhRJeIAhPhgfHmB9L9RSm9JThEZDGcQHfhUHzVm0Q== 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 | 36 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.h | 11 +++++++++++ drivers/gpu/drm/vkms/vkms_formats.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 9254086f23ff..989bcf59f375 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -159,6 +159,42 @@ 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 + * + * 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. + * + * @rotation: Rotation to analyze. It correspond the field @frame_info.rotation. + */ +static enum pixel_read_direction direction_for_rotation(unsigned int rotation) +{ + if (rotation & DRM_MODE_ROTATE_0) { + if (rotation & DRM_MODE_REFLECT_X) + return READ_RIGHT_TO_LEFT; + else + return READ_LEFT_TO_RIGHT; + } else if (rotation & DRM_MODE_ROTATE_90) { + if (rotation & DRM_MODE_REFLECT_Y) + return READ_BOTTOM_TO_TOP; + else + return READ_TOP_TO_BOTTOM; + } else if (rotation & DRM_MODE_ROTATE_180) { + if (rotation & DRM_MODE_REFLECT_X) + return READ_LEFT_TO_RIGHT; + else + return READ_RIGHT_TO_LEFT; + } else if (rotation & DRM_MODE_ROTATE_270) { + if (rotation & DRM_MODE_REFLECT_Y) + return READ_TOP_TO_BOTTOM; + else + return READ_BOTTOM_TO_TOP; + } + 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 3ead8b39af4a..985e7a92b7bc 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 649d75d05b1f..743b6fd06db5 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -75,6 +75,36 @@ static void packed_pixels_addr(const struct vkms_frame_info *frame_info, *addr = (u8 *)frame_info->map[0].vaddr + offset; } +/** + * get_step_next_block() - Common helper to compute the correct step value between each pixel block + * to read in a certain direction. + * + * As the returned offset is the number of bytes between two consecutive blocks in a direction, + * the caller may have to read multiple pixel 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. + * + * @fb: Framebuffer to iter on + * @direction: Direction of the reading + * @plane_index: Plane to get the step from + */ +static int get_step_next_block(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]; + case READ_BOTTOM_TO_TOP: + return -(int)fb->pitches[plane_index]; + } + + return 0; +} + static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y, int plane_index) { From patchwork Wed Mar 13 17:45:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591673 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 4746DC54E68 for ; Wed, 13 Mar 2024 17:45:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 28A1F10F809; Wed, 13 Mar 2024 17:45:41 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="VFADyqag"; 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 9E77510F7F7 for ; Wed, 13 Mar 2024 17:45:38 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 56B3B40013; Wed, 13 Mar 2024 17:45:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351937; 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=TnvwdimqSEcQBKzA3c0Z3gb3fjfIWYyWkufTOOgxbvw=; b=VFADyqag91NT0YlTG9GSgoVD2aYsTwh4zamQs+V+3/hrl//5Wt5SUrLPRxaMCULD1GcUNk GH8Mwc1e4luA6ZMmlT24PUJGFoaOKP1bd9KaD1T16AYYKLU2MMW5GnjLwxynzsSa4lqfL2 nFa/Zwq9W/BhGev0ZBh0RV1hMUF8vYwAfGzqko5BuPxrktbqtKXsAdMj2MJmLmIFG/G9y3 mIqdQeEgOmJzNKOjlAZ+OsbeHuNlVCC0FiYRxTc6cNh/ZPoQN/t0+S9bRXdQEQ3P4xmVLC cUqdO6dSzEhbNUVojUUUPsXQSMl7nymAPfQjQCXaF8Z7jZRsWqF9nNYWp8zqxg== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:04 +0100 Subject: [PATCH v5 10/16] drm/vkms: Re-introduce line-per-line composition algorithm MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-10-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=27042; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=4m3MZLm+SLybI8mDO1PzEFLIuxCLsbs2u+oKHfliEaY=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eY0UeEenlAI/xAzloeo3dN8Oh3dI4lPyXNhMyj8 Mr/o+w+JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmNAAKCRAgrS7GWxAs4phqEA CVB5iKL+GvsTu5349qw+/zayreDeCi8OqkX98iBtpAWDgKY0dBro93lRcCcZbukdm3U4q+xLLGA2xU BDw1Un3Q+eKroxoT58Xcm4io1gFuUiSIHOquiXpG8sndxUupskBMzRaI5cnd0FlmlZQ98JDBJmzymS yHSk2T1WkmBj61sHe1iwyCSejFeZXM7ZO/QgbXwvQQnQibB641mKFu4mcnyT+XYv3w48iQeOBLluzz XAT8rXjUzQlXFwMuw58SghR779HHu0EXLZcYQ7Q6e/4GG7zlDzIf85tOC0HQcn6gzDsNDaqcP9+rE4 aJTvHuNvOmexlVEhhUWETFwUHnBvQe0+eK0Aam+tVt2rf6Fn30GrU1NycqwL7L9Ost+1h3NCYkICJv pGedfu1NyWB7wyyMSyQ4IFoWpkHW8qgRVkw79dKJY74Cb79j+SycTaRIk5xtIFz/pu4jHKwMyF5Uuh +QcmkKOR8vxs2eDP94mdnaX/RTWsOsamSW2H6Jq3kqxRnmqbzXMX8kP7kTGP7tIRU4QIHWWByRrhTz XpnjeXu9V0u9jeG8C+f21Unvap7K24+2UhpD01a1T6rFpg2u2hvDPoipe//c+jbCEdpVrINSd/7jGJ U5DvCefzKgI/wN/Zo5n/IhgFZUOoGFPQmdJr8qP7Aq/0/LIMLXqtz0g4vsDQ== 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 [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]: Signed-off-by: Louis Chauvet Acked-by: Pekka Paalanen --- drivers/gpu/drm/vkms/vkms_composer.c | 167 +++++++++++++++++++------ drivers/gpu/drm/vkms/vkms_drv.h | 27 ++-- drivers/gpu/drm/vkms/vkms_formats.c | 236 ++++++++++++++++++++++------------- drivers/gpu/drm/vkms/vkms_formats.h | 2 +- drivers/gpu/drm/vkms/vkms_plane.c | 5 +- 5 files changed, 292 insertions(+), 145 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 989bcf59f375..5d78c33dbf41 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -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) @@ -215,34 +188,146 @@ 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, x_limit; 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++) { 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; - x_limit = min_t(size_t, drm_rect_width(&plane[i]->frame_info->dst), - stage_buffer->n_pixels); - y_pos = get_y_pos(plane[i]->frame_info, y); + struct vkms_plane_state *current_plane = plane[i]; - if (!check_limit(plane[i]->frame_info, y_pos)) + /* Avoid rendering useless lines */ + if (y < current_plane->frame_info->dst.y1 || + y >= current_plane->frame_info->dst.y2) continue; - vkms_compose_row(stage_buffer, plane[i], y_pos); - pre_mul_alpha_blend(stage_buffer, output_buffer, x_dst, x_limit); + /* + * 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. + */ + struct drm_rect dst_line = DRM_RECT_INIT( + current_plane->frame_info->dst.x1, y, + drm_rect_width(¤t_plane->frame_info->dst), 1); + struct drm_rect tmp_src; + + 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) + continue; + + struct drm_rect 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); + + int x_start = src_line.x1; + int y_start = src_line.y1; + int pixel_count; + /* [2]: Compute and clamp the number of pixel to read */ + if (direction == READ_LEFT_TO_RIGHT || direction == READ_RIGHT_TO_LEFT) { + /* + * In horizontal reading, the src_line width is the number of pixel + * to read + */ + pixel_count = drm_rect_width(&src_line); + if (x_start < 0) { + pixel_count += x_start; + x_start = 0; + } + if (x_start + pixel_count > current_plane->frame_info->fb->width) { + pixel_count = + (int)current_plane->frame_info->fb->width - x_start; + } + } else { + /* + * In vertical reading, the src_line height is the number of pixel + * to read + */ + pixel_count = drm_rect_height(&src_line); + if (y_start < 0) { + pixel_count += y_start; + y_start = 0; + } + if (y_start + pixel_count > current_plane->frame_info->fb->height) { + pixel_count = + (int)current_plane->frame_info->fb->width - y_start; + } + } + + if (pixel_count <= 0) { + /* Nothing to read, so avoid multiple function calls for nothing */ + continue; + } + + /* + * 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) { + // x_start is now the right point + x_start += pixel_count - 1; + } else if (direction == READ_BOTTOM_TO_TOP) { + // y_start is now the bottom point + 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, x_start, y_start, direction, pixel_count, + &stage_buffer->pixels[current_plane->frame_info->dst.x1]); + + pre_mul_alpha_blend(stage_buffer, output_buffer, + current_plane->frame_info->dst.x1, + pixel_count); } apply_lut(crtc_state, output_buffer); @@ -250,7 +335,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); } } @@ -261,7 +346,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 985e7a92b7bc..23e1d247468d 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,37 @@ 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 positive and smaller than @plane->frame_info->fb->width. + * @y_start: Y (width) coordinate of the first pixel to copy. The caller must ensure that y_start + * is positive 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] + * to @out_pixel[@count]. 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[]); /** * 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 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 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 { @@ -204,7 +214,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 743b6fd06db5..1449a0e6c706 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -105,77 +105,45 @@ static int get_step_next_block(struct drm_framebuffer *fb, enum pixel_read_direc return 0; } -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; - - 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 + * The following functions take pixel data (a, r, g, b, pixel, ...), convert them to the format * ARGB16161616 in out_pixel. * - * 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(int a, int r, int g, int 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(int a, int r, int g, int b) { - u16 *pixel = (u16 *)in_pixel; + struct pixel_argb_u16 out_pixel; - 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]); -} + out_pixel.a = le16_to_cpu(a); + out_pixel.r = le16_to_cpu(r); + out_pixel.g = le16_to_cpu(g); + out_pixel.b = le16_to_cpu(b); -static void XRGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) -{ - u16 *pixel = (u16 *)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 out_pixel; } -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 u16 *pixel) { - u16 *pixel = (u16 *)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)); @@ -185,12 +153,26 @@ 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; } +/* + * 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. + * + * Those function are very similar, but it is required for performance reason. In the past, some + * experiment were done, and with a generic loop the performance are very reduced [1]. + * + * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/ + */ + /** * black_to_argb_u16() - pixel_read callback which always read black * @@ -198,42 +180,116 @@ static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pi * It is used to avoid null pointer to be used as a function. In theory, this function should * never be called, except if you found a bug in the driver/DRM core. */ -static void black_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void black_to_argb_u16(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[]) { - out_pixel->a = (u16)0xFFFF; - out_pixel->r = 0; - out_pixel->g = 0; - out_pixel->b = 0; + struct pixel_argb_u16 *end = out_pixel + count; + + while (out_pixel < end) { + *out_pixel = argb_u16_from_u8888(255, 0, 0, 0); + out_pixel += 1; + } } -/** - * 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 - * - * 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. - */ -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; + int rem_x, rem_y; + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + + int step = get_step_next_block(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; + int rem_x, rem_y; + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + + int step = get_step_next_block(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; + int rem_x, rem_y; + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + + int step = get_step_next_block(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; + int rem_x, rem_y; + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + + int step = get_step_next_block(plane->frame_info->fb, direction, 0); + + while (out_pixel < end) { + u16 *px = (u16 *)src_pixels; + *out_pixel = argb_u16_from_u16161616(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; + int rem_x, rem_y; + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); - 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_step_next_block(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) { + u16 *px = (u16 *)src_pixels; - plane->pixel_read(src_pixels, &out_pixels[x_pos]); + *out_pixel = argb_u16_from_RGB565(px); + out_pixel += 1; + src_pixels += step; } } @@ -343,25 +399,25 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, } /** - * Retrieve the correct read_pixel function for a specific format. + * Retrieve the correct read_line function for a specific format. * If the format is not supported by VKMS a warn is emitted and a dummy "always read black" * function is returned. * * @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 Wed Mar 13 17:45:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591672 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 24794C54E66 for ; Wed, 13 Mar 2024 17:45:47 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5B59E10F819; Wed, 13 Mar 2024 17:45:41 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="Fvvd5fm+"; 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 7EE6610F7F7 for ; Wed, 13 Mar 2024 17:45:39 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 5B6DD40016; Wed, 13 Mar 2024 17:45:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351938; 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=RmbGHzpoiSKgZqMjcDD066gXk2gdMcvk9QYsJ8M1b5o=; b=Fvvd5fm+sp4KfrA2DORmK7/UyEtGyr4R7uX7QRi/c0ZIJhVuo+vqKpjmVpRoFlYIzkNpDX 45YL4JuNccejU04XAVFmPUSrKfWLsnBD/cm9vpRiIVA8kVIGDobO4rPLdnITWKxnBLWEyn QDR81ixQ3V5aXm2qlyy1S7ukH11H534vErdtpUPklslG/K2c9Q4Zwm7ZY9hHf5h4mkzCO1 FqEOZ3OuqyuqWtQzhPn2X5rMlRnHBHXr3b5utt4MW8qZPMu27FssYPOD24Mxeu8TUMjL3z pWVbnbeBLmHVNCZ4RlAIJSriqgrXLv/dGSxru738RhhnLTkhAXn9J0F2UMtWrw== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:05 +0100 Subject: [PATCH v5 11/16] drm/vkms: Add YUV support MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-11-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=20137; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=DuAUBevyqcFfsLfdI+QWb9XAI1PLzm1uuvy20tfcpmI=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eY07IpwsyWJ3/fsEYacswu9VzyZJvtla9F1mudI 2iDh8PWJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmNAAKCRAgrS7GWxAs4mUUD/ 0XYPtqJ1kApKf5H0qK9WAzgimIUlV5Sr2srBACyIiHDIKefHX+CaRq0+t5bFrNMMvxf63hK9F0MzFy i8jrM14Anpsuavg/xI8QbVS9dHqigx2V7EuGahjppYHnYTpKXayFef3IHJmBXx2jTce+yCeMlogas7 6gnkQBP/svU1ZPLsRGeM6wVQ783ChXv7x8d7KM9deKdce5ttlp3F/Jubmg4tVfsQVmpeXfOREFmZpp 5UUoXE8Wo0E1gA2LyrcUm43oR+KFNfotYEo3LYiTLn7zN56jzYE5vp4Wk9gny0nWCUoclOJx2tu9ft JcQDPz8kyp+Z7kjHe1BCJOh3F/o5fQNKMk4hNAwleVz4OqoSGd1RkgoXFF0i62reQ1aMLZjpdDJlJ5 VWow+iQ0qbBwT9EutO6vIBaNmwXN33rMhz1rxSM+8hkBXRH06a55o7KswFDxvul6hhAh0T5megeo5+ FK1paZ8hdVx5Th0ni3DuHSkDLIwDyHseaeNG43yB0SBpiHiQOFaCvniyfrC7Rxsd0hAY+JRQhRMBeU bhWY+kGwkhZhUGbU5RdxoKgSFSsVirMy/KMgISZbG2Xdmg7p8e8L3GVIRNpUtNjsxiaBrkqv7FwGPl +aoVgYrl1LMx0V+R1tIhqAqkTGzeEyXIiKuTmpGOrpmtUQf7gpiliAhmFwKA== 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 floats 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 - 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 | 22 ++ drivers/gpu/drm/vkms/vkms_formats.c | 431 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_formats.h | 4 + drivers/gpu/drm/vkms/vkms_plane.c | 17 +- 4 files changed, 473 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 23e1d247468d..f3116084de5a 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -99,6 +99,27 @@ 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[]); +/** + * CONVERSION_MATRIX_FLOAT_DEPTH - Number of digits after the point for conversion matrix values + */ +#define CONVERSION_MATRIX_FLOAT_DEPTH 32 + +/** + * 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 fixed floats, 32.CONVERSION_MATRIX_FLOAT_DEPTH + * @y_offest: Offset to apply on the y value. + */ +struct conversion_matrix { + s64 matrix[3][3]; + s64 y_offset; +}; + /** * vkms_plane_state - Driver specific plane state * @base: base plane state @@ -110,6 +131,7 @@ 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 1449a0e6c706..edbf4b321b91 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -105,6 +105,44 @@ static int get_step_next_block(struct drm_framebuffer *fb, enum pixel_read_direc return 0; } +/** + * get_subsampling() - Get the subsampling divisor value on a specific direction + */ +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 + */ +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, ...), convert them to the format * ARGB16161616 in out_pixel. @@ -161,6 +199,42 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const u16 *pixel) return out_pixel; } +static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 cb, u8 cr, + struct conversion_matrix *matrix) +{ + u8 r, g, b; + s64 fp_y, fp_cb, fp_cr; + s64 fp_r, fp_g, fp_b; + + fp_y = y - matrix->y_offset; + fp_cb = cb - 128; + fp_cr = cr - 128; + + fp_y = drm_int2fixp(fp_y); + fp_cb = drm_int2fixp(fp_cb); + fp_cr = drm_int2fixp(fp_cr); + + fp_r = drm_fixp_mul(matrix->matrix[0][0], fp_y) + + drm_fixp_mul(matrix->matrix[0][1], fp_cb) + + drm_fixp_mul(matrix->matrix[0][2], fp_cr); + fp_g = drm_fixp_mul(matrix->matrix[1][0], fp_y) + + drm_fixp_mul(matrix->matrix[1][1], fp_cb) + + drm_fixp_mul(matrix->matrix[1][2], fp_cr); + fp_b = drm_fixp_mul(matrix->matrix[2][0], fp_y) + + drm_fixp_mul(matrix->matrix[2][1], fp_cb) + + drm_fixp_mul(matrix->matrix[2][2], fp_cr); + + 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, 0xff); + g = clamp(fp_g, 0, 0xff); + b = clamp(fp_b, 0, 0xff); + + return argb_u16_from_u8888(255, r, g, b); +} + /* * The following functions are read_line function for each pixel format supported by VKMS. * @@ -293,6 +367,79 @@ static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start, } } +/* + * This callback can be used for yuv and yvu formats, given a properly modified conversion matrix + * (column inversion) + */ +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[]) +{ + int rem_x, rem_y; + u8 *y_plane; + u8 *uv_plane; + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &y_plane, &rem_x, &rem_y); + packed_pixels_addr(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, + 1, &uv_plane, &rem_x, &rem_y); + int step_y = get_step_next_block(plane->frame_info->fb, direction, 0); + int step_uv = get_step_next_block(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); + 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 and yvu formats, given a properly modified conversion matrix + * (column inversion) + */ +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[]) +{ + int rem_x, rem_y; + u8 *y_plane; + u8 *u_plane; + u8 *v_plane; + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &y_plane, &rem_x, &rem_y); + packed_pixels_addr(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, + 1, &u_plane, &rem_x, &rem_y); + packed_pixels_addr(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, + 2, &v_plane, &rem_x, &rem_y); + int step_y = get_step_next_block(plane->frame_info->fb, direction, 0); + int step_u = get_step_next_block(plane->frame_info->fb, direction, 1); + int step_v = get_step_next_block(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); + struct conversion_matrix *conversion_matrix = plane->conversion_matrix; + + for (int i = 0; i < count; i++) { + *out_pixel = argb_u16_from_yuv888(*y_plane, *u_plane, *v_plane, conversion_matrix); + out_pixel += 1; + y_plane += step_y; + if ((i + subsampling_offset + 1) % subsampling == 0) { + u_plane += step_u; + v_plane += step_v; + } + } +} + /* * The following functions take one argb_u16 pixel and convert it to a specific format. The * result is stored in @out_pixel. @@ -418,6 +565,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 @@ -435,6 +596,276 @@ pixel_read_line_t get_pixel_read_line_function(u32 format) } } +/** + * get_conversion_matrix_to_argb_u16() - Retrieve the correct yuv to rgb conversion matrix for a + * given encoding and range. + * + * If the matrix is not found, return a null pointer. In all other cases, it return a simple + * diagonal matrix, which act as a "no-op". + * + * @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 + */ +struct conversion_matrix * +get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding, + enum drm_color_range range) +{ + static struct conversion_matrix no_operation = { + .matrix = { + { 4294967296, 0, 0, }, + { 0, 4294967296, 0, }, + { 0, 0, 4294967296, }, + }, + .y_offset = 0, + }; + + /* + * Those matrixies were generated using the colour python framework + * + * Below are the function calls used to generate eac 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 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 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 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 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 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 struct conversion_matrix yuv_bt2020_limited = { + .matrix = { + { 5020601039, 0, 7238124312 }, + { 5020601039, -807714626, -2804506279 }, + { 5020601039, 9234915964, 0 }, + }, + .y_offset = 16, + }; + + /* + * The next matrices are just the previous ones, but with the first and + * second columns swapped + */ + static struct conversion_matrix yvu_bt601_full = { + .matrix = { + { 4294967296, 6021544149, 0 }, + { 4294967296, -3067191994, -1478054095 }, + { 4294967296, 0, 7610682049 }, + }, + .y_offset = 0, + }; + static struct conversion_matrix yvu_bt601_limited = { + .matrix = { + { 5020601039, 6881764740, 0 }, + { 5020601039, -3505362278, -1689204679 }, + { 5020601039, 0, 8697922339 }, + }, + .y_offset = 16, + }; + static struct conversion_matrix yvu_bt709_full = { + .matrix = { + { 4294967296, 6763714498, 0 }, + { 4294967296, -2010578443, -804551626 }, + { 4294967296, 0, 7969741314 }, + }, + .y_offset = 0, + }; + static struct conversion_matrix yvu_bt709_limited = { + .matrix = { + { 5020601039, 7729959424, 0 }, + { 5020601039, -2297803934, -919487572 }, + { 5020601039, 0, 9108275786 }, + }, + .y_offset = 16, + }; + static struct conversion_matrix yvu_bt2020_full = { + .matrix = { + { 4294967296, 6333358775, 0 }, + { 4294967296, -2453942994, -706750298 }, + { 4294967296, 0, 8080551471 }, + }, + .y_offset = 0, + }; + static struct conversion_matrix yvu_bt2020_limited = { + .matrix = { + { 5020601039, 7238124312, 0 }, + { 5020601039, -2804506279, -807714626 }, + { 5020601039, 0, 9234915964 }, + }, + .y_offset = 16, + }; + + /* Breaking in this switch means that the color format+encoding+range is not supported */ + switch (format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV24: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YUV444: + switch (encoding) { + case DRM_COLOR_YCBCR_BT601: + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + return &yuv_bt601_limited; + case DRM_COLOR_YCBCR_FULL_RANGE: + return &yuv_bt601_full; + case DRM_COLOR_RANGE_MAX: + break; + } + break; + case DRM_COLOR_YCBCR_BT709: + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + return &yuv_bt709_limited; + case DRM_COLOR_YCBCR_FULL_RANGE: + return &yuv_bt709_full; + case DRM_COLOR_RANGE_MAX: + break; + } + break; + case DRM_COLOR_YCBCR_BT2020: + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + return &yuv_bt2020_limited; + case DRM_COLOR_YCBCR_FULL_RANGE: + return &yuv_bt2020_full; + case DRM_COLOR_RANGE_MAX: + break; + } + break; + case DRM_COLOR_ENCODING_MAX: + break; + } + break; + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YVU444: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV42: + switch (encoding) { + case DRM_COLOR_YCBCR_BT601: + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + return &yvu_bt601_limited; + case DRM_COLOR_YCBCR_FULL_RANGE: + return &yvu_bt601_full; + case DRM_COLOR_RANGE_MAX: + break; + } + break; + case DRM_COLOR_YCBCR_BT709: + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + return &yvu_bt709_limited; + case DRM_COLOR_YCBCR_FULL_RANGE: + return &yvu_bt709_full; + case DRM_COLOR_RANGE_MAX: + break; + } + break; + case DRM_COLOR_YCBCR_BT2020: + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + return &yvu_bt2020_limited; + case DRM_COLOR_YCBCR_FULL_RANGE: + return &yvu_bt2020_full; + case DRM_COLOR_RANGE_MAX: + break; + } + break; + case DRM_COLOR_ENCODING_MAX: + break; + } + break; + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB16161616: + case DRM_FORMAT_XRGB16161616: + case DRM_FORMAT_RGB565: + /* + * Those formats are supported, but they don't need a conversion matrix. Return + * a valid pointer to avoid kernel panic in case this matrix is used/checked + * somewhere. + */ + return &no_operation; + default: + break; + } + WARN(true, "Unsupported encoding (%d), range (%d) and format (%p4cc) combination\n", + encoding, range, &format); + return &no_operation; +} + /** * Retrieve the correct write_pixel function for a specific format. * If the format is not supported by VKMS a warn is emitted and a dummy "don't do anything" diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h index 8d2bef95ff79..e1d324764b17 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); +struct conversion_matrix * +get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding, + enum drm_color_range range); + #endif /* _VKMS_FORMATS_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 8875bed76410..987dd2b686a8 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 * @@ -117,12 +129,15 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, 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_180 | DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y); vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt); + vkms_plane_state->conversion_matrix = get_conversion_matrix_to_argb_u16 + (fmt, new_state->color_encoding, new_state->color_range); } static int vkms_plane_atomic_check(struct drm_plane *plane, From patchwork Wed Mar 13 17:45:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591674 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 4007DC54791 for ; Wed, 13 Mar 2024 17:45:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F1A3810F81F; Wed, 13 Mar 2024 17:45:41 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="SeJaOX7n"; 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 7C9C410F7F7 for ; Wed, 13 Mar 2024 17:45:40 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 591544000C; Wed, 13 Mar 2024 17:45:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351939; 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=HGht90527wTlRNy6SY5xIteQweC9dJDueCATJTo/DTY=; b=SeJaOX7n6doU+eefHX7cVezfOdU1JJCLw0gKn17svzaauJd1hPiZ4FZuKeI5T/64yHJgv3 H//8p2QGtw/FiNo/vrIDuOYGfodKgQL/nMeehr+Uam7OYU2mIgeYj/yCAIGPNFz7NmFEEd jhKVDGtrkcKjbx6gMSMH6oc8qrByOWZdQ9UD3SwvqjEapusXTsOaThFZnwgVWxUjhUt275 SzMbLjLRhWasXkCV1tE5iQ1OfnWFsr+me08qrQMMYVDNPoy5apKDDRM6sKrYdwj2WK+a7d goUArI/ETkMaF5fXLU/hD4RDbQAYO2mQoscdnmBZ06YTgW2XFrQW9JvffzOztA== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:06 +0100 Subject: [PATCH v5 12/16] drm/vkms: Add range and encoding properties to the plane MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-12-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1196; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=6BLB7fPlNtj8wcSXI7NyfW833syTdxfhkEAKw4gWOys=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eY0kDZ4PGG0/Q6LPMiTDAw3lAupi3pDIHSzJQz9 PApOGKeJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmNAAKCRAgrS7GWxAs4pfVEA DRV22TaZl1roNuVVHsfj+Bth6rfCVXeGHm/xKG3ZE0sFvFotdnUNph4WAxPIWEr7uSB5edl8ENW7FM KN3vY92Gg0IImK4kf8Ic1PLzoNphjEzoCdW4KKMYSpEDwAXwmR830Zj72/6HjcSPr7z2gmj3GZLskx D63BJicemRyNf3tqjPjjj1gVzh7ElHkrE9F/GtMlUHxRrE8grX/Ou8E9FdqoPisIoXjbp0KMT21zTH +GiFhVC032j7Mlj2c7PiVvzs8hm1u0unfnnh5e3l5Wxk3h4jEZK1lPyMO5yOnlbC1QnO0kL//UJT0v l7/SDE87x2SkFgAOzNxRGpQ6dqIBelt+JoSQjEE2HVy8J9uyuTo0aImTpdZ68PYIEihBX3vO4bnkZK GrcBybVZApfk5TdIJV1h2hZPOyHwTQOAkPLdcEqgHWRy3r0Ir6bFf8Gs3wfiNb+OxWz8IqIos9d1k8 OjAxFv5CveSzJh1JTPusxkLGRYAyHW4U+KetUPOD8/+ecC5O/OXpmi4TNVEw9ctQIt3Q63BD8XJ8st NUwsBJuTUwZKwLDdLi8vs8nPhvPSjxojrFmXZl21gtgGLJ82SJ//7ZQ6E3tCtT1QKyrfx2LMtZZrA9 ChgDxZeOmIP40qSyeWLQXRwDTo14Nd4+y3KgPRHC3e9iThAb6sl6FsdIZlMg== 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] 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 987dd2b686a8..e21cc92cf497 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -224,5 +224,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 Wed Mar 13 17:45:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591675 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 64D7BC54E66 for ; Wed, 13 Mar 2024 17:46:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4A4F410F7F7; Wed, 13 Mar 2024 17:46:01 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="C17aOn2S"; 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 8E56E10F6C1 for ; Wed, 13 Mar 2024 17:45:41 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 548B340003; Wed, 13 Mar 2024 17:45:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351940; 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=1mJQirOrh5uVlCQFN4AJsimww+6ayqe/xDiVoFk4V7I=; b=C17aOn2SwmfUwqtxzCrK39wG/2jjP8yjS1HTKUdVG5VwmS+QkJF9R8k4HP12CqqtPLC+H9 CnKpdEbM61q9WcVM8hy4au9Dn+qTR3wYiU6iwf2sq78tD1zR5WTPgJLGCaM5YArxQdRI9x CLhRRu/IJwQD3DarkM9mEYk7KvCHFR07MpTYl3sC7maz7LslCsoCDX2qvWSHIvw8wVxUJ0 uJpiHJNgvtxbvgHYv5cI3mIRcsMXdRCL1gawcGjCWUima1VA0snk4i8JNf6tHnY8Gw0o3a nd3bDDNAxtF45pc3t2fw8c/b7xZF2cVc8N6yZT2Hj9OXdGuGHPsd6KKPku9CDQ== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:07 +0100 Subject: [PATCH v5 13/16] drm/vkms: Drop YUV formats TODO MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-13-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=881; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=cRkkP1b8eceTuEm0QTSGTTTnDinaYzDjRJLok06bIiI=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eY0+z3WAhCy2IMeG8a1Zkre9wnYeZj8SIIpx9sY HczWmz6JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmNAAKCRAgrS7GWxAs4jW4D/ 4qAo1dZm2a0nRqQiHL6nTT0z4G5R7SoJRefwwbIQ9oLn/87s7B7lyyvNnZ5twDZHPD7NMALtU2x3R9 hOyeInWO1ZcOa6ilo8NZjAZE2wUBkM8X1hDd0G4rV7cGNzxr6YvLNKm+sY7w3QZzQNuXOXmPc9k2z2 50WEb8f/NnXGZfg9lfTsyAxoAe5mgnPrarHmMNTGO0ji1z8tj5xY96Az9fTx68JH8lgFJ2zk4n7N3l Je0bDoz0U63X4Ir7MVm1QohDt6+GiKU+brYD20ldmdYd3AtOl2W0h59ExJi3CdfNm0DO2+uZkHUkDV l3ooPA7SqZ1D+//2ahX0s1e+5p0Lhhd5yomiOuaaFslehGHLXN/tqPi4j0xA8GWmOH/jLERJ3IP+Ie 7AZqUU3WUWIDliNwzqknwAKhhTHH2LaZOCUqArJBcZm4qWeghPZyGo5hAiFo3JCXg1ZBzdVE3yrgaQ sjxKUYvrHokeUUl9SlyMtNuJG3rcxH9iC9CaviRM9PCno3Egx3DGWw/AkE+nIAtCkIMjz5wSRkX0Xg aFH+3A23XZL+QIOC9kGmEsNrAEMR1FzKmvCyz0X2IO0i/hJO+bd67hexUth/y+Qb0jGzjtXL+cLEEI NjqwSNlAtd+XEQQYtS0BsuNjXjXCIMH0xUG3cPOjtPYzOZgtmPAnnnoPYjQw== 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 Wed Mar 13 17:45:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591676 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 9559EC54791 for ; Wed, 13 Mar 2024 17:46:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6448610F801; Wed, 13 Mar 2024 17:46:01 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="N5eK5rLz"; 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 7D0D410F6C1 for ; Wed, 13 Mar 2024 17:45:42 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 4218140011; Wed, 13 Mar 2024 17:45:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351941; 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=L+8KoEpO2IWGv9JRRqBCQWLwDOAVJikmAaabAeNMcO8=; b=N5eK5rLzFLoDtTffxYXn816j2dpZh03nbAhOu6EGXMDfHEwWNLYSPjcFV+5xC18+XHhwTV mTRzoHHPvciQIOe7PByb0gJbygURLIgZkRHimBlHUE1vGjVVdiyLfXNek3O6cBp5k//yRX wyUe3jjyo7J/C5o+wHaFkbZJOQPwYyqZVX+i5ZNabjj37uhRafZ2AAcWoJBt/L2stNZbsx Cc+tFR6GbmU/+w1tF5Zhp/jQ2UfGz4VJz8R7dfDuK4Hi5QeRU1rNiFnmeoLICQO4JFQdW9 TEU4msfkHc2OraLfdcw0rKT05QaSkLj4lZQ4XYTm4XqoRElrwIknZAeNVzrVwA== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:08 +0100 Subject: [PATCH v5 14/16] drm/vkms: Create KUnit tests for YUV conversions MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-14-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=13522; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=NwSv/ORkaecyeVISHs/IZQX2eP++OQsZXLK46HRqCCw=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eY1NngNRWpFwcpGK3UcWmNcLdoE0nOzy6RfPfCG NuqHNrGJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmNQAKCRAgrS7GWxAs4npeD/ 9ZDUcwUlW6M2FG4ou8XVds4sMXcbEtfSY155dxF1uojjlQeMHymffdUlg2vkOsPGsx8RFUseE5h1n8 Tp4ZufRQLuxaq8bLTwvdUR9MPr/OkLBmMO7QZ+6PUIR7WFNzmNvki5tGwtC1nc5lhD1SvqhHgSO7Fy jRBfBcree1BltQCQl39LbPCOqKVPyejn1hB4cfncsEKF/EQbboF7/Cf6yatYdG5uNxWCaRMPzYOD0X rOMwXSAD3I8FjA2HGKU/N04MZ2NeXM89qUNOYzcLOxSiP/xHqAQNnYMoJw2b/PlBsbVihGj49pDaNl 9gr+2leS/x2Nw8Pn9NXAkgAv9BwiUPWkSa/Jw2sW1ylKTaDY1SUk6/kLleP+PoF/qq513PFHKT3/hA OhuBrAckMZBjQUdzsPxQGf/vmTzgwjptIwP5ezo/aYn3nexio0cN5aLHJkZnhRD149ikZ5DENiTUrX t3dcgZlZVXUw7eeD7/PJ7nMsBCMny+lHVObvriKdLFn/TpzHF1JFdE4clFryFF6A1r40+cPuB6wIJr nhJwafJmA4vg05AimDqRPGOxwEVLkEcQD2ObdBkUBMlUrtc0vTxNBC+CHidMSxmdiSfCpuFU4XzIvC j0Cb6hJC76JiYk+tGRA/LpnZK1nPcRhJZsGOII4f5FLmnfXr8qluBUEj/gyg== 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. Signed-off-by: Arthur Grillo [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: Louis Chauvet Acked-by: Pekka Paalanen --- 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 | 230 ++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_formats.c | 7 +- drivers/gpu/drm/vkms/vkms_formats.h | 4 + 7 files changed, 262 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig index b9ecdebecb0b..9b0e1940c14f 100644 --- a/drivers/gpu/drm/vkms/Kconfig +++ b/drivers/gpu/drm/vkms/Kconfig @@ -13,3 +13,18 @@ config DRM_VKMS a VKMS. If M is selected the module will be called vkms. + +config DRM_VKMS_KUNIT_TESTS + tristate "Tests for VKMS" if !KUNIT_ALL_TESTS + depends on DRM_VKMS && 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". \ No newline at end of file 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..0954d606e44a --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +#include +#include +#include + +#include "../../drm_crtc_internal.h" + +#include "../vkms_drv.h" +#include "../vkms_formats.h" + +#define TEST_BUFF_SIZE 50 + +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); + + 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"); diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index edbf4b321b91..863fc91d6d48 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" /** @@ -199,8 +201,8 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const u16 *pixel) return out_pixel; } -static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 cb, u8 cr, - struct conversion_matrix *matrix) +VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 cb, u8 cr, + struct conversion_matrix *matrix) { u8 r, g, b; s64 fp_y, fp_cb, fp_cr; @@ -234,6 +236,7 @@ static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 cb, u8 cr, return argb_u16_from_u8888(255, 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 e1d324764b17..21e66a0cac16 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -13,4 +13,8 @@ struct conversion_matrix * get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding, enum drm_color_range range); +#if IS_ENABLED(CONFIG_KUNIT) +struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 cb, u8 cr, struct conversion_matrix *matrix); +#endif + #endif /* _VKMS_FORMATS_H_ */ From patchwork Wed Mar 13 17:45:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591678 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 4055DC54E66 for ; Wed, 13 Mar 2024 17:46:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8AFD510F81E; Wed, 13 Mar 2024 17:46:07 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="bLW3cNJR"; 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 5C3D810F82F for ; Wed, 13 Mar 2024 17:45:43 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 2C1AD40006; Wed, 13 Mar 2024 17:45:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351942; 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=8vk8BNwGJAqLAVQ9fBvlyUPWgU+vNkf+DhOlg0zqa0Y=; b=bLW3cNJRdq9O69RxPLYwYn6gVkVh9n1OZD37GkUSiUe/lcj91kk1cnaUzNfeFuy3gc72KS SCvwMXpkDxQA8vedGwSz1IrrxOfEoCatKQEUzN4h3qUuihkDaLrDr6FVPk7ngF34nOeMPD 668mmp6IiX3f+P4xsY9R987a4PQo5C7Yar2VCeqrOGz03F7zzQ1YVGFuJYupY9x599CXQf H+wlLImP9gysyEkJgrxDnl5ZisuYDPX5xzi9XF7RjbOLm609rj0+tzf246r9thI+cJQXVE qHszhokmo00bvsDSZhy/DzUliC2G1ifUZ7lSoOdJ4w628TCIzUT+dpWtzUcSNw== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:09 +0100 Subject: [PATCH v5 15/16] drm/vkms: Add how to run the Kunit tests MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-15-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1115; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=jNe6Bg7KTpSpUer0keg/YQY7YaZCbb33mwHbW/nyqss=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eY12s9vTfK6gwWnR4reCKg4IXVlpGyhmzhmWrto MPwKF5SJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmNQAKCRAgrS7GWxAs4hTVEA C2PHQezur5a6ktgpKuZBu6etHWoSjMt8FaDmTTzOXNY+P6s0IYJ23vG2KymK/KwyY9llh20XM74lsm 3BsShoiasnrBMOQhUm3R5EajOLFC+vw2h1RjuOTbVzAZCCpNOwuSMmFGDUMau/FCQRd646pUu4f0gI kBQCbicjKmWk0rmtdRw4694pmILamnfehF2LBsywpXOmU3nFHd6xSsqcJZv9f6/qJXqOhIRbvPKe4H iTM3bGLyYZjD66MSfHHgFcVyIOC24wKxWwYegNmfK4Fo+Z3EyGQ2rckh37eo4KPje1hYVY4eoj4YJd s1MXh7/PdhuqbcIu8gODqsriyLtOR3fm/cEtIeYl4n4Au3v4p/fHew0bZSrjYSYg5t4iCSuRNrjr6I Pq89f7LtAodaO6k6SAVKRXscIGdGF4psqQYs3cuElgu8p8iw+gVQG7rs141cWbD3risexzxiLtqrtg QtrJqC4b4hruBbCNCyO3a8ObB0iHK9XuzBHgH+M0tQfNLNCKIpPQ43Vg1U1M/T+JvM9r1T/mpYds/K Tmz86+RNrI6ALMHSUNqX65awQZhBvnGKzFRalB0LnTxtMqAFbwWKP3IhoLJ6Z39VHy0eyY7mZrvlJ5 Q9CFGTTESlMpuUh9xNWVDIj4JgTu6UsgXzzxEGy+YmVSQblv9PMiPKzWi63Q== 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 Wed Mar 13 17:45:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13591677 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 0ACF9C54E67 for ; Wed, 13 Mar 2024 17:46:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DD92E10F814; Wed, 13 Mar 2024 17:46:01 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="mBg24YhG"; 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 322CA10F6C1 for ; Wed, 13 Mar 2024 17:45:44 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 125AC40005; Wed, 13 Mar 2024 17:45:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1710351942; 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=jXogfLj07V/5NU7N2k8u25LuCo1tbpPLvfUwLakxFt8=; b=mBg24YhGBR7be0MtBRaL+gbZvRu8G2jc/m6rx8XACcY4qIPL61153Jvi2GVpxAURWIG/eH qhouCXV56ohvAUu0vKgenodoVtQ8S6e7XsbxXRhAEx4g014UVvpa2mSEqVoBRPe4mtxE6/ lAz+zJiYagtudyMYNBPirj65O2YXe3BWwJ82dqt9TuPtXlOpdAcUjSAKYO6LkbkT7SGTQ6 17cg+wCFHRddC77Gq8CVOjWYbg9UIOdPVdl1mFuGqA6zhHMIFWMJanswzHKOimsxL87CHG H1/0H5OKAlbWLxmMGjcJniPGqyKNZ2bkyD9vijxa83KRIdMDqTibdYRhUe4T7g== From: Louis Chauvet Date: Wed, 13 Mar 2024 18:45:10 +0100 Subject: [PATCH v5 16/16] drm/vkms: Add support for DRM_FORMAT_R* MIME-Version: 1.0 Message-Id: <20240313-yuv-v5-16-e610cbd03f52@bootlin.com> References: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> In-Reply-To: <20240313-yuv-v5-0-e610cbd03f52@bootlin.com> To: Rodrigo Siqueira , Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, jeremie.dautheribes@bootlin.com, miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, seanpaul@google.com, marcheu@google.com, nicolejadeyee@google.com, Louis Chauvet X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5760; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=9rA67U9H0cUfYO3fgMPTyUG7C69zMCKQfaLOUG8oJ+A=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBl8eY1Q7D2/rrZJHb7RkqnZoULnQUuc8BbwKC3nJG4 UflwfJqJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZfHmNQAKCRAgrS7GWxAs4pLaEA C3FRWES+R2Y2GR1j8ZLeP/Ccwoq2SgYrj8b9O6eq/tWPy+6QhRXTg01U+5wcCjRFfZIeZUnLtu/XOQ 2fUHPXOy4wEwIqKW3jtYsihl/9vBnCPKBfQ2vXFQYflzEI0iV6Tx8X1SjRgG9oIiF2KyqlO9n4cVBR rhpCFNnlos8ubrVQaG/xDvdrMVMjHn5rvwYSTW3ct6xbxue7Otzb7NLVdE2b/Awq22upazC7UPfHYr mvKopiLDw/hDJN8FCmOPqyCMyJ08IkKQk5CVt3qbo09I9e8Ns1cpLFnXdFPIkzK5EAdlM0NzQ/H0dB j31pBCx103LClrItIaHL9PK06ZRrIKgsso97Gym3FVyeQDmYNpQH1oIQDqTk45VlNvY4hshRP89wTQ sa3pl5c46krOY5VdiAKXwCDDik4oKAP1H6Dcgoq6+ZGmkMtQlcxioPKGms9N9/+/AhL7SujLVrbeOW eYYxglRYGtjmr0G2BtSrWIc6Efhqf/QTnvFpM1R1TfRAUrVnnnQkIlwg5G/LU0IRYbbLuhMoV1IaNG wMP10VNhe2FAZdzNPQCEcl5E6ET5uDj0BuqetAdWoOChHbkx/15KWUmP5pEuVVSDXvV9w3mRTYVHql Koc9fm2n0XA8GwAJbvvA3+ZM6+QYfXHQWKnFenwBXXrbtXxqbPgECVdUu68A== 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/ Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_formats.c | 100 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_plane.c | 6 ++- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 863fc91d6d48..cbb2ec09564a 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -201,6 +201,11 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const u16 *pixel) return out_pixel; } +static struct pixel_argb_u16 argb_u16_from_gray8(u8 gray) +{ + return argb_u16_from_u8888(255, gray, gray, gray); +} + VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 cb, u8 cr, struct conversion_matrix *matrix) { @@ -269,6 +274,89 @@ static void black_to_argb_u16(const struct vkms_plane_state *plane, int x_start, } } +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[], u8 bit_per_pixel, u8 lum_per_level) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + int rem_x, rem_y; + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + int bit_offset = (int)rem_x * bit_per_pixel; + int step = get_step_next_block(plane->frame_info->fb, direction, 0); + int mask = (0x1 << bit_per_pixel) - 1; + + if (direction == READ_LEFT_TO_RIGHT || direction == READ_RIGHT_TO_LEFT) { + int restart_bit_offset = 0; + int step_bit_offset = bit_per_pixel; + + if (direction == READ_RIGHT_TO_LEFT) { + restart_bit_offset = 8 - bit_per_pixel; + step_bit_offset = -bit_per_pixel; + } + + while (out_pixel < end) { + u8 val = (*src_pixels & (mask << bit_offset)) >> bit_offset; + + *out_pixel = argb_u16_from_gray8(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 & (mask << bit_offset)) >> bit_offset; + *out_pixel = argb_u16_from_gray8(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, 1, 0xFF); +} + +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, 2, 0x55); +} + +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, 4, 0x11); +} + +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 rem_x, rem_y; + int step = get_step_next_block(plane->frame_info->fb, direction, 0); + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + + 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[]) @@ -582,6 +670,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 @@ -855,6 +951,10 @@ get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding, case DRM_FORMAT_ARGB16161616: case DRM_FORMAT_XRGB16161616: case DRM_FORMAT_RGB565: + case DRM_FORMAT_R1: + case DRM_FORMAT_R2: + case DRM_FORMAT_R4: + case DRM_FORMAT_R8: /* * Those formats are supported, but they don't need a conversion matrix. Return * a valid pointer to avoid kernel panic in case this matrix is used/checked diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index e21cc92cf497..dc9d62acf350 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -29,7 +29,11 @@ static const u32 vkms_formats[] = { DRM_FORMAT_YUV444, DRM_FORMAT_YVU420, DRM_FORMAT_YVU422, - DRM_FORMAT_YVU444 + DRM_FORMAT_YVU444, + DRM_FORMAT_R1, + DRM_FORMAT_R2, + DRM_FORMAT_R4, + DRM_FORMAT_R8 }; static struct drm_plane_state *