All of lore.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:51 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.