public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] drm/vkms: Reimplement line-per-line pixel conversion for writeback
@ 2024-08-14  8:42 Louis Chauvet
  2024-08-14  8:42 ` [PATCH v2 1/3] drm/vkms: Re-introduce line-by-line algorithm " Louis Chauvet
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Louis Chauvet @ 2024-08-14  8:42 UTC (permalink / raw)
  To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie
  Cc: dri-devel, arthurgrillo, linux-kernel, jeremie.dautheribes,
	miquel.raynal, thomas.petazzoni, seanpaul, nicolejadeyee,
	Louis Chauvet

This series re-introduce the line-by-line algorithm. This is simpler than 
the read part because no rotation/translations are involved. 

PATCH 1/3 is the re-introduction itself
PATCH 2/3 is a proposition to avoid code repetition using a "big" macro.
PATCJ 3/3 is the usage of PATCH 2 to support a new format

This series depends on [1].

[1]: https://lore.kernel.org/all/20240814-b4-new-color-formats-v2-0-8b3499cfe90e@bootlin.com/

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Changes in v2:
- PATCH 2/3: Remove YUV from supported format list, it is not supported 
- Link to v1: https://lore.kernel.org/r/20240516-writeback_line_by_line-v1-0-7b2e3bf9f1c9@bootlin.com

---
Louis Chauvet (3):
      drm/vkms: Re-introduce line-by-line algorithm for writeback
      drm/vkms: Add a macro for write_line functions
      drm/vkms: Add support for XRGB2101010

 drivers/gpu/drm/vkms/vkms_composer.c  | 17 +++++++
 drivers/gpu/drm/vkms/vkms_drv.h       | 20 ++++----
 drivers/gpu/drm/vkms/vkms_formats.c   | 86 ++++++++++++++++++++++++-----------
 drivers/gpu/drm/vkms/vkms_formats.h   |  2 +-
 drivers/gpu/drm/vkms/vkms_writeback.c |  5 +-
 5 files changed, 93 insertions(+), 37 deletions(-)
---
base-commit: 219b45d023ed0902b05c5902a4f31c2c38bcf68c
change-id: 20240222-writeback_line_by_line-8475605b1d5c
prerequisite-message-id: <20240809-yuv-v10-0-1a7c764166f7@bootlin.com>
prerequisite-patch-id: ae2d8b2efbbaa9decce56632c498c87e708288b3
prerequisite-patch-id: c26b6d4867eaf6566195aa0002765357d4f69f8c
prerequisite-patch-id: 8791d34a6f3148dc518da5249453067e40d346e3
prerequisite-patch-id: 26ec7cd5a449004bcfd6ce483671f87655f8635c
prerequisite-patch-id: 2e855ba871f2e99d4b6b7d85da2ddac6bb32262e
prerequisite-patch-id: 82523a917646793deeec7cdcc7ff286bd924fd21
prerequisite-patch-id: 0e355e5316281f53ab5e97ab6e63b0a682f3eb9e
prerequisite-patch-id: 7a63d245a377d5f5283f48e8f52421b912811752
prerequisite-patch-id: dda6bf4692cd1795c489ff58e72c0841ea8ffbc4
prerequisite-patch-id: f70e535b6086cc587975fbfa75741f485f679a32
prerequisite-patch-id: 6c2aa2645c7d854951608aa4d15a02e076abe1fe
prerequisite-patch-id: dc61c6d3db73053fc36e115af561e0c42b467de2
prerequisite-patch-id: deda292af6d8bbf6762b0bf4d351ffd2225995d8
prerequisite-patch-id: 18554f49b53cbcfd4a8ca50dc83b17dd3cf96474
prerequisite-patch-id: 5633292e10132d29be2467812e6e2e824cfedb67
prerequisite-patch-id: 43f37e9c1bc041d491e41dfb59548ed258a1e071
prerequisite-message-id: <20240814-b4-new-color-formats-v2-0-8b3499cfe90e@bootlin.com>
prerequisite-patch-id: d10db4cb12a88de2e5f6440e9fcf5ddda191e3cd
prerequisite-patch-id: 16bac0ef1f1dc010a72ce2faae66631797d23d3f
prerequisite-patch-id: 8e0e5cc0727e8fd2d14ebafc5538fd987c2dd38e
prerequisite-patch-id: 32bad3bf3df46d042e9edd4c1259c2e2a3fb8975
prerequisite-patch-id: 4bd9e4cef308abd17b7b274a5575a3de73a1503b
prerequisite-patch-id: a98fac5a2c60fe23fbc6a455e9a4ab8b0f187ee8
prerequisite-patch-id: 62c8d109a22b9978f755255b67f13fe74fb7008d
prerequisite-patch-id: baa8da4871dd90b03a07c6d9ddb45e10929ee70a

Best regards,
-- 
Louis Chauvet <louis.chauvet@bootlin.com>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/3] drm/vkms: Re-introduce line-by-line algorithm for writeback
  2024-08-14  8:42 [PATCH v2 0/3] drm/vkms: Reimplement line-per-line pixel conversion for writeback Louis Chauvet
@ 2024-08-14  8:42 ` Louis Chauvet
  2024-10-26 15:05   ` Maíra Canal
  2024-08-14  8:42 ` [PATCH v2 2/3] drm/vkms: Add a macro for write_line functions Louis Chauvet
  2024-08-14  8:42 ` [PATCH v2 3/3] drm/vkms: Add support for XRGB2101010 Louis Chauvet
  2 siblings, 1 reply; 8+ messages in thread
From: Louis Chauvet @ 2024-08-14  8:42 UTC (permalink / raw)
  To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie
  Cc: dri-devel, arthurgrillo, linux-kernel, jeremie.dautheribes,
	miquel.raynal, thomas.petazzoni, seanpaul, nicolejadeyee,
	Louis Chauvet

Re-introduce a line-by-line writeback algorithm for each pixel format.
This allows more performance by not requiring an indirection per pixel
write.

Line-by-line writeback 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 with some effort to avoid code
duplication. Now only the loop is repeated, but it is required to have
good performances.

The performance gain is around 5 to 10%.

[1]: https://lore.kernel.org/all/20211005201637.58563-7-igormtorrente@gmail.com/
[2]: https://lore.kernel.org/all/20230515135204.115393-4-mcanal@igalia.com/

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
 drivers/gpu/drm/vkms/vkms_composer.c  |  17 +++++
 drivers/gpu/drm/vkms/vkms_drv.h       |  20 +++---
 drivers/gpu/drm/vkms/vkms_formats.c   | 117 +++++++++++++++++++++++++++-------
 drivers/gpu/drm/vkms/vkms_formats.h   |   2 +-
 drivers/gpu/drm/vkms/vkms_writeback.c |   2 +-
 5 files changed, 124 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 76d4aa8a0ef6..f0cae142ac22 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -176,6 +176,23 @@ static enum pixel_read_direction direction_for_rotation(unsigned int rotation)
 	return READ_LEFT_TO_RIGHT;
 }
 
+/**
+ * Write a line to the writeback buffer
+ *
+ * @wb: Job where to insert the final image
+ * @src_buffer: Line to write
+ * @y: Row to write in the writeback buffer
+ */
+static void vkms_writeback_row(struct vkms_writeback_job *wb,
+			       const struct line_buffer *src_buffer, size_t y_start)
+{
+	struct vkms_frame_info *frame_info = &wb->wb_frame_info;
+	int x_start = frame_info->dst.x1;
+	int count = min_t(size_t, drm_rect_width(&frame_info->dst), src_buffer->n_pixels);
+
+	wb->pixel_write(wb, src_buffer->pixels, count, x_start, y_start);
+}
+
 /**
  * clamp_line_coordinates() - Compute and clamp the coordinate to read and write during the blend
  * process.
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 3870e825da81..526bf5207524 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -52,20 +52,25 @@ struct line_buffer {
 	struct pixel_argb_u16 *pixels;
 };
 
+struct vkms_writeback_job;
 /**
- * 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.
+ * typedef pixel_write_line_t - These functions are used to read a pixel line from a
+ * struct pixel_argb_u16 buffer, convert it and write it in the @wb job.
  *
- * @out_pixel: destination address to write the pixel
- * @in_pixel: pixel to write
+ * @wb: the writeback job to write the output of the conversion
+ * @in_pixels: Source buffer containing the line to convert
+ * @count: The width of a line
+ * @x_start: The x (width) coordinate in the destination plane
+ * @y_start: The y (height) coordinate in the destination plane
  */
-typedef void (*pixel_write_t)(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel);
+typedef void (*pixel_write_line_t)(struct vkms_writeback_job *wb,
+			      struct pixel_argb_u16 *in_pixels, int count, int x_start,
+			      int y_start);
 
 struct vkms_writeback_job {
 	struct iosys_map data[DRM_FORMAT_MAX_PLANES];
 	struct vkms_frame_info wb_frame_info;
-	pixel_write_t pixel_write;
+	pixel_write_line_t pixel_write;
 };
 
 /**
@@ -232,7 +237,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_writeback_row(struct vkms_writeback_job *wb, const struct line_buffer *src_buffer, int y);
 
 /* Writeback */
 int vkms_enable_writeback_connector(struct vkms_device *vkmsdev);
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index d1abfb1c3e3c..d1309f6d307f 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -587,7 +587,7 @@ static void planar_yuv_read_line(const struct vkms_plane_state *plane, int x_sta
  * The following functions take one &struct pixel_argb_u16 and convert it to a specific format.
  * 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
+ * They are used in the `write_line` functions to convert and store a pixel from the src_buffer to
  * the writeback buffer.
  */
 static void argb_u16_to_ARGB8888(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
@@ -654,28 +654,97 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
 	*pixel = 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.
+/*
+ * The following functions are write_line function for each pixel format supported by VKMS.
+ *
+ * They write a full line at index y. They must read data from the line src_pixels.
+ *
+ * The caller must ensure that count is not larger than the framebuffer and the src_pixels.
+ *
+ * Those function are very similar, but it is required for performance reason. In the past, some
+ * experiment were done, and with a generic loop the performance are very reduced [1].
  *
- * @wb: Job where to insert the final image
- * @src_buffer: Line to write
- * @y: Row to write in the writeback buffer
+ * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
  */
-void vkms_writeback_row(struct vkms_writeback_job *wb,
-			const struct line_buffer *src_buffer, int y)
+
+static void ARGB8888_write_line(struct vkms_writeback_job *wb,
+				struct pixel_argb_u16 *src_pixels, int count, int x_start,
+				int y_start)
 {
-	struct vkms_frame_info *frame_info = &wb->wb_frame_info;
-	int x_dst = frame_info->dst.x1;
 	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);
+	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
 
-	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]);
+	while (count) {
+		argb_u16_to_ARGB8888(dst_pixels, src_pixels);
+		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
+		src_pixels += 1;
+		count--;
+	}
+}
+
+static void XRGB8888_write_line(struct vkms_writeback_job *wb,
+				struct pixel_argb_u16 *src_pixels, int count, int x_start,
+				int y_start)
+{
+	u8 *dst_pixels;
+
+	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
+
+	while (count) {
+		argb_u16_to_XRGB8888(dst_pixels, src_pixels);
+		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
+		src_pixels += 1;
+		count--;
+	}
+}
+
+static void ARGB16161616_write_line(struct vkms_writeback_job *wb,
+				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
+				    int y_start)
+{
+	u8 *dst_pixels;
+
+	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
+
+	while (count) {
+		argb_u16_to_ARGB16161616(dst_pixels, src_pixels);
+		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
+		src_pixels += 1;
+		count--;
+	}
+}
+
+static void XRGB16161616_write_line(struct vkms_writeback_job *wb,
+				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
+				    int y_start)
+{
+	u8 *dst_pixels;
+
+	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
+
+	while (count) {
+		argb_u16_to_XRGB16161616(dst_pixels, src_pixels);
+		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
+		src_pixels += 1;
+		count--;
+	}
+}
+
+static void RGB565_write_line(struct vkms_writeback_job *wb,
+			      struct pixel_argb_u16 *src_pixels, int count, int x_start,
+			      int y_start)
+{
+	u8 *dst_pixels;
+
+	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
+
+	while (count) {
+		argb_u16_to_RGB565(dst_pixels, src_pixels);
+		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
+		src_pixels += 1;
+		count--;
+	}
 }
 
 /**
@@ -936,25 +1005,25 @@ void get_conversion_matrix_to_argb_u16(u32 format,
 }
 
 /**
- * get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format.
+ * get_pixel_write_function() - Retrieve the correct write_line function for a specific format.
  * The returned pointer is NULL for unsupported pixel formats. The caller must ensure that the
  * pointer is valid before using it in a vkms_writeback_job.
  *
  * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h])
  */
-pixel_write_t get_pixel_write_function(u32 format)
+pixel_write_line_t get_pixel_write_line_function(u32 format)
 {
 	switch (format) {
 	case DRM_FORMAT_ARGB8888:
-		return &argb_u16_to_ARGB8888;
+		return &ARGB8888_write_line;
 	case DRM_FORMAT_XRGB8888:
-		return &argb_u16_to_XRGB8888;
+		return &XRGB8888_write_line;
 	case DRM_FORMAT_ARGB16161616:
-		return &argb_u16_to_ARGB16161616;
+		return &ARGB16161616_write_line;
 	case DRM_FORMAT_XRGB16161616:
-		return &argb_u16_to_XRGB16161616;
+		return &XRGB16161616_write_line;
 	case DRM_FORMAT_RGB565:
-		return &argb_u16_to_RGB565;
+		return &RGB565_write_line;
 	default:
 		/*
 		 * This is a bug in vkms_writeback_atomic_check. All the supported
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
index eeb208cdd6b1..852ab9a4cee5 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -7,7 +7,7 @@
 
 pixel_read_line_t get_pixel_read_line_function(u32 format);
 
-pixel_write_t get_pixel_write_function(u32 format);
+pixel_write_line_t get_pixel_write_line_function(u32 format);
 
 void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding,
 				       enum drm_color_range range,
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c
index c8582df1f739..f6ed3aa69af8 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -150,7 +150,7 @@ static void vkms_wb_atomic_commit(struct drm_connector *conn,
 	crtc_state->wb_pending = true;
 	spin_unlock_irq(&output->composer_lock);
 	drm_writeback_queue_job(wb_conn, connector_state);
-	active_wb->pixel_write = get_pixel_write_function(wb_format);
+	active_wb->pixel_write = get_pixel_write_line_function(wb_format);
 	drm_rect_init(&wb_frame_info->src, 0, 0, crtc_width, crtc_height);
 	drm_rect_init(&wb_frame_info->dst, 0, 0, crtc_width, crtc_height);
 }

-- 
2.44.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/3] drm/vkms: Add a macro for write_line functions
  2024-08-14  8:42 [PATCH v2 0/3] drm/vkms: Reimplement line-per-line pixel conversion for writeback Louis Chauvet
  2024-08-14  8:42 ` [PATCH v2 1/3] drm/vkms: Re-introduce line-by-line algorithm " Louis Chauvet
