From patchwork Tue Apr 9 13:25:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622503 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 A7172CD1284 for ; Tue, 9 Apr 2024 13:25:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3C0B0112D90; Tue, 9 Apr 2024 13:25:50 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="gPaNz7GW"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id B798B112D8E for ; Tue, 9 Apr 2024 13:25:45 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 6714324000C; Tue, 9 Apr 2024 13:25:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669144; 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=UcMT+vo8fgkNrjXMLk1SAa4ydpU1c4KtU31Ws4EQRDU=; b=gPaNz7GWryUK3TbCh1q2424leY0K5zz+Fqv/oSZahzQKVdXc9bYlRSZ1Q2rKn44q6+Hhuf tIb400qYhL2Q/OLgdI7+ivcnGR2Jy/8uAY3tNvTCNYigvc2KS4K9zcs4cG/QUvxi/agFJj nx8j3bfAb4IP4RQEzBbba0o27xrkKaH23X8CC27rTKAVckAMCcsg1kF8x3WAR+JdRLixau ZH4TIH7bJ4lLh1GyFVQPZHNT9cD04JUSBCOqNpXgxpqD7NPWLb80dsn8YhboE5QAiQodXN Rxg3ITVwynlV51mhxOSJ/eLLjB8xM9FgZOphbAJU6+19C/L5VKfkIV5cA3P5aA== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:19 +0200 Subject: [PATCH v6 01/17] drm/vkms: Code formatting MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-1-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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 , Pekka Paalanen , =?utf-8?q?Ma=C3=ADra_Canal?= X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=4941; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=Ctv1MLMXYDKALnFrvVXqUApJNktccSvUqf8PTlsd3Vk=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHQwrnzUv6M1IvWqx0+WR0ga0Kukxl8T5kva PKZNehQWNGJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0AAKCRAgrS7GWxAs 4nwOD/wMs4iRxdi19yyIe8cJVIZFNbrOuM/Q/uMYdfrDV3EskEQMNAcHCgh0fH6/hEIP8TtQ1Hj uq/Es8EaqP5bkAQ6PSoSsesWR6DiVxwg6MeFO2rF8GyOH48ubVTibNg1LWu+Nd4ArLUsMgGENg8 v3zEKPWpGO0rxhtObELnwwfEMpHYlQnVIbwSsQVrl22t/awxShi2hK/znsVsDcF91kKjyd8uIyh jANLnFl8UDRG36AYEXO9ktONw9yAgNrkqmePLMuQ2hCupCxo2VynMAP275mhF2E2zhqhQybhDv0 srmbkzXeVZhEHlMrz3EjrCXkOxRoF+KdVoj/0HzXlkilkNvsdTp5LDM9/KNzLQOUyg9IiruAEWm iBO1Y5+wfnpyVgnqbsqElkyXmFTJu3aRuUyQ+teuvrOadT2ANeFWjkqzYC9q0cvBdxsquoQJrjs WWEqkDFWz9qizsVzzZua7b8XnLeZmPLNoiI9ObdaiS3hxW1C/GlrLkFjCr0rMMdNlFvLNfbPY20 IGdsmLenhtTDCOUP66iPNQn1ibNmSND+hM/hlf3Ov6613wf6cdegEuOWmc0TtFunRz0Ji8qnZ72 reLYPnPs8fJyIMWONqSrN0KnqtV5vMnqX8/ToO6BKG7JUqPSBBG6uUwjLunWD3AZBlUA1MWIFQc Kd0gBgBemYjlv0Q== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Few no-op changes to remove double spaces and fix wrong alignments. Reviewed-by: Pekka Paalanen Reviewed-by: Maíra Canal Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_composer.c | 10 +++++----- drivers/gpu/drm/vkms/vkms_crtc.c | 6 ++---- drivers/gpu/drm/vkms/vkms_drv.c | 3 +-- drivers/gpu/drm/vkms/vkms_plane.c | 8 ++++---- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 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 Tue Apr 9 13:25:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622519 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 95F14CD1296 for ; Tue, 9 Apr 2024 13:26:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 615A4112DB6; Tue, 9 Apr 2024 13:26:24 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="lwQj/0fV"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 106ED1123D3 for ; Tue, 9 Apr 2024 13:25:46 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 835DE240011; Tue, 9 Apr 2024 13:25:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669145; 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=Oi7GyBKm/1sZhqvwqoQ6b5yrUzjVC/wNzft01alK/6w=; b=lwQj/0fVX0QprDSVhQmQWMFBbITaVosfjSOJd6IfydVaOuOwuUBIRxQSjMnmkbtWjpa9uz OQPWu5oPHMyN+lGcx3FpfhM5TJ67xCs70TmfvDXF4jVE0giGoyHpkdE5LBw54n0jjeuUOU GU1y7q/v9E+/7ZKZx7qEdHF8m9cdH+a5pU96b14rGu0fFk9ycCrvLCApBkjR7tn5vSumc8 JTPh/SU9v66IUFw5nuhx6AGst5QZmeictJeULAQACIO2Nka68Byg1osavIPAhnPu6VMO49 LVt3GaVGtcnooacg0HQwhiI4lO8qQy/lZEt9CLvD/payun5+4d8v5kuG10YE5w== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:20 +0200 Subject: [PATCH v6 02/17] drm/vkms: Use drm_frame directly MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-2-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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 , Pekka Paalanen , =?utf-8?q?Ma=C3=ADra_Canal?= X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=4272; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=P538Lnjn6stqlM903i7YJicw7rzokxcvfQ5Tjel3y4I=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHRw8F7cP2+JyqWuZPhNLWy9PUY5CeyIw9Cj WmfxkV5PxOJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0QAKCRAgrS7GWxAs 4m4+D/4j4woHHXNs2iL/hOVZNAu/SFEu/ecWEOKLdVntYRs5eSMjQf6rihg014v4uZZEo9XMoSR tTgRoP6Y8m4Vufq+fTV7l56VTlL1a1UJ40o/LvCSD5BIcjcZl78zlkFpUBFMg3we7vHaM2/eR/R QxQ1V0yqW9HEoysyL7svkGZbEXz12Y7ylbxvLXgzdpR5HGaFVPknQiKN1rRkG27iLNKabVjNMIB tVM4117TheKc9MUK8D9T0Z+v1hi4PcQpZBcdh0dAQOo/x4YIoVG/8Rf1i2cLIXgQM99BH4I8yw+ jfc6M/wejQfEBUPQqKwmobg4rjXqYkqJMxX0u3HD7fHM6qLfqNHTbeChNmfRSE8uLbDmmJCGz5f JgGw5zTipnenhlgiyxnenqxyK3IDyaG/EmilTpH5MmsS/p5DFxAwp0OCLqegLd1CKUhjCUQmgrP ti5S/vpAMpTxmslSlb6HnyzXTOnPcKhRp8DAUMnOBpbxXb/Eewjaa3Ia1dOY84Q9sHlqKXAUY7H 1F7iOPx+R4C8lKRM4pR9FzQU9c2tOtv/EJaVrlk07aTojnBdsg2eVUBc3XNJ0KOYsQDomyek4L8 8L6zpZ2yQWwnxasbrVLDjSb2n3n9423P16zG+yYWVjHMxCzuH3JCi5muSCulWPBZvgwEGYFw7kY 8rdsy3VAxvJm+VA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Remove intermidiary variables and access the variables directly from drm_frame. These changes should be noop. Signed-off-by: Arthur Grillo Acked-by: Pekka Paalanen Reviewed-by: Maíra Canal Reviewed-by: Louis Chauvet [Louis Chauvet: Applied review from Maíra] Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_drv.h | 3 --- drivers/gpu/drm/vkms/vkms_formats.c | 11 ++++++----- drivers/gpu/drm/vkms/vkms_plane.c | 3 --- drivers/gpu/drm/vkms/vkms_writeback.c | 5 ----- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 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..d597c48452ac 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -11,8 +11,9 @@ static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int y) { - return frame_info->offset + (y * frame_info->pitch) - + (x * frame_info->cpp); + struct drm_framebuffer *fb = frame_info->fb; + + return fb->offsets[0] + (y * fb->pitches[0]) + (x * fb->format->cpp[0]); } /* @@ -131,12 +132,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 +224,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 Tue Apr 9 13:25:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622517 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 14CC7C67861 for ; Tue, 9 Apr 2024 13:26:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D66FC112DA7; Tue, 9 Apr 2024 13:26:21 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="T7xIZI+D"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 23111112AA5 for ; Tue, 9 Apr 2024 13:25:47 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id BDAC3240013; Tue, 9 Apr 2024 13:25:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669146; 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=4hjEDAG/XIZxKuMYGyzJPCctK8bCbeQAujWuOuwxeXw=; b=T7xIZI+DEqmYE/WHent4D0qKg/OJpwgjfZm+31XT2vZTJ7ENoXnM+SktMzm7emOcgRJZp8 X+tnlgo7QK7LFP4iTAw0Dl61bESa3xCm5lAGb8rbCqTejCh+uEcIs388C3tGeuaqIeUrkI zpSlX3ObOlXDdcy2oYHhgyqMSK5nGFjb8l+VWlPoK4TK11WRfwLFtu6HurxyblHd2A7Hc7 5UgTRwGrllPNFS3KuTbfnQKKg3sbobLETHQORq51kvdtoz+rRTgtfXbYi58q08f9br/xTL VECa19B/4rpfiUCORx9SM1D/69s6JZKmrJ4nfuhngkkdEWljmX9b7fsq8N1/cw== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:21 +0200 Subject: [PATCH v6 03/17] drm/vkms: write/update the documentation for pixel conversion and pixel write functions MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-3-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=7486; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=164qTOxE3KUK4t9/ok9gCy0euOEROLUxKU8GIhJ3Pdk=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHRQbhMmtKgiHZ3xFZs0vN1XIgKcinWV8pKB UfSttpTHYGJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0QAKCRAgrS7GWxAs 4vcMD/43m7oXnoZmN6DKhdh0V0MtqNJ5HtRltDn2tmxdMufCXChzNMrszhDLsC6sGyVAh3un7Jy 7sCNK4JE+IzM6K9QM56C7Quzum/siXjvQW2veI5/3oQCor34yt+y27vjzEjAFOSJoC7mXRZDrBp uYRMM/DrtwmTgeBDv3QcJ1sC6Zl/Cr/sHaCbhGy0KKVCmVqmBlxT3rgTirl1zYp6UUKrbi2+9KE VtLzDH9ZTBG+bW47F+GIyDMP8+aLzu21QzYyRKz6FyyQ2C9G5W8QQs6Acuzr9cfmhCdRn23+uNI 4jQKEvcP/weoueKCGsB8LfZeEhqC1ZMmb6J58vk9zH7k6xSiV8AFP74X5GO/iEojdWpjLms8I4X Ecr6YkLJ4Nd/YMkHHGUnGuVU0ntXL5DGhE2JKGy+O3ojP1yc9NY2a48XdNXFjcpbR0udR2iuLlV dsamVhFfK0AMuX7e+k+phEohwtTvP3X4637Hzs+E204tt35KDaWen4o+LdqRpTru4IYppc611/J cJV7GK5s8Iq1cp2dS6hAWaLn1eLgt7O5SAF5EPDVE1opHBvOtm/kZcs53Dj2RHetlf4rtAM3EZM NnX6nPOKSAhB0bPTJQW6gY+spnC1Qfrl2aYpd1QJxlMhz8mmOF2ze9mG6XyVmOzsHYZztfbSkqm t28Pkk0DnuOg5Nw== 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 Acked-by: Pekka Paalanen --- drivers/gpu/drm/vkms/vkms_composer.c | 7 ++++ drivers/gpu/drm/vkms/vkms_drv.h | 15 ++++++++- drivers/gpu/drm/vkms/vkms_formats.c | 62 ++++++++++++++++++++++++++++++------ 3 files changed, 74 insertions(+), 10 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..a86cb537d6aa 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; @@ -49,9 +60,11 @@ struct vkms_writeback_job { }; /** - * vkms_plane_state - Driver specific plane state + * struct vkms_plane_state - Driver specific plane state * @base: base plane state * @frame_info: data required for composing computation + * @pixel_read: function to read a pixel in this plane. The creator of a 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 d597c48452ac..f157c43da4d6 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; @@ -16,18 +28,22 @@ static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int return fb->offsets[0] + (y * fb->pitches[0]) + (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) @@ -52,6 +68,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) { /* @@ -144,12 +167,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 &struct pixel_argb_u16 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 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) { @@ -215,6 +237,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); } +/** + * vkms_writeback_row() - 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) { @@ -228,6 +258,13 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, wb->pixel_write(dst_pixels, &in_pixels[x]); } +/** + * get_pixel_conversion_function() - Retrieve the correct read_pixel function for a specific + * format. The returned pointer is NULL for unsupported pixel formats. The caller must ensure that + * the pointer is valid before using it in a vkms_plane_state. + * + * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) + */ void *get_pixel_conversion_function(u32 format) { switch (format) { @@ -246,6 +283,13 @@ void *get_pixel_conversion_function(u32 format) } } +/** + * get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format. + * The returned pointer is NULL for unsupported pixel formats. The caller must ensure that the + * 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 Tue Apr 9 13:25:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622506 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 5DEC0CD1284 for ; Tue, 9 Apr 2024 13:26:05 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D3043112D96; Tue, 9 Apr 2024 13:26:03 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="PIeyH31h"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 71E8F1123D3 for ; Tue, 9 Apr 2024 13:25:49 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id D358A24000B; Tue, 9 Apr 2024 13:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669147; 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=CNzoEZ/z9QrJVyBrzpuMJr5lfZGOEej1fX2AbtIAvRw=; b=PIeyH31h4DL1Pi+x/J7wROKTEGowBQROfxdyUFGnfXn8yjT8csBgakwN2NQbaSOZ7IF0f2 dXiutAqza+6RIEW3bybCwLZuWzu+ECOZBaPHcEdI5qhxrbDv7i5w2bqv1n20CAYlOU/ObT XjLaU9sRsCV9CEU+S00Yw65Lrp0qV4bhM0ueCisx8XkgUKMT/D+mupdzP9Ll8B2lfFodrP AuiNTXTd2Ml8johS96wLiZDbOPsEBu9AOSlnDNFMRXcWpD1wNyS8NrEHmCTF9dYcP+zSOM QhCFwW7I4Y1IzmYutE3oguWnuiV2lrvUrxGBOiKNG4dWnpPmND2vSDQgsomJkg== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:22 +0200 Subject: [PATCH v6 04/17] drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-4-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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 , Pekka Paalanen X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=12736; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=D743RPPybcYKuYzH44Oi8Xkyf5eJbc6UjZL9Lmlrdtw=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHRuscs0+XM5tidWSC4RY4d6qT3EOcDG+v4c Grf3wu2PDmJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0QAKCRAgrS7GWxAs 4q8eEACSkEBd7VfY4cEvjSAiavuL6ZF81KC/TSt1CFIslgiTnQPXfvh8k65hTqT/QnPQJYbMrf0 PMg70bXz+qg2tzxL4e/yKmZnyzFIUqoTaLfIDVjvWdBy0c0gBRHmoBtN+1Of7PfeYGi26wOcMmV wnDq1JMye+Cjj55p2RaifHBhK/tkHixKYQuoVinmONR0i3r+zlf5Ps1/34LDcd7oOlJPf84+Fuy 8Vx9kkAhSfsWg7tpVYEuqa1X9WKePfql+BFjXLskBTI2shH1V7YgzIQHCn5knpheCUSt8E6dmog Sr3Tnbby2DxoD/a8CMzuwzDffXPfSzTVRTlE49Jc09GHzKghOekV1yNTZBWo0Ry726JUN+mY4am 72SavYKJyeJ1FN6Ofx8igWgQHz4kad5ggcCzK/hadZnWVWJ9UTEPgQSV9DdaNQC6wwgiZqurbeE 8wHloTQqC92brmN5dM+amaEDb2H2I8LIvMhJ1sWh2939w+LyB0+cdWy0lR7v91S1yogZYtR4Gih dWj3tllTa+m4JHRaBGm/WZ6QdQLCdB/zQRNdyV0Irca9Ohj7kYx8g1MA/d04J2jlcEY9E3zUNbC MrwmqIDNYH2uXPmPlpO713CDnRSpfE5OAZl0AmNMpzHwK6ziecVUIxWK89EH6JQBtV6FH6jKkK2 xScJ9+TeoQR5fmA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Introduce two typedefs: pixel_read_t and pixel_write_t. It allows the compiler to check if the passed functions take the correct arguments. Such typedefs will help ensuring consistency across the code base in case of update of these prototypes. Rename input/output variable in a consistent way between read_line and write_line. A warn has been added in get_pixel_*_function to alert when an unsupported pixel format is requested. As those formats are checked before atomic_update callbacks, it should never happen. Document for those typedefs. Reviewed-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_drv.h | 23 ++++++- drivers/gpu/drm/vkms/vkms_formats.c | 124 +++++++++++++++++++++--------------- drivers/gpu/drm/vkms/vkms_formats.h | 4 +- drivers/gpu/drm/vkms/vkms_plane.c | 2 +- 4 files changed, 95 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index a86cb537d6aa..d6fd9ff973d1 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); + /** * struct vkms_plane_state - Driver specific plane state * @base: base plane state @@ -69,7 +88,7 @@ struct vkms_writeback_job { struct vkms_plane_state { struct drm_shadow_plane_state base; struct vkms_frame_info *frame_info; - void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel); + pixel_read_t pixel_read; }; struct vkms_plane { diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index f157c43da4d6..6b3e17374b19 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -75,7 +75,7 @@ static int get_x_position(const struct vkms_frame_info *frame_info, int limit, i * They are used in the vkms_compose_row() function to handle multiple formats. */ -static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) +static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { /* * The 257 is the "conversion ratio". This number is obtained by the @@ -83,48 +83,48 @@ static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixe * the best color value in a pixel format with more possibilities. * A similar idea applies to others RGB color conversions. */ - out_pixel->a = (u16)src_pixels[3] * 257; - out_pixel->r = (u16)src_pixels[2] * 257; - out_pixel->g = (u16)src_pixels[1] * 257; - out_pixel->b = (u16)src_pixels[0] * 257; + out_pixel->a = (u16)in_pixel[3] * 257; + out_pixel->r = (u16)in_pixel[2] * 257; + out_pixel->g = (u16)in_pixel[1] * 257; + out_pixel->b = (u16)in_pixel[0] * 257; } -static void XRGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) +static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { out_pixel->a = (u16)0xffff; - out_pixel->r = (u16)src_pixels[2] * 257; - out_pixel->g = (u16)src_pixels[1] * 257; - out_pixel->b = (u16)src_pixels[0] * 257; + out_pixel->r = (u16)in_pixel[2] * 257; + out_pixel->g = (u16)in_pixel[1] * 257; + out_pixel->b = (u16)in_pixel[0] * 257; } -static void ARGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) +static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { - 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); @@ -168,12 +168,12 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state /* * The following functions take one &struct pixel_argb_u16 and convert it to a specific format. - * The result is stored in @dst_pixels. + * The result is stored in @out_pixel. * * They are used in vkms_writeback_row() to convert and store a pixel from the src_buffer to * the writeback buffer. */ -static void argb_u16_to_ARGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_ARGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) { /* * This sequence below is important because the format's byte order is @@ -185,43 +185,43 @@ static void argb_u16_to_ARGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel * | Addr + 2 | = Red channel * | Addr + 3 | = Alpha channel */ - dst_pixels[3] = DIV_ROUND_CLOSEST(in_pixel->a, 257); - dst_pixels[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); - dst_pixels[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257); - dst_pixels[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); + out_pixel[3] = DIV_ROUND_CLOSEST(in_pixel->a, 257); + out_pixel[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); + out_pixel[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257); + out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); } -static void argb_u16_to_XRGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_XRGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) { - dst_pixels[3] = 0xff; - dst_pixels[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); - dst_pixels[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257); - dst_pixels[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); + out_pixel[3] = 0xff; + out_pixel[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257); + out_pixel[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257); + out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257); } -static void argb_u16_to_ARGB16161616(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_ARGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) { - 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)); @@ -234,7 +234,7 @@ static void argb_u16_to_RGB565(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) u16 g = drm_fixp2int(drm_fixp_div(fp_g, fp_g_ratio)); u16 b = drm_fixp2int(drm_fixp_div(fp_b, fp_rb_ratio)); - *pixels = cpu_to_le16(r << 11 | g << 5 | b); + *pixel = cpu_to_le16(r << 11 | g << 5 | b); } /** @@ -265,7 +265,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: @@ -279,7 +279,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; } } @@ -290,7 +299,7 @@ void *get_pixel_conversion_function(u32 format) * * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) */ -void *get_pixel_write_function(u32 format) +pixel_write_t get_pixel_write_function(u32 format) { switch (format) { case DRM_FORMAT_ARGB8888: @@ -304,6 +313,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 Tue Apr 9 13:25:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622504 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 5A361CD1296 for ; Tue, 9 Apr 2024 13:25:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4E441112AA5; Tue, 9 Apr 2024 13:25:54 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="X6PrbbC8"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7DC701123D3 for ; Tue, 9 Apr 2024 13:25:50 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 0AB57240012; Tue, 9 Apr 2024 13:25:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669149; 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=otbY3dyaK1xzegWiEm+JvrF5ZlRlYhNif7wGB0lFHTo=; b=X6PrbbC8W2JXMRiYSZo+XIEvRXF8D3ZRCUZe/k4HBCXGBG8M+BC73vvsiyItC2sp/9UAPG fVKbg5lBdKaqz0c0cw44aEJTXSnQ8+TAxRM4CrYxYlfH9kPSs4LgwV4JP/q1JFhvj+vbPG 9h0NXd8fAvxYFmAYBIILlPrHZgJQax3eCuVGHTPnz8iKl56A/WPzP+WAXkjlWtRUyeld/5 WeoLZHb+Jo1fGIon5/n8jXU4dZ72Iosvf/ASXll9ujHtJVWqGL+lvujF0Swb0vDDM8A9aI 2uuPT5EUhq/NsujjLuBPDijrVZofnvjM0bq9a3Q01QvrZLOqYF8ZlfW04dDWaA== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:23 +0200 Subject: [PATCH v6 05/17] drm/vkms: Add dummy pixel_read/pixel_write callbacks to avoid NULL pointers MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-5-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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 , Pekka Paalanen X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=4683; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=jy8xSXJEOqn5wUFVqbS80+Pv0J4IEDT2C+geoMLpavQ=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHRjnIKr6XaGUdRrQ/zSO85JD+Bgx2elpHeg azBWENJYTqJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0QAKCRAgrS7GWxAs 4gTcEACqiz1/FHfzWsEmZe/7eBdcnJaNPjHjeR+Xmw56wExV0oSp0264h431jkCPK+3is6hQBGG auMMUJ5EGF60T0tvGxT06VVsALKj3EKY11Qjt+pAH69ESGJJLrc34QKutBkhrzUQgfet0pWD173 BW96lXufbZOihE0OKmPcAFb72pjOguTiq9CJ7z4cjHc2odJ6XNwznsLO2xhTYuzb19joflTPj3X ecsk/sbUNDSymYqiN09GRvAwM5hBGmpSYML50ls5vGAEaBdwbRMJzuyVL9dr2mVNwznGANQgE6l OiNeI/i46Zs6MZCLmxRsa5UJDMCxKFt67l1JxhsINioogyiJP89+KB+MgPhxToUX72NdmKmudFp 1aImmor5YUAUDm+aWk8ac4utobGbXfPAhaOSwEf/cdCIZHdICgi04BfG8porn4xzfx0xN/iyPiF pFrmLFF3tjG3wZOUxyHo+1taWyO2lLVHHZeSHUETt6jkoDS4DiioEyBGd/5tBEtMXf2h0vJ8DnJ koZ4gb+ii/LsDruFQVMlEop1I807KkErax1LyJNAQBRGiZEe90LoQAb54dlRc7ZCInHAlgZNL+Z kWiII67BhGqlGEQnp3/IsvuIeZbdm/gHeyyQ9BdBt2Beh0n0BuYLfDDH8YrZotXwb+ql35d9xUo Sz/epifT4/hJkeA== 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. Acked-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_formats.c | 45 ++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 6b3e17374b19..c28c32b00e39 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -135,6 +135,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)); } +/** + * magenta_to_argb_u16() - pixel_read callback which always read magenta + * + * 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 magenta_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +{ + out_pixel->a = (u16)0xFFFF; + out_pixel->r = (u16)0xFFFF; + out_pixel->g = 0; + out_pixel->b = (u16)0xFFFF; +} + /** * vkms_compose_row - compose a single row of a plane * @stage_buffer: output line with the composed pixels @@ -237,6 +252,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) +{} + /** * vkms_writeback_row() - Generic loop for all supported writeback format. It is executed just * after the blending to write a line in the writeback buffer. @@ -260,8 +285,10 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, /** * get_pixel_conversion_function() - Retrieve the correct read_pixel function for a specific - * format. The returned pointer is NULL for unsupported pixel formats. The caller must ensure that - * the pointer is valid before using it in a vkms_plane_state. + * format. + * + * If the format is not supported by VKMS a warning is emitted and a dummy "always read magenta" + * function is returned. * * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) */ @@ -284,18 +311,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 magenta" function is used. It means + * that during the composition, this plane will always be magenta. */ 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 &magenta_to_argb_u16; } } /** * get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format. - * The returned pointer is NULL for unsupported pixel formats. The caller must ensure that the - * pointer is valid before using it in a vkms_writeback_job. + * If the format is not supported by VKMS a warning 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]) */ @@ -318,10 +348,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 Tue Apr 9 13:25:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622505 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 AB9ADCD1284 for ; Tue, 9 Apr 2024 13:25:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 22E8F1123D3; Tue, 9 Apr 2024 13:25:56 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="UJxGcM6P"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 82596112D92 for ; Tue, 9 Apr 2024 13:25:51 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 1482C240009; Tue, 9 Apr 2024 13:25:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669150; 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=SEB6zkSJJhnV1xPil5tjnP9+rrhWJG+icwGJTNeHQgY=; b=UJxGcM6PxsnEKn47Kik77njQu/Vz/XN3WLlqHuegbgJ2fxvKvRCINg5eNtzhCboUN4YqTG 1svtcnw8U+WHflW4+yT/1wVFfGl07SsLeYwHyLjB0ahmtdEK5R0PpKNtcqPnOAgKyLgoO3 X1plVb5TGCGzoIgO1is2bWgvlKK7+2pImDKTQw0QjNxylA6yz1G5L7fi6XgDh7PilKvAdk +kiFiIwB8VyX6CFPNjybpbMj/cvhQm53+hdOHVLxtcYVu7GhsagTCVGm4ebuTa0D5NoiMy lFelde+QLzJrnh1wtvt8Xm4yNcUPLJDvLjJM6ox6v3H3A3Gi0/JPl5lA443qJA== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:24 +0200 Subject: [PATCH v6 06/17] drm/vkms: Use const for input pointers in pixel_read an pixel_write functions MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-6-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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 , Pekka Paalanen , =?utf-8?q?Ma=C3=ADra_Canal?= X-Mailer: b4 0.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=6553; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=wrfbM/7ZhlgBzw2eIfyFq2UguxKdPGwVe5WR560stW4=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHReLu1TUTPGXBIoeV/hQvLaw34rmSTm5RCT j7D5lBLV9KJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0QAKCRAgrS7GWxAs 4i7iEACganlvjVU3KseR0lOtb+fL4ulJlUTvHNvUqrUJtURnUpyv301A/mxZIhsA/JyTixnEGak TGnV45EZGf8cK/3gJEkUy/0C8mLCr5vtbZPWydG2BLB0XOOhz9HbhsQv896JSz65956vc8ZziZz s9nWFfg0gsR0GgX/2Ye4nGTbK9BDZq1qU3zzpQB7h8iozp1JJgSVG3cw4rZNgPVHFT3msslK7vP oRWAe6IcQJ/g1fTrGUiPFod+fmRy21rbSq/hL6BH73A3bsjILKyPUfwVPubMIRDeufclv6rc+5S CGf/sQ6BWeaHLLxOjirOTAbTmKSFzbR6RnlKEj6OVVt8T+64F1XxM1QdTQmm/lk9WwcSQgfDup9 l3piY3jzdllR3JDwrWYlrjKj5wRg5Mv4aRimNjep/SGr69aeFMevwbsHR+W5qPlUjZXvt2Q0Z6f YoNQRSgW6bpOsc97Rjyh4fMINXyI1W1dlHhztN2fUY1rAAI952RU17qeQeBaGY/rO7NPI0ax8Gg invVpUZqOGnbG/v3cDcVYhRPaXGHnHKC8U0Gkb/W+exXQCseUmyD8WWkt6ojvHrR0+qguGiRV0V xLxgt0pmiWKPw7inYnjdYlOwSSGtV0bHWt7kF+CfnBiGJFC2vrg2/WCvkXhVoulibrZi3nwuiM1 oxevHDgFIJA4D4g== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" As the pixel_read and pixel_write function should never modify the input buffer, mark those pointers const. Reviewed-by: Pekka Paalanen Reviewed-by: Maíra Canal Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_drv.h | 4 ++-- drivers/gpu/drm/vkms/vkms_formats.c | 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 d6fd9ff973d1..2e1a1b824a3c 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -61,7 +61,7 @@ struct line_buffer { * @out_pixel: destination address to write the pixel * @in_pixel: pixel to write */ -typedef void (*pixel_write_t)(u8 *out_pixel, struct pixel_argb_u16 *in_pixel); +typedef void (*pixel_write_t)(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel); struct vkms_writeback_job { struct iosys_map data[DRM_FORMAT_MAX_PLANES]; @@ -76,7 +76,7 @@ struct vkms_writeback_job { * @in_pixel: pointer to the pixel to read * @out_pixel: pointer to write the converted pixel */ -typedef void (*pixel_read_t)(u8 *in_pixel, struct pixel_argb_u16 *out_pixel); +typedef void (*pixel_read_t)(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel); /** * struct vkms_plane_state - Driver specific plane state diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index c28c32b00e39..69cf9733fec5 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -75,7 +75,7 @@ static int get_x_position(const struct vkms_frame_info *frame_info, int limit, i * They are used in the vkms_compose_row() function to handle multiple formats. */ -static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void ARGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { /* * The 257 is the "conversion ratio". This number is obtained by the @@ -89,7 +89,7 @@ static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) out_pixel->b = (u16)in_pixel[0] * 257; } -static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void XRGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { out_pixel->a = (u16)0xffff; out_pixel->r = (u16)in_pixel[2] * 257; @@ -97,7 +97,7 @@ static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) out_pixel->b = (u16)in_pixel[0] * 257; } -static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void ARGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { u16 *pixel = (u16 *)in_pixel; @@ -107,7 +107,7 @@ static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pi out_pixel->b = le16_to_cpu(pixel[0]); } -static void XRGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void XRGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { u16 *pixel = (u16 *)in_pixel; @@ -117,7 +117,7 @@ static void XRGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pi out_pixel->b = le16_to_cpu(pixel[0]); } -static void RGB565_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { u16 *pixel = (u16 *)in_pixel; @@ -142,7 +142,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 magenta_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void magenta_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) { out_pixel->a = (u16)0xFFFF; out_pixel->r = (u16)0xFFFF; @@ -188,7 +188,7 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state * They are used in vkms_writeback_row() to convert and store a pixel from the src_buffer to * the writeback buffer. */ -static void argb_u16_to_ARGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel) +static void argb_u16_to_ARGB8888(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel) { /* * This sequence below is important because the format's byte order is @@ -206,7 +206,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); @@ -214,7 +214,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; @@ -224,7 +224,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; @@ -234,7 +234,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; @@ -259,7 +259,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 Tue Apr 9 13:25:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622508 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 D3FD5CD1296 for ; Tue, 9 Apr 2024 13:26:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 96E48112D92; Tue, 9 Apr 2024 13:26:06 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="K/gDMQMI"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id EBDFC112AA5 for ; Tue, 9 Apr 2024 13:25:52 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 4EA95240015; Tue, 9 Apr 2024 13:25:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669151; 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=kKfCbAYW4rXkv6BYjOSiRSj9s8zIipInrp9O4l0hCbY=; b=K/gDMQMI8hHBUolMjC2j2IsjkAuByuRDABjU1YNOqAddjYjiWVKpDGvW6pbxYDngUdkoFp kZ12hJCKQBX3/YyndZWBr2qksJ4WHjpC0q/xz5yHaw9X2XGSfEn3b1fxnbNbDnMlJxQiyG ur1Q9Fn2VTpsYsqEDkoY9ujPCPa9L8ZYNCuq4paBhRDmUiO90yr1rZsjj4PEWzU8wG+SIT rUqyyTKRuKMLIYJ4LIa1ofXtmTcOt10zlXmMcM/JNRcz4JPSikLjx49B1INMMU4vKRTgXY ABVJsFT8ZpLuspbRvctUkm16TsZ94oEovs7dDBH5TDOCCtXVoVzF0rjFzAPe4A== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:25 +0200 Subject: [PATCH v6 07/17] drm/vkms: Update pixels accessor to support packed and multi-plane formats. MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-7-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=8553; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=bApw2fd9r1g4lEoqGsctmEAfSEELUERH7BXSO0MphVk=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHSRvR2iRWacX4xCp5eoJb2DHDjmafNduj0B +bJ+FSMKU6JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0gAKCRAgrS7GWxAs 4oSRD/4gdKNDr5TmX049zGT60VMfIxf9g8Ki9P2I7DeZA3LYPI4PLKaZe6cQcNW1YRTlcka4JsT W6r6TagWHo+SpCy+PQjDM6oHH2FzlAicvP2gUElLfjRHA7CH6jGY/wk7S7S2ds+LXC8oSJJSe0F 3ntkSsWc8aLL+7ctlu9Y2WqyFleCgFDJEVDtIq4aGB+6joFDRvasMDDZFHinzUkLXJUXwdhjXk9 jEekX/5V1wLhhuEEMQlMId/njoEPy+KPTKBboCE1ntiLZNj0e+jEhz/l8pt3Ea7TrkW5+IqyBjc N/P9bLxFmqcpFDsx40yfhRBNgXzjZqbHgrjv3DFm56TGWBOlkgIrvu1QbGT37SanM52g84iI9Km hnMJ2pOgek0VaX0DPyJ4XN/Kujiy4/qoN96VpYGM5pOXCdwXT/ZOWucx/CPuyEPvv8zilxNY2XU 8zZl2TaRYbvnl+Uy5m3dM2HWScmLfbJ306uGTinIZoxce7sbiGHVtzuK/1V0Z7nuuxQKtc/s9A3 PVcaPyxobrhdMyj+TCN3ZQfikbcJ4AJlA1XdwFSrO6wq+ejECtPMXXv7q2yw0tTuGYUBDSLL+iC gOdEhzTSFeajo16cD3fVELNgE29SuPpNfIxqlmOPVsOKCwIeuLNE2ac9PqZCE1qd9ZDaiQqcQYT b4YM+FOXKJtYF1w== 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 | 110 ++++++++++++++++++++++++++++-------- 1 file changed, 87 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 69cf9733fec5..9a1400ad4db6 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -10,22 +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 = y % 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]; } /** @@ -35,30 +56,70 @@ 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) +/** + * packed_pixels_addr_1x1() - Get the pointer to the block containing the pixel at the given + * coordinates + * + * @frame_info: Buffer metadata + * @x: The x (width) coordinate inside the plane + * @y: The y (height) coordinate inside the plane + * @plane_index: The index of the plane + * @addr: The returned pointer + * + * This function can only be used with format where block_h == block_w == 1. + */ +static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info, + int x, int y, int plane_index, u8 **addr) +{ + int offset, rem_x, rem_y; + + WARN_ONCE(drm_format_info_block_width(frame_info->fb->format, + plane_index) != 1, + "%s() only support formats with block_w == 1", __func__); + WARN_ONCE(drm_format_info_block_height(frame_info->fb->format, + plane_index) != 1, + "%s() only support formats with block_h == 1", __func__); + + packed_pixels_offset(frame_info, x, y, plane_index, &offset, &rem_x, + &rem_y); + *addr = (u8 *)frame_info->map[0].vaddr + offset; +} + +static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y, + int plane_index) { int x_src = frame_info->src.x1 >> 16; int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16); + u8 *addr; + int rem_x, rem_y; + + WARN_ONCE(drm_format_info_block_width(frame_info->fb->format, plane_index) != 1, + "%s() only support formats with block_w == 1", __func__); + WARN_ONCE(drm_format_info_block_height(frame_info->fb->format, plane_index) != 1, + "%s() only support formats with block_h == 1", __func__); - return packed_pixels_addr(frame_info, x_src, y_src); + packed_pixels_addr(frame_info, x_src, y_src, plane_index, &addr, &rem_x, &rem_y); + + return addr; } static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x) @@ -167,14 +228,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]); @@ -275,7 +336,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 Tue Apr 9 13:25:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622507 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 D30E5C67861 for ; Tue, 9 Apr 2024 13:26:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A0B24112D9C; Tue, 9 Apr 2024 13:26:05 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="iHAeqj2C"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 113341123D3 for ; Tue, 9 Apr 2024 13:25:53 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 7CACF240014; Tue, 9 Apr 2024 13:25:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669152; 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=3J4b+nj6kf4aWQDjptbnmcHrG88ny05nRttOGw9gTdw=; b=iHAeqj2CiXCHWrZny388uKfqM7Rm3R6r0mQIdTwCuWEkSYDJBNJWWnczMez4yTrTqMuUkG 5wUiBLiiT27liOpbfs2lak0nIuE1Ewm/blagCMgttbzgzvcNo31mD5kntIMF8Sx5a/Cmj+ 5BaVHsoeFQ/crANSEeM6EzNduaoq1T39xPczCi4SIYCyalZzO9PNpqy3lskTbe2ChdkYSM M/4ldWr5Ym50OIpQmSo7GbNy/TrHv+CTB7mu5BIwOenpTPkYK2znE0A4TU1jlqoSc2ECHH S7Mlohc8nKzin6z2KgV1lHsVMhBvPFobCjgKzg+MZrx6ELRjLLXmAV5NFIul8w== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:26 +0200 Subject: [PATCH v6 08/17] drm/vkms: Avoid computing blending limits inside pre_mul_alpha_blend MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-8-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=4015; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=yADtRXVKW9eJ+FMWpWTJbC0RyEvP6Fm0YKwrRfIPJKE=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHSZUQ6kMwtbBmuo01Nc0Xr4jVnXV+2t8Whm wMWDpaQRqCJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0gAKCRAgrS7GWxAs 4lylEAC3AIZ9FwjZinvBqAjzOOei5+h9FHfID37FkIrFcXVY157n0f5PyXglexch5q11AABgJ+t nIDwFCinFfcxYPO2rI16udV7+0fo6o1Eoew8BSYdALP9eFTNOcbLXPQqLsqQ1XOssx3n7fS7M/k VH5NZFrunYn3baerSKS8Stv9w1e8ChmSn6vh42FfhjdahZMM7v0XIa2d8FRD1nOi69cXORw//t9 sgfAw686jZnbSUNERJWq3Ce+NtDFUO573vxp2+16nCWsV0edxUktSX+WTQ5H6K3Hf2b3O2cfp4Q pztI+r7mlKQqpjPKPaPgePEYnD8GtKqbiHg2y2CE+x5IHykb8BhdhUWAfuaOK2qIk9JQ88nKPTn FnfryXZgwoB+9yDT1M/6GD3Wks2s/rnh2aDZd3G/JZwsRs+CPUl9613mgDBxwmgawntm1Su93wq 66gYZvOGRcfNWUVucN0QfagqQUuzeub2mrEwaT6eeDK9Wd+BPoVbv8seRXYgGpcUDq7zFTGGUzz ap8o/xNpcZvT1uXKWWJKSLs2J4c9AC7INVkrUpYAg56VcJbIhtZWP1rT2hyXdTPiON0nhBI5vrJ YHpcDFVrjhS7LJ27wK5/OSqsWCyqpCSwgD4M+j23HZcjo5v+1wHi1Dpg6KqRpZtniSePf2u108o 6Xd8346Yohxj7lg== 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 Reviewed-by: Pekka Paalanen --- 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..45b111c74884 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -24,34 +24,30 @@ static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha) /** * pre_mul_alpha_blend - alpha blending equation - * @frame_info: Source framebuffer's metadata * @stage_buffer: The line with the pixels from src_plane * @output_buffer: A line buffer that receives all the blends output + * @x_start: The start offset + * @pixel_count: The number of pixels to blend * - * Using the information from the `frame_info`, this blends only the - * necessary pixels from the `stage_buffer` to the `output_buffer` - * using premultiplied blend formula. + * The pixels 0..@pixel_count in stage_buffer are blended at @x_start..@x_start+@pixel_count in + * output_buffer. * * The current DRM assumption is that pixel color values have been already * pre-multiplied with the alpha channel values. See more * drm_plane_create_blend_mode_property(). Also, this formula assumes a * completely opaque background. */ -static void pre_mul_alpha_blend(struct vkms_frame_info *frame_info, - struct line_buffer *stage_buffer, - struct line_buffer *output_buffer) +static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer, + struct line_buffer *output_buffer, int x_start, int pixel_count) { - int x_dst = frame_info->dst.x1; - struct pixel_argb_u16 *out = output_buffer->pixels + x_dst; - struct pixel_argb_u16 *in = stage_buffer->pixels; - int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), - stage_buffer->n_pixels); - - for (int x = 0; x < x_limit; x++) { - out[x].a = (u16)0xffff; - out[x].r = pre_mul_blend_channel(in[x].r, out[x].r, in[x].a); - out[x].g = pre_mul_blend_channel(in[x].g, out[x].g, in[x].a); - out[x].b = pre_mul_blend_channel(in[x].b, out[x].b, in[x].a); + struct pixel_argb_u16 *out = &output_buffer->pixels[x_start]; + const struct pixel_argb_u16 *in = stage_buffer->pixels; + + for (int i = 0; i < pixel_count; i++) { + out[i].a = (u16)0xffff; + out[i].r = pre_mul_blend_channel(in[i].r, out[i].r, in[i].a); + out[i].g = pre_mul_blend_channel(in[i].g, out[i].g, in[i].a); + out[i].b = pre_mul_blend_channel(in[i].b, out[i].b, in[i].a); } } @@ -183,7 +179,7 @@ static void blend(struct vkms_writeback_job *wb, { struct vkms_plane_state **plane = crtc_state->active_planes; u32 n_active_planes = crtc_state->num_active_planes; - int y_pos; + int y_pos, x_dst, pixel_count; const struct pixel_argb_u16 background_color = { .a = 0xffff }; @@ -201,14 +197,16 @@ static void blend(struct vkms_writeback_job *wb, /* The active planes are composed associatively in z-order. */ for (size_t i = 0; i < n_active_planes; i++) { + x_dst = plane[i]->frame_info->dst.x1; + pixel_count = min_t(int, drm_rect_width(&plane[i]->frame_info->dst), + (int)stage_buffer->n_pixels); y_pos = get_y_pos(plane[i]->frame_info, y); if (!check_limit(plane[i]->frame_info, y_pos)) continue; vkms_compose_row(stage_buffer, plane[i], y_pos); - pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer, - output_buffer); + pre_mul_alpha_blend(stage_buffer, output_buffer, x_dst, pixel_count); } apply_lut(crtc_state, output_buffer); From patchwork Tue Apr 9 13:25:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622510 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 72EA4C67861 for ; Tue, 9 Apr 2024 13:26:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AA6EA112D9E; Tue, 9 Apr 2024 13:26:09 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="f9pMjhR3"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 640B6112D92 for ; Tue, 9 Apr 2024 13:25:55 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id B262124001A; Tue, 9 Apr 2024 13:25:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669153; 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=DUE71gsvF+O8LiPn3Cww9o4Q8NkzACOq7bQghVtFikM=; b=f9pMjhR3U5jmJ4VfKAKvEHgSsLNOdWKw9uF0hqTuSy+By0EQQVo7Koyhxplv46EQe0gwdq dkyy+iVRdDlNJugupNlOGMupm0lK2XKjzhaR9wuFqaFBhRD6upBS9QfMC9Mh5/mNNhOIw5 dXvjq8MOO1GEDClOaDtdGRVQtoGD5O1nR3K2c67Xk9iDXg1qNboVrXsx5SC0vYOW4S8hyi S/Ns41poKMJgpnO/wEbrPVvQCMzqQPsvPpRNZuA1iN3yGpW5qYK75N/OVQaN7XlPeLPgnD JpksHz1rjUJq6B4yMWifsLgJwlk4YTaQp1M5zbooQvT0Ww0wb36psEvhGjGyzA== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:27 +0200 Subject: [PATCH v6 09/17] drm/vkms: Introduce pixel_read_direction enum MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-9-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=4783; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=Sfh4O+PqEC7Ra3tm97F32x1rZZ3jsiSoO6x9STnYV+0=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHSE5TRpRROVpTIcXXs9789QEBbMnFyxQqWQ 0qaI49ij2KJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0gAKCRAgrS7GWxAs 4r1lEACI3a+IaDSA9EePy7BRCpLL7QLEB65F6qkCJQCF3q7eASEgKZ5Hu36xT0+QmCpzyqioSHb zzUoY2KGwe2b895to3mBAghhNAYk4FRw3Z+wtyr/ABWGOJAhvc+g4bTXwxSSH1WV4YM71vzC6Gv pcx+pick75r0t+aNVkds9O6PGw2a4NN7dBRYFfgm9eE3ZQKNbBgCirEGfIkqGKOE2lmJSGOUHnb HHlUNV/QrCLH+uEzTdY8k6K1TugcEUsMmT9fzcSaewXX0WY07c7rrXpgVQzTZjAbXjM0tUpIrXU ZBSN0qPSdgXhDEwder5xgQTL+3dwWMucJoEPVN4Vw3vwtNG2jIpR3cTqDOxME69JfJfqhzqrCZ8 CJ+bn53vYBiMGpK9kj8tzv4pB3Fr5kRQ+6JJxUgF68cvo5irErVXLByQ/jsduXewp2v/1C/5unU C/A0E96BK6R9kG7n12jeJCOjuSjIyNdxUq4FxQjc7gENQpPqKdnQl50R7WqwScfOgXORD7NFK1m fb1AdwFJuveYVOIVTz4lCT8v0Pl1VZN8vxHbdtTFSRiIwASojg1+PFp8oth4WWswf5GznqJWwkq SCatN/aKW0TlgBU/u9nI/fuG6+Hht++8CPBRi4Z0Fxpr1Dgi5/RlUbR7znyyy/Awx19Pij0IsoG qDpdL0Osbqy4UOA== 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 | 42 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.h | 11 ++++++++++ drivers/gpu/drm/vkms/vkms_formats.c | 30 ++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 45b111c74884..7c2e328c9510 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -159,6 +159,48 @@ static void apply_lut(const struct vkms_crtc_state *crtc_state, struct line_buff } } +/** + * direction_for_rotation() - Get the correct reading direction for a given rotation + * + * @rotation: Rotation to analyze. It correspond the field @frame_info.rotation. + * + * This function will use the @rotation setting of a source plane to compute the reading + * direction in this plane which correspond to a "left to right writing" in the CRTC. + * For example, if the buffer is reflected on X axis, the pixel must be read from right to left + * to be written from left to right on the CRTC. + */ +static enum pixel_read_direction direction_for_rotation(unsigned int rotation) +{ + struct drm_rect tmp_a, tmp_b; + int x, y; + + /* + * The direction is computed by rotating the vector AB (top-left to top-right) in a + * 1x1 square. + */ + + tmp_a = DRM_RECT_INIT(0, 0, 0, 0); + tmp_b = DRM_RECT_INIT(1, 0, 0, 0); + drm_rect_rotate_inv(&tmp_a, 1, 1, rotation); + drm_rect_rotate_inv(&tmp_b, 1, 1, rotation); + + x = tmp_b.x1 - tmp_a.x1; + y = tmp_b.y1 - tmp_a.y1; + + if (x == 1) + return READ_LEFT_TO_RIGHT; + else if (x == -1) + return READ_RIGHT_TO_LEFT; + else if (y == 1) + return READ_TOP_TO_BOTTOM; + else if (y == -1) + return READ_BOTTOM_TO_TOP; + + + WARN_ONCE(true, "The inverse of the rotation gives an incorrect direction."); + return READ_LEFT_TO_RIGHT; +} + /** * blend - blend the pixels from all planes and compute crc * @wb: The writeback frame buffer metadata diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 2e1a1b824a3c..16317b063c20 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 9a1400ad4db6..f76944874fe7 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_block_step_byte() - Common helper to compute the correct step value between each pixel block + * to read in a certain direction. + * + * @fb: Framebuffer to iter on + * @direction: Direction of the reading + * @plane_index: Plane to get the step from + * + * As the returned 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. + */ +static int get_block_step_byte(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; +} + /** * packed_pixels_addr_1x1() - Get the pointer to the block containing the pixel at the given * coordinates From patchwork Tue Apr 9 13:25:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622514 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 6BB1BCD1284 for ; Tue, 9 Apr 2024 13:26:18 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E5995112DAB; Tue, 9 Apr 2024 13:26:16 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="ZSJaitEn"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3FB2E112D92 for ; Tue, 9 Apr 2024 13:25:56 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id DEE5B24001B; Tue, 9 Apr 2024 13:25:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669155; 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=F7MqH53Mi2+vD97DpWYNuhALEeJoED4yvxYDn1eAC7U=; b=ZSJaitEniBjaTvm7BoYCR6zsmCws1Q8H/ppvHbO8L1oOSCqxiPeQVw+F4s4P/OQbt+d9WE Otb0JO65k0+O/RzjpuTY4sflmSmudlQ2p8W+o6S9Y5BsNMaXCL3QZd8vDdpC3oYCxVMfEI SvmnzM5o8zi2qUIW2jE69M9kqjSX2eE+RGIopQufTd1NHGVsuD7HPI3IyC9IhF1BnBdIjV bPzd1OLRIW+Jb49V8ayS2FBgyhpAynRVKa6ZVqV4wDULYxgpUE/bcB3JxszUPSiIDP3ZHR DnoG/nAsMcA/TzhVBrZYSQkWC4U6bhoJJGJhnHQX6QHy9RCBun050pzvCtHTig== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:28 +0200 Subject: [PATCH v6 10/17] drm/vkms: Re-introduce line-per-line composition algorithm MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-10-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=30458; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=CpVIEuZUyZ49jUg/7Vi9wH/UZ0THyU8gchWS1zLGgoM=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHS2d2KFiT4sjP3IKcLfW5IKu75mPaXMSZrC aMMmZ8G7/KJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0gAKCRAgrS7GWxAs 4iTjEACZusGCt+tUzSteGJGKojxz1FUUvvsp4caaE8UmxZ3HJE33PPB42Z5sVMUNQerGoeuZfY4 Sf7CRQCtA/8v7pbyGI63rPFufYnkQbB8ioXooWPhB3p73hc23Ov21vsroKAvoVFhlpIDrGhiRc/ K0XPkVMJpwZjzgcDaspwkUwqzixPES9oGuDbhnXKCoGWlS8ba0q6w8z6OUy37BtdTd64n788jme nuM8ihK7gzrfe0f7wK4aNzmzDef0zo5K6c07NQsh1jWNA+LjSIUpwhqpnZHLJXr1YAc+vU6suek sqW6U9jwf5QP9vf3y3wdTX/md5lh2oDAGZtWwjK1HsOnM6xya5Fz1qa+h6ydQk0TQqgjvAHSRmr EJjbsC02sLGcOjSd006+H7IL1kGcLg/icL8cDk3p4M5tt4BOGdC9zrSFj10s5xeOcMH7UB0907K SGpBUzkLQSD/Mth3U08UC0OckWVsK8WK8SSmkFcJAQiOY8s5a07FrES40bjn0Anjy6rU3xW1CxM iIy14A6bXtu92lRuviMRkjPVoJ6Ja83I1V/irli5i9oLHciUJZ4DZ4GL4uVTT5/JjBK4Lnjv7I3 SskCrnXPN6rk2XwmPaz3wb2v7ubWfs2Hk/+yq7oJqNDpn+/kbqyjIziBDyV1FfSPl2iKVufl0yr I+Ck/naAI8R9P5A== 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]: https://lore.kernel.org/igt-dev/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com/ Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_composer.c | 230 ++++++++++++++++++++++++++------- drivers/gpu/drm/vkms/vkms_drv.h | 27 ++-- drivers/gpu/drm/vkms/vkms_formats.c | 240 +++++++++++++++++++++-------------- drivers/gpu/drm/vkms/vkms_formats.h | 2 +- drivers/gpu/drm/vkms/vkms_plane.c | 5 +- 5 files changed, 347 insertions(+), 157 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 7c2e328c9510..8c8a3c629485 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -29,8 +29,8 @@ static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha) * @x_start: The start offset * @pixel_count: The number of pixels to blend * - * The pixels 0..@pixel_count in stage_buffer are blended at @x_start..@x_start+@pixel_count in - * output_buffer. + * The pixels @x_start..@x_start+@pixel_count in stage_buffer are blended at + * @x_start..@x_start+@pixel_count in output_buffer. * * The current DRM assumption is that pixel color values have been already * pre-multiplied with the alpha channel values. See more @@ -41,7 +41,7 @@ static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer, struct line_buffer *output_buffer, int x_start, int pixel_count) { struct pixel_argb_u16 *out = &output_buffer->pixels[x_start]; - const struct pixel_argb_u16 *in = stage_buffer->pixels; + const struct pixel_argb_u16 *in = &stage_buffer->pixels[x_start]; for (int i = 0; i < pixel_count; i++) { out[i].a = (u16)0xffff; @@ -51,33 +51,6 @@ static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer, } } -static int get_y_pos(struct vkms_frame_info *frame_info, int y) -{ - if (frame_info->rotation & DRM_MODE_REFLECT_Y) - return drm_rect_height(&frame_info->rotated) - y - 1; - - switch (frame_info->rotation & DRM_MODE_ROTATE_MASK) { - case DRM_MODE_ROTATE_90: - return frame_info->rotated.x2 - y - 1; - case DRM_MODE_ROTATE_270: - return y + frame_info->rotated.x1; - default: - return y; - } -} - -static bool check_limit(struct vkms_frame_info *frame_info, int pos) -{ - if (drm_rotation_90_or_270(frame_info->rotation)) { - if (pos >= 0 && pos < drm_rect_width(&frame_info->rotated)) - return true; - } else { - if (pos >= frame_info->rotated.y1 && pos < frame_info->rotated.y2) - return true; - } - - return false; -} static void fill_background(const struct pixel_argb_u16 *background_color, struct line_buffer *output_buffer) @@ -201,6 +174,180 @@ static enum pixel_read_direction direction_for_rotation(unsigned int rotation) return READ_LEFT_TO_RIGHT; } +/** + * clamp_line_coordinates() - Compute and clamp the coordinate to read and write during the blend + * process. + * + * @direction: direction of the reading + * @current_plane: current plane blended + * @src_line: source line of the reading + * @dst: destination rectangle + * @src_x_start: final x start coordinate for the line reading + * @src_y_start: final y start coordinate for the line reading + * @dst_x_start: final x coordinate to blend the read line + * @pixel_count: number of pixel to blend + * + * This function is mainly a safety net to avoid reading outside the source buffer. As the + * userspace should never ask to read outside the source plane, all the cases covered here should + * be dead code. + */ +static void clamp_line_coordinates(enum pixel_read_direction direction, + const struct vkms_plane_state *current_plane, + const struct drm_rect *src_line, int *src_x_start, + int *src_y_start, int *dst_x_start, int *pixel_count) +{ + /* By default the start points are correct */ + *src_x_start = src_line->x1; + *src_y_start = src_line->y1; + *dst_x_start = current_plane->frame_info->dst.x1; + + /* Get the correct number of pixel to blend, it depends of the direction */ + switch (direction) { + case READ_LEFT_TO_RIGHT: + case READ_RIGHT_TO_LEFT: + *pixel_count = drm_rect_width(src_line); + break; + case READ_BOTTOM_TO_TOP: + case READ_TOP_TO_BOTTOM: + *pixel_count = drm_rect_height(src_line); + break; + } + + /* + * Clamp the coordinates to avoid reading outside the buffer + * + * This is mainly a security to avoid reading outside the buffer, the userspace should + * never request to read outside the source buffer. + */ + switch (direction) { + case READ_LEFT_TO_RIGHT: + case READ_RIGHT_TO_LEFT: + if (*src_x_start < 0) { + *pixel_count += *src_x_start; + *dst_x_start -= *src_x_start; + *src_x_start = 0; + } + if (*src_x_start + *pixel_count > current_plane->frame_info->fb->width) + *pixel_count = (int)current_plane->frame_info->fb->width - *src_x_start; + break; + case READ_BOTTOM_TO_TOP: + case READ_TOP_TO_BOTTOM: + if (*src_y_start < 0) { + *pixel_count += *src_y_start; + *dst_x_start -= *src_y_start; + *src_y_start = 0; + } + if (*src_y_start + *pixel_count > current_plane->frame_info->fb->height) + *pixel_count = (int)current_plane->frame_info->fb->height - *src_y_start; + break; + } +} + +/** + * blend_line() - Blend a line from a plane to the output buffer + * + * @current_plane: current plane to work on + * @y: line to write in the output buffer + * @crtc_x_limit: width of the output buffer + * @stage_buffer: temporary buffer to convert the pixel line from the source buffer + * @output_buffer: buffer to blend the read line. + */ +static void blend_line(struct vkms_plane_state *current_plane, int y, + int crtc_x_limit, struct line_buffer *stage_buffer, + struct line_buffer *output_buffer) +{ + int src_x_start, src_y_start, dst_x_start, pixel_count; + struct drm_rect dst_line, tmp_src, src_line; + + /* Avoid rendering useless lines */ + if (y < current_plane->frame_info->dst.y1 || + y >= current_plane->frame_info->dst.y2) + return; + + /* + * dst_line is the line to copy. The initial coordinates are inside the + * destination framebuffer, and then drm_rect_* helpers are used to + * compute the correct position into the source framebuffer. + */ + dst_line = DRM_RECT_INIT(current_plane->frame_info->dst.x1, y, + drm_rect_width(¤t_plane->frame_info->dst), + 1); + + drm_rect_fp_to_int(&tmp_src, ¤t_plane->frame_info->src); + + /* + * [1]: Clamping src_line to the crtc_x_limit to avoid writing outside of + * the destination buffer + */ + dst_line.x1 = max_t(int, dst_line.x1, 0); + dst_line.x2 = min_t(int, dst_line.x2, crtc_x_limit); + /* The destination is completely outside of the crtc. */ + if (dst_line.x2 <= dst_line.x1) + return; + + src_line = dst_line; + + /* + * Transform the coordinate x/y from the crtc to coordinates into + * coordinates for the src buffer. + * + * - Cancel the offset of the dst buffer. + * - Invert the rotation. This assumes that + * dst = drm_rect_rotate(src, rotation) (dst and src have the + * same size, but can be rotated). + * - Apply the offset of the source rectangle to the coordinate. + */ + drm_rect_translate(&src_line, -current_plane->frame_info->dst.x1, + -current_plane->frame_info->dst.y1); + drm_rect_rotate_inv(&src_line, drm_rect_width(&tmp_src), + drm_rect_height(&tmp_src), + current_plane->frame_info->rotation); + drm_rect_translate(&src_line, tmp_src.x1, tmp_src.y1); + + /* Get the correct reading direction in the source buffer. */ + + enum pixel_read_direction direction = + direction_for_rotation(current_plane->frame_info->rotation); + + /* [2]: Compute and clamp the number of pixel to read */ + clamp_line_coordinates(direction, current_plane, &src_line, &src_x_start, &src_y_start, + &dst_x_start, &pixel_count); + + if (pixel_count <= 0) { + /* Nothing to read, so avoid multiple function calls */ + return; + } + + /* + * Modify the starting point to take in account the rotation + * + * src_line is the top-left corner, so when reading READ_RIGHT_TO_LEFT or + * READ_BOTTOM_TO_TOP, it must be changed to the top-right/bottom-left + * corner. + */ + if (direction == READ_RIGHT_TO_LEFT) { + // src_x_start is now the right point + src_x_start += pixel_count - 1; + } else if (direction == READ_BOTTOM_TO_TOP) { + // src_y_start is now the bottom point + src_y_start += pixel_count - 1; + } + + /* + * Perform the conversion and the blending + * + * Here we know that the read line (x_start, y_start, pixel_count) is + * inside the source buffer [2] and we don't write outside the stage + * buffer [1]. + */ + current_plane->pixel_read_line( + current_plane, src_x_start, src_y_start, direction, pixel_count, + &stage_buffer->pixels[dst_x_start]); + + pre_mul_alpha_blend(stage_buffer, output_buffer, + dst_x_start, pixel_count); +} + /** * blend - blend the pixels from all planes and compute crc * @wb: The writeback frame buffer metadata @@ -221,34 +368,25 @@ static void blend(struct vkms_writeback_job *wb, { struct vkms_plane_state **plane = crtc_state->active_planes; u32 n_active_planes = crtc_state->num_active_planes; - int y_pos, x_dst, pixel_count; const struct pixel_argb_u16 background_color = { .a = 0xffff }; - size_t crtc_y_limit = crtc_state->base.crtc->mode.vdisplay; + int crtc_y_limit = crtc_state->base.crtc->mode.vdisplay; + int crtc_x_limit = crtc_state->base.crtc->mode.hdisplay; /* * The planes are composed line-by-line to avoid heavy memory usage. It is a necessary * complexity to avoid poor blending performance. * - * The function vkms_compose_row is used to read a line, pixel-by-pixel, into the staging - * buffer. + * The function pixel_read_line callback is used to read a line, using an efficient + * algorithm for a specific format, into the staging buffer. */ for (size_t y = 0; y < crtc_y_limit; y++) { fill_background(&background_color, output_buffer); /* The active planes are composed associatively in z-order. */ for (size_t i = 0; i < n_active_planes; i++) { - x_dst = plane[i]->frame_info->dst.x1; - pixel_count = min_t(int, drm_rect_width(&plane[i]->frame_info->dst), - (int)stage_buffer->n_pixels); - y_pos = get_y_pos(plane[i]->frame_info, y); - - if (!check_limit(plane[i]->frame_info, y_pos)) - continue; - - vkms_compose_row(stage_buffer, plane[i], y_pos); - pre_mul_alpha_blend(stage_buffer, output_buffer, x_dst, pixel_count); + blend_line(plane[i], y, crtc_x_limit, stage_buffer, output_buffer); } apply_lut(crtc_state, output_buffer); @@ -256,7 +394,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); } } @@ -267,7 +405,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 16317b063c20..a62a11e67ab1 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 non-negative 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 non-negative and smaller than @plane->frame_info->fb->height. + * @direction: direction to use for the copy, starting at @x_start/@y_start + * @count: number of pixels to copy + * @out_pixel: pointer where to write the pixel values. They will be written from @out_pixel[0] + * 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[]); /** * struct vkms_plane_state - Driver specific plane state * @base: base plane state * @frame_info: data required for composing computation - * @pixel_read: function to read a pixel in this plane. The creator of a 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 f76944874fe7..302c7f3ea54c 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -134,83 +134,45 @@ static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info, *addr = (u8 *)frame_info->map[0].vaddr + offset; } -static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y, - int plane_index) -{ - int x_src = frame_info->src.x1 >> 16; - int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16); - u8 *addr; - int rem_x, rem_y; - - WARN_ONCE(drm_format_info_block_width(frame_info->fb->format, plane_index) != 1, - "%s() only support formats with block_w == 1", __func__); - WARN_ONCE(drm_format_info_block_height(frame_info->fb->format, plane_index) != 1, - "%s() only support formats with block_h == 1", __func__); - - packed_pixels_addr(frame_info, x_src, y_src, plane_index, &addr, &rem_x, &rem_y); - - return addr; -} - -static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x) -{ - if (frame_info->rotation & (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270)) - return limit - x - 1; - return x; -} - /* - * The following functions take pixel data from the buffer and convert them to the format - * ARGB16161616 in out_pixel. + * The following functions take pixel data (a, r, g, b, pixel, ...) and convert them to + * &struct pixel_argb_u16 * - * They are used in the vkms_compose_row() function to handle multiple formats. + * They are used in the `read_line`s functions to avoid duplicate work for some pixel formats. */ -static void ARGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static struct pixel_argb_u16 argb_u16_from_u8888(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; - - 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]); -} + 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; + 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); - 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)); @@ -220,12 +182,27 @@ 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. + * + * These functions are very repetitive, but the innermost pixel loops must be kept inside these + * functions for performance reasons. Some benchmarking was done in [1] where having the innermost + * loop factored out of these functions showed a slowdown by a factor of three. + * + * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/ + */ + /** * magenta_to_argb_u16() - pixel_read callback which always read magenta * @@ -233,42 +210,111 @@ 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 magenta_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel) +static void magenta_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 = (u16)0xFFFF; - out_pixel->g = 0; - out_pixel->b = (u16)0xFFFF; + struct pixel_argb_u16 *end = out_pixel + count; + + while (out_pixel < end) { + *out_pixel = argb_u16_from_u8888(255, 255, 0, 255); + 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 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + int step = get_block_step_byte(plane->frame_info->fb, direction, 0); + + while (out_pixel < end) { + u8 *px = (u8 *)src_pixels; + *out_pixel = argb_u16_from_u8888(px[3], px[2], px[1], px[0]); + out_pixel += 1; + src_pixels += step; + } +} + +static void XRGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, + enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + int step = get_block_step_byte(plane->frame_info->fb, direction, 0); + + while (out_pixel < end) { + u8 *px = (u8 *)src_pixels; + *out_pixel = argb_u16_from_u8888(255, px[2], px[1], px[0]); + out_pixel += 1; + src_pixels += step; + } +} + +static void ARGB16161616_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + int step = get_block_step_byte(plane->frame_info->fb, direction, 0); + + while (out_pixel < end) { + u16 *px = (u16 *)src_pixels; + *out_pixel = argb_u16_from_u16161616(px[3], px[2], px[1], px[0]); + out_pixel += 1; + src_pixels += step; + } +} + +static void XRGB16161616_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + int step = get_block_step_byte(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 *out_pixels = stage_buffer->pixels; - struct vkms_frame_info *frame_info = plane->frame_info; - u8 *src_pixels = get_packed_src_addr(frame_info, y, 0); - int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels); + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); - for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) { - int x_pos = get_x_position(frame_info, limit, x); + int step = get_block_step_byte(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; } } @@ -378,7 +424,7 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, } /** - * get_pixel_conversion_function() - Retrieve the correct read_pixel function for a specific + * get_pixel_read_function() - Retrieve the correct read_line function for a specific * format. * * If the format is not supported by VKMS a warning is emitted and a dummy "always read magenta" @@ -386,19 +432,19 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, * * @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 Tue Apr 9 13:25:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622518 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 3B7F1C67861 for ; Tue, 9 Apr 2024 13:26:27 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CE408112DB2; Tue, 9 Apr 2024 13:26:25 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="mPc1BX4S"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1C33D112D92 for ; Tue, 9 Apr 2024 13:25:58 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 1F5D0240018; Tue, 9 Apr 2024 13:25:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669156; 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=E2u0GRNid3Th9H3bLBVSqGYconIdWdfP+/YzKnPowrI=; b=mPc1BX4S65GLkMe6nzqtjBgmqUYrlBW+ho+xt6OPBW9BuF5slLywY3ngZfmifLRdWe3qnE dl9b9ry3mg9wBeIiJXFnWxG4/VvCSE20iU0xLz3EQs3ze1lHLmyLYcb0JtAP/yWI1mIxXo AfNgnB2SvXkG2fknBLbeG0qDm7PTzlqqUtm38N5fzL4sd0vSUJ3k1OClmyoGD/bHSY07eP k6YDKzP1XNjs4e1WJXmksLpZBEPwMax26YekQI4tQVnlHDHoZw54Q0G4HvXvMz53a+Bnhi gwKD2M5PPqIkPMM/oVl5V4C/lwdu4fDHM35Fqt8ELneqT2a++pQxHCGbMc1NMw== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:29 +0200 Subject: [PATCH v6 11/17] drm/vkms: Remove useless drm_rotation_simplify MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-11-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1084; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=4XaxvY/cAweYN7SOJe5yq3QGEn/dKNihs/Jfqv1vCLE=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHS0flirwrtAxXfjk0mjdEIFfOqu0cP2F7YR Jt/Uzh8/L+JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0gAKCRAgrS7GWxAs 4sPTD/9dujULLjIHUBix3mcO6jW64FcLIURlem6vdE9lSg3/s37eFNMvhnuq3jl/jOC+k/krX2U D34NSBiLpzOCgTpL3KKEV87jeV8E9+8/gnmM1HFp9+4Wxxqbq14BaEYvXkobwiPkU+s0oybSUXu r3yhlhpP6TYgMO7A9PcuQUN4uxZnVqlJa9uZVoOaJ5Go8nzuOXYLrXBPXOCRDj8zMXgmDYVoc4t 7o7aue4BFA7PRP9gx7MnctHplbboMmauggyI31smiV117HZ4NWT0jqriomgGfjZRIYU4j8V2M4Q Uuz414R96p8WdBg9a3ZPBweL+Px+59Eu504xFkGVUuRByRHhb8tVkPF2CC9UYpSrnuXO0t77Tap 4bSIaP2gmoRuelsilNXB2zpFZZuFqD307KjrEeya/0lCBkHoMn75PPmvTT920cAoNQRdMtJcmti gpn83OMjc/SOZRaaEq15gEACAqIZq86tA3kaIiHogzs08D0gL2nqzdcy83FsZ0j01tI5OztW3GS tVA5bs0wC3nHxaqOcxYiisOf1it8M1PnVeOypNen/8bB+6wJSU7tYYPMfCmncdaAlObG5eCTwrV ua2DSBV1hKfrFfNukSbNkud+Kng9ilNvPoloVXTU5pUsjTgP5kP16rXxlugDgp4y+r4uVrutKfG Xr34vVMQ9laYStg== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" As all the rotation are now supported by VKMS, this simplification does not make sense anymore, so remove it. Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_plane.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 8875bed76410..5a028ee96c91 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, frame_info->fb = fb; memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map)); drm_framebuffer_get(frame_info->fb); - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 | - DRM_MODE_ROTATE_90 | - DRM_MODE_ROTATE_270 | - DRM_MODE_REFLECT_X | - DRM_MODE_REFLECT_Y); - + frame_info->rotation = new_state->rotation; vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt); } From patchwork Tue Apr 9 13:25:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622511 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 EF282CD1284 for ; Tue, 9 Apr 2024 13:26:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CA2BD112DA0; Tue, 9 Apr 2024 13:26:09 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="TDdicj4/"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1CE73112D9D for ; Tue, 9 Apr 2024 13:25:58 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 9940E24001C; Tue, 9 Apr 2024 13:25:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669157; 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=J5krQSIbnonHxXnBuaTBGupNhzb+5EtHauGTpxtXNkc=; b=TDdicj4/nDW2NLwQVPtYEmFiRwg3Ccd6VKkZPvPlGj4uExFFYC+nWKET4AROhJBA5zIQyC 7LQGuGuTETbkEowFvfRqezJgbp7l/PLzn+RiHE+Lf9Rf9RiU2vXv35LwYhgYrHNX8k/moS kLScq+h0WzVH+xmElCGnqChLFjDcNPcYJXq7F+YhD7+mHTihzw5NHeG6Y+l67EaOSAzFAD 7Q+XuphEaYh89lkr611FoQ/s+6Qhfx/SP6LKJSKjU09jzKbZ0GK8V0eCOkMSt3ljPjqO4A JeMYgAR1O+bTSVIgpolC3/Q3fyBlL8l7terGmlsvchyo2WC1IGNy+R76dpsdiA== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:30 +0200 Subject: [PATCH v6 12/17] drm/vkms: Add YUV support MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-12-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=18573; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=NrLwkVWA36n3DTb2wBrfG1cjgE4XSCHk7HBg49kMk4s=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHT8/xONw1DLfX8mamxPgdnN4UTHECN2eZMv jqenO1rk4WJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0wAKCRAgrS7GWxAs 4jCVD/959rrvhYc9C1HJVUhMFJSYYJfxhvLPZUnr070egPo6hjq1ulSbftXKMT18clIoQNHwwNf PO2d5tKhIQw4lLEC6v1dLlc5mhUDQ/hiY9KBd7m8tgUWZfhnJYyE4mP+JMSvPNkoS0lcQbfJX11 Qw+DSBrJRWykh203nHXqXytMJjDSOpPawcaAb1Ea9xBgP8JEnXf2FOribOh3AS/Y56eAf3DLUXo Bs33bs7B8/lKX/WjVU7bbL3eFXky68cVQQvkWDaG39/f1fVzAd8BB1QoiZhNm+6BP6xpzaWJpvN RygKfVKaFO07tz4sb5xy5oNPwEtk3RHhZ8Vp8+UyhVqFIy4aQoO3udnp1MfeBIrH2zHWnHO4ViQ yl261wUrYEgtkl7vMw7H9MydnwrwieYq36cA8Fo1g1z73xlXRZHCL3hL84+EaaHInEqAtVOJ8LR /7yRk1doYmU3q7cOLPsxHKuNHNyNl26AnTGbtQuFjI2uqdK35bfuDZLECNirDAPoBIwXL+3mMmC c9c4gUUzwK18Ca4mGfn1/CLK6ALvPqN/t3w3Rjd15E/4d/UWtbf56xqj4cUNSKBypXSLEpkYU/H Cf/9qUSLX17XQYqP11moDr0mDPZZh3DeWjSTvEA+HvF7adep7FNNtoucDDtDjiBqKrtFWEA5r5r Kct7ySxYEU5Scsw== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Add support to the YUV formats bellow: - NV12/NV16/NV24 - NV21/NV61/NV42 - YUV420/YUV422/YUV444 - YVU420/YVU422/YVU444 The conversion from yuv to rgb is done with fixed-point arithmetic, using 32.32 fixed-point numbers and the drm_fixed helpers. To do the conversion, a specific matrix must be used for each color range (DRM_COLOR_*_RANGE) and encoding (DRM_COLOR_*). This matrix is stored in the `conversion_matrix` struct, along with the specific y_offset needed. This matrix is queried only once, in `vkms_plane_atomic_update` and stored in a `vkms_plane_state`. Those conversion matrices of each encoding and range were obtained by rounding the values of the original conversion matrices multiplied by 2^32. This is done to avoid the use of floating point operations. The same reading function is used for YUV and YVU formats. As the only difference between those two category of formats is the order of field, a simple swap in conversion matrix columns allows using the same function. Signed-off-by: Arthur Grillo [Louis Chauvet: - Adapted Arthur's work - Implemented the read_line_t callbacks for yuv - add struct conversion_matrix - store the whole conversion_matrix in the plane state - remove struct pixel_yuv_u8 - update the commit message - Merge the modifications from Arthur] Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_drv.h | 18 ++ drivers/gpu/drm/vkms/vkms_formats.c | 356 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_formats.h | 4 + drivers/gpu/drm/vkms/vkms_plane.c | 16 +- 4 files changed, 393 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index a62a11e67ab1..831454325d9d 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -99,17 +99,35 @@ typedef void (*pixel_read_line_t)(const struct vkms_plane_state *plane, int x_st int y_start, enum pixel_read_direction direction, int count, struct pixel_argb_u16 out_pixel[]); +/** + * struct conversion_matrix - Matrix to use for a specific encoding and range + * + * @matrix: Conversion matrix from yuv to rgb. The matrix is stored in a row-major manner and is + * used to compute rgb values from yuv values: + * [[r],[g],[b]] = @matrix * [[y],[u],[v]] + * OR for yvu formats: + * [[r],[g],[b]] = @matrix * [[y],[v],[u]] + * The values of the matrix are signed fixed-point values with 32 bits fractional part. + * @y_offset: Offset to apply on the y value. + */ +struct conversion_matrix { + s64 matrix[3][3]; + int y_offset; +}; + /** * struct vkms_plane_state - Driver specific plane state * @base: base plane state * @frame_info: data required for composing computation * @pixel_read_line: function to read a pixel line in this plane. The creator of a vkms_plane_state * must ensure that this pointer is valid + * @conversion_matrix: matrix used for yuv formats to convert to rgb */ struct vkms_plane_state { struct drm_shadow_plane_state base; struct vkms_frame_info *frame_info; pixel_read_line_t pixel_read_line; + struct conversion_matrix conversion_matrix; }; struct vkms_plane { diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 302c7f3ea54c..2d7445a3de93 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -134,6 +134,51 @@ static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info, *addr = (u8 *)frame_info->map[0].vaddr + offset; } +/** + * get_subsampling() - Get the subsampling divisor value on a specific direction + * + * @format: format to extarct the subsampling from + * @direction: direction of the subsampling requested + */ +static int get_subsampling(const struct drm_format_info *format, + enum pixel_read_direction direction) +{ + switch (direction) { + case READ_BOTTOM_TO_TOP: + case READ_TOP_TO_BOTTOM: + return format->vsub; + case READ_RIGHT_TO_LEFT: + case READ_LEFT_TO_RIGHT: + return format->hsub; + } + WARN_ONCE(true, "Invalid direction for pixel reading: %d\n", direction); + return 1; +} + +/** + * get_subsampling_offset() - An offset for keeping the chroma siting consistent regardless of + * x_start and y_start values + * + * @direction: direction of the reading to properly compute this offset + * @x_start: x coordinate of the starting point of the readed line + * @y_start: y coordinate of the starting point of the readed line + */ +static int get_subsampling_offset(enum pixel_read_direction direction, int x_start, int y_start) +{ + switch (direction) { + case READ_BOTTOM_TO_TOP: + return -y_start - 1; + case READ_TOP_TO_BOTTOM: + return y_start; + case READ_RIGHT_TO_LEFT: + return -x_start - 1; + case READ_LEFT_TO_RIGHT: + return x_start; + } + WARN_ONCE(true, "Invalid direction for pixel reading: %d\n", direction); + return 0; +} + /* * The following functions take pixel data (a, r, g, b, pixel, ...) and convert them to * &struct pixel_argb_u16 @@ -190,6 +235,38 @@ 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 channel_1, u8 channel_2, + const struct conversion_matrix *matrix) +{ + u8 r, g, b; + s64 fp_y, fp_channel_1, fp_channel_2; + s64 fp_r, fp_g, fp_b; + + fp_y = drm_int2fixp(((int)y - matrix->y_offset) * 257); + fp_channel_1 = drm_int2fixp(((int)channel_1 - 128) * 257); + fp_channel_2 = drm_int2fixp(((int)channel_2 - 128) * 257); + + fp_r = drm_fixp_mul(matrix->matrix[0][0], fp_y) + + drm_fixp_mul(matrix->matrix[0][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[0][2], fp_channel_2); + fp_g = drm_fixp_mul(matrix->matrix[1][0], fp_y) + + drm_fixp_mul(matrix->matrix[1][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[1][2], fp_channel_2); + fp_b = drm_fixp_mul(matrix->matrix[2][0], fp_y) + + drm_fixp_mul(matrix->matrix[2][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[2][2], fp_channel_2); + + fp_r = drm_fixp2int_round(fp_r); + fp_g = drm_fixp2int_round(fp_g); + fp_b = drm_fixp2int_round(fp_b); + + r = clamp(fp_r, 0, 0xffff); + g = clamp(fp_g, 0, 0xffff); + b = clamp(fp_b, 0, 0xffff); + + return argb_u16_from_u16161616(0xffff, r, g, b); +} + /* * The following functions are read_line function for each pixel format supported by VKMS. * @@ -318,6 +395,92 @@ static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start, } } +/* + * This callback can be used for YUV format where each color component is + * stored in a different plane (often called planar formats). It will + * handle correctly subsampling. + * + * The conversion matrix stored in the @plane is used to: + * - Apply the correct color range and encoding + * - Convert YUV and YVU with the same function (a simple column swap is + * needed) + */ +static void semi_planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + u8 *y_plane; + u8 *uv_plane; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, + &y_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 1, + &uv_plane); + int step_y = get_block_step_byte(plane->frame_info->fb, direction, 0); + int step_uv = get_block_step_byte(plane->frame_info->fb, direction, 1); + int subsampling = get_subsampling(plane->frame_info->fb->format, direction); + int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); + const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; + + for (int i = 0; i < count; i++) { + *out_pixel = argb_u16_from_yuv888(y_plane[0], uv_plane[0], uv_plane[1], + conversion_matrix); + out_pixel += 1; + y_plane += step_y; + if ((i + subsampling_offset + 1) % subsampling == 0) + uv_plane += step_uv; + } +} + +/* + * This callback can be used for YUV formats where U and V values are + * stored in the same plane (often called semi-planar formats). It will + * correctly handle subsampling. + * + * The conversion matrix stored in the @plane is used to: + * - Apply the correct color range and encoding + * - Convert YUV and YVU with the same function (a simple column swap is + * needed) + */ +static void planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + u8 *y_plane; + u8 *channel_1_plane; + u8 *channel_2_plane; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, + &y_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 1, + &channel_1_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 2, + &channel_2_plane); + int step_y = get_block_step_byte(plane->frame_info->fb, direction, 0); + int step_channel_1 = get_block_step_byte(plane->frame_info->fb, direction, 1); + int step_channel_2 = get_block_step_byte(plane->frame_info->fb, direction, 2); + int subsampling = get_subsampling(plane->frame_info->fb->format, direction); + int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); + const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; + + for (int i = 0; i < count; i++) { + *out_pixel = argb_u16_from_yuv888(*y_plane, *channel_1_plane, *channel_2_plane, + conversion_matrix); + out_pixel += 1; + y_plane += step_y; + if ((i + subsampling_offset + 1) % subsampling == 0) { + channel_1_plane += step_channel_1; + channel_2_plane += step_channel_2; + } + } +} + /* * The following functions take one &struct pixel_argb_u16 and convert it to a specific format. * The result is stored in @out_pixel. @@ -445,6 +608,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 @@ -462,6 +639,185 @@ pixel_read_line_t get_pixel_read_line_function(u32 format) } } +/* + * Those matrices were generated using the colour python framework + * + * Below are the function calls used to generate each matrix, go to + * https://colour.readthedocs.io/en/develop/generated/colour.matrix_YCbCr.html + * for more info: + * + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static struct conversion_matrix no_operation = { + .matrix = { + { 4294967296, 0, 0, }, + { 0, 4294967296, 0, }, + { 0, 0, 4294967296, }, + }, + .y_offset = 0, +}; + +static const struct conversion_matrix yuv_bt601_full = { + .matrix = { + { 4294967296, 0, 6021544149 }, + { 4294967296, -1478054095, -3067191994 }, + { 4294967296, 7610682049, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt601_limited = { + .matrix = { + { 5020601039, 0, 6881764740 }, + { 5020601039, -1689204679, -3505362278 }, + { 5020601039, 8697922339, 0 }, + }, + .y_offset = 16, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt709_full = { + .matrix = { + { 4294967296, 0, 6763714498 }, + { 4294967296, -804551626, -2010578443 }, + { 4294967296, 7969741314, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt709_limited = { + .matrix = { + { 5020601039, 0, 7729959424 }, + { 5020601039, -919487572, -2297803934 }, + { 5020601039, 9108275786, 0 }, + }, + .y_offset = 16, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt2020_full = { + .matrix = { + { 4294967296, 0, 6333358775 }, + { 4294967296, -706750298, -2453942994 }, + { 4294967296, 8080551471, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt2020_limited = { + .matrix = { + { 5020601039, 0, 7238124312 }, + { 5020601039, -807714626, -2804506279 }, + { 5020601039, 9234915964, 0 }, + }, + .y_offset = 16, +}; + +/** + * swap_uv_columns() - Swap u and v column of a given matrix + * + * @matrix: Matrix in which column are swapped + */ +static void swap_uv_columns(struct conversion_matrix *matrix) +{ + swap(matrix->matrix[0][2], matrix->matrix[0][1]); + swap(matrix->matrix[1][2], matrix->matrix[1][1]); + swap(matrix->matrix[2][2], matrix->matrix[2][1]); +} + +/** + * get_conversion_matrix_to_argb_u16() - Retrieve the correct yuv to rgb conversion matrix for a + * given encoding and range. + * + * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) + * @encoding: DRM_COLOR_* value for which to obtain a conversion matrix + * @range: DRM_COLOR_*_RANGE value for which to obtain a conversion matrix + * @matrix: Pointer to store the value into + */ +void get_conversion_matrix_to_argb_u16(u32 format, + enum drm_color_encoding encoding, + enum drm_color_range range, + struct conversion_matrix *matrix) +{ + const struct conversion_matrix *matrix_to_copy; + bool limited_range; + + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + limited_range = true; + break; + case DRM_COLOR_YCBCR_FULL_RANGE: + limited_range = false; + break; + case DRM_COLOR_RANGE_MAX: + limited_range = false; + WARN_ONCE(true, "The requested range is not supported."); + break; + } + + switch (encoding) { + case DRM_COLOR_YCBCR_BT601: + matrix_to_copy = limited_range ? &yuv_bt601_limited : + &yuv_bt601_full; + break; + case DRM_COLOR_YCBCR_BT709: + matrix_to_copy = limited_range ? &yuv_bt709_limited : + &yuv_bt709_full; + break; + case DRM_COLOR_YCBCR_BT2020: + matrix_to_copy = limited_range ? &yuv_bt2020_limited : + &yuv_bt2020_full; + break; + case DRM_COLOR_ENCODING_MAX: + matrix_to_copy = &no_operation; + WARN_ONCE(true, "The requested encoding is not supported."); + break; + } + + memcpy(matrix, matrix_to_copy, sizeof(*matrix_to_copy)); + + /* + * Breaking in this switch means that the color format + encoding + range is not supported + */ + switch (format) { + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YVU444: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV42: + swap_uv_columns(matrix); + break; + default: + break; + } +} + /** * get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format. * If the format is not supported by VKMS a warning 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..d583855cb320 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -9,4 +9,8 @@ pixel_read_line_t get_pixel_read_line_function(u32 format); pixel_write_t get_pixel_write_function(u32 format); +void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding, + enum drm_color_range range, + struct conversion_matrix *matrix); + #endif /* _VKMS_FORMATS_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 5a028ee96c91..d4e375913122 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -17,7 +17,19 @@ static const u32 vkms_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, - DRM_FORMAT_RGB565 + DRM_FORMAT_RGB565, + DRM_FORMAT_NV12, + DRM_FORMAT_NV16, + DRM_FORMAT_NV24, + DRM_FORMAT_NV21, + DRM_FORMAT_NV61, + DRM_FORMAT_NV42, + DRM_FORMAT_YUV420, + DRM_FORMAT_YUV422, + DRM_FORMAT_YUV444, + DRM_FORMAT_YVU420, + DRM_FORMAT_YVU422, + DRM_FORMAT_YVU444, }; static struct drm_plane_state * @@ -118,6 +130,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, frame_info->rotation = new_state->rotation; vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt); + get_conversion_matrix_to_argb_u16(fmt, new_state->color_encoding, new_state->color_range, + &vkms_plane_state->conversion_matrix); } static int vkms_plane_atomic_check(struct drm_plane *plane, From patchwork Tue Apr 9 13:25:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622512 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 90EE2CD129A for ; Tue, 9 Apr 2024 13:26:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B12D9112DA1; Tue, 9 Apr 2024 13:26:11 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="NPTZ89v1"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4423D112DA0 for ; Tue, 9 Apr 2024 13:26:00 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 04C8A240021; Tue, 9 Apr 2024 13:25:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669159; 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=iNNUCkQ2cyInliwCdgtDUyF4TqooA01tBHRW2ik0cvU=; b=NPTZ89v1+tWlV0wBp7IVsyIjxuWwvi6XhNCIcMudsLJCInU7qots5PYo5YcPIykBUdElCc 8ctRbFVXlWN4PSoM3XvfrUveVnGGdY92s/keEVnsWCh8Www3BUnmfCnjtgNQewOfQ4ItK5 ySUgxaY7i3vSU6QJVNIM6RurY6wKrdqC2fQleGgMOW2Z1oe+LxkfrmMhUc9wZG6fHC0MBI m2Zsz7Qc59Tz72LiS7Iq7pqbF+PJ3e5mvcZuPQ+rdMncukvuDFKU7q/XWIY6w7d6er7kfO vvXCozJd5bV7xKPwq1LmgXLYQIrREBe7lLUYV4cBYsApaIaBlBFcHO7zued5sQ== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:31 +0200 Subject: [PATCH v6 13/17] drm/vkms: Add range and encoding properties to the plane MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-13-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1804; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=GuIKbTcZM/N7g93eJKZQXArSIEda7yyerndYbXPpZc8=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHT8fAqgtW0+UxhuEUv9drK2hP1v/IwEajg1 aiTzd8kZRCJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0wAKCRAgrS7GWxAs 4sBPD/9VvtfhYp0AXiF2aRidb45/dDbD/H4twtHgNHbP2Pr1Q72QQ5fNtPQX7R1hx1e9xnRlB0K lJF0GAyjqUMRxtjkk1/t8L5bjfUWF4jtEFPEIGBqge1ybRnxmloDksfWccss1dfXyY4s0NFjope kMYgjmzudZZAsDJoptL4/kCe+Nt/m3VdR/ikv5kJfDDS5ZlpzMQs+/jZsUn5Ypei/nPGg2cAQ6j x7bKxP6hFCGGf+R2V9WhfPHHF+v15orEpbgcEvsWpy6xazXRp74bSxBdIRLZ1t+tUKhNKiK+L8B iQZtoUPnfIF9KeLL9+pNNjk8dpgm9G3D7BEcDLpEBfyqVJqG2bhG18UMwdHF6QEfsN+/ATg/z3e 2WEBXZIrui4OYwPEGT9ADPkiS7ddbIIYXIRJDyMUOyFs/Qog2SMe0C5JcQy215RkZHHvnnoGR3j fpTzKG3eMH3zqSOG9N1/8nnbK5YqdEePe/Jxyxe29bpKLozYtT9JuxUvJjc1uXn1NdWQh7mZjAO jzHGRVpyqc4REagxmW0H44znlfwH4+sE7OteCs2QcJk5nNR1D6XikKG+o6Qluadccsv8Emq1RFk Y4S9axvSRRaH1k96JbpD+U3YlwuDuhiVGwbjgwuWuJaS+eYU/dU0MnF0uUa0ek3o+vieCICsI/h 7ZbTMgKgIVIQT+w== 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 Acked-by: Pekka Paalanen --- drivers/gpu/drm/vkms/vkms_formats.c | 2 +- drivers/gpu/drm/vkms/vkms_plane.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 2d7445a3de93..a294744d29d6 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -238,7 +238,7 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const u16 *pixel) static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, const struct conversion_matrix *matrix) { - u8 r, g, b; + u16 r, g, b; s64 fp_y, fp_channel_1, fp_channel_2; s64 fp_r, fp_g, fp_b; diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index d4e375913122..8f764a108b00 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -218,5 +218,14 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0, DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK); + drm_plane_create_color_properties(&plane->base, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709) | + BIT(DRM_COLOR_YCBCR_BT2020), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_FULL_RANGE); + return plane; } From patchwork Tue Apr 9 13:25:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622516 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 00AF3CD129A for ; Tue, 9 Apr 2024 13:26:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D8166112DAD; Tue, 9 Apr 2024 13:26:18 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="WZhjgNZb"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1D738112D9E for ; Tue, 9 Apr 2024 13:26:01 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 2974124000D; Tue, 9 Apr 2024 13:25:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669160; 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=WZhjgNZbhe1inJQhx+kDzoapFvhfDpMn5etEIcFsZc+BmHOQNOt8sHCtRjQ+ODQrtrNQPU M+8/DGF9DX9qxUYDEFIx++rbYOak1jBLNvrPN88xrAY08F7lZWde9AhKZzG3eVeHgxvV3w GIz+ekBton2PYpdGV6VYkX3uHuqZxd+4NJGO8c3uvRMzCl2ZZIuZtyZEei4SQoXG4dfCuU ANqPJQ1fZBvxsrarzjgGRiy5wglhnA3OI1RWbNA8120jpwGKg5nTUIaC3tX+DKcWaNTuzS PXfQvfw8GHJrgeZQKiExFg2Fi83iGZXGDJA7N/bsM6cLXA5qK3SeEnV2DDeVOw== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:32 +0200 Subject: [PATCH v6 14/17] drm/vkms: Drop YUV formats TODO MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-14-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=881; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=cRkkP1b8eceTuEm0QTSGTTTnDinaYzDjRJLok06bIiI=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHTz8zP9efvg7NCkW4Fqc9/zG18J9dEg8Olx ahIBysKX9OJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0wAKCRAgrS7GWxAs 4iRKD/0a9HNXg9O6s7vJrac/m6ZXWrzNtKZ9DzL2pPgFhXr8pZzn1N0//qZ8oiQEhwnkoQ3LLJt kvWONGAnc1+7SLlwpINXPDmRcfAn+/aq1goLAMG0ywVwHm81x9aNpAoGsZ89qaUXbgbHjBgJxbE u3JUFOnhoZKN2npdgnohMch0ZjuS8tckhJBxbAZM8Awo1fJYPz/EFBND/zrT+EXXg76R4Ts6YxK 49T8O/6a068hQHq0zeUIwR9V7aaj9y3NzoZWdp0JxtoLD7zhBskiJC3lD81zmL/EVU/2tQCS2XO ULT9deKVobVQuLOi8+hA1aTDuO7L1BpR+weKyHtoVn3C2+fSLf9PvMgy/YJjPGua+JZHr90I+gA qmUtPky1+b6MUUMeQG4UitHh6nAMw05djNlieMiFuHdxhnGuyzLrFQhukRSWpxPW/SHs+4y2Y0n cI1bGr+4Rp+LXVn5HzaZrF2HTBvaY/CDzxB9tCCoRY9RXtlkahdFz13wl7tquSjd+2sksG/JWZj 59TcdyEkfDTqaln/IBjDe0oVlT+wsbfVgtUD63Crf80qnI3JMCOP55ZzfIoPb7SARywSuF6fqrW No5kozExrJvD1DaxBK135//iQ585PyQGdlAV0hLO+CptFOemqwi242cbl/D5uN6WbMPP9uW1RNX hXzb9VjU1HUN9FA== 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 Tue Apr 9 13:25:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622515 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 83C9ECD1296 for ; Tue, 9 Apr 2024 13:26:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 081AE112DA9; Tue, 9 Apr 2024 13:26:18 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="CbcTfrNF"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 501E6112DA1 for ; Tue, 9 Apr 2024 13:26:02 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 44A94240010; Tue, 9 Apr 2024 13:26:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669161; 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=qKnLr9Cdpbb+UUgDs/jSKOYD+jFUWQBn+0kCQdSy/2M=; b=CbcTfrNFdxqyS9y6RP7rRVx8lQBn0mRkkU8LziXFRmhjvAKnDAWfPcY/1OTH8J4c0lv4LI mOgIg5yLCtBJEQIuwutaitZ6KfvCecyr+3NJmma45fMDKI7f0zMMlVVFHwYrCBobAeJJZG TbYw7oPGqjeukithDhhh0ga8SMyw7AluLOponkF8NGR6eAcKtNKMfcezNaOfb/gflNB9zO jhsmoOcmqwvkkSNPqNg1rQFUGkJTMbB1vXpw1fFt0QsJJ9u7hL4xjzg/XC3T6gDuYjiusU dUEZUcwVgq22mTUxbjCGfuujn8UHdGJ3gilOgXJmpZ9i/cMsBx6P5haCnWXdNA== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:33 +0200 Subject: [PATCH v6 15/17] drm/vkms: Create KUnit tests for YUV conversions MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-15-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=13626; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=c1PbZFy9Y/Qfg26UK6N8pPbavaEH8lxwoYsLrPqIBck=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHTR0v+NyyG/heq6scHR/IHuZFzgZOu8W/33 FHIGxAeDUCJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0wAKCRAgrS7GWxAs 4lhSEACMAbPInROLvKCr6veSGTXQyC+oYWhafPkZOnBgx0wvcK6qfxyfiCo/RoC96hO8Tzx9rri +mjCSsIBaOEaM61URmt95m8FBw51O1PEUAwNFgOdRc4R5FoT9d+NT1I2+Y1T4Ige/5PT+E1Qi23 1jHwLc36cxeYTEUfPSv63SJrBXUSf4uU336dxZR2rRFo6W7iYlIt8n7a3n3Km0vegr9Kpr1O9i/ Z2sSry5X6GDZYsC/bTrS8t2Zv2jBNmGaCQydtMnjaqzrwj3bMWu73ccSMQL65O3kFR3gnbv1RnO PemG2pLA9tRTt1/wQorr1797NZWXi6PF6CUVR3kzjLJi8pK8yXABVy03R5MJiePtisW/ZhMWTFb 5QLArbMVaksLdrMvuFf1qW90xGZIF/lJ2OjBgIY8nNvzXTZj7B6qloD437EKzhdAnhFj34ImWd8 LDvGTaZeCLUKxllAqYxkzLp6KfVIUWMHZ/bM7ooRXw+jn25ErrG8O7njjL5sI9G8vN6fV9xIRK5 NdjwgSb8/Iwps1bMxyWfFRyeGs1/J5sEsERfJWpLyJADjCRh/pD/j7iBk8hCSMMadKg9nlqV9I3 COT3Wl6djbPXQGNZ1puylEuCGAWuJ0TSOFJwBI4OsEn3NYkebtxJ2ZGGcsWXvicfYiGRU0HjLsS UQ75b6e6c9QYfow== 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 | 5 + 7 files changed, 263 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig index b9ecdebecb0b..5b6efabdbb17 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 "KUnit 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". 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..c7c556b4fd98 --- /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 a294744d29d6..ca9028c1ef1a 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" /** @@ -235,8 +237,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 channel_1, u8 channel_2, - const struct conversion_matrix *matrix) +VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, + const struct conversion_matrix *matrix) { u16 r, g, b; s64 fp_y, fp_channel_1, fp_channel_2; @@ -266,6 +268,7 @@ static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel return argb_u16_from_u16161616(0xffff, r, g, b); } +EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888); /* * The following functions are read_line function for each pixel format supported by VKMS. diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h index d583855cb320..b4fe62ab9c65 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -13,4 +13,9 @@ void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encod enum drm_color_range range, struct conversion_matrix *matrix); +#if IS_ENABLED(CONFIG_KUNIT) +struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, + const struct conversion_matrix *matrix); +#endif + #endif /* _VKMS_FORMATS_H_ */ From patchwork Tue Apr 9 13:25:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622509 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 B197FCD129A for ; Tue, 9 Apr 2024 13:26:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5EBFC112D9D; Tue, 9 Apr 2024 13:26:07 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="HZk0uG4t"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id E7CF7112DA7 for ; Tue, 9 Apr 2024 13:26:03 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 561B6240008; Tue, 9 Apr 2024 13:26:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669162; 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=HZk0uG4ti889oBfCdvCY1MxTUwOlSf/9ZUP2j5SU3IoAvZZDEupUSmVuU3dpKqyJyNKkE5 +Zl5gz2P3W/MAs6qCJy2DBanyX+opk/f4gdvAhlMI2UpQhZnNcO+gsy3Gvp1CVU3CBDxgC tgEy1FUMfdEycuhGJfPucJNwuDn7XJ0rL+3dRzy+cz+nyZzGrWp2xPhFFJnin3HqCevKDp C+cNxtfbynlqLtt37JwkwGlmxGxigVj5wKyOHsPRFDz+9/eWD6m+Vw6tEx9Ar9Hp1FPX+U W5aWoMYkR1NA/mKXLJxPT166+T2AW9jiyg6nhQbe6eF6roIjIhIxuyPE8ngdJw== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:34 +0200 Subject: [PATCH v6 16/17] drm/vkms: Add how to run the Kunit tests MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-16-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev 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/ZANAwAIASCtLsZbECziAcsmYgBmFUHTMLf4/jCJUHnHT+Fa6Naia0FVWTgBVdY/R WVGrT779H+JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB0wAKCRAgrS7GWxAs 4gigEADYRmbR0OEQ2q8wVP/YVMKRdQzaQGbLpuwp2ZSY5c0rnsIdrEbcSL/ljP8Bhi7yvGp5L9N C6PJu8hhe6MJRWHolg5ah6CfB0ckL7KR+0oxdGUbVsGaYlvbMyjVIz/Z0vMoQ2OHRIX2s4S9LBO H9kuvAq7M6mnF0DCEIb4TeZCJxtAT/S1XBV3izXHzwguAND5PBlnCeRedCETea4DGjwk6Do1xgH VeDUpmh3+AgT4omzQDNZEzRjo5siLDS59gjCmJOWFM1fN0eK+mWCk9jEfpK9cZwy4qG8S8w1ldQ 28OnlhY25qWozgisQkM27IvukZQUtEMhVfsPXeCDGbsEfyLdT4jvKH6fHdejxNR5Wg+yYdmdIgV 52jFT4UUCda0zDsM+dDufAs0X+XH/RvQAPIu/fg6Nkmguz3z3oVl+oIaihmFEDk+KIsvpJaXI3s MQ0al+SSDqB9WYWOQoPny6M1sF9J45Gh7m6LqxTzz0p5v4wWtZ//8cx36N4mJx3w4zYvOp82ths AiHeBA4GEjjJ2TLUmvq2tOXXPMh9z6gv7VFuHAGpona7j55hw7R8X2PZw66h11HthHeZ63NsmZ0 5Gr3nGLQHflUO5dZ6MfaDSPRbnJsfGLBV0N7wqPZuom5y8FPpKjo6mLLEQ1kfkkn+SQ62pkNiAM xTxSHObriauBylQ== 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 Tue Apr 9 13:25:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 13622513 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 F34FCCD129C for ; Tue, 9 Apr 2024 13:26:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D36FD112DA3; Tue, 9 Apr 2024 13:26:11 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="lRa+fbQb"; dkim-atps=neutral Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2BF0B112D92 for ; Tue, 9 Apr 2024 13:26:04 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 65232240009; Tue, 9 Apr 2024 13:26:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1712669163; 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=/5y7cEADgJR1FrJhDqhCbiuvpO5e8sfvTGUsiJEPc5I=; b=lRa+fbQb+Labjf5gpNtFPKXIyntOd1SvvYRJ8bZiE9MMgzF9Be1T5v8heL2qBj0unxzfGC VGYAApd5BMUwRXfzm9ERpZPcYb/OkK7lLhgrTY4BSUMmJLyIxJ8IKFoJ9bdSTpXvwPEuSK 3ptnJVCGyBqmanssMpSujFyGtlnA5143VnqT3s8Gj1aG9M5kTdBqWiY8bXkAQnvHDVOl1h r4NYrZIRI1oRp3skhVoWNz3LE4vyB1aBBg/Z02Ot+d0G5zP+zRN5cvXgOtLuey6po4v8DG 3IjDNJ5ftXp6xDD+oe2D+TrQjtPjircrHVcr8SymXiePwcq5y6Emwh46K4nc4A== From: Louis Chauvet Date: Tue, 09 Apr 2024 15:25:35 +0200 Subject: [PATCH v6 17/17] drm/vkms: Add support for DRM_FORMAT_R* MIME-Version: 1.0 Message-Id: <20240409-yuv-v6-17-de1c5728fd70@bootlin.com> References: <20240409-yuv-v6-0-de1c5728fd70@bootlin.com> In-Reply-To: <20240409-yuv-v6-0-de1c5728fd70@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 , rdunlap@infradead.org, 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.14-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=5425; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=iFX/kDaK9uqUiX85yO7iy5cASmjIam5Hn5owEa5VUUc=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBmFUHUkwcowQGm/PfTR2bdUt4cq74nbLc5jeYX/ vRcUuf1WaaJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZhVB1AAKCRAgrS7GWxAs 4qIRD/99A6U72HS1NntwwJjUFS5m/94kekCIgsGmI3mcLS3ofZVt4cqo6TUToG59jAwOiB0W8GM wjafDy6boZh8p4E+wWT+z9U0eh2crRi0kv2zhUHX/JQzIwHiZiMWoXCp30x8qVK6HavB+TOZNzi qZy24YaygqBxG7S8zsPhev6eIjw/S1oysruG4ihKlqgVDRE2aK0c0OCUSc3UFtEzZ/uRuiZZE21 XYXKWTNNK69NMZg9sqzA/o824BWyfMJwOOfBzWsQHNTStMFXwz3Jo//v2QeoVRk2bfQq6IG/2+A Hx8yUVaD+GuqCmUuwSIZJGlY3DUhbranBTyri6NUPC4hfDMB2g2kHuzKggbriPYBCFgWT08kT2X Byzqz1/5zJs5bEuiFe/f0tqt9MhLOvrDeayZ/MFLWri/TQg9piiq8WjfIq4R/KjsPpDJU3NeSR+ E+FH55fS1YKf6jWdkiLgeDPj0Cl6P/SEiSHMloA7SR16l+oTMHnj/znIjdWlkQK13oh667FX8BF uk4fER4nA69i8bCYPI+GI9+T4LsTBZYTYf1NpdfR8ulF/Q31Il8xSPqVPgC6iWTRhjgQOHp3U1j TzyflzhriHxoVqlIMdJoBRec0YUJUinvkxAXqybb1HKAxW3i42NTcuOEjB8xDqTrqk+OTyDz8Cs FvR76faSH0SUcKA== 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 Reviewed-by: Pekka Paalanen --- drivers/gpu/drm/vkms/vkms_formats.c | 101 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_plane.c | 4 ++ 2 files changed, 105 insertions(+) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index ca9028c1ef1a..7f49995686fd 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -237,6 +237,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 channel_1, u8 channel_2, const struct conversion_matrix *matrix) { @@ -302,6 +307,94 @@ static void magenta_to_argb_u16(const struct vkms_plane_state *plane, int x_star } } +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; + + WARN_ONCE(drm_format_info_block_height(plane->frame_info->fb->format, 0) != 1, + "%s() only support formats with block_h == 1", __func__); + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + int bit_offset = (8-bit_per_pixel) - rem_x * bit_per_pixel; + int step = get_block_step_byte(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; + int step_bit_offset; + + if (direction == READ_LEFT_TO_RIGHT) { + restart_bit_offset = 8 - bit_per_pixel; + step_bit_offset = -bit_per_pixel; + } else { + restart_bit_offset = 0; + step_bit_offset = bit_per_pixel; + } + + while (out_pixel < end) { + u8 val = ((*src_pixels) >> bit_offset) & mask; + + *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 >> bit_offset) & mask; + *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 step = get_block_step_byte(plane->frame_info->fb, direction, 0); + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + while (out_pixel < end) { + *out_pixel = argb_u16_from_gray8(*src_pixels); + src_pixels += step; + out_pixel += 1; + } +} + static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, enum pixel_read_direction direction, int count, struct pixel_argb_u16 out_pixel[]) @@ -625,6 +718,14 @@ pixel_read_line_t get_pixel_read_line_function(u32 format) case DRM_FORMAT_YVU422: case DRM_FORMAT_YVU444: return &planar_yuv_read_line; + case DRM_FORMAT_R1: + return &R1_read_line; + case DRM_FORMAT_R2: + return &R2_read_line; + case DRM_FORMAT_R4: + return &R4_read_line; + case DRM_FORMAT_R8: + return &R8_read_line; default: /* * This is a bug in vkms_plane_atomic_check(). All the supported diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 8f764a108b00..67f891e7ac58 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -30,6 +30,10 @@ static const u32 vkms_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU422, DRM_FORMAT_YVU444, + DRM_FORMAT_R1, + DRM_FORMAT_R2, + DRM_FORMAT_R4, + DRM_FORMAT_R8, }; static struct drm_plane_state *