From patchwork Tue Apr 15 13:55:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 14052291 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 A9B5DC369B4 for ; Tue, 15 Apr 2025 13:55:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 370E610E799; Tue, 15 Apr 2025 13:55:45 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="Vwqd5ErU"; dkim-atps=neutral Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3E0CC10E798 for ; Tue, 15 Apr 2025 13:55:42 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 8607043B69; Tue, 15 Apr 2025 13:55:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1744725341; 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=rPLsl1Wnw6xTV3qjhgNJ3a8w6kDKqvDpNfraRh10WKc=; b=Vwqd5ErUsBzVd7t+z9qx9cqu680AKhsz5XLupbchacHR+PFaQ89kyygFI4OKIAEujgoBU2 eWVv4pSUUSHi61HWVTZHm67QdLvyQd3hNuj6VQgMLaQVQ21OXLPH0IMRvFA1qmuPfanybP L1E9eZYgdlU5e69SFzQLlHYRttShzMv+YKs7eXg5dtL2dKxAOKxUDIwcC3xJDzWhdpkKHK r0iQqp4vXcNVyu5rzhcfeH7xNWocVd57J0EEpG6VXSp61Q7WF3XeObCVucq2t68iAPbXjn 0Q6JwrX96xs2tngNH7ailUS1D00dR033KHFjjHmqqHK7xEDwiDZw4SwpHsaPmQ== From: Louis Chauvet Date: Tue, 15 Apr 2025 15:55:32 +0200 Subject: [PATCH v18 1/8] drm/vkms: Document pixel_argb_u16 MIME-Version: 1.0 Message-Id: <20250415-yuv-v18-1-f2918f71ec4b@bootlin.com> References: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> In-Reply-To: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> To: Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , rdunlap@infradead.org, arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi, Simona Vetter , Rodrigo Siqueira , Simona Vetter 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, linux-doc@vger.kernel.org, Louis Chauvet X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1469; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=5LDLsxCEIxV8itrSYorWjRJlHdMGvtxfdDaQVosJF28=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBn/mVW1pZvfvfZ/YRIJ902gTBR6UwmY6m4YZBlz F6GY/AZR1eJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ/5lVgAKCRAgrS7GWxAs 4p44D/4spb4ytbTu1L+klIP4ICXGauN1D2c5PMTITVGjTtLO1YZbFWhDTkM2qlk/xGXHVplYuGQ D0D6GMlWUmaG/5otnETCpgv6PvRAhhRdpDCqJPPdWavT1mJnwMZ5KomhogrLU7YZf+VIMBRq81f N3LtTZTnP+5KnI4Cce90turkIKoqaC54qEuUXKu9SYFcRtAB5NtA+h5JHDpgG5P+oegz2sqxTzp uoFEHzBv5PXbDTVRjmMc7aTa7k0S+NaKaihVe/m7ojGQfLSh9eM5zFzSZs+1FqpoF9k/iGSwuYP RcIcgiRBzW6GHi1KLdsWdsevqEXuj6RPu7sPOyfTRUhjNgLT+ilAOul8DB1bZ21WqEutPzAx4HD i5xHXAiBFYbGphNq4KO7NAG+r+WLyvOoRQ8VOe5CqitbXJVIzpo8R64WPyprX4v5GIP5cqRJS9+ S/cpbubiPKro6wqSQ7gYJKUOhMT4f6CYBlBmAq8BqdRndoc/xAap1OFmjZUMei9UguW2/1AmL5i lMe2eNZuPX6fTXsWJqn30K8rn4wRTX5FGd0l0KDJSkqN274+26K3G2CuHNnwfNCzdHbaUwdavON D3cA7uKghouNoDFdMFjs8+yBMQxH8HARXyJ2yNNerFE9n5OPJjpJ+lKKJ4Fepd1CTxHkCRzl0ZX xvzbWm3tC8vPnTw== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvvdefieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhfffugggtgffkfhgjvfevofesthejredtredtjeenucfhrhhomhepnfhouhhishcuvehhrghuvhgvthcuoehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeehtdejtddtteeiiefgleejkeetteevhfdukeegleffjeehgeeivefhgeduffdvvdenucfkphepledtrdekledrudeifedruddvjeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeeltddrkeelrdduieefrdduvdejpdhhvghloheplgdujedvrddukedrtddrudgnpdhmrghilhhfrhhomheplhhouhhishdrtghhrghuvhgvthessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepvdegpdhrtghpthhtohepshhimhhonhgrrdhvvghtthgvrhesfhhffihllhdrtghhpdhrtghpthhtohepughrihdquggvvhgvlheslhhishhtshdrfhhrvggvuggvshhkthhophdrohhrghdprhgtphhtthhopehthhhomhgrshdrphgvthgriiiiohhnihessghoohhtlhhinhdrtghomhdprhgtphhtthhopehmrghirhgrtggrnhgrlhesrhhishgvuhhprdhnvghtpdhrtghpthhtohepnhhitghol hgvjhgruggvhigvvgesghhoohhglhgvrdgtohhmpdhrtghpthhtohepshhimhhonhgrsehffhiflhhlrdgthhdprhgtphhtthhopehmrghrtghhvghusehgohhoghhlvgdrtghomhdprhgtphhtthhopehtiihimhhmvghrmhgrnhhnsehsuhhsvgdruggv 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 meaning of each member of the structure was not specified. To clarify the format used and the reason behind those choices, add some documentation. Signed-off-by: Louis Chauvet Reviewed-by: Pekka Paalanen Reviewed-by: Pekka Paalanen --- drivers/gpu/drm/vkms/vkms_drv.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index a74a7fc3a056..3b7b46dd026f 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -45,6 +45,23 @@ struct vkms_frame_info { unsigned int rotation; }; +/** + * struct pixel_argb_u16 - Internal representation of a pixel color. + * @a: Alpha component value, stored in 16 bits, without padding, using + * machine endianness + * @r: Red component value, stored in 16 bits, without padding, using + * machine endianness + * @g: Green component value, stored in 16 bits, without padding, using + * machine endianness + * @b: Blue component value, stored in 16 bits, without padding, using + * machine endianness + * + * The goal of this structure is to keep enough precision to ensure + * correct composition results in VKMS and simplifying color + * manipulation by splitting each component into its own field. + * Caution: the byte ordering of this structure is machine-dependent, + * you can't cast it directly to AR48 or xR48. + */ struct pixel_argb_u16 { u16 a, r, g, b; }; From patchwork Tue Apr 15 13:55:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 14052289 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 9F879C369AB for ; Tue, 15 Apr 2025 13:55:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E7A2010E00F; Tue, 15 Apr 2025 13:55:44 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="WM+3ezXb"; dkim-atps=neutral Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id A97CE10E799 for ; Tue, 15 Apr 2025 13:55:43 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 1CE0543B6A; Tue, 15 Apr 2025 13:55:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1744725342; 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=piQOBnO7Dm55MboPlQC1dNnuyorLpHqURSdDoD/cU1s=; b=WM+3ezXb18TS+16xXXL6QZSLqNe8mIIzT/sxcboWBSIPIcAlf7EH8Y10BGlUVTfo9jCa1K qpJMVy/eJGmD7dG2QiZGhM66CCefZG7+V5l61vgZOGrYqEVI1EL03Sl+a0UnVKPtYksIIn w02AurPBm8hiTrqR/5ei2FySK7U4JAEEDV0bvGYl9y+VWqNFYWR+Wx/9yLV0oMDS4ZAQGA /M1wxWWJEgXl1AZIDqIhFmkV4ZDmTLdp7qBJB/MWNCqhUczpathz6u+nonVQlGOUat7x5d pveW3qvx9HNVtXczSir0Cng45IBMMYqxCWqN9vcMTTTJ7YxN0SSAKwBe3buyGA== From: Louis Chauvet Date: Tue, 15 Apr 2025 15:55:33 +0200 Subject: [PATCH v18 2/8] drm/vkms: Add YUV support MIME-Version: 1.0 Message-Id: <20250415-yuv-v18-2-f2918f71ec4b@bootlin.com> References: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> In-Reply-To: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> To: Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , rdunlap@infradead.org, arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi, Simona Vetter , Rodrigo Siqueira , Simona Vetter 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, linux-doc@vger.kernel.org, Louis Chauvet X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=18710; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=yuoohMe7TmzpHWvdhU8ivYc9oKpN/28rhDawRaA9hmY=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBn/mVWabPu9joZ4sGzRCzNnsQRqUdv004ABg41X PtQHVt99piJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ/5lVgAKCRAgrS7GWxAs 4uG9D/97U8YldHUp/r/t01CIgjmYsgqcCCxuI/oYH7RNUFEpMa7y1l4M4kdIwVbQBZL18JLM03F wL6oL3VgGZ7NJM1vgkfdLQX7y0xDrLevJ/XWakWJdzzEqla38GuuzwsVLJ/7JgqPL4gCRTs+wsr SnUCc9m49T5Ph6uYkQErDgxhCTkVf/RFmPrVbF2YscPOPAnYn07FTSCiZ+3eG1fcsnlvUhnYIFq h+Cc++8uztr07+q0bfGrIjlHklHAJUp9B9kc+5Vdz8SkErvtuFADs17qfPhKw2pWS4OVnXvLRci SDmSn1GxOFQW+98AqJ4eMC9GABrWKkn/iLvDwOSDtREpZmt/HLYNVYKezyRkjkCliJGxCfhBRtX lq9srzvg834ZzbsCr3hyW32qR2tL1KtaJNKmtjq58m3Dkdh2Aqn9GyRsoHyhokaVUny0YkUG5gm nS8q6t6z8qHdagcnC5zrgTsXTK4cjXYyY+cMOLDfvwUF/0zjEqwfQg20pa33jh/ucBXgRamawft GVQ2IyuinOIezyuCJ1Ec84uJGWulcLmqFGNGdE1APq2Z1T/AHywzoQ5dho3CqphTdKS5KDocUcB TURBC5freH/Rtz+uRMT9uHPS9nGKn9hUFhUZpTz6dbsEoiSdUE0CqlToYXgSk1uYPvDuKCcn3iL kItaSQwb+tBTLWg== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvvdefieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhfffugggtgffkfhgjvfevofesthejredtredtjeenucfhrhhomhepnfhouhhishcuvehhrghuvhgvthcuoehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeelfeekffffkefgffejueejiefhieffleelhedvvdetvdffvdfghefhfeevhedtheenucffohhmrghinheprhgvrgguthhhvgguohgtshdrihhonecukfhppeeltddrkeelrdduieefrdduvdejnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepledtrdekledrudeifedruddvjedphhgvlhhopegludejvddrudekrddtrddungdpmhgrihhlfhhrohhmpehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmpdhnsggprhgtphhtthhopedvgedprhgtphhtthhopehsihhmohhnrgdrvhgvthhtvghrsehffhiflhhlrdgthhdprhgtphhtthhopegurhhiqdguvghvvghlsehlihhsthhsrdhfrhgvvgguvghskhhtohhprdhorhhgpdhrtghpthhtohepthhhohhmrghsrdhpvghtrgiiiihonhhisegsohhothhlihhnrdgtohhmpdhrtghpthhtohepmhgrihhrrggtrghnrghls ehrihhsvghuphdrnhgvthdprhgtphhtthhopehnihgtohhlvghjrgguvgihvggvsehgohhoghhlvgdrtghomhdprhgtphhtthhopehsihhmohhnrgesfhhffihllhdrtghhpdhrtghpthhtohepmhgrrhgthhgvuhesghhoohhglhgvrdgtohhmpdhrtghpthhtohepthiiihhmmhgvrhhmrghnnhesshhushgvrdguvg 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 | 354 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_formats.h | 4 + drivers/gpu/drm/vkms/vkms_plane.c | 16 +- 4 files changed, 391 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 3b7b46dd026f..68b5e3fce455 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -119,17 +119,35 @@ typedef void (*pixel_read_line_t)(const struct vkms_plane_state *plane, int x_st int y_start, enum pixel_read_direction direction, int count, struct pixel_argb_u16 out_pixel[]); +/** + * struct conversion_matrix - Matrix to use for a specific encoding and range + * + * @matrix: Conversion matrix from yuv to rgb. The matrix is stored in a row-major manner and is + * used to compute rgb values from yuv values: + * [[r],[g],[b]] = @matrix * [[y],[u],[v]] + * OR for yvu formats: + * [[r],[g],[b]] = @matrix * [[y],[v],[u]] + * The values of the matrix are signed fixed-point values with 32 bits fractional part. + * @y_offset: Offset to apply on the y value. + */ +struct conversion_matrix { + s64 matrix[3][3]; + int y_offset; +}; + /** * struct vkms_plane_state - Driver specific plane state * @base: base plane state * @frame_info: data required for composing computation * @pixel_read_line: function to read a pixel line in this plane. The creator of a * struct vkms_plane_state must ensure that this pointer is valid + * @conversion_matrix: matrix used for yuv formats to convert to rgb */ struct vkms_plane_state { struct drm_shadow_plane_state base; struct vkms_frame_info *frame_info; pixel_read_line_t pixel_read_line; + struct conversion_matrix conversion_matrix; }; struct vkms_plane { diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 30a64ecca87c..8f7a5d54a076 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -140,6 +140,51 @@ static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info, *addr = (u8 *)frame_info->map[0].vaddr + offset; } +/** + * get_subsampling() - Get the subsampling divisor value on a specific direction + * + * @format: format to extarct the subsampling from + * @direction: direction of the subsampling requested + */ +static int get_subsampling(const struct drm_format_info *format, + enum pixel_read_direction direction) +{ + switch (direction) { + case READ_BOTTOM_TO_TOP: + case READ_TOP_TO_BOTTOM: + return format->vsub; + case READ_RIGHT_TO_LEFT: + case READ_LEFT_TO_RIGHT: + return format->hsub; + } + WARN_ONCE(true, "Invalid direction for pixel reading: %d\n", direction); + return 1; +} + +/** + * get_subsampling_offset() - An offset for keeping the chroma siting consistent regardless of + * x_start and y_start values + * + * @direction: direction of the reading to properly compute this offset + * @x_start: x coordinate of the starting point of the readed line + * @y_start: y coordinate of the starting point of the readed line + */ +static int get_subsampling_offset(enum pixel_read_direction direction, int x_start, int y_start) +{ + switch (direction) { + case READ_BOTTOM_TO_TOP: + return -y_start - 1; + case READ_TOP_TO_BOTTOM: + return y_start; + case READ_RIGHT_TO_LEFT: + return -x_start - 1; + case READ_LEFT_TO_RIGHT: + return x_start; + } + WARN_ONCE(true, "Invalid direction for pixel reading: %d\n", direction); + return 0; +} + /* * The following functions take pixel data (a, r, g, b, pixel, ...) and convert them to * &struct pixel_argb_u16 @@ -202,6 +247,38 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel) return out_pixel; } +static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, + const struct conversion_matrix *matrix) +{ + u16 r, g, b; + s64 fp_y, fp_channel_1, fp_channel_2; + s64 fp_r, fp_g, fp_b; + + fp_y = drm_int2fixp(((int)y - matrix->y_offset) * 257); + fp_channel_1 = drm_int2fixp(((int)channel_1 - 128) * 257); + fp_channel_2 = drm_int2fixp(((int)channel_2 - 128) * 257); + + fp_r = drm_fixp_mul(matrix->matrix[0][0], fp_y) + + drm_fixp_mul(matrix->matrix[0][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[0][2], fp_channel_2); + fp_g = drm_fixp_mul(matrix->matrix[1][0], fp_y) + + drm_fixp_mul(matrix->matrix[1][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[1][2], fp_channel_2); + fp_b = drm_fixp_mul(matrix->matrix[2][0], fp_y) + + drm_fixp_mul(matrix->matrix[2][1], fp_channel_1) + + drm_fixp_mul(matrix->matrix[2][2], fp_channel_2); + + fp_r = drm_fixp2int_round(fp_r); + fp_g = drm_fixp2int_round(fp_g); + fp_b = drm_fixp2int_round(fp_b); + + r = clamp(fp_r, 0, 0xffff); + g = clamp(fp_g, 0, 0xffff); + b = clamp(fp_b, 0, 0xffff); + + return argb_u16_from_u16161616(0xffff, r, g, b); +} + /* * The following functions are read_line function for each pixel format supported by VKMS. * @@ -331,6 +408,92 @@ static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start, } } +/* + * This callback can be used for YUV formats where U and V values are + * stored in the same plane (often called semi-planar formats). It will + * correctly handle subsampling as described in the drm_format_info of the plane. + * + * The conversion matrix stored in the @plane is used to: + * - Apply the correct color range and encoding + * - Convert YUV and YVU with the same function (a column swap is needed when setting up + * plane->conversion_matrix) + */ +static void semi_planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + u8 *y_plane; + u8 *uv_plane; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, + &y_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 1, + &uv_plane); + int step_y = get_block_step_bytes(plane->frame_info->fb, direction, 0); + int step_uv = get_block_step_bytes(plane->frame_info->fb, direction, 1); + int subsampling = get_subsampling(plane->frame_info->fb->format, direction); + int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); + const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; + + for (int i = 0; i < count; i++) { + *out_pixel = argb_u16_from_yuv888(y_plane[0], uv_plane[0], uv_plane[1], + conversion_matrix); + out_pixel += 1; + y_plane += step_y; + if ((i + subsampling_offset + 1) % subsampling == 0) + uv_plane += step_uv; + } +} + +/* + * This callback can be used for YUV format where each color component is + * stored in a different plane (often called planar formats). It will + * correctly handle subsampling as described in the drm_format_info of the plane. + * + * The conversion matrix stored in the @plane is used to: + * - Apply the correct color range and encoding + * - Convert YUV and YVU with the same function (a column swap is needed when setting up + * plane->conversion_matrix) + */ +static void planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + u8 *y_plane; + u8 *channel_1_plane; + u8 *channel_2_plane; + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, + &y_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 1, + &channel_1_plane); + packed_pixels_addr_1x1(plane->frame_info, + x_start / plane->frame_info->fb->format->hsub, + y_start / plane->frame_info->fb->format->vsub, 2, + &channel_2_plane); + int step_y = get_block_step_bytes(plane->frame_info->fb, direction, 0); + int step_channel_1 = get_block_step_bytes(plane->frame_info->fb, direction, 1); + int step_channel_2 = get_block_step_bytes(plane->frame_info->fb, direction, 2); + int subsampling = get_subsampling(plane->frame_info->fb->format, direction); + int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); + const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; + + for (int i = 0; i < count; i++) { + *out_pixel = argb_u16_from_yuv888(*y_plane, *channel_1_plane, *channel_2_plane, + conversion_matrix); + out_pixel += 1; + y_plane += step_y; + if ((i + subsampling_offset + 1) % subsampling == 0) { + channel_1_plane += step_channel_1; + channel_2_plane += step_channel_2; + } + } +} + /* * The following functions take one &struct pixel_argb_u16 and convert it to a specific format. * The result is stored in @out_pixel. @@ -456,6 +619,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 @@ -469,6 +646,183 @@ pixel_read_line_t get_pixel_read_line_function(u32 format) } } +/* + * Those matrices were generated using the colour python framework + * + * Below are the function calls used to generate each matrix, go to + * https://colour.readthedocs.io/en/develop/generated/colour.matrix_YCbCr.html + * for more info: + * + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix no_operation = { + .matrix = { + { 4294967296, 0, 0, }, + { 0, 4294967296, 0, }, + { 0, 0, 4294967296, }, + }, + .y_offset = 0, +}; + +static const struct conversion_matrix yuv_bt601_full = { + .matrix = { + { 4294967296, 0, 6021544149 }, + { 4294967296, -1478054095, -3067191994 }, + { 4294967296, 7610682049, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt601_limited = { + .matrix = { + { 5020601039, 0, 6881764740 }, + { 5020601039, -1689204679, -3505362278 }, + { 5020601039, 8697922339, 0 }, + }, + .y_offset = 16, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt709_full = { + .matrix = { + { 4294967296, 0, 6763714498 }, + { 4294967296, -804551626, -2010578443 }, + { 4294967296, 7969741314, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt709_limited = { + .matrix = { + { 5020601039, 0, 7729959424 }, + { 5020601039, -919487572, -2297803934 }, + { 5020601039, 9108275786, 0 }, + }, + .y_offset = 16, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"], + * is_legal = False, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt2020_full = { + .matrix = { + { 4294967296, 0, 6333358775 }, + { 4294967296, -706750298, -2453942994 }, + { 4294967296, 8080551471, 0 }, + }, + .y_offset = 0, +}; + +/* + * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"], + * is_legal = True, + * bits = 8) * 2**32).astype(int) + */ +static const struct conversion_matrix yuv_bt2020_limited = { + .matrix = { + { 5020601039, 0, 7238124312 }, + { 5020601039, -807714626, -2804506279 }, + { 5020601039, 9234915964, 0 }, + }, + .y_offset = 16, +}; + +/** + * swap_uv_columns() - Swap u and v column of a given matrix + * + * @matrix: Matrix in which column are swapped + */ +static void swap_uv_columns(struct conversion_matrix *matrix) +{ + swap(matrix->matrix[0][2], matrix->matrix[0][1]); + swap(matrix->matrix[1][2], matrix->matrix[1][1]); + swap(matrix->matrix[2][2], matrix->matrix[2][1]); +} + +/** + * get_conversion_matrix_to_argb_u16() - Retrieve the correct yuv to rgb conversion matrix for a + * given encoding and range. + * + * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) + * @encoding: DRM_COLOR_* value for which to obtain a conversion matrix + * @range: DRM_COLOR_*_RANGE value for which to obtain a conversion matrix + * @matrix: Pointer to store the value into + */ +void get_conversion_matrix_to_argb_u16(u32 format, + enum drm_color_encoding encoding, + enum drm_color_range range, + struct conversion_matrix *matrix) +{ + const struct conversion_matrix *matrix_to_copy; + bool limited_range; + + switch (range) { + case DRM_COLOR_YCBCR_LIMITED_RANGE: + limited_range = true; + break; + case DRM_COLOR_YCBCR_FULL_RANGE: + limited_range = false; + break; + case DRM_COLOR_RANGE_MAX: + limited_range = false; + WARN_ONCE(true, "The requested range is not supported."); + break; + } + + switch (encoding) { + case DRM_COLOR_YCBCR_BT601: + matrix_to_copy = limited_range ? &yuv_bt601_limited : + &yuv_bt601_full; + break; + case DRM_COLOR_YCBCR_BT709: + matrix_to_copy = limited_range ? &yuv_bt709_limited : + &yuv_bt709_full; + break; + case DRM_COLOR_YCBCR_BT2020: + matrix_to_copy = limited_range ? &yuv_bt2020_limited : + &yuv_bt2020_full; + break; + case DRM_COLOR_ENCODING_MAX: + matrix_to_copy = &no_operation; + WARN_ONCE(true, "The requested encoding is not supported."); + break; + } + + memcpy(matrix, matrix_to_copy, sizeof(*matrix_to_copy)); + + switch (format) { + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YVU444: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV42: + swap_uv_columns(matrix); + break; + default: + break; + } +} +EXPORT_SYMBOL(get_conversion_matrix_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 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 e34f8c7f83c3..6388928412f6 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -18,7 +18,19 @@ static const u32 vkms_formats[] = { DRM_FORMAT_ABGR8888, 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 * @@ -119,6 +131,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 15 13:55:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 14052297 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 01704C369B5 for ; Tue, 15 Apr 2025 13:56:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4123C10E79F; Tue, 15 Apr 2025 13:56:01 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="gWyt0Z8f"; dkim-atps=neutral Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0F40910E798 for ; Tue, 15 Apr 2025 13:55:44 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 89C5243B70; Tue, 15 Apr 2025 13:55:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1744725343; 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=Lh69y91DUFOtI34xFPwTFsuk49kOa56c1BplcJ4yxbw=; b=gWyt0Z8fTePyQEmwHPX95ZloHkcDhrKwlgy16chPuhtYkAI9Cmz26g11VrAW4IOGGndop+ GMOzb31mSJLrp+lgs6bHiHhU/Woe24112Q+y+rC3iPQvt3pNHH2CE4winpJAOYZsk6a7bo TgHCwWNYBILblnn3ZWg/EHflAYVkPGzdq410wOx9S+YTiwBtMoYCbT+csTqlPAtuWiZdD6 pVXYRz1IT6C93DoFp03d/ihkwHzMZUfDqx3j0EB1cuX9FUQtSWAottxhno9n46Kz3Bfs7c LfHe4N7Bv7XVFbftc/4UwZkSoULxOEaZ19xgZGzxuLM8CN0Q/TxFnVujG8p8+w== From: Louis Chauvet Date: Tue, 15 Apr 2025 15:55:34 +0200 Subject: [PATCH v18 3/8] drm/vkms: Add range and encoding properties to the plane MIME-Version: 1.0 Message-Id: <20250415-yuv-v18-3-f2918f71ec4b@bootlin.com> References: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> In-Reply-To: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> To: Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , rdunlap@infradead.org, arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi, Simona Vetter , Rodrigo Siqueira , Simona Vetter 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, linux-doc@vger.kernel.org, Louis Chauvet , Pekka Paalanen X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1253; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=62SVKpGa01amnKiiY4w9DV/3kXdnVR+79LQVwQUm9n8=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBn/mVXZmrHFBT/Cc/Rb7U+9AeyRNqOzDBW8oyZ+ 3R8spDzzMaJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ/5lVwAKCRAgrS7GWxAs 4rvREACaBO7wgxyza86AZYLOuJjGQDDtR0/X0523My4qQRp6BnfrpxuKT0RhKokC1FuRH4AdmKl xeOVUHL6OO4Qivl0soBbS1IhkILrnWSwqQulatgYdB6pZaVbxmCpWvQB3PrI1bFRZZVSmCXhJ93 xEEnZYM7WpeKy02HBlP4QIFUW1r3ve2IcVnt3CeD36UhvGkR3n3Hvd0Zl1oA3FvhVHIcuOOwX1i n3B4Cieejac0wZuQZqtbkIDEqSCg+drzwtLW3FQsgTyBK7y0ORrCANuNge/Pdewo6gboPCxv2P5 wyiahvhSS+s3l6s9V1SX2qo1SpupR8Y/WULFyvCFks4dKm10waBCDWLpcDlFyXevMgbkL6tI5H9 O1zYF4JKstQW7HY3wFktDUXcCFIiU0ecdAtxsblP0bop3+ExPHACsJQf6+BHv1JJSKoqSOnfe8Y paJai3u2gkwzuxujxUUDpbXNc6/iG296KEl9+eI3+WML7PKdMmLV8T70dRAExGvy2cqcKKa1V2e RLZsTY9qd06sT9fM5C6991QazRiR7j6EZc4x2yglT6iagm3XR8he6i2CinSxMehmlv846M8WGTk q8TVSdE9WwqU1YXAn7cZVnGHUqX4PZNwzZ46V+VI29bZ6ggZJrH08hfeUF2ax43IM/6ht9+YSBE n8OC5NAV05MItLg== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvvdefieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhfffugggtgffkfhgjvfevofesthejredtredtjeenucfhrhhomhepnfhouhhishcuvehhrghuvhgvthcuoehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeehtdejtddtteeiiefgleejkeetteevhfdukeegleffjeehgeeivefhgeduffdvvdenucfkphepledtrdekledrudeifedruddvjeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeeltddrkeelrdduieefrdduvdejpdhhvghloheplgdujedvrddukedrtddrudgnpdhmrghilhhfrhhomheplhhouhhishdrtghhrghuvhgvthessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepvdehpdhrtghpthhtohepshhimhhonhgrrdhvvghtthgvrhesfhhffihllhdrtghhpdhrtghpthhtohepughrihdquggvvhgvlheslhhishhtshdrfhhrvggvuggvshhkthhophdrohhrghdprhgtphhtthhopehthhhomhgrshdrphgvthgriiiiohhnihessghoohhtlhhinhdrtghomhdprhgtphhtthhopehmrghirhgrtggrnhgrlhesrhhishgvuhhprdhnvghtpdhrtghpthhtohepnhhitghol hgvjhgruggvhigvvgesghhoohhglhgvrdgtohhmpdhrtghpthhtohepshhimhhonhgrsehffhiflhhlrdgthhdprhgtphhtthhopehmrghrtghhvghusehgohhoghhlvgdrtghomhdprhgtphhtthhopehtiihimhhmvghrmhgrnhhnsehsuhhsvgdruggv X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Now that the driver internally handles these quantization ranges and YUV encoding matrices, expose the UAPI for setting them. Signed-off-by: Arthur Grillo [Louis Chauvet: retained only relevant parts, updated the commit message] Acked-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_plane.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 6388928412f6..fbfbe424e558 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -219,5 +219,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 15 13:55:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 14052296 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 80E7BC369AB for ; Tue, 15 Apr 2025 13:56:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E1D0810E79D; Tue, 15 Apr 2025 13:56:00 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="ame845Xa"; dkim-atps=neutral Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id 57CCE10E798 for ; Tue, 15 Apr 2025 13:55:46 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id DE3F043396; Tue, 15 Apr 2025 13:55:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1744725345; 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=dR9yWEIRRHJ25nlTr1+EBuKO+fo6LUQvlyPhe1j7Leo=; b=ame845Xa4/vDWc4kquMFbyAF8HPoAiTehqvTt3LK2TVfasIxeQvAS1kKmgIhYBoLgkC/qz bl2N4dazjzWjROjDxpXSTCmJ7pfWOPonukuaQJ5LEPL9VjiPoYaqCF3LKfPrLAPyQxIc1i PGe4/uCJyuSXBuua2pCPG6n9PoyPUBLM4+X1wiNpDExqvmbFJ6Z4xR4xXiI6gOH7vVlnx+ WFqBpMe2kJDq77A82/f+/lHHDtiVdDgkawfOel76DEF9BJgGhwfEzVLvHPnWtHMXGf4qpT GFK72PCnDMUBsPXrGS3/BZObQX3Y93rD6nEpX33EZG2bqcnr3ctosoWLNmgdPg== From: Louis Chauvet Date: Tue, 15 Apr 2025 15:55:35 +0200 Subject: [PATCH v18 4/8] drm/vkms: Drop YUV formats TODO MIME-Version: 1.0 Message-Id: <20250415-yuv-v18-4-f2918f71ec4b@bootlin.com> References: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> In-Reply-To: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> To: Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , rdunlap@infradead.org, arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi, Simona Vetter , Rodrigo Siqueira , Simona Vetter 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, linux-doc@vger.kernel.org, Louis Chauvet , Pekka Paalanen X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=966; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=BFg9CaGVVOEbb1ePvX1HYTdy4iQZcBj7S0puGrXjR1k=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBn/mVXOr+3zUszbJLtfrrZ8RU3BoIYbd/+f4aAB hRTI6cUiZCJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ/5lVwAKCRAgrS7GWxAs 4qTDD/9Ah96YxbrCb8edvPFzeVvvYh4SIfCdr/nc+m34kdvysv/1KtrdYMbVQHpE/p6ALGDaYB9 yF2FrxO87r0dTmFw+vDN2lnp+IViq+yZYhOA/R8v4xitsNP0zN1Y5lPjExvQskLq0oYWE5ojLy+ ycD6+msj0VwsNdKyb5Bxu3nFEihWZnxXAF6fvTwN5csn+S5aXV/DYiBW6e61Jrva7Kt8hkBa4G/ FBpNRof5KM+k6C8+mkgLxyAbVKi6NPEzoLFryynmL14MJBmnBYTMgmf2t/ySOrSdX4zS/ccSn+l SyYd2O75WTyZ+Cdalax6UWmi6yU5PKK4BrrW8fwvQ0YE9Y1qz2X/79ymuW0stiI+hWHTwH4vBUA O0ckhGR6ljHijcN96pWV/kuVUTrFVYco2UTjTvHU1oVz1yFuRLn9V7VPARwFDoJUtX1qK4zIgPk UdMBiEB830UcPvNlF0FoVVcBYxT7N8xULjQKoj+in15HyUKFVWQsG2Ecq+Q+OKfM9UL6YmJKMSn YpxiBKysFEXQmckVJ978DJV2zHZIDOIy9FzZaJKOyvOFX4eoE8Y8a/+2745GwsgkNO+0QvL2xxk i77gaICWKMQrlhc4oYhlywb/oRh9H5ik9U+SN5+OHsfnXE1cmN7B8e7cr0eiHGqydt7gLOOORlw Td/64rTBEGhG3XA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvvdefieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhfffugggtgffkfhgjvfevofesthejredtredtjeenucfhrhhomhepnfhouhhishcuvehhrghuvhgvthcuoehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeehtdejtddtteeiiefgleejkeetteevhfdukeegleffjeehgeeivefhgeduffdvvdenucfkphepledtrdekledrudeifedruddvjeenucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepihhnvghtpeeltddrkeelrdduieefrdduvdejpdhhvghloheplgdujedvrddukedrtddrudgnpdhmrghilhhfrhhomheplhhouhhishdrtghhrghuvhgvthessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepvdehpdhrtghpthhtohepshhimhhonhgrrdhvvghtthgvrhesfhhffihllhdrtghhpdhrtghpthhtohepughrihdquggvvhgvlheslhhishhtshdrfhhrvggvuggvshhkthhophdrohhrghdprhgtphhtthhopehthhhomhgrshdrphgvthgriiiiohhnihessghoohhtlhhinhdrtghomhdprhgtphhtthhopehmrghirhgrtggrnhgrlhesrhhishgvuhhprdhnvghtpdhrtghpthhtohepnhhitghol hgvjhgruggvhigvvgesghhoohhglhgvrdgtohhmpdhrtghpthhtohepshhimhhonhgrsehffhiflhhlrdgthhdprhgtphhtthhopehmrghrtghhvghusehgohhoghhlvgdrtghomhdprhgtphhtthhopehtiihimhhmvghrmhgrnhhnsehsuhhsvgdruggv 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 Acked-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- Documentation/gpu/vkms.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index ba04ac7c2167..88e0913ca33a 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -122,8 +122,8 @@ 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 + [Good to get started]. - Async updates (currently only possible on cursor plane using the legacy cursor api). From patchwork Tue Apr 15 13:55:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 14052294 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 6EECEC369B5 for ; Tue, 15 Apr 2025 13:55:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B4B0110E79C; Tue, 15 Apr 2025 13:55:53 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="h16p2gHX"; dkim-atps=neutral Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id A752A10E798 for ; Tue, 15 Apr 2025 13:55:47 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 3BCC543B34; Tue, 15 Apr 2025 13:55:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1744725346; 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=W/kxBS+R7AatRUaACkLiwnROBm8TvWT/gTUSAyzoqDo=; b=h16p2gHXzQNCgSJWhxKwugqErCfuCWAkC3D6bYeYUDthSR67fOdbo8Lpo3iH9Zkza+XdQF i8ALEVLE0cfwfFtPUEftAgz8/AcqcJv7nKcwS8LGu/ArWZbnUPhS3VWy4xlvkDxn4eLQFo WknukgwzaPEmO/XyGDPsjtacRi8AWqTQvh1gfeiL7+ITMJfx1fN2Jx1GTJZIwrtJ3/cHh0 e7FNOWzX+nDL0NHpOWvU5yY4qeB77QT/iWfUyQ6CxwK250iWPzqRRhf9v1rd+xHN2mYCci uSPOL8/n/uzPgrixwXcIEndnwDDgkqgbHDnUXCifw7N2lUNrshTebHBsCvOyAA== From: Louis Chauvet Date: Tue, 15 Apr 2025 15:55:36 +0200 Subject: [PATCH v18 5/8] drm: Export symbols to use in tests MIME-Version: 1.0 Message-Id: <20250415-yuv-v18-5-f2918f71ec4b@bootlin.com> References: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> In-Reply-To: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> To: Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , rdunlap@infradead.org, arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi, Simona Vetter , Rodrigo Siqueira , Simona Vetter 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, linux-doc@vger.kernel.org, Louis Chauvet , =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1321; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=oFZEeYV9E7SVwSiSnD5a6fJUQNr5BRcYxn1NNJcKmJ4=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBn/mVXzaq5d/Otd49/nUx4n0o1bpU0gEVJfJEwj FqvNibXQw+JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ/5lVwAKCRAgrS7GWxAs 4vsUD/9vxX/9vJRhKpWbEDP+E1LsjZiq8xrofY3+sO5G1fxynS8kq84NTPo2ObielE7V1c1Smpq kskPPd+pAFd3NSwih7qfVh0Cr3lBRpwDbLRvIhmJz9FoSyFBtAvHV8oHJOIbZrsNeV575Mz5rK9 lxY0gvB5HODEQ0I0uNK8xccWP9i6ULvPdJAtXcj46j4NQE/X5xYqpgE3kKVzsY15o/CZf0lwSNL bNScNtSuMCD6OHQ+xHkLpxNYReQWYKIKiezToECms++1bEp8TRm/ACLlLZho+Hlajfp62fviuoh Uyb4aTqClrZ4QIMFdnYyvxt7RefHw5BPEa92Eemp2mgh1HkslRZIO9nivw5L0ATrtoLKHPZEKKt cZzzYsIne+Xy14YLDG79BkJU4URt3qSmrTYC1XOV2Z2NuoaQEOLz5sWmwlOQt1QuTsFJJ/mtXeQ Hl3jTW+/LCtVzlgKM3G4VmMEh36hXXUzYbBmMaqfFPYqn6axExnxIdWvrRZ9dLPOGGYO8c94H4K X3mzG4wcoySsJbMc+Cp2CXz2hT95wC0B2EX4dSdiK99/vm0qieWf7xX2UoaOsgD7w7cTjwMyBb+ t/vDDZ9JWnVNpH1YlLscS7Vm/MnoXQV5x5nA+gGzY+XZ2xBQ+qNQS9a7r8xijQYdjux3s/6Ox9B 7v/wdyDw9WAU5ow== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvvdefieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhfffugggtgffkfhgjvfevofesthekredtredtjeenucfhrhhomhepnfhouhhishcuvehhrghuvhgvthcuoehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpedtieevieduhedttdfgtefhuddufeffudetkeegveeuteduveehheeivedttddtkeenucfkphepledtrdekledrudeifedruddvjeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeeltddrkeelrdduieefrdduvdejpdhhvghloheplgdujedvrddukedrtddrudgnpdhmrghilhhfrhhomheplhhouhhishdrtghhrghuvhgvthessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepvdehpdhrtghpthhtohepshhimhhonhgrrdhvvghtthgvrhesfhhffihllhdrtghhpdhrtghpthhtohepughrihdquggvvhgvlheslhhishhtshdrfhhrvggvuggvshhkthhophdrohhrghdprhgtphhtthhopehthhhomhgrshdrphgvthgriiiiohhnihessghoohhtlhhinhdrtghomhdprhgtphhtthhopehmrghirhgrtggrnhgrlhesrhhishgvuhhprdhnvghtpdhrtghpthhtohepnhhitghol hgvjhgruggvhigvvgesghhoohhglhgvrdgtohhmpdhrtghpthhtohepshhimhhonhgrsehffhiflhhlrdgthhdprhgtphhtthhopehmrghrtghhvghusehgohhoghhlvgdrtghomhdprhgtphhtthhopehjohhsvgdrvgigphhoshhithhokeelsehgmhgrihhlrdgtohhm 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 functions drm_get_color_encoding_name and drm_get_color_range_name are useful for clarifying test results. Therefore, export them so they can be used in tests built as modules. Reviewed-by: José Expósito Signed-off-by: Louis Chauvet --- drivers/gpu/drm/drm_color_mgmt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 3969dc548cff..b73a998352d1 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "drm_crtc_internal.h" @@ -494,6 +495,7 @@ const char *drm_get_color_encoding_name(enum drm_color_encoding encoding) return color_encoding_name[encoding]; } +EXPORT_SYMBOL_IF_KUNIT(drm_get_color_encoding_name); /** * drm_get_color_range_name - return a string for color range @@ -509,6 +511,7 @@ const char *drm_get_color_range_name(enum drm_color_range range) return color_range_name[range]; } +EXPORT_SYMBOL_IF_KUNIT(drm_get_color_range_name); /** * drm_plane_create_color_properties - color encoding related plane properties From patchwork Tue Apr 15 13:55:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 14052292 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 4CC24C369AB for ; Tue, 15 Apr 2025 13:55:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AA3A510E79A; Tue, 15 Apr 2025 13:55:50 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="hDgI9bb8"; dkim-atps=neutral Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1815810E798 for ; Tue, 15 Apr 2025 13:55:48 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 89E4C43B74; Tue, 15 Apr 2025 13:55:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1744725347; 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=fwUs7iqgjkBYyG731kDZlEUqcHE7BXAVFe6OaKYgir8=; b=hDgI9bb8I44m0WpAkWQjOddW/y1+bfs1LqNydqbfO5OU3m2SIy8Qwuy+U4A+sC2IaUQ012 2RRc3Pvx4Haj1g1UCw8dA6L3Oltt+PZ9WAJXKxoRh64twh4Xao7E+XJyIvR0NEx27rNNO5 l1BCRl3RsIGtByd39BlD7aKrmFcOvv/iVDEDJ4pACZTseShUdHmelsiJ19W5MWhvp6K2// gIOOoGFoTyFPxdMzZb5sIR8JBCrXt++PbaWYUJmx/Lb6KEOE917KUI5ZoNtky7bWMPUu80 iFTo4b/ehw2z0EeBfadEYrxl8CbIOziRTRJWvpi5VzccrAzKn7W7s/LHZyHWMA== From: Louis Chauvet Date: Tue, 15 Apr 2025 15:55:37 +0200 Subject: [PATCH v18 6/8] drm/vkms: Create KUnit tests for YUV conversions MIME-Version: 1.0 Message-Id: <20250415-yuv-v18-6-f2918f71ec4b@bootlin.com> References: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> In-Reply-To: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> To: Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , rdunlap@infradead.org, arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi, Simona Vetter , Rodrigo Siqueira , Simona Vetter 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, linux-doc@vger.kernel.org, Louis Chauvet , Pekka Paalanen X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=14609; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=rITblXXoxBn3V8r9dtCiRvk/wc1v0ug/RnbsUK7iXB0=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBn/mVYNUpR6HuNZJd+PBPiKoErVNkqd9yN6jGAq WA9DWIxoQSJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ/5lWAAKCRAgrS7GWxAs 4o23EACY8WZ1OodyUX2oPgMfvo5g+vtlteLd4Z/lAzl6PdG+0xEkKznKtnruQwk8AC2i8xBGfki EuHFkLnlUN0lSuaiApFGoebs/RhuqLcNEDObqJdgG0MsRMYZPiot824B20SWno43KTW7STc9gsb AKJrBMp1JXzv+Xm71Sob3qEEXmOGWllOCMzgA/nt/szQRgkT0ODMzU1Lglz5FhUAL4casbGaX2x J6wyTXDK17vTB8Yd2pvLRFYyH1TzmAAj6RxkGJQ3KvgTXkaQco6uM+aRdu83clgz9w20BAyVPAq 13jFIcSrLIcoQmk2mOVBlGhNz9vqTJtViqwg/1i7v1zma/gCWngc1CfGJMkxKN26CTkxN2SKfd0 jv0cUwogwK4wOWRl201FNqz2C69U+nWwlm6qGVOoZA+0GZJpJFXslPniUk2iG8fluSZxfEgvuDI v3l6Gpo5Bg4guQ1dF4nxONPz8xvJayJ7xmwx63NitR+9DclOBXe+UHgVLYF/bfuv1mDubj+Wyvi j3j3z/G7TYfTJIaAIxn2G2h0L7VKxMVAm4pUkOki50l9PSOHoFah4uwhKqZW5u036ctqr+thgq8 6C4wRWcU405qqeEBtoKnrXCx2MykFaQGzztgchNXGKJkSy/58mBGomMMTJU09+e5UtJuXb4MV13 xt1rOear2WukYWQ== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvvdefieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhfffugggtgffkfhgjvfevofesthejredtredtjeenucfhrhhomhepnfhouhhishcuvehhrghuvhgvthcuoehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeelfeekffffkefgffejueejiefhieffleelhedvvdetvdffvdfghefhfeevhedtheenucffohhmrghinheprhgvrgguthhhvgguohgtshdrihhonecukfhppeeltddrkeelrdduieefrdduvdejnecuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehinhgvthepledtrdekledrudeifedruddvjedphhgvlhhopegludejvddrudekrddtrddungdpmhgrihhlfhhrohhmpehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmpdhnsggprhgtphhtthhopedvhedprhgtphhtthhopehsihhmohhnrgdrvhgvthhtvghrsehffhiflhhlrdgthhdprhgtphhtthhopegurhhiqdguvghvvghlsehlihhsthhsrdhfrhgvvgguvghskhhtohhprdhorhhgpdhrtghpthhtohepthhhohhmrghsrdhpvghtrgiiiihonhhisegsohhothhlihhnrdgtohhmpdhrtghpthhtohepmhgrihhrrggtrghnrghls ehrihhsvghuphdrnhgvthdprhgtphhtthhopehnihgtohhlvghjrgguvgihvggvsehgohhoghhlvgdrtghomhdprhgtphhtthhopehsihhmohhnrgesfhhffihllhdrtghhpdhrtghpthhtohepmhgrrhgthhgvuhesghhoohhglhgvrdgtohhmpdhrtghpthhtohepthiiihhmmhgvrhhmrghnnhesshhushgvrdguvg X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Arthur Grillo Create KUnit tests to test the conversion between YUV and RGB. Test each conversion and range combination with some common colors. The code used to compute the expected result can be found in comment. [Louis Chauvet: - fix minor formating issues (whitespace, double line) - change expected alpha from 0x0000 to 0xffff - adapt to the new get_conversion_matrix usage - apply the changes from Arthur - move struct pixel_yuv_u8 to the test itself] Signed-off-by: Arthur Grillo Acked-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/tests/Makefile | 1 + drivers/gpu/drm/vkms/tests/vkms_format_test.c | 280 ++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_formats.c | 7 +- drivers/gpu/drm/vkms/vkms_formats.h | 5 + 4 files changed, 291 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile index 9ded37b67a46..0ee077942ae2 100644 --- a/drivers/gpu/drm/vkms/tests/Makefile +++ b/drivers/gpu/drm/vkms/tests/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) += vkms_config_test.o +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..2e1daef94831 --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c @@ -0,0 +1,280 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +#include +#include + +#include "../../drm_crtc_internal.h" + +#include "../vkms_formats.h" + +#define TEST_BUFF_SIZE 50 + +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); + +/** + * struct pixel_yuv_u8 - Internal representation of a pixel color. + * @y: Luma value, stored in 8 bits, without padding, using + * machine endianness + * @u: Blue difference chroma value, stored in 8 bits, without padding, using + * machine endianness + * @v: Red difference chroma value, stored in 8 bits, without padding, using + * machine endianness + */ +struct pixel_yuv_u8 { + u8 y, u, v; +}; + +/* + * struct yuv_u8_to_argb_u16_case - Reference values to test the color + * conversions in VKMS between YUV to ARGB + * + * @encoding: Encoding used to convert RGB to YUV + * @range: Range used to convert RGB to YUV + * @n_colors: Count of test colors in this case + * @format_pair.name: Name used for this color conversion, used to + * clarify the test results + * @format_pair.rgb: RGB color tested + * @format_pair.yuv: Same color as @format_pair.rgb, but converted to + * YUV using @encoding and @range. + */ +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) + * + * Tests cases for color conversion generated by converting RGB + * values to YUV BT601 full range using the ITU-R BT.601 weights. + */ + { + .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) + * Tests cases for color conversion generated by converting RGB + * values to YUV BT601 limited range using the ITU-R BT.601 weights. + */ + { + .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) + * Tests cases for color conversion generated by converting RGB + * values to YUV BT709 full range using the ITU-R BT.709 weights. + */ + { + .encoding = DRM_COLOR_YCBCR_BT709, + .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", { 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) + * Tests cases for color conversion generated by converting RGB + * values to YUV BT709 limited range using the ITU-R BT.709 weights. + */ + { + .encoding = DRM_COLOR_YCBCR_BT709, + .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", { 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) + * Tests cases for color conversion generated by converting RGB + * values to YUV BT2020 full range using the ITU-R BT.2020 weights. + */ + { + .encoding = DRM_COLOR_YCBCR_BT2020, + .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", { 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) + * Tests cases for color conversion generated by converting RGB + * values to YUV BT2020 limited range using the ITU-R BT.2020 weights. + */ + { + .encoding = DRM_COLOR_YCBCR_BT2020, + .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", { 0x4a, 0x61, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, + { "green", { 0xa4, 0x2f, 0x19 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, + { "blue", { 0x1d, 0xf0, 0x77 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, + }, + }, +}; + +/* + * vkms_format_test_yuv_u8_to_argb_u16 - Testing the conversion between YUV + * colors to ARGB colors in VKMS + * + * This test will use the functions get_conversion_matrix_to_argb_u16 and + * argb_u16_from_yuv888 to convert YUV colors (stored in + * yuv_u8_to_argb_u16_cases) into ARGB colors. + * + * The conversion between YUV and RGB is not totally reversible, so there may be + * some difference between the expected value and the result. + * In addition, there may be some rounding error as the input color is 8 bits + * and output color is 16 bits. + */ +static void vkms_format_test_yuv_u8_to_argb_u16(struct kunit *test) +{ + const struct yuv_u8_to_argb_u16_case *param = test->param_value; + struct pixel_argb_u16 argb; + + for (size_t i = 0; i < param->n_colors; i++) { + const struct format_pair *color = ¶m->colors[i]; + struct conversion_matrix matrix; + + get_conversion_matrix_to_argb_u16 + (DRM_FORMAT_NV12, param->encoding, param->range, &matrix); + + argb = argb_u16_from_yuv888(color->yuv.y, color->yuv.u, color->yuv.v, &matrix); + + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.a, color->argb.a), 0x1ff, + "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), 0x1ff, + "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), 0x1ff, + "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), 0x1ff, + "On the B channel of the color %s expected 0x%04x, got 0x%04x", + color->name, color->argb.b, argb.b); + } +} + +static void vkms_format_test_yuv_u8_to_argb_u16_case_desc(struct yuv_u8_to_argb_u16_case *t, + char *desc) +{ + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s - %s", + drm_get_color_encoding_name(t->encoding), drm_get_color_range_name(t->range)); +} + +KUNIT_ARRAY_PARAM(yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_cases, + vkms_format_test_yuv_u8_to_argb_u16_case_desc +); + +static struct kunit_case vkms_format_test_cases[] = { + KUNIT_CASE_PARAM(vkms_format_test_yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_gen_params), + {} +}; + +static struct kunit_suite vkms_format_test_suite = { + .name = "vkms-format", + .test_cases = vkms_format_test_cases, +}; + +kunit_test_suite(vkms_format_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Kunit test for vkms format conversion"); diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 8f7a5d54a076..9972780f3fa9 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -7,6 +7,8 @@ #include #include +#include + #include "vkms_formats.h" /** @@ -247,8 +249,8 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel) return out_pixel; } -static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, - const struct conversion_matrix *matrix) +VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, + const struct conversion_matrix *matrix) { u16 r, g, b; s64 fp_y, fp_channel_1, fp_channel_2; @@ -278,6 +280,7 @@ static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel return argb_u16_from_u16161616(0xffff, r, g, b); } +EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888); /* * The following functions are read_line function for each pixel format supported by VKMS. diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h index d583855cb320..b4fe62ab9c65 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -13,4 +13,9 @@ void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encod enum drm_color_range range, struct conversion_matrix *matrix); +#if IS_ENABLED(CONFIG_KUNIT) +struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, + const struct conversion_matrix *matrix); +#endif + #endif /* _VKMS_FORMATS_H_ */ From patchwork Tue Apr 15 13:55:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 14052293 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 39849C369AB for ; Tue, 15 Apr 2025 13:55:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 943CE10E798; Tue, 15 Apr 2025 13:55:53 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="Y7PIHt3T"; dkim-atps=neutral Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6599A10E798 for ; Tue, 15 Apr 2025 13:55:50 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id EF27B43B62; Tue, 15 Apr 2025 13:55:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1744725349; 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=vltx8mX8ESD4Izg3jWX1FdzqFZybnTpIrj/T6kwhbj4=; b=Y7PIHt3TdvglBtvpaf71cuytlUfvac/z1WF3tpqrQf+0fRmcq7Al7CCupeBl+okgYFsmqH 4tO+r0QA+rfegpOj0M4adti30DXuFD0pRWnuH3TD3AKLy8WMkHgTYMkQUXYr/HELSAUH4E s9/IhI/yulLeSNXZzYecrAYZWcd+2BmgjSAI+tv+yLPeRWw0eWCBQuaJuP31V7t/dUj2Tv VG9vb2TSvnU6rIDJ7dxF9aRkAv4n8l5fzZXK5L3bTSarzGsX0Gj9t74YaM2nfyxHGpP7HI kecFSkSWc5KdFT79HKkKdujixSnVYracvJinT9tuCXpCscn2+SvN56zKGHafqg== From: Louis Chauvet Date: Tue, 15 Apr 2025 15:55:38 +0200 Subject: [PATCH v18 7/8] drm/vkms: Add how to run the Kunit tests MIME-Version: 1.0 Message-Id: <20250415-yuv-v18-7-f2918f71ec4b@bootlin.com> References: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> In-Reply-To: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> To: Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , rdunlap@infradead.org, arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi, Simona Vetter , Rodrigo Siqueira , Simona Vetter 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, linux-doc@vger.kernel.org, Louis Chauvet , =?utf-8?b?Sm9zw6kgRXhww7NzaXRv?= , Pekka Paalanen X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1230; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=YGppOmZ08w7cdLZ6VCQdJA6v437CNcrpfGrTCIG4Hjw=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBn/mVYl7A5OdU5wgLFgyJqo3WRwjpjBtmyRzIeF DTRv82maMmJAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ/5lWAAKCRAgrS7GWxAs 4sVcEACT01B7kphm74TDymnMyKEpMCa9bKQPZte1wJeWHiY7H9cgAS8xT9rhnERo2sDe/GzI3D5 MN9bXVJ60rTo2XK14CNwaEf5BRWzpmtF9YrgqIcx90bB288yAgz6FwaKqOwhH8EAwXvj0yXO5KT mPqUG0qjJDSiJ7YmAWjXdNaIpeT/86M9sSf2KXZxVwaX/fLMBJpmvwhn6AHsuGn5EG2kWTD9gCM xXQ/mv88CxmhAQ/fSrAETbrmxEGLOinaLCxwNt+jOecr7dIO12W++lYSU1JMtGBVRU3l9fK8BvF 7jhDq8vj0QCnzqB6zOcfMx00E/cXXHhrVB13t/MdrPwvCF9qEZgh7vOLBh809FeFM72vipaU9De U5LfMTuAQZT25Yc+wMYATzN5MGTXaBCNqFoonfd/BTvnuHQEQLlS+aIXoZlaHXop1xJRLW+SzR+ 5hn8cZG4Vb99ikWhtVTX8YrsAi268SuiXkneHfOrnrCBaPUBNlO+H9IxVHfXryroipPQKhLUs7I WQG17CqbnqNOmOXZYqvIESSenQYhrDab1fTTFh5g3KMiEvPTbI+a8lmfcmxHJgfESFVviczAvcq QKrM5LCp3OzuTDh46Szvrq86zlQv3FX2YUAGFR3DTOHb1+U0hC/7Rp399clCnuBKOf9YI/cE+sw ENBQvcl5xu8eshg== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvvdefieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhfffugggtgffkfhgjvfevofesthekredtredtjeenucfhrhhomhepnfhouhhishcuvehhrghuvhgvthcuoehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeelfeffhfffhfeukefhvdeftdejhfevfefhffffheeiffelieejkeehvdettdffveenucffohhmrghinheprhhsthdrthhonecukfhppeeltddrkeelrdduieefrdduvdejnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepledtrdekledrudeifedruddvjedphhgvlhhopegludejvddrudekrddtrddungdpmhgrihhlfhhrohhmpehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmpdhnsggprhgtphhtthhopedviedprhgtphhtthhopehsihhmohhnrgdrvhgvthhtvghrsehffhiflhhlrdgthhdprhgtphhtthhopegurhhiqdguvghvvghlsehlihhsthhsrdhfrhgvvgguvghskhhtohhprdhorhhgpdhrtghpthhtohepthhhohhmrghsrdhpvghtrgiiiihonhhisegsohhothhlihhnrdgtohhmpdhrtghpthhtohepmhgrihhrrggtrghnrghlsehrihhsvghuphdrn hgvthdprhgtphhtthhopehnihgtohhlvghjrgguvgihvggvsehgohhoghhlvgdrtghomhdprhgtphhtthhopehsihhmohhnrgesfhhffihllhdrtghhpdhrtghpthhtohepmhgrrhgthhgvuhesghhoohhglhgvrdgtohhmpdhrtghpthhtohepjhhoshgvrdgvgihpohhsihhtohekleesghhmrghilhdrtghomh 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 Reviewed-by: José Expósito Acked-by: Pekka Paalanen 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 88e0913ca33a..8a8b1002931f 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 15 13:55:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Louis Chauvet X-Patchwork-Id: 14052295 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 CCC04C369B4 for ; Tue, 15 Apr 2025 13:55:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7A3BF10E7A7; Tue, 15 Apr 2025 13:55:54 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.b="QyA+MeXU"; dkim-atps=neutral Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id C8E8610E79C for ; Tue, 15 Apr 2025 13:55:51 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 4627243B6F; Tue, 15 Apr 2025 13:55:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1744725350; 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=BFStFxiSNP6zsD+AVy+GK0+VsuHYEAh+UshoPL2W+PI=; b=QyA+MeXUWnp6pEbxl3KxBSTOmW/PF64EFp3sxeHIQg28FvjU5GmPxdKEuWkV6aWJ9jP3yQ jYuZ4ELlj0Q4sFAnyLBX1cmgyibhWLmxv6OLxJ+Sy6IqJAhmBkR3/eJU3Phmqbfw4Azf4a TaiK5KJZZeFgNlVx3qipAva/f3sbhDWsOllFjzWzAw6cL+SzlzTu+xrQhHzFCU9UWJQSsl NBUwpwkBgA9oNHFRd/S5vei7DFxfpYw+SnReYu0hAtFCUSwwqQj52eR2U/rMocqZCySYwB njKuaWqibkPLNmhSOvIioVLf/jCP0vArB2Wk2m5mbZJKCu7Sknv/p/6WpSpepw== From: Louis Chauvet Date: Tue, 15 Apr 2025 15:55:39 +0200 Subject: [PATCH v18 8/8] drm/vkms: Add support for DRM_FORMAT_R* MIME-Version: 1.0 Message-Id: <20250415-yuv-v18-8-f2918f71ec4b@bootlin.com> References: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> In-Reply-To: <20250415-yuv-v18-0-f2918f71ec4b@bootlin.com> To: Melissa Wen , =?utf-8?q?Ma=C3=ADra_Canal?= , Haneen Mohammed , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , rdunlap@infradead.org, arthurgrillo@riseup.net, Jonathan Corbet , pekka.paalanen@haloniitty.fi, Simona Vetter , Rodrigo Siqueira , Simona Vetter 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, linux-doc@vger.kernel.org, Louis Chauvet , Pekka Paalanen X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=6382; i=louis.chauvet@bootlin.com; h=from:subject:message-id; bh=iKOzetAfZReJAcdUlG7eolu/4x+NwgMFpiXfDMB5C4Q=; b=owEBbQKS/ZANAwAIASCtLsZbECziAcsmYgBn/mVYv2iqDg6txz2cwAxi/bCFgY45fKWYaRKZz xn1pnJ1Rr+JAjMEAAEIAB0WIQRPj7g/vng8MQxQWQQgrS7GWxAs4gUCZ/5lWAAKCRAgrS7GWxAs 4vSPD/9MwtqczyZh/kFcUBOQLE97zHN6nmDGsazBH8w50PP3EJyXrROwLqlp/t0k3duE1ZsFCcm 1RHaxkpuGy1SFKHB04vRay5PzGmrkhXH2jOn4WTjvVGsla6XNsVbhYyNxDFXD5/WvvzP9kzBmv1 PFSbl6IpcW3CTYwAAjYBtNWu5rhgzICQq5IFt8cHq1stGI5YMWj+nUYjDB45SWMl1q9JM7QP4ef aO3q2W0U1Z8Affekm2zw63+pCo50tSfopufqkv+2mc48NJhclLJDdPAM9sjCd/XkwQZuGFQicku 2AcuFIrQ6zul2ZcQZ4jI7fD7oXx1JHEZ+tD3UNZ6EY0P06rLT/azr/Lb6V1/czhJs8OM8driO6Z Tzj3lcXFY1mjWLRsj6PQWJeckdxpQ2rx8IOSGUef+Ux+/4xZazwDM3+ZPmdEF7OWHJtOf+u7YPN 7A3+uCe6y9PwlR38M93c2oJTQNbSTZKNez2nBdO9ARL7Es0bnrFNQ9wx25PCIfiZK0bxM2rANu7 +Ja1Xu2nTgx38hzE7wsF+u4/Vw6bNz624xKRHCKUhPC4pWud+0jLO9HQC+Qzjk/UgJJcfsVEzFe qg9M1icqGham9nfWNdQArUbTRNPfTs4JGwjTH6xdARQzBIorHdd+ZdGBzduO9R7vrUfWJldcBoo 7/TeqSDQ9XsDHeA== X-Developer-Key: i=louis.chauvet@bootlin.com; a=openpgp; fpr=8B7104AE9A272D6693F527F2EC1883F55E0B40A5 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvvdefieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhfffugggtgffkfhgjvfevofesthejredtredtjeenucfhrhhomhepnfhouhhishcuvehhrghuvhgvthcuoehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpedvgfefgfehtefghfffteffgfehfeetledtvdduueeifedvtdeltdeuheejleeftdenucffohhmrghinhepkhgvrhhnvghlrdhorhhgnecukfhppeeltddrkeelrdduieefrdduvdejnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepledtrdekledrudeifedruddvjedphhgvlhhopegludejvddrudekrddtrddungdpmhgrihhlfhhrohhmpehlohhuihhsrdgthhgruhhvvghtsegsohhothhlihhnrdgtohhmpdhnsggprhgtphhtthhopedvhedprhgtphhtthhopehsihhmohhnrgdrvhgvthhtvghrsehffhiflhhlrdgthhdprhgtphhtthhopegurhhiqdguvghvvghlsehlihhsthhsrdhfrhgvvgguvghskhhtohhprdhorhhgpdhrtghpthhtohepthhhohhmrghsrdhpvghtrgiiiihonhhisegsohhothhlihhnrdgtohhmpdhrtghpthhtohepmhgrihhrrggtrghnrghlsehrihhsv ghuphdrnhgvthdprhgtphhtthhopehnihgtohhlvghjrgguvgihvggvsehgohhoghhlvgdrtghomhdprhgtphhtthhopehsihhmohhnrgesfhhffihllhdrtghhpdhrtghpthhtohepmhgrrhgthhgvuhesghhoohhglhgvrdgtohhmpdhrtghpthhtohepthiiihhmmhgvrhhmrghnnhesshhushgvrdguvg X-GND-Sasl: louis.chauvet@bootlin.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" This add the support for: - R1/R2/R4/R8 R1 format was tested with [1] and [2]. [1]: https://lore.kernel.org/r/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com [2]: https://lore.kernel.org/igt-dev/20240306-b4-kms_tests-v1-0-8fe451efd2ac@bootlin.com/ Reviewed-by: Pekka Paalanen Signed-off-by: Louis Chauvet --- drivers/gpu/drm/vkms/vkms_formats.c | 110 +++++++++++++++++++++++++++++++++++- drivers/gpu/drm/vkms/vkms_plane.c | 4 ++ 2 files changed, 113 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 9972780f3fa9..6d0227c6635a 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -249,6 +249,16 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel) return out_pixel; } +static struct pixel_argb_u16 argb_u16_from_gray8(u8 gray) +{ + return argb_u16_from_u8888(255, gray, gray, gray); +} + +static struct pixel_argb_u16 argb_u16_from_grayu16(u16 gray) +{ + return argb_u16_from_u16161616(0xFFFF, gray, gray, gray); +} + VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, const struct conversion_matrix *matrix) { @@ -286,7 +296,7 @@ EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888); * The following functions are read_line function for each pixel format supported by VKMS. * * They read a line starting at the point @x_start,@y_start following the @direction. The result - * is stored in @out_pixel and in the format ARGB16161616. + * is stored in @out_pixel and in a 64 bits format, see struct pixel_argb_u16. * * These functions are very repetitive, but the innermost pixel loops must be kept inside these * functions for performance reasons. Some benchmarking was done in [1] where having the innermost @@ -295,6 +305,96 @@ EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888); * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/ */ +static void Rx_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + int bits_per_pixel = drm_format_info_bpp(plane->frame_info->fb->format, 0); + u8 *src_pixels; + int rem_x, rem_y; + + WARN_ONCE(drm_format_info_block_height(plane->frame_info->fb->format, 0) != 1, + "%s() only support formats with block_h == 1", __func__); + + packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y); + int bit_offset = (8 - bits_per_pixel) - rem_x * bits_per_pixel; + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); + int mask = (0x1 << bits_per_pixel) - 1; + int lum_per_level = 0xFFFF / mask; + + if (direction == READ_LEFT_TO_RIGHT || direction == READ_RIGHT_TO_LEFT) { + int restart_bit_offset; + int step_bit_offset; + + if (direction == READ_LEFT_TO_RIGHT) { + restart_bit_offset = 8 - bits_per_pixel; + step_bit_offset = -bits_per_pixel; + } else { + restart_bit_offset = 0; + step_bit_offset = bits_per_pixel; + } + + while (out_pixel < end) { + u8 val = ((*src_pixels) >> bit_offset) & mask; + + *out_pixel = argb_u16_from_grayu16((int)val * lum_per_level); + + bit_offset += step_bit_offset; + if (bit_offset < 0 || 8 <= bit_offset) { + bit_offset = restart_bit_offset; + src_pixels += step; + } + out_pixel += 1; + } + } else if (direction == READ_TOP_TO_BOTTOM || direction == READ_BOTTOM_TO_TOP) { + while (out_pixel < end) { + u8 val = (*src_pixels >> bit_offset) & mask; + *out_pixel = argb_u16_from_grayu16((int)val * lum_per_level); + src_pixels += step; + out_pixel += 1; + } + } +} + +static void R1_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + Rx_read_line(plane, x_start, y_start, direction, count, out_pixel); +} + +static void R2_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + Rx_read_line(plane, x_start, y_start, direction, count, out_pixel); +} + +static void R4_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + Rx_read_line(plane, x_start, y_start, direction, count, out_pixel); +} + +static void R8_read_line(const struct vkms_plane_state *plane, int x_start, + int y_start, enum pixel_read_direction direction, int count, + struct pixel_argb_u16 out_pixel[]) +{ + struct pixel_argb_u16 *end = out_pixel + count; + u8 *src_pixels; + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); + + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); + + while (out_pixel < end) { + *out_pixel = argb_u16_from_gray8(*src_pixels); + src_pixels += step; + out_pixel += 1; + } +} + static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, enum pixel_read_direction direction, int count, struct pixel_argb_u16 out_pixel[]) @@ -636,6 +736,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 fbfbe424e558..e3fdd161d0f0 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -31,6 +31,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 *