@ 2024-08-14  8:42 ` Louis Chauvet
  2024-10-26 15:08   ` Maíra Canal
  2024-08-14  8:42 ` [PATCH v2 3/3] drm/vkms: Add support for XRGB2101010 Louis Chauvet
  2 siblings, 1 reply; 8+ messages in thread
From: Louis Chauvet @ 2024-08-14  8:42 UTC (permalink / raw)
  To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie
  Cc: dri-devel, arthurgrillo, linux-kernel, jeremie.dautheribes,
	miquel.raynal, thomas.petazzoni, seanpaul, nicolejadeyee,
	Louis Chauvet

As stated in [2], the write_line functions are very similar and force code
duplication. This patch add a macro to avoid code repetition.

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
 drivers/gpu/drm/vkms/vkms_formats.c | 107 ++++++++++--------------------------
 1 file changed, 30 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index d1309f6d307f..a25cdf656d8a 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -654,6 +654,31 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
 	*pixel = cpu_to_le16(r << 11 | g << 5 | b);
 }
 
+/**
+ * WRITE_LINE() - Generic generator for write_line functions
+ *
+ * This generator can only be used for format with only one plane and block_w == block_h == 1
+ *
+ * @function_name: Name to use for the generated function
+ * @conversion_function: Fonction to use for the conversion from argb_u16 to the required format.
+ */
+#define WRITE_LINE(function_name, conversion_function)					\
+static void function_name(struct vkms_writeback_job *wb,				\
+			  struct pixel_argb_u16 *src_pixels, int count, int x_start,	\
+			  int y_start)							\
+{											\
+	u8 *dst_pixels;									\
+											\
+	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);	\
+											\
+	while (count) {									\
+		(conversion_function)(dst_pixels, src_pixels);				\
+		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];		\
+		src_pixels += 1;							\
+		count--;								\
+	}										\
+}
+
 /*
  * The following functions are write_line function for each pixel format supported by VKMS.
  *
@@ -667,85 +692,13 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
  * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
  */
 
-static void ARGB8888_write_line(struct vkms_writeback_job *wb,
-				struct pixel_argb_u16 *src_pixels, int count, int x_start,
-				int y_start)
-{
-	u8 *dst_pixels;
+WRITE_LINE(ARGB8888_write_line, argb_u16_to_ARGB8888)
+WRITE_LINE(XRGB8888_write_line, argb_u16_to_XRGB8888)
 
-	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
+WRITE_LINE(ARGB16161616_write_line, argb_u16_to_ARGB16161616)
+WRITE_LINE(XRGB16161616_write_line, argb_u16_to_XRGB16161616)
 
-	while (count) {
-		argb_u16_to_ARGB8888(dst_pixels, src_pixels);
-		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
-		src_pixels += 1;
-		count--;
-	}
-}
-
-static void XRGB8888_write_line(struct vkms_writeback_job *wb,
-				struct pixel_argb_u16 *src_pixels, int count, int x_start,
-				int y_start)
-{
-	u8 *dst_pixels;
-
-	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
-
-	while (count) {
-		argb_u16_to_XRGB8888(dst_pixels, src_pixels);
-		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
-		src_pixels += 1;
-		count--;
-	}
-}
-
-static void ARGB16161616_write_line(struct vkms_writeback_job *wb,
-				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
-				    int y_start)
-{
-	u8 *dst_pixels;
-
-	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
-
-	while (count) {
-		argb_u16_to_ARGB16161616(dst_pixels, src_pixels);
-		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
-		src_pixels += 1;
-		count--;
-	}
-}
-
-static void XRGB16161616_write_line(struct vkms_writeback_job *wb,
-				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
-				    int y_start)
-{
-	u8 *dst_pixels;
-
-	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
-
-	while (count) {
-		argb_u16_to_XRGB16161616(dst_pixels, src_pixels);
-		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
-		src_pixels += 1;
-		count--;
-	}
-}
-
-static void RGB565_write_line(struct vkms_writeback_job *wb,
-			      struct pixel_argb_u16 *src_pixels, int count, int x_start,
-			      int y_start)
-{
-	u8 *dst_pixels;
-
-	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
-
-	while (count) {
-		argb_u16_to_RGB565(dst_pixels, src_pixels);
-		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
-		src_pixels += 1;
-		count--;
-	}
-}
+WRITE_LINE(RGB565_write_line, argb_u16_to_RGB565)
 
 /**
  * get_pixel_read_function() - Retrieve the correct read_line function for a specific

-- 
2.44.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/3] drm/vkms: Add support for XRGB2101010
  2024-08-14  8:42 [PATCH v2 0/3] drm/vkms: Reimplement line-per-line pixel conversion for writeback Louis Chauvet
  2024-08-14  8:42 ` [PATCH v2 1/3] drm/vkms: Re-introduce line-by-line algorithm " Louis Chauvet
  2024-08-14  8:42 ` [PATCH v2 2/3] drm/vkms: Add a macro for write_line functions Louis Chauvet
@ 2024-08-14  8:42 ` Louis Chauvet
  2 siblings, 0 replies; 8+ messages in thread
From: Louis Chauvet @ 2024-08-14  8:42 UTC (permalink / raw)
  To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie
  Cc: dri-devel, arthurgrillo, linux-kernel, jeremie.dautheribes,
	miquel.raynal, thomas.petazzoni, seanpaul, nicolejadeyee,
	Louis Chauvet

Thanks to the WRITE_LINE macro, adding the format XRGB210101010 is trivial.

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
 drivers/gpu/drm/vkms/vkms_formats.c   | 12 ++++++++++++
 drivers/gpu/drm/vkms/vkms_writeback.c |  3 ++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index a25cdf656d8a..65fdd3999441 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -654,6 +654,14 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
 	*pixel = cpu_to_le16(r << 11 | g << 5 | b);
 }
 
+static void argb_u16_to_XRGB2101010(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
+{
+	out_pixel[0] = (u8)(in_pixel->b & 0xFF);
+	out_pixel[1] = (u8)((in_pixel->b >> 8) & 0x03) | (u8)((in_pixel->g << 2) & 0xFC);
+	out_pixel[2] = (u8)((in_pixel->g >> 6) & 0x0F) | (u8)((in_pixel->r << 4) & 0xF0);
+	out_pixel[3] = (u8)((in_pixel->r >> 4) & 0x3F);
+}
+
 /**
  * WRITE_LINE() - Generic generator for write_line functions
  *
@@ -700,6 +708,8 @@ WRITE_LINE(XRGB16161616_write_line, argb_u16_to_XRGB16161616)
 
 WRITE_LINE(RGB565_write_line, argb_u16_to_RGB565)
 
+WRITE_LINE(XRGB2101010_write_line, argb_u16_to_XRGB2101010)
+
 /**
  * get_pixel_read_function() - Retrieve the correct read_line function for a specific
  * format. The returned pointer is NULL for unsupported pixel formats. The caller must ensure that
@@ -977,6 +987,8 @@ pixel_write_line_t get_pixel_write_line_function(u32 format)
 		return &XRGB16161616_write_line;
 	case DRM_FORMAT_RGB565:
 		return &RGB565_write_line;
+	case DRM_FORMAT_XRGB2101010:
+		return &XRGB2101010_write_line;
 	default:
 		/*
 		 * This is a bug in vkms_writeback_atomic_check. All the supported
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c
index f6ed3aa69af8..7e0302c0830c 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -19,7 +19,8 @@ static const u32 vkms_wb_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_XRGB16161616,
 	DRM_FORMAT_ARGB16161616,
-	DRM_FORMAT_RGB565
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_XRGB2101010,
 };
 
 static const struct drm_connector_funcs vkms_wb_connector_funcs = {

-- 
2.44.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/3] drm/vkms: Re-introduce line-by-line algorithm for writeback
  2024-08-14  8:42 ` [PATCH v2 1/3] drm/vkms: Re-introduce line-by-line algorithm " Louis Chauvet
@ 2024-10-26 15:05   ` Maíra Canal
  2024-10-28  9:50     ` Louis Chauvet
  0 siblings, 1 reply; 8+ messages in thread
From: Maíra Canal @ 2024-10-26 15:05 UTC (permalink / raw)
  To: Louis Chauvet, Rodrigo Siqueira, Melissa Wen, Haneen Mohammed,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie
  Cc: dri-devel, arthurgrillo, linux-kernel, jeremie.dautheribes,
	miquel.raynal, thomas.petazzoni, seanpaul, nicolejadeyee

Hi Louis,

On 14/08/24 05:42, Louis Chauvet wrote:
> Re-introduce a line-by-line writeback algorithm for each pixel format.
> This allows more performance by not requiring an indirection per pixel
> write.
> 
> Line-by-line writeback 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 with some effort to avoid code
> duplication. Now only the loop is repeated, but it is required to have
> good performances.
> 
> The performance gain is around 5 to 10%.
> 
> [1]: https://lore.kernel.org/all/20211005201637.58563-7-igormtorrente@gmail.com/
> [2]: https://lore.kernel.org/all/20230515135204.115393-4-mcanal@igalia.com/
> 
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
>   drivers/gpu/drm/vkms/vkms_composer.c  |  17 +++++
>   drivers/gpu/drm/vkms/vkms_drv.h       |  20 +++---
>   drivers/gpu/drm/vkms/vkms_formats.c   | 117 +++++++++++++++++++++++++++-------
>   drivers/gpu/drm/vkms/vkms_formats.h   |   2 +-
>   drivers/gpu/drm/vkms/vkms_writeback.c |   2 +-
>   5 files changed, 124 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
> index 76d4aa8a0ef6..f0cae142ac22 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> @@ -176,6 +176,23 @@ static enum pixel_read_direction direction_for_rotation(unsigned int rotation)
>   	return READ_LEFT_TO_RIGHT;
>   }
>   
> +/**
> + * Write a line to the writeback buffer > + *
> + * @wb: Job where to insert the final image
> + * @src_buffer: Line to write
> + * @y: Row to write in the writeback buffer
> + */

Please, review the documentation using the kernel-doc format.

> +static void vkms_writeback_row(struct vkms_writeback_job *wb,
> +			       const struct line_buffer *src_buffer, size_t y_start)
> +{
> +	struct vkms_frame_info *frame_info = &wb->wb_frame_info;
> +	int x_start = frame_info->dst.x1;
> +	int count = min_t(size_t, drm_rect_width(&frame_info->dst), src_buffer->n_pixels);
> +
> +	wb->pixel_write(wb, src_buffer->pixels, count, x_start, y_start);
> +}
> +
>   /**
>    * clamp_line_coordinates() - Compute and clamp the coordinate to read and write during the blend
>    * process.
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
> index 3870e825da81..526bf5207524 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.h
> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
> @@ -52,20 +52,25 @@ struct line_buffer {
>   	struct pixel_argb_u16 *pixels;
>   };
>   
> +struct vkms_writeback_job;
>   /**
> - * 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.
> + * typedef pixel_write_line_t - These functions are used to read a pixel line from a
> + * struct pixel_argb_u16 buffer, convert it and write it in the @wb job.
>    *
> - * @out_pixel: destination address to write the pixel
> - * @in_pixel: pixel to write
> + * @wb: the writeback job to write the output of the conversion
> + * @in_pixels: Source buffer containing the line to convert
> + * @count: The width of a line
> + * @x_start: The x (width) coordinate in the destination plane
> + * @y_start: The y (height) coordinate in the destination plane
>    */
> -typedef void (*pixel_write_t)(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel);
> +typedef void (*pixel_write_line_t)(struct vkms_writeback_job *wb,
> +			      struct pixel_argb_u16 *in_pixels, int count, int x_start,
> +			      int y_start);
>   
>   struct vkms_writeback_job {
>   	struct iosys_map data[DRM_FORMAT_MAX_PLANES];
>   	struct vkms_frame_info wb_frame_info;
> -	pixel_write_t pixel_write;
> +	pixel_write_line_t pixel_write;
>   };
>   
>   /**
> @@ -232,7 +237,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_writeback_row(struct vkms_writeback_job *wb, const struct line_buffer *src_buffer, int y);
>   
>   /* Writeback */
>   int vkms_enable_writeback_connector(struct vkms_device *vkmsdev);
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
> index d1abfb1c3e3c..d1309f6d307f 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.c
> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> @@ -587,7 +587,7 @@ static void planar_yuv_read_line(const struct vkms_plane_state *plane, int x_sta
>    * The following functions take one &struct pixel_argb_u16 and convert it to a specific format.
>    * 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
> + * They are used in the `write_line` functions to convert and store a pixel from the src_buffer to
>    * the writeback buffer.
>    */
>   static void argb_u16_to_ARGB8888(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
> @@ -654,28 +654,97 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
>   	*pixel = 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.
> +/*
> + * The following functions are write_line function for each pixel format supported by VKMS.
> + *
> + * They write a full line at index y. They must read data from the line src_pixels.
> + *
> + * The caller must ensure that count is not larger than the framebuffer and the src_pixels.
> + *
> + * Those function are very similar, but it is required for performance reason. In the past, some
> + * experiment were done, and with a generic loop the performance are very reduced [1].
>    *
> - * @wb: Job where to insert the final image
> - * @src_buffer: Line to write
> - * @y: Row to write in the writeback buffer
> + * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/

I'm not sure if a link is approriate here.

>    */
> -void vkms_writeback_row(struct vkms_writeback_job *wb,
> -			const struct line_buffer *src_buffer, int y)
> +
> +static void ARGB8888_write_line(struct vkms_writeback_job *wb,
> +				struct pixel_argb_u16 *src_pixels, int count, int x_start,
> +				int y_start)
>   {
> -	struct vkms_frame_info *frame_info = &wb->wb_frame_info;
> -	int x_dst = frame_info->dst.x1;
>   	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);
> +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
>   
> -	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]);
> +	while (count) {
> +		argb_u16_to_ARGB8888(dst_pixels, src_pixels);
> +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> +		src_pixels += 1;
> +		count--;
> +	}
> +}
> +
> +static void XRGB8888_write_line(struct vkms_writeback_job *wb,
> +				struct pixel_argb_u16 *src_pixels, int count, int x_start,
> +				int y_start)
> +{
> +	u8 *dst_pixels;
> +
> +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> +
> +	while (count) {
> +		argb_u16_to_XRGB8888(dst_pixels, src_pixels);
> +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> +		src_pixels += 1;
> +		count--;
> +	}
> +}
> +
> +static void ARGB16161616_write_line(struct vkms_writeback_job *wb,
> +				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
> +				    int y_start)
> +{
> +	u8 *dst_pixels;
> +
> +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> +
> +	while (count) {
> +		argb_u16_to_ARGB16161616(dst_pixels, src_pixels);
> +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> +		src_pixels += 1;
> +		count--;
> +	}
> +}
> +
> +static void XRGB16161616_write_line(struct vkms_writeback_job *wb,
> +				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
> +				    int y_start)
> +{
> +	u8 *dst_pixels;
> +
> +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> +
> +	while (count) {
> +		argb_u16_to_XRGB16161616(dst_pixels, src_pixels);
> +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> +		src_pixels += 1;
> +		count--;
> +	}
> +}
> +
> +static void RGB565_write_line(struct vkms_writeback_job *wb,
> +			      struct pixel_argb_u16 *src_pixels, int count, int x_start,
> +			      int y_start)
> +{
> +	u8 *dst_pixels;
> +
> +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> +
> +	while (count) {
> +		argb_u16_to_RGB565(dst_pixels, src_pixels);
> +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> +		src_pixels += 1;
> +		count--;
> +	}
>   }
>   
>   /**
> @@ -936,25 +1005,25 @@ void get_conversion_matrix_to_argb_u16(u32 format,
>   }
>   
>   /**
> - * get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format.
> + * get_pixel_write_function() - Retrieve the correct write_line function for a specific format.

Correct the docs.

Best Regards,
- Maíra

>    * 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])
>    */
> -pixel_write_t get_pixel_write_function(u32 format)
> +pixel_write_line_t get_pixel_write_line_function(u32 format) >   {
>   	switch (format) {
>   	case DRM_FORMAT_ARGB8888:
> -		return &argb_u16_to_ARGB8888;
> +		return &ARGB8888_write_line;
>   	case DRM_FORMAT_XRGB8888:
> -		return &argb_u16_to_XRGB8888;
> +		return &XRGB8888_write_line;
>   	case DRM_FORMAT_ARGB16161616:
> -		return &argb_u16_to_ARGB16161616;
> +		return &ARGB16161616_write_line;
>   	case DRM_FORMAT_XRGB16161616:
> -		return &argb_u16_to_XRGB16161616;
> +		return &XRGB16161616_write_line;
>   	case DRM_FORMAT_RGB565:
> -		return &argb_u16_to_RGB565;
> +		return &RGB565_write_line;
>   	default:
>   		/*
>   		 * This is a bug in vkms_writeback_atomic_check. All the supported
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
> index eeb208cdd6b1..852ab9a4cee5 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.h
> +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> @@ -7,7 +7,7 @@
>   
>   pixel_read_line_t get_pixel_read_line_function(u32 format);
>   
> -pixel_write_t get_pixel_write_function(u32 format);
> +pixel_write_line_t get_pixel_write_line_function(u32 format);
>   
>   void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding,
>   				       enum drm_color_range range,
> diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c
> index c8582df1f739..f6ed3aa69af8 100644
> --- a/drivers/gpu/drm/vkms/vkms_writeback.c
> +++ b/drivers/gpu/drm/vkms/vkms_writeback.c
> @@ -150,7 +150,7 @@ static void vkms_wb_atomic_commit(struct drm_connector *conn,
>   	crtc_state->wb_pending = true;
>   	spin_unlock_irq(&output->composer_lock);
>   	drm_writeback_queue_job(wb_conn, connector_state);
> -	active_wb->pixel_write = get_pixel_write_function(wb_format);
> +	active_wb->pixel_write = get_pixel_write_line_function(wb_format);
>   	drm_rect_init(&wb_frame_info->src, 0, 0, crtc_width, crtc_height);
>   	drm_rect_init(&wb_frame_info->dst, 0, 0, crtc_width, crtc_height);
>   }
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/3] drm/vkms: Add a macro for write_line functions
  2024-08-14  8:42 ` [PATCH v2 2/3] drm/vkms: Add a macro for write_line functions Louis Chauvet
@ 2024-10-26 15:08   ` Maíra Canal
  2024-10-28  9:50     ` Louis Chauvet
  0 siblings, 1 reply; 8+ messages in thread
From: Maíra Canal @ 2024-10-26 15:08 UTC (permalink / raw)
  To: Louis Chauvet, Rodrigo Siqueira, Melissa Wen, Haneen Mohammed,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie
  Cc: dri-devel, arthurgrillo, linux-kernel, jeremie.dautheribes,
	miquel.raynal, thomas.petazzoni, seanpaul, nicolejadeyee

Hi Louis,

On 14/08/24 05:42, Louis Chauvet wrote:
> As stated in [2], the write_line functions are very similar and force code

Where is [2]?

> duplication. This patch add a macro to avoid code repetition.
> 
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
>   drivers/gpu/drm/vkms/vkms_formats.c | 107 ++++++++++--------------------------
>   1 file changed, 30 insertions(+), 77 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
> index d1309f6d307f..a25cdf656d8a 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.c
> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> @@ -654,6 +654,31 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
>   	*pixel = cpu_to_le16(r << 11 | g << 5 | b);
>   }
>   
> +/**
> + * WRITE_LINE() - Generic generator for write_line functions
> + *
> + * This generator can only be used for format with only one plane and block_w == block_h == 1
> + *
> + * @function_name: Name to use for the generated function
> + * @conversion_function: Fonction to use for the conversion from argb_u16 to the required format.

s/Fonction/Function

> + */
> +#define WRITE_LINE(function_name, conversion_function)					\
> +static void function_name(struct vkms_writeback_job *wb,				\
> +			  struct pixel_argb_u16 *src_pixels, int count, int x_start,	\
> +			  int y_start)							\
> +{											\
> +	u8 *dst_pixels;									\
> +											\
> +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);	\
> +											\
> +	while (count) {									\
> +		(conversion_function)(dst_pixels, src_pixels);				\
> +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];		\
> +		src_pixels += 1;							\
> +		count--;								\

Just a nit: What do you think about this loop?

for (; count > 0; src_pixels++, count--)

It doesn't really matter what option you pick.

Best Regards,
- Maíra

> +	}										\
> +}
> +
>   /*
>    * The following functions are write_line function for each pixel format supported by VKMS.
>    *
> @@ -667,85 +692,13 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
>    * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
>    */
>   
> -static void ARGB8888_write_line(struct vkms_writeback_job *wb,
> -				struct pixel_argb_u16 *src_pixels, int count, int x_start,
> -				int y_start)
> -{
> -	u8 *dst_pixels;
> +WRITE_LINE(ARGB8888_write_line, argb_u16_to_ARGB8888)
> +WRITE_LINE(XRGB8888_write_line, argb_u16_to_XRGB8888)
>   
> -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> +WRITE_LINE(ARGB16161616_write_line, argb_u16_to_ARGB16161616)
> +WRITE_LINE(XRGB16161616_write_line, argb_u16_to_XRGB16161616)
>   
> -	while (count) {
> -		argb_u16_to_ARGB8888(dst_pixels, src_pixels);
> -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> -		src_pixels += 1;
> -		count--;
> -	}
> -}
> -
> -static void XRGB8888_write_line(struct vkms_writeback_job *wb,
> -				struct pixel_argb_u16 *src_pixels, int count, int x_start,
> -				int y_start)
> -{
> -	u8 *dst_pixels;
> -
> -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> -
> -	while (count) {
> -		argb_u16_to_XRGB8888(dst_pixels, src_pixels);
> -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> -		src_pixels += 1;
> -		count--;
> -	}
> -}
> -
> -static void ARGB16161616_write_line(struct vkms_writeback_job *wb,
> -				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
> -				    int y_start)
> -{
> -	u8 *dst_pixels;
> -
> -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> -
> -	while (count) {
> -		argb_u16_to_ARGB16161616(dst_pixels, src_pixels);
> -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> -		src_pixels += 1;
> -		count--;
> -	}
> -}
> -
> -static void XRGB16161616_write_line(struct vkms_writeback_job *wb,
> -				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
> -				    int y_start)
> -{
> -	u8 *dst_pixels;
> -
> -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> -
> -	while (count) {
> -		argb_u16_to_XRGB16161616(dst_pixels, src_pixels);
> -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> -		src_pixels += 1;
> -		count--;
> -	}
> -}
> -
> -static void RGB565_write_line(struct vkms_writeback_job *wb,
> -			      struct pixel_argb_u16 *src_pixels, int count, int x_start,
> -			      int y_start)
> -{
> -	u8 *dst_pixels;
> -
> -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> -
> -	while (count) {
> -		argb_u16_to_RGB565(dst_pixels, src_pixels);
> -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> -		src_pixels += 1;
> -		count--;
> -	}
> -}
> +WRITE_LINE(RGB565_write_line, argb_u16_to_RGB565)
>   
>   /**
>    * get_pixel_read_function() - Retrieve the correct read_line function for a specific
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/3] drm/vkms: Add a macro for write_line functions
  2024-10-26 15:08   ` Maíra Canal
@ 2024-10-28  9:50     ` Louis Chauvet
  0 siblings, 0 replies; 8+ messages in thread
From: Louis Chauvet @ 2024-10-28  9:50 UTC (permalink / raw)
  To: Maíra Canal
  Cc: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	dri-devel, arthurgrillo, linux-kernel, jeremie.dautheribes,
	miquel.raynal, thomas.petazzoni, seanpaul, nicolejadeyee

On 26/10/24 - 12:08, Maíra Canal wrote:
> Hi Louis,
> 
> On 14/08/24 05:42, Louis Chauvet wrote:
> > As stated in [2], the write_line functions are very similar and force code
> 
> Where is [2]?
> 
> > duplication. This patch add a macro to avoid code repetition.
> > 
> > Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> > ---
> >   drivers/gpu/drm/vkms/vkms_formats.c | 107 ++++++++++--------------------------
> >   1 file changed, 30 insertions(+), 77 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
> > index d1309f6d307f..a25cdf656d8a 100644
> > --- a/drivers/gpu/drm/vkms/vkms_formats.c
> > +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> > @@ -654,6 +654,31 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
> >   	*pixel = cpu_to_le16(r << 11 | g << 5 | b);
> >   }
> > +/**
> > + * WRITE_LINE() - Generic generator for write_line functions
> > + *
> > + * This generator can only be used for format with only one plane and block_w == block_h == 1
> > + *
> > + * @function_name: Name to use for the generated function
> > + * @conversion_function: Fonction to use for the conversion from argb_u16 to the required format.
> 
> s/Fonction/Function
> 
> > + */
> > +#define WRITE_LINE(function_name, conversion_function)					\
> > +static void function_name(struct vkms_writeback_job *wb,				\
> > +			  struct pixel_argb_u16 *src_pixels, int count, int x_start,	\
> > +			  int y_start)							\
> > +{											\
> > +	u8 *dst_pixels;									\
> > +											\
> > +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);	\
> > +											\
> > +	while (count) {									\
> > +		(conversion_function)(dst_pixels, src_pixels);				\
> > +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];		\
> > +		src_pixels += 1;							\
> > +		count--;								\
> 
> Just a nit: What do you think about this loop?
> 
> for (; count > 0; src_pixels++, count--)
> 
> It doesn't really matter what option you pick.

I take this version, a bit shorter and not less explicit, thanks!

Thanks,
Louis Chauvet
 
> Best Regards,
> - Maíra
> 
> > +	}										\
> > +}
> > +
> >   /*
> >    * The following functions are write_line function for each pixel format supported by VKMS.
> >    *
> > @@ -667,85 +692,13 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
> >    * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
> >    */
> > -static void ARGB8888_write_line(struct vkms_writeback_job *wb,
> > -				struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > -				int y_start)
> > -{
> > -	u8 *dst_pixels;
> > +WRITE_LINE(ARGB8888_write_line, argb_u16_to_ARGB8888)
> > +WRITE_LINE(XRGB8888_write_line, argb_u16_to_XRGB8888)
> > -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > +WRITE_LINE(ARGB16161616_write_line, argb_u16_to_ARGB16161616)
> > +WRITE_LINE(XRGB16161616_write_line, argb_u16_to_XRGB16161616)
> > -	while (count) {
> > -		argb_u16_to_ARGB8888(dst_pixels, src_pixels);
> > -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > -		src_pixels += 1;
> > -		count--;
> > -	}
> > -}
> > -
> > -static void XRGB8888_write_line(struct vkms_writeback_job *wb,
> > -				struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > -				int y_start)
> > -{
> > -	u8 *dst_pixels;
> > -
> > -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > -
> > -	while (count) {
> > -		argb_u16_to_XRGB8888(dst_pixels, src_pixels);
> > -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > -		src_pixels += 1;
> > -		count--;
> > -	}
> > -}
> > -
> > -static void ARGB16161616_write_line(struct vkms_writeback_job *wb,
> > -				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > -				    int y_start)
> > -{
> > -	u8 *dst_pixels;
> > -
> > -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > -
> > -	while (count) {
> > -		argb_u16_to_ARGB16161616(dst_pixels, src_pixels);
> > -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > -		src_pixels += 1;
> > -		count--;
> > -	}
> > -}
> > -
> > -static void XRGB16161616_write_line(struct vkms_writeback_job *wb,
> > -				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > -				    int y_start)
> > -{
> > -	u8 *dst_pixels;
> > -
> > -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > -
> > -	while (count) {
> > -		argb_u16_to_XRGB16161616(dst_pixels, src_pixels);
> > -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > -		src_pixels += 1;
> > -		count--;
> > -	}
> > -}
> > -
> > -static void RGB565_write_line(struct vkms_writeback_job *wb,
> > -			      struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > -			      int y_start)
> > -{
> > -	u8 *dst_pixels;
> > -
> > -	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > -
> > -	while (count) {
> > -		argb_u16_to_RGB565(dst_pixels, src_pixels);
> > -		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > -		src_pixels += 1;
> > -		count--;
> > -	}
> > -}
> > +WRITE_LINE(RGB565_write_line, argb_u16_to_RGB565)
> >   /**
> >    * get_pixel_read_function() - Retrieve the correct read_line function for a specific
> > 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/3] drm/vkms: Re-introduce line-by-line algorithm for writeback
  2024-10-26 15:05   ` Maíra Canal
@ 2024-10-28  9:50     ` Louis Chauvet
  0 siblings, 0 replies; 8+ messages in thread
From: Louis Chauvet @ 2024-10-28  9:50 UTC (permalink / raw)
  To: Maíra Canal
  Cc: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	dri-devel, arthurgrillo, linux-kernel, jeremie.dautheribes,
	miquel.raynal, thomas.petazzoni, seanpaul, nicolejadeyee

On 26/10/24 - 12:05, Maíra Canal wrote:
> Hi Louis,
> 
> On 14/08/24 05:42, Louis Chauvet wrote:
> > Re-introduce a line-by-line writeback algorithm for each pixel format.
> > This allows more performance by not requiring an indirection per pixel
> > write.
> > 
> > Line-by-line writeback 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 with some effort to avoid code
> > duplication. Now only the loop is repeated, but it is required to have
> > good performances.
> > 
> > The performance gain is around 5 to 10%.
> > 
> > [1]: https://lore.kernel.org/all/20211005201637.58563-7-igormtorrente@gmail.com/
> > [2]: https://lore.kernel.org/all/20230515135204.115393-4-mcanal@igalia.com/
> > 
> > Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> > ---
> >   drivers/gpu/drm/vkms/vkms_composer.c  |  17 +++++
> >   drivers/gpu/drm/vkms/vkms_drv.h       |  20 +++---
> >   drivers/gpu/drm/vkms/vkms_formats.c   | 117 +++++++++++++++++++++++++++-------
> >   drivers/gpu/drm/vkms/vkms_formats.h   |   2 +-
> >   drivers/gpu/drm/vkms/vkms_writeback.c |   2 +-
> >   5 files changed, 124 insertions(+), 34 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
> > index 76d4aa8a0ef6..f0cae142ac22 100644
> > --- a/drivers/gpu/drm/vkms/vkms_composer.c
> > +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> > @@ -176,6 +176,23 @@ static enum pixel_read_direction direction_for_rotation(unsigned int rotation)
> >   	return READ_LEFT_TO_RIGHT;
> >   }
> > +/**
> > + * Write a line to the writeback buffer > + *
> > + * @wb: Job where to insert the final image
> > + * @src_buffer: Line to write
> > + * @y: Row to write in the writeback buffer
> > + */
> 
> Please, review the documentation using the kernel-doc format.
> 
> > +static void vkms_writeback_row(struct vkms_writeback_job *wb,
> > +			       const struct line_buffer *src_buffer, size_t y_start)
> > +{
> > +	struct vkms_frame_info *frame_info = &wb->wb_frame_info;
> > +	int x_start = frame_info->dst.x1;
> > +	int count = min_t(size_t, drm_rect_width(&frame_info->dst), src_buffer->n_pixels);
> > +
> > +	wb->pixel_write(wb, src_buffer->pixels, count, x_start, y_start);
> > +}
> > +
> >   /**
> >    * clamp_line_coordinates() - Compute and clamp the coordinate to read and write during the blend
> >    * process.
> > diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
> > index 3870e825da81..526bf5207524 100644
> > --- a/drivers/gpu/drm/vkms/vkms_drv.h
> > +++ b/drivers/gpu/drm/vkms/vkms_drv.h
> > @@ -52,20 +52,25 @@ struct line_buffer {
> >   	struct pixel_argb_u16 *pixels;
> >   };
> > +struct vkms_writeback_job;
> >   /**
> > - * 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.
> > + * typedef pixel_write_line_t - These functions are used to read a pixel line from a
> > + * struct pixel_argb_u16 buffer, convert it and write it in the @wb job.
> >    *
> > - * @out_pixel: destination address to write the pixel
> > - * @in_pixel: pixel to write
> > + * @wb: the writeback job to write the output of the conversion
> > + * @in_pixels: Source buffer containing the line to convert
> > + * @count: The width of a line
> > + * @x_start: The x (width) coordinate in the destination plane
> > + * @y_start: The y (height) coordinate in the destination plane
> >    */
> > -typedef void (*pixel_write_t)(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel);
> > +typedef void (*pixel_write_line_t)(struct vkms_writeback_job *wb,
> > +			      struct pixel_argb_u16 *in_pixels, int count, int x_start,
> > +			      int y_start);
> >   struct vkms_writeback_job {
> >   	struct iosys_map data[DRM_FORMAT_MAX_PLANES];
> >   	struct vkms_frame_info wb_frame_info;
> > -	pixel_write_t pixel_write;
> > +	pixel_write_line_t pixel_write;
> >   };
> >   /**
> > @@ -232,7 +237,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_writeback_row(struct vkms_writeback_job *wb, const struct line_buffer *src_buffer, int y);
> >   /* Writeback */
> >   int vkms_enable_writeback_connector(struct vkms_device *vkmsdev);
> > diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
> > index d1abfb1c3e3c..d1309f6d307f 100644
> > --- a/drivers/gpu/drm/vkms/vkms_formats.c
> > +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> > @@ -587,7 +587,7 @@ static void planar_yuv_read_line(const struct vkms_plane_state *plane, int x_sta
> >    * The following functions take one &struct pixel_argb_u16 and convert it to a specific format.
> >    * 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
> > + * They are used in the `write_line` functions to convert and store a pixel from the src_buffer to
> >    * the writeback buffer.
> >    */
> >   static void argb_u16_to_ARGB8888(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
> > @@ -654,28 +654,97 @@ static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pi
> >   	*pixel = 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.
> > +/*
> > + * The following functions are write_line function for each pixel format supported by VKMS.
> > + *
> > + * They write a full line at index y. They must read data from the line src_pixels.
> > + *
> > + * The caller must ensure that count is not larger than the framebuffer and the src_pixels.
> > + *
> > + * Those function are very similar, but it is required for performance reason. In the past, some
> > + * experiment were done, and with a generic loop the performance are very reduced [1].
> >    *
> > - * @wb: Job where to insert the final image
> > - * @src_buffer: Line to write
> > - * @y: Row to write in the writeback buffer
> > + * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
> 
> I'm not sure if a link is approriate here.

It was to have some context about the comment. If someone wants to modify 
this in the future (for example, factorise again the code :)), he will 
have some informations.
 
> >    */
> > -void vkms_writeback_row(struct vkms_writeback_job *wb,
> > -			const struct line_buffer *src_buffer, int y)
> > +
> > +static void ARGB8888_write_line(struct vkms_writeback_job *wb,
> > +				struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > +				int y_start)
> >   {
> > -	struct vkms_frame_info *frame_info = &wb->wb_frame_info;
> > -	int x_dst = frame_info->dst.x1;
> >   	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);
> > +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > -	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]);
> > +	while (count) {
> > +		argb_u16_to_ARGB8888(dst_pixels, src_pixels);
> > +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > +		src_pixels += 1;
> > +		count--;
> > +	}
> > +}
> > +
> > +static void XRGB8888_write_line(struct vkms_writeback_job *wb,
> > +				struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > +				int y_start)
> > +{
> > +	u8 *dst_pixels;
> > +
> > +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > +
> > +	while (count) {
> > +		argb_u16_to_XRGB8888(dst_pixels, src_pixels);
> > +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > +		src_pixels += 1;
> > +		count--;
> > +	}
> > +}
> > +
> > +static void ARGB16161616_write_line(struct vkms_writeback_job *wb,
> > +				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > +				    int y_start)
> > +{
> > +	u8 *dst_pixels;
> > +
> > +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > +
> > +	while (count) {
> > +		argb_u16_to_ARGB16161616(dst_pixels, src_pixels);
> > +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > +		src_pixels += 1;
> > +		count--;
> > +	}
> > +}
> > +
> > +static void XRGB16161616_write_line(struct vkms_writeback_job *wb,
> > +				    struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > +				    int y_start)
> > +{
> > +	u8 *dst_pixels;
> > +
> > +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > +
> > +	while (count) {
> > +		argb_u16_to_XRGB16161616(dst_pixels, src_pixels);
> > +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > +		src_pixels += 1;
> > +		count--;
> > +	}
> > +}
> > +
> > +static void RGB565_write_line(struct vkms_writeback_job *wb,
> > +			      struct pixel_argb_u16 *src_pixels, int count, int x_start,
> > +			      int y_start)
> > +{
> > +	u8 *dst_pixels;
> > +
> > +	packed_pixels_addr_1x1(&wb->wb_frame_info, x_start, y_start, 0, &dst_pixels);
> > +
> > +	while (count) {
> > +		argb_u16_to_RGB565(dst_pixels, src_pixels);
> > +		dst_pixels += wb->wb_frame_info.fb->format->char_per_block[0];
> > +		src_pixels += 1;
> > +		count--;
> > +	}
> >   }
> >   /**
> > @@ -936,25 +1005,25 @@ void get_conversion_matrix_to_argb_u16(u32 format,
> >   }
> >   /**
> > - * get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format.
> > + * get_pixel_write_function() - Retrieve the correct write_line function for a specific format.
> 
> Correct the docs.

Nice catch!

Thanks,
Louis Chauvet

> Best Regards,
> - Maíra
> 
> >    * 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])
> >    */
> > -pixel_write_t get_pixel_write_function(u32 format)
> > +pixel_write_line_t get_pixel_write_line_function(u32 format) >   {
> >   	switch (format) {
> >   	case DRM_FORMAT_ARGB8888:
> > -		return &argb_u16_to_ARGB8888;
> > +		return &ARGB8888_write_line;
> >   	case DRM_FORMAT_XRGB8888:
> > -		return &argb_u16_to_XRGB8888;
> > +		return &XRGB8888_write_line;
> >   	case DRM_FORMAT_ARGB16161616:
> > -		return &argb_u16_to_ARGB16161616;
> > +		return &ARGB16161616_write_line;
> >   	case DRM_FORMAT_XRGB16161616:
> > -		return &argb_u16_to_XRGB16161616;
> > +		return &XRGB16161616_write_line;
> >   	case DRM_FORMAT_RGB565:
> > -		return &argb_u16_to_RGB565;
> > +		return &RGB565_write_line;
> >   	default:
> >   		/*
> >   		 * This is a bug in vkms_writeback_atomic_check. All the supported
> > diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
> > index eeb208cdd6b1..852ab9a4cee5 100644
> > --- a/drivers/gpu/drm/vkms/vkms_formats.h
> > +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> > @@ -7,7 +7,7 @@
> >   pixel_read_line_t get_pixel_read_line_function(u32 format);
> > -pixel_write_t get_pixel_write_function(u32 format);
> > +pixel_write_line_t get_pixel_write_line_function(u32 format);
> >   void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding,
> >   				       enum drm_color_range range,
> > diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c
> > index c8582df1f739..f6ed3aa69af8 100644
> > --- a/drivers/gpu/drm/vkms/vkms_writeback.c
> > +++ b/drivers/gpu/drm/vkms/vkms_writeback.c
> > @@ -150,7 +150,7 @@ static void vkms_wb_atomic_commit(struct drm_connector *conn,
> >   	crtc_state->wb_pending = true;
> >   	spin_unlock_irq(&output->composer_lock);
> >   	drm_writeback_queue_job(wb_conn, connector_state);
> > -	active_wb->pixel_write = get_pixel_write_function(wb_format);
> > +	active_wb->pixel_write = get_pixel_write_line_function(wb_format);
> >   	drm_rect_init(&wb_frame_info->src, 0, 0, crtc_width, crtc_height);
> >   	drm_rect_init(&wb_frame_info->dst, 0, 0, crtc_width, crtc_height);
> >   }
> > 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-10-28  9:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-14  8:42 [PATCH v2 0/3] drm/vkms: Reimplement line-per-line pixel conversion for writeback Louis Chauvet
2024-08-14  8:42 ` [PATCH v2 1/3] drm/vkms: Re-introduce line-by-line algorithm " Louis Chauvet
2024-10-26 15:05   ` Maíra Canal
2024-10-28  9:50     ` Louis Chauvet
2024-08-14  8:42 ` [PATCH v2 2/3] drm/vkms: Add a macro for write_line functions Louis Chauvet
2024-10-26 15:08   ` Maíra Canal
2024-10-28  9:50     ` Louis Chauvet
2024-08-14  8:42 ` [PATCH v2 3/3] drm/vkms: Add support for XRGB2101010 Louis Chauvet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox