dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/6] drm/vkms: introduce plane rotation property
@ 2023-04-18 13:05 Maíra Canal
  2023-04-18 13:05 ` [PATCH v4 1/6] drm/vkms: isolate pixel conversion functionality Maíra Canal
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Maíra Canal @ 2023-04-18 13:05 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter, Rodrigo Siqueira, Melissa Wen,
	Haneen Mohammed, Igor Matheus Andrade Torrente, Arthur Grillo,
	Ville Syrjälä
  Cc: Maíra Canal, dri-devel

This patchset implements all possible rotation value in vkms. All operations
were implemented by software by changing the way the pixels are read. The way
the blending is performed can be depicted as:

- rotate-0:
    (x) ---->
    ----------------------
(y) |                    |
  | |                    |
  | |                    |
  ˇ |                    |
    ----------------------

- rotate-90:
    <---- (y)
    ----------------------
(x) |                    |
  | |                    |
  | |                    |
  ˇ |                    |
    ----------------------

- rotate-180:
    <---- (x)
    ----------------------
(y) |                    |
  ^ |                    |
  | |                    |
  | |                    |
    ----------------------

- rotate-270:
    (y) ---->
    ----------------------
(x) |                    |
  ^ |                    |
  | |                    |
  | |                    |
    ----------------------

- reflect-x:
    <---- (x)
    ----------------------
(y) |                    |
  | |                    |
  | |                    |
  ˇ |                    |
    ----------------------

- reflect-y:
    (x) ---->
    ----------------------
(y) |                    |
  ^ |                    |
  | |                    |
  | |                    |
    ----------------------

The patchset was tested with IGT's kms_rotation_crc tests and also with some
additional tests [1] for the reflection operations.

In order to avoid code duplication, I introduced a patch that isolates the
pixel format convertion and wraps it in a single loop.

I tried to apply Ville's suggestion to avoid hand rolled coordinate
calculation stuff. Although I couldn't apply all the code suggested by
Ville, I was able to remove all the hardcoded code related to the x-offset.
As VKMS' composition is performed by line, I still need to indicate the
right pixel, which means that I still have some hardcoded code. Thanks for
the suggestion, Ville! It really reduced the code complexity. 

v1 -> v2: https://lore.kernel.org/dri-devel/20230406130138.70752-1-mcanal@igalia.com/T/

* Add patch to isolate pixel format conversion (Arthur Grillo).

v2 -> v3: https://lore.kernel.org/dri-devel/20230414135151.75975-1-mcanal@igalia.com/T/

* Use cpp to calculate pixel size instead of hard-coding (Arthur Grillo).
* Don't use the x coordinate in the pixel_read functions (Arthur Grillo).
* Use drm_rotate_simplify() to avoid hard-coding rotate-180 (Ville Syrjälä).
* Use u8* to input the src_pixels instead of using u16*.

v3 -> v4: https://lore.kernel.org/dri-devel/20230417121056.63917-1-mcanal@igalia.com/T/

* Create a original rectangle and a rotated rectangle and use the original
  rectangle to offset the x-axis (Ville Syrjälä).

[1] https://patchwork.freedesktop.org/series/116025/

Best Regards,
- Maíra Canal

Maíra Canal (6):
  drm/vkms: isolate pixel conversion functionality
  drm/vkms: add rotate-0 and reflect-x property
  drm/vkms: add reflect-y and rotate-180 property
  drm/vkms: add rotate-90 property
  drm/vkms: add rotate-270 property
  drm/vkms: drop "Rotation" TODO

 Documentation/gpu/vkms.rst           |   2 +-
 drivers/gpu/drm/vkms/vkms_composer.c |  38 ++++++--
 drivers/gpu/drm/vkms/vkms_drv.h      |   6 +-
 drivers/gpu/drm/vkms/vkms_formats.c  | 139 +++++++++++++--------------
 drivers/gpu/drm/vkms/vkms_formats.h  |   2 +-
 drivers/gpu/drm/vkms/vkms_plane.c    |  16 ++-
 6 files changed, 117 insertions(+), 86 deletions(-)

-- 
2.39.2


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

* [PATCH v4 1/6] drm/vkms: isolate pixel conversion functionality
  2023-04-18 13:05 [PATCH v4 0/6] drm/vkms: introduce plane rotation property Maíra Canal
@ 2023-04-18 13:05 ` Maíra Canal
  2023-04-24 21:22   ` Maíra Canal
  2023-04-18 13:05 ` [PATCH v4 2/6] drm/vkms: add rotate-0 and reflect-x property Maíra Canal
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Maíra Canal @ 2023-04-18 13:05 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter, Rodrigo Siqueira, Melissa Wen,
	Haneen Mohammed, Igor Matheus Andrade Torrente, Arthur Grillo,
	Ville Syrjälä
  Cc: Maíra Canal, dri-devel

Currently, the pixel conversion functions repeat the same loop to
iterate the rows. Instead of repeating the same code for each pixel
format, create a function to wrap the loop and isolate the pixel
conversion functionality.

Suggested-by: Arthur Grillo <arthurgrillo@riseup.net>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Reviewed-by: Arthur Grillo <arthurgrillo@riseup.net>
---
 drivers/gpu/drm/vkms/vkms_composer.c |   4 +-
 drivers/gpu/drm/vkms/vkms_drv.h      |   4 +-
 drivers/gpu/drm/vkms/vkms_formats.c  | 125 +++++++++++----------------
 drivers/gpu/drm/vkms/vkms_formats.h  |   2 +-
 drivers/gpu/drm/vkms/vkms_plane.c    |   2 +-
 5 files changed, 56 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 8e53fa80742b..80164e79af00 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -99,7 +99,7 @@ static void blend(struct vkms_writeback_job *wb,
 			if (!check_y_limit(plane[i]->frame_info, y))
 				continue;
 
-			plane[i]->plane_read(stage_buffer, plane[i]->frame_info, y);
+			vkms_compose_row(stage_buffer, plane[i], y);
 			pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer,
 					    output_buffer);
 		}
@@ -118,7 +118,7 @@ static int check_format_funcs(struct vkms_crtc_state *crtc_state,
 	u32 n_active_planes = crtc_state->num_active_planes;
 
 	for (size_t i = 0; i < n_active_planes; i++)
-		if (!planes[i]->plane_read)
+		if (!planes[i]->pixel_read)
 			return -1;
 
 	if (active_wb && !active_wb->wb_write)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 4a248567efb2..f152d54baf76 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -56,8 +56,7 @@ struct vkms_writeback_job {
 struct vkms_plane_state {
 	struct drm_shadow_plane_state base;
 	struct vkms_frame_info *frame_info;
-	void (*plane_read)(struct line_buffer *buffer,
-			   const struct vkms_frame_info *frame_info, int y);
+	void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel);
 };
 
 struct vkms_plane {
@@ -155,6 +154,7 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
 /* Composer Support */
 void vkms_composer_worker(struct work_struct *work);
 void vkms_set_composer(struct vkms_output *out, bool enabled);
+void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y);
 
 /* 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 d4950688b3f1..8d948c73741e 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -42,100 +42,75 @@ static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y
 	return packed_pixels_addr(frame_info, x_src, y_src);
 }
 
-static void ARGB8888_to_argb_u16(struct line_buffer *stage_buffer,
-				 const struct vkms_frame_info *frame_info, int y)
+static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
 {
-	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
-	u8 *src_pixels = get_packed_src_addr(frame_info, y);
-	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
-			    stage_buffer->n_pixels);
-
-	for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
-		/*
-		 * The 257 is the "conversion ratio". This number is obtained by the
-		 * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
-		 * the best color value in a pixel format with more possibilities.
-		 * A similar idea applies to others RGB color conversions.
-		 */
-		out_pixels[x].a = (u16)src_pixels[3] * 257;
-		out_pixels[x].r = (u16)src_pixels[2] * 257;
-		out_pixels[x].g = (u16)src_pixels[1] * 257;
-		out_pixels[x].b = (u16)src_pixels[0] * 257;
-	}
+	/*
+	 * The 257 is the "conversion ratio". This number is obtained by the
+	 * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
+	 * the best color value in a pixel format with more possibilities.
+	 * A similar idea applies to others RGB color conversions.
+	 */
+	out_pixel->a = (u16)src_pixels[3] * 257;
+	out_pixel->r = (u16)src_pixels[2] * 257;
+	out_pixel->g = (u16)src_pixels[1] * 257;
+	out_pixel->b = (u16)src_pixels[0] * 257;
 }
 
-static void XRGB8888_to_argb_u16(struct line_buffer *stage_buffer,
-				 const struct vkms_frame_info *frame_info, int y)
+static void XRGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
 {
-	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
-	u8 *src_pixels = get_packed_src_addr(frame_info, y);
-	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
-			    stage_buffer->n_pixels);
-
-	for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
-		out_pixels[x].a = (u16)0xffff;
-		out_pixels[x].r = (u16)src_pixels[2] * 257;
-		out_pixels[x].g = (u16)src_pixels[1] * 257;
-		out_pixels[x].b = (u16)src_pixels[0] * 257;
-	}
+	out_pixel->a = (u16)0xffff;
+	out_pixel->r = (u16)src_pixels[2] * 257;
+	out_pixel->g = (u16)src_pixels[1] * 257;
+	out_pixel->b = (u16)src_pixels[0] * 257;
 }
 
-static void ARGB16161616_to_argb_u16(struct line_buffer *stage_buffer,
-				     const struct vkms_frame_info *frame_info,
-				     int y)
+static void ARGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
 {
-	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
-	u16 *src_pixels = get_packed_src_addr(frame_info, y);
-	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
-			    stage_buffer->n_pixels);
+	u16 *pixels = (u16 *)src_pixels;
 
-	for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
-		out_pixels[x].a = le16_to_cpu(src_pixels[3]);
-		out_pixels[x].r = le16_to_cpu(src_pixels[2]);
-		out_pixels[x].g = le16_to_cpu(src_pixels[1]);
-		out_pixels[x].b = le16_to_cpu(src_pixels[0]);
-	}
+	out_pixel->a = le16_to_cpu(pixels[3]);
+	out_pixel->r = le16_to_cpu(pixels[2]);
+	out_pixel->g = le16_to_cpu(pixels[1]);
+	out_pixel->b = le16_to_cpu(pixels[0]);
 }
 
-static void XRGB16161616_to_argb_u16(struct line_buffer *stage_buffer,
-				     const struct vkms_frame_info *frame_info,
-				     int y)
+static void XRGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
 {
-	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
-	u16 *src_pixels = get_packed_src_addr(frame_info, y);
-	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
-			    stage_buffer->n_pixels);
+	u16 *pixels = (u16 *)src_pixels;
 
-	for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
-		out_pixels[x].a = (u16)0xffff;
-		out_pixels[x].r = le16_to_cpu(src_pixels[2]);
-		out_pixels[x].g = le16_to_cpu(src_pixels[1]);
-		out_pixels[x].b = le16_to_cpu(src_pixels[0]);
-	}
+	out_pixel->a = (u16)0xffff;
+	out_pixel->r = le16_to_cpu(pixels[2]);
+	out_pixel->g = le16_to_cpu(pixels[1]);
+	out_pixel->b = le16_to_cpu(pixels[0]);
 }
 
-static void RGB565_to_argb_u16(struct line_buffer *stage_buffer,
-			       const struct vkms_frame_info *frame_info, int y)
+static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
 {
-	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
-	u16 *src_pixels = get_packed_src_addr(frame_info, y);
-	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
-			       stage_buffer->n_pixels);
+	u16 *pixels = (u16 *)src_pixels;
 
 	s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
 	s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
 
-	for (size_t x = 0; x < x_limit; x++, src_pixels++) {
-		u16 rgb_565 = le16_to_cpu(*src_pixels);
-		s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
-		s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
-		s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
+	u16 rgb_565 = le16_to_cpu(*pixels);
+	s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
+	s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
+	s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
 
-		out_pixels[x].a = (u16)0xffff;
-		out_pixels[x].r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio));
-		out_pixels[x].g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio));
-		out_pixels[x].b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio));
-	}
+	out_pixel->a = (u16)0xffff;
+	out_pixel->r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio));
+	out_pixel->g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio));
+	out_pixel->b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio));
+}
+
+void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
+{
+	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
+	struct vkms_frame_info *frame_info = plane->frame_info;
+	u8 *src_pixels = get_packed_src_addr(frame_info, y);
+	int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
+
+	for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp)
+		plane->pixel_read(src_pixels, &out_pixels[x]);
 }
 
 /*
@@ -249,7 +224,7 @@ static void argb_u16_to_RGB565(struct vkms_frame_info *frame_info,
 	}
 }
 
-void *get_frame_to_line_function(u32 format)
+void *get_pixel_conversion_function(u32 format)
 {
 	switch (format) {
 	case DRM_FORMAT_ARGB8888:
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
index 43b7c1979018..c5b113495d0c 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -5,7 +5,7 @@
 
 #include "vkms_drv.h"
 
-void *get_frame_to_line_function(u32 format);
+void *get_pixel_conversion_function(u32 format);
 
 void *get_line_to_frame_function(u32 format);
 
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index c41cec7dcb70..0a23875900ec 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -123,7 +123,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
 	frame_info->offset = fb->offsets[0];
 	frame_info->pitch = fb->pitches[0];
 	frame_info->cpp = fb->format->cpp[0];
-	vkms_plane_state->plane_read = get_frame_to_line_function(fmt);
+	vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
 }
 
 static int vkms_plane_atomic_check(struct drm_plane *plane,
-- 
2.39.2


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

* [PATCH v4 2/6] drm/vkms: add rotate-0 and reflect-x property
  2023-04-18 13:05 [PATCH v4 0/6] drm/vkms: introduce plane rotation property Maíra Canal
  2023-04-18 13:05 ` [PATCH v4 1/6] drm/vkms: isolate pixel conversion functionality Maíra Canal
@ 2023-04-18 13:05 ` Maíra Canal
  2023-04-18 13:05 ` [PATCH v4 3/6] drm/vkms: add reflect-y and rotate-180 property Maíra Canal
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Maíra Canal @ 2023-04-18 13:05 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter, Rodrigo Siqueira, Melissa Wen,
	Haneen Mohammed, Igor Matheus Andrade Torrente, Arthur Grillo,
	Ville Syrjälä
  Cc: Maíra Canal, dri-devel

Currently, vkms doesn't support any reflection property. Therefore, add
the reflect-x property to vkms through a software implementation of the
operation. This is possible by reverse reading the x axis during the
blending.

Tested with igt@kms_rotation_crc@primary-reflect-x and
igt@kms_rotation_crc@sprite-reflect-x [1].

[1] https://patchwork.freedesktop.org/series/116025/

Signed-off-by: Maíra Canal <mcanal@igalia.com>
---
 drivers/gpu/drm/vkms/vkms_composer.c |  2 +-
 drivers/gpu/drm/vkms/vkms_drv.h      |  2 ++
 drivers/gpu/drm/vkms/vkms_formats.c  | 16 +++++++++++++---
 drivers/gpu/drm/vkms/vkms_plane.c    | 12 ++++++++++++
 4 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 80164e79af00..a4436981cbcd 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -55,7 +55,7 @@ static void pre_mul_alpha_blend(struct vkms_frame_info *frame_info,
 
 static bool check_y_limit(struct vkms_frame_info *frame_info, int y)
 {
-	if (y >= frame_info->dst.y1 && y < frame_info->dst.y2)
+	if (y >= frame_info->rotated.y1 && y < frame_info->rotated.y2)
 		return true;
 
 	return false;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index f152d54baf76..5f1a0a44a78c 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -26,7 +26,9 @@
 struct vkms_frame_info {
 	struct drm_framebuffer *fb;
 	struct drm_rect src, dst;
+	struct drm_rect rotated;
 	struct iosys_map map[DRM_FORMAT_MAX_PLANES];
+	unsigned int rotation;
 	unsigned int offset;
 	unsigned int pitch;
 	unsigned int cpp;
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index 8d948c73741e..f59b1c48a563 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -37,11 +37,18 @@ static void *packed_pixels_addr(const struct vkms_frame_info *frame_info,
 static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y)
 {
 	int x_src = frame_info->src.x1 >> 16;
-	int y_src = y - frame_info->dst.y1 + (frame_info->src.y1 >> 16);
+	int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16);
 
 	return packed_pixels_addr(frame_info, x_src, y_src);
 }
 
+static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x)
+{
+	if (frame_info->rotation & DRM_MODE_REFLECT_X)
+		return limit - x - 1;
+	return x;
+}
+
 static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
 {
 	/*
@@ -109,8 +116,11 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state
 	u8 *src_pixels = get_packed_src_addr(frame_info, y);
 	int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
 
-	for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp)
-		plane->pixel_read(src_pixels, &out_pixels[x]);
+	for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) {
+		int x_pos = get_x_position(frame_info, limit, x);
+
+		plane->pixel_read(src_pixels, &out_pixels[x_pos]);
+	}
 }
 
 /*
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 0a23875900ec..3639afd7da47 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -4,6 +4,7 @@
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
@@ -117,9 +118,16 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
 	frame_info = vkms_plane_state->frame_info;
 	memcpy(&frame_info->src, &new_state->src, sizeof(struct drm_rect));
 	memcpy(&frame_info->dst, &new_state->dst, sizeof(struct drm_rect));
+	memcpy(&frame_info->rotated, &new_state->dst, sizeof(struct drm_rect));
 	frame_info->fb = fb;
 	memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
 	drm_framebuffer_get(frame_info->fb);
+	frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
+						     DRM_MODE_REFLECT_X);
+
+	drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
+			drm_rect_height(&frame_info->rotated), frame_info->rotation);
+
 	frame_info->offset = fb->offsets[0];
 	frame_info->pitch = fb->pitches[0];
 	frame_info->cpp = fb->format->cpp[0];
@@ -229,5 +237,9 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
 
 	drm_plane_helper_add(&plane->base, funcs);
 
+	drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
+					   DRM_MODE_ROTATE_0 |
+					   DRM_MODE_REFLECT_X);
+
 	return plane;
 }
-- 
2.39.2


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

* [PATCH v4 3/6] drm/vkms: add reflect-y and rotate-180 property
  2023-04-18 13:05 [PATCH v4 0/6] drm/vkms: introduce plane rotation property Maíra Canal
  2023-04-18 13:05 ` [PATCH v4 1/6] drm/vkms: isolate pixel conversion functionality Maíra Canal
  2023-04-18 13:05 ` [PATCH v4 2/6] drm/vkms: add rotate-0 and reflect-x property Maíra Canal
@ 2023-04-18 13:05 ` Maíra Canal
  2023-04-18 13:05 ` [PATCH v4 4/6] drm/vkms: add rotate-90 property Maíra Canal
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Maíra Canal @ 2023-04-18 13:05 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter, Rodrigo Siqueira, Melissa Wen,
	Haneen Mohammed, Igor Matheus Andrade Torrente, Arthur Grillo,
	Ville Syrjälä
  Cc: Maíra Canal, dri-devel

Currently, vkms only supports the reflect-x property. Therefore, add the
reflect-y property to vkms through a software implementation of the
operation. This is possible by reverse reading the y axis during the
blending.

Note that, by implementing the reflect-x and reflect-y properties, it is
also possible to add the rotate-180 property, as it is a combination
of those two properties.

Tested with igt@kms_rotation_crc@primary-reflect-y [1],
igt@kms_rotation_crc@sprite-reflect-y [1],
igt@kms_rotation_crc@primary-rotation-180,
igt@kms_rotation_crc@sprite-rotation-180,
and igt@kms_rotation_crc@cursor-rotation-180.

Signed-off-by: Maíra Canal <mcanal@igalia.com>
---
 drivers/gpu/drm/vkms/vkms_composer.c | 16 +++++++++++++---
 drivers/gpu/drm/vkms/vkms_plane.c    |  7 +++++--
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index a4436981cbcd..6c5ef11b3943 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -53,6 +53,13 @@ static void pre_mul_alpha_blend(struct vkms_frame_info *frame_info,
 	}
 }
 
+static int get_y_pos(struct vkms_frame_info *frame_info, int y)
+{
+	if (frame_info->rotation & DRM_MODE_REFLECT_Y)
+		return drm_rect_height(&frame_info->rotated) - y - 1;
+	return y;
+}
+
 static bool check_y_limit(struct vkms_frame_info *frame_info, int y)
 {
 	if (y >= frame_info->rotated.y1 && y < frame_info->rotated.y2)
@@ -86,6 +93,7 @@ static void blend(struct vkms_writeback_job *wb,
 {
 	struct vkms_plane_state **plane = crtc_state->active_planes;
 	u32 n_active_planes = crtc_state->num_active_planes;
+	int y_pos;
 
 	const struct pixel_argb_u16 background_color = { .a = 0xffff };
 
@@ -96,10 +104,12 @@ static void blend(struct vkms_writeback_job *wb,
 
 		/* The active planes are composed associatively in z-order. */
 		for (size_t i = 0; i < n_active_planes; i++) {
-			if (!check_y_limit(plane[i]->frame_info, y))
+			y_pos = get_y_pos(plane[i]->frame_info, y);
+
+			if (!check_y_limit(plane[i]->frame_info, y_pos))
 				continue;
 
-			vkms_compose_row(stage_buffer, plane[i], y);
+			vkms_compose_row(stage_buffer, plane[i], y_pos);
 			pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer,
 					    output_buffer);
 		}
@@ -107,7 +117,7 @@ static void blend(struct vkms_writeback_job *wb,
 		*crc32 = crc32_le(*crc32, (void *)output_buffer->pixels, row_size);
 
 		if (wb)
-			wb->wb_write(&wb->wb_frame_info, output_buffer, y);
+			wb->wb_write(&wb->wb_frame_info, output_buffer, y_pos);
 	}
 }
 
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 3639afd7da47..904a278e07d7 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -123,7 +123,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
 	memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
 	drm_framebuffer_get(frame_info->fb);
 	frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
-						     DRM_MODE_REFLECT_X);
+						     DRM_MODE_REFLECT_X |
+						     DRM_MODE_REFLECT_Y);
 
 	drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
 			drm_rect_height(&frame_info->rotated), frame_info->rotation);
@@ -239,7 +240,9 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
 
 	drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
 					   DRM_MODE_ROTATE_0 |
-					   DRM_MODE_REFLECT_X);
+					   DRM_MODE_ROTATE_180 |
+					   DRM_MODE_REFLECT_X |
+					   DRM_MODE_REFLECT_Y);
 
 	return plane;
 }
-- 
2.39.2


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

* [PATCH v4 4/6] drm/vkms: add rotate-90 property
  2023-04-18 13:05 [PATCH v4 0/6] drm/vkms: introduce plane rotation property Maíra Canal
                   ` (2 preceding siblings ...)
  2023-04-18 13:05 ` [PATCH v4 3/6] drm/vkms: add reflect-y and rotate-180 property Maíra Canal
@ 2023-04-18 13:05 ` Maíra Canal
  2023-05-07 20:48   ` Melissa Wen
  2023-04-18 13:05 ` [PATCH v4 5/6] drm/vkms: add rotate-270 property Maíra Canal
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Maíra Canal @ 2023-04-18 13:05 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter, Rodrigo Siqueira, Melissa Wen,
	Haneen Mohammed, Igor Matheus Andrade Torrente, Arthur Grillo,
	Ville Syrjälä
  Cc: Maíra Canal, dri-devel

Currently, vkms only supports the rotate-180, reflect-x and reflect-y
properties. Therefore, improve the vkms IGT test coverage by adding the
rotate-90 property to vkms. The rotation was implement by software: rotate
the way the blending occurs by making the source x axis be the destination
y axis and the source y axis be the destination x axis.

Tested with igt@kms_rotation_crc@primary-rotation-90,
igt@kms_rotation_crc@sprite-rotation-90, and
igt@kms_rotation_crc@sprite-rotation-90-pos-100-0.

Signed-off-by: Maíra Canal <mcanal@igalia.com>
---
 drivers/gpu/drm/vkms/vkms_composer.c | 21 ++++++++++++++++-----
 drivers/gpu/drm/vkms/vkms_formats.c  |  4 ++++
 drivers/gpu/drm/vkms/vkms_plane.c    |  2 ++
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 6c5ef11b3943..491850ffeac9 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -57,13 +57,24 @@ static int get_y_pos(struct vkms_frame_info *frame_info, int y)
 {
 	if (frame_info->rotation & DRM_MODE_REFLECT_Y)
 		return drm_rect_height(&frame_info->rotated) - y - 1;
-	return y;
+
+	switch (frame_info->rotation & DRM_MODE_ROTATE_MASK) {
+	case DRM_MODE_ROTATE_90:
+		return frame_info->rotated.x2 - y - 1;
+	default:
+		return y;
+	}
 }
 
-static bool check_y_limit(struct vkms_frame_info *frame_info, int y)
+static bool check_limit(struct vkms_frame_info *frame_info, int pos)
 {
-	if (y >= frame_info->rotated.y1 && y < frame_info->rotated.y2)
-		return true;
+	if (frame_info->rotation & DRM_MODE_ROTATE_90) {
+		if (pos >= 0 && pos < drm_rect_width(&frame_info->rotated))
+			return true;
+	} else {
+		if (pos >= frame_info->rotated.y1 && pos < frame_info->rotated.y2)
+			return true;
+	}
 
 	return false;
 }
@@ -106,7 +117,7 @@ static void blend(struct vkms_writeback_job *wb,
 		for (size_t i = 0; i < n_active_planes; i++) {
 			y_pos = get_y_pos(plane[i]->frame_info, y);
 
-			if (!check_y_limit(plane[i]->frame_info, y_pos))
+			if (!check_limit(plane[i]->frame_info, y_pos))
 				continue;
 
 			vkms_compose_row(stage_buffer, plane[i], y_pos);
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index f59b1c48a563..f56f359e0d2d 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -119,6 +119,10 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state
 	for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) {
 		int x_pos = get_x_position(frame_info, limit, x);
 
+		if (frame_info->rotation & DRM_MODE_ROTATE_90)
+			src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1)
+				+ frame_info->cpp * y;
+
 		plane->pixel_read(src_pixels, &out_pixels[x_pos]);
 	}
 }
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 904a278e07d7..9e451ce97099 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -123,6 +123,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
 	memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
 	drm_framebuffer_get(frame_info->fb);
 	frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
+						     DRM_MODE_ROTATE_90 |
 						     DRM_MODE_REFLECT_X |
 						     DRM_MODE_REFLECT_Y);
 
@@ -240,6 +241,7 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
 
 	drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
 					   DRM_MODE_ROTATE_0 |
+					   DRM_MODE_ROTATE_90 |
 					   DRM_MODE_ROTATE_180 |
 					   DRM_MODE_REFLECT_X |
 					   DRM_MODE_REFLECT_Y);
-- 
2.39.2


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

* [PATCH v4 5/6] drm/vkms: add rotate-270 property
  2023-04-18 13:05 [PATCH v4 0/6] drm/vkms: introduce plane rotation property Maíra Canal
                   ` (3 preceding siblings ...)
  2023-04-18 13:05 ` [PATCH v4 4/6] drm/vkms: add rotate-90 property Maíra Canal
@ 2023-04-18 13:05 ` Maíra Canal
  2023-04-18 13:05 ` [PATCH v4 6/6] drm/vkms: drop "Rotation" TODO Maíra Canal
  2023-05-07 20:54 ` [PATCH v4 0/6] drm/vkms: introduce plane rotation property Melissa Wen
  6 siblings, 0 replies; 11+ messages in thread
From: Maíra Canal @ 2023-04-18 13:05 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter, Rodrigo Siqueira, Melissa Wen,
	Haneen Mohammed, Igor Matheus Andrade Torrente, Arthur Grillo,
	Ville Syrjälä
  Cc: Maíra Canal, dri-devel

Currently, vkms supports the rotate-90, rotate-180, reflect-x and
reflect-y properties.  Therefore, improve the vkms IGT test coverage by
adding the rotate-270 property to vkms. The rotation was implement by
software: rotate the way the blending occurs by making the source x axis
be the destination y axis and the source y axis be the destination x
axis and reverse-read the axis.

Now, vkms supports all possible rotation values.

Tested with igt@kms_rotation_crc@primary-rotation-270,
and igt@kms_rotation_crc@sprite-rotation-270.

Signed-off-by: Maíra Canal <mcanal@igalia.com>
---
 drivers/gpu/drm/vkms/vkms_composer.c | 5 ++++-
 drivers/gpu/drm/vkms/vkms_formats.c  | 6 ++++--
 drivers/gpu/drm/vkms/vkms_plane.c    | 7 ++-----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 491850ffeac9..906d3df40cdb 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -4,6 +4,7 @@
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_vblank.h>
@@ -61,6 +62,8 @@ static int get_y_pos(struct vkms_frame_info *frame_info, int y)
 	switch (frame_info->rotation & DRM_MODE_ROTATE_MASK) {
 	case DRM_MODE_ROTATE_90:
 		return frame_info->rotated.x2 - y - 1;
+	case DRM_MODE_ROTATE_270:
+		return y + frame_info->rotated.x1;
 	default:
 		return y;
 	}
@@ -68,7 +71,7 @@ static int get_y_pos(struct vkms_frame_info *frame_info, int y)
 
 static bool check_limit(struct vkms_frame_info *frame_info, int pos)
 {
-	if (frame_info->rotation & DRM_MODE_ROTATE_90) {
+	if (drm_rotation_90_or_270(frame_info->rotation)) {
 		if (pos >= 0 && pos < drm_rect_width(&frame_info->rotated))
 			return true;
 	} else {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index f56f359e0d2d..ebacb8efa055 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -2,6 +2,8 @@
 
 #include <linux/kernel.h>
 #include <linux/minmax.h>
+
+#include <drm/drm_blend.h>
 #include <drm/drm_rect.h>
 #include <drm/drm_fixed.h>
 
@@ -44,7 +46,7 @@ static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y
 
 static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x)
 {
-	if (frame_info->rotation & DRM_MODE_REFLECT_X)
+	if (frame_info->rotation & (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270))
 		return limit - x - 1;
 	return x;
 }
@@ -119,7 +121,7 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state
 	for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) {
 		int x_pos = get_x_position(frame_info, limit, x);
 
-		if (frame_info->rotation & DRM_MODE_ROTATE_90)
+		if (drm_rotation_90_or_270(frame_info->rotation))
 			src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1)
 				+ frame_info->cpp * y;
 
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 9e451ce97099..66263081639d 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -124,6 +124,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
 	drm_framebuffer_get(frame_info->fb);
 	frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
 						     DRM_MODE_ROTATE_90 |
+						     DRM_MODE_ROTATE_270 |
 						     DRM_MODE_REFLECT_X |
 						     DRM_MODE_REFLECT_Y);
 
@@ -240,11 +241,7 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
 	drm_plane_helper_add(&plane->base, funcs);
 
 	drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
-					   DRM_MODE_ROTATE_0 |
-					   DRM_MODE_ROTATE_90 |
-					   DRM_MODE_ROTATE_180 |
-					   DRM_MODE_REFLECT_X |
-					   DRM_MODE_REFLECT_Y);
+					   DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
 
 	return plane;
 }
-- 
2.39.2


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

* [PATCH v4 6/6] drm/vkms: drop "Rotation" TODO
  2023-04-18 13:05 [PATCH v4 0/6] drm/vkms: introduce plane rotation property Maíra Canal
                   ` (4 preceding siblings ...)
  2023-04-18 13:05 ` [PATCH v4 5/6] drm/vkms: add rotate-270 property Maíra Canal
@ 2023-04-18 13:05 ` Maíra Canal
  2023-05-07 20:54 ` [PATCH v4 0/6] drm/vkms: introduce plane rotation property Melissa Wen
  6 siblings, 0 replies; 11+ messages in thread
From: Maíra Canal @ 2023-04-18 13:05 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter, Rodrigo Siqueira, Melissa Wen,
	Haneen Mohammed, Igor Matheus Andrade Torrente, Arthur Grillo,
	Ville Syrjälä
  Cc: Maíra Canal, dri-devel

Now that VKMS supports all values of rotation and reflection, drop the
"Rotation" task from the TODO list.

Signed-off-by: Maíra Canal <mcanal@igalia.com>
---
 Documentation/gpu/vkms.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 49db221c0f52..413e6815b9bc 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -125,7 +125,7 @@ There's lots of plane features we could add support for:
 
 - Full alpha blending on all planes.
 
-- Rotation, scaling.
+- Scaling.
 
 - Additional buffer formats, especially YUV formats for video like NV12.
   Low/high bpp RGB formats would also be interesting.
-- 
2.39.2


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

* Re: [PATCH v4 1/6] drm/vkms: isolate pixel conversion functionality
  2023-04-18 13:05 ` [PATCH v4 1/6] drm/vkms: isolate pixel conversion functionality Maíra Canal
@ 2023-04-24 21:22   ` Maíra Canal
  0 siblings, 0 replies; 11+ messages in thread
From: Maíra Canal @ 2023-04-24 21:22 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter, Rodrigo Siqueira, Melissa Wen,
	Haneen Mohammed, Igor Matheus Andrade Torrente, Arthur Grillo,
	Ville Syrjälä
  Cc: dri-devel

On 4/18/23 10:05, Maíra Canal wrote:
> Currently, the pixel conversion functions repeat the same loop to
> iterate the rows. Instead of repeating the same code for each pixel
> format, create a function to wrap the loop and isolate the pixel
> conversion functionality.
> 
> Suggested-by: Arthur Grillo <arthurgrillo@riseup.net>
> Signed-off-by: Maíra Canal <mcanal@igalia.com>
> Reviewed-by: Arthur Grillo <arthurgrillo@riseup.net>

Applied to drm/drm-misc (drm-misc-next).

Best Regards,
- Maíra Canal

> ---
>   drivers/gpu/drm/vkms/vkms_composer.c |   4 +-
>   drivers/gpu/drm/vkms/vkms_drv.h      |   4 +-
>   drivers/gpu/drm/vkms/vkms_formats.c  | 125 +++++++++++----------------
>   drivers/gpu/drm/vkms/vkms_formats.h  |   2 +-
>   drivers/gpu/drm/vkms/vkms_plane.c    |   2 +-
>   5 files changed, 56 insertions(+), 81 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
> index 8e53fa80742b..80164e79af00 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> @@ -99,7 +99,7 @@ static void blend(struct vkms_writeback_job *wb,
>   			if (!check_y_limit(plane[i]->frame_info, y))
>   				continue;
>   
> -			plane[i]->plane_read(stage_buffer, plane[i]->frame_info, y);
> +			vkms_compose_row(stage_buffer, plane[i], y);
>   			pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer,
>   					    output_buffer);
>   		}
> @@ -118,7 +118,7 @@ static int check_format_funcs(struct vkms_crtc_state *crtc_state,
>   	u32 n_active_planes = crtc_state->num_active_planes;
>   
>   	for (size_t i = 0; i < n_active_planes; i++)
> -		if (!planes[i]->plane_read)
> +		if (!planes[i]->pixel_read)
>   			return -1;
>   
>   	if (active_wb && !active_wb->wb_write)
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
> index 4a248567efb2..f152d54baf76 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.h
> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
> @@ -56,8 +56,7 @@ struct vkms_writeback_job {
>   struct vkms_plane_state {
>   	struct drm_shadow_plane_state base;
>   	struct vkms_frame_info *frame_info;
> -	void (*plane_read)(struct line_buffer *buffer,
> -			   const struct vkms_frame_info *frame_info, int y);
> +	void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel);
>   };
>   
>   struct vkms_plane {
> @@ -155,6 +154,7 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
>   /* Composer Support */
>   void vkms_composer_worker(struct work_struct *work);
>   void vkms_set_composer(struct vkms_output *out, bool enabled);
> +void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y);
>   
>   /* 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 d4950688b3f1..8d948c73741e 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.c
> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> @@ -42,100 +42,75 @@ static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y
>   	return packed_pixels_addr(frame_info, x_src, y_src);
>   }
>   
> -static void ARGB8888_to_argb_u16(struct line_buffer *stage_buffer,
> -				 const struct vkms_frame_info *frame_info, int y)
> +static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
>   {
> -	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
> -	u8 *src_pixels = get_packed_src_addr(frame_info, y);
> -	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
> -			    stage_buffer->n_pixels);
> -
> -	for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
> -		/*
> -		 * The 257 is the "conversion ratio". This number is obtained by the
> -		 * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
> -		 * the best color value in a pixel format with more possibilities.
> -		 * A similar idea applies to others RGB color conversions.
> -		 */
> -		out_pixels[x].a = (u16)src_pixels[3] * 257;
> -		out_pixels[x].r = (u16)src_pixels[2] * 257;
> -		out_pixels[x].g = (u16)src_pixels[1] * 257;
> -		out_pixels[x].b = (u16)src_pixels[0] * 257;
> -	}
> +	/*
> +	 * The 257 is the "conversion ratio". This number is obtained by the
> +	 * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
> +	 * the best color value in a pixel format with more possibilities.
> +	 * A similar idea applies to others RGB color conversions.
> +	 */
> +	out_pixel->a = (u16)src_pixels[3] * 257;
> +	out_pixel->r = (u16)src_pixels[2] * 257;
> +	out_pixel->g = (u16)src_pixels[1] * 257;
> +	out_pixel->b = (u16)src_pixels[0] * 257;
>   }
>   
> -static void XRGB8888_to_argb_u16(struct line_buffer *stage_buffer,
> -				 const struct vkms_frame_info *frame_info, int y)
> +static void XRGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
>   {
> -	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
> -	u8 *src_pixels = get_packed_src_addr(frame_info, y);
> -	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
> -			    stage_buffer->n_pixels);
> -
> -	for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
> -		out_pixels[x].a = (u16)0xffff;
> -		out_pixels[x].r = (u16)src_pixels[2] * 257;
> -		out_pixels[x].g = (u16)src_pixels[1] * 257;
> -		out_pixels[x].b = (u16)src_pixels[0] * 257;
> -	}
> +	out_pixel->a = (u16)0xffff;
> +	out_pixel->r = (u16)src_pixels[2] * 257;
> +	out_pixel->g = (u16)src_pixels[1] * 257;
> +	out_pixel->b = (u16)src_pixels[0] * 257;
>   }
>   
> -static void ARGB16161616_to_argb_u16(struct line_buffer *stage_buffer,
> -				     const struct vkms_frame_info *frame_info,
> -				     int y)
> +static void ARGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
>   {
> -	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
> -	u16 *src_pixels = get_packed_src_addr(frame_info, y);
> -	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
> -			    stage_buffer->n_pixels);
> +	u16 *pixels = (u16 *)src_pixels;
>   
> -	for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
> -		out_pixels[x].a = le16_to_cpu(src_pixels[3]);
> -		out_pixels[x].r = le16_to_cpu(src_pixels[2]);
> -		out_pixels[x].g = le16_to_cpu(src_pixels[1]);
> -		out_pixels[x].b = le16_to_cpu(src_pixels[0]);
> -	}
> +	out_pixel->a = le16_to_cpu(pixels[3]);
> +	out_pixel->r = le16_to_cpu(pixels[2]);
> +	out_pixel->g = le16_to_cpu(pixels[1]);
> +	out_pixel->b = le16_to_cpu(pixels[0]);
>   }
>   
> -static void XRGB16161616_to_argb_u16(struct line_buffer *stage_buffer,
> -				     const struct vkms_frame_info *frame_info,
> -				     int y)
> +static void XRGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
>   {
> -	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
> -	u16 *src_pixels = get_packed_src_addr(frame_info, y);
> -	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
> -			    stage_buffer->n_pixels);
> +	u16 *pixels = (u16 *)src_pixels;
>   
> -	for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
> -		out_pixels[x].a = (u16)0xffff;
> -		out_pixels[x].r = le16_to_cpu(src_pixels[2]);
> -		out_pixels[x].g = le16_to_cpu(src_pixels[1]);
> -		out_pixels[x].b = le16_to_cpu(src_pixels[0]);
> -	}
> +	out_pixel->a = (u16)0xffff;
> +	out_pixel->r = le16_to_cpu(pixels[2]);
> +	out_pixel->g = le16_to_cpu(pixels[1]);
> +	out_pixel->b = le16_to_cpu(pixels[0]);
>   }
>   
> -static void RGB565_to_argb_u16(struct line_buffer *stage_buffer,
> -			       const struct vkms_frame_info *frame_info, int y)
> +static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
>   {
> -	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
> -	u16 *src_pixels = get_packed_src_addr(frame_info, y);
> -	int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
> -			       stage_buffer->n_pixels);
> +	u16 *pixels = (u16 *)src_pixels;
>   
>   	s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
>   	s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
>   
> -	for (size_t x = 0; x < x_limit; x++, src_pixels++) {
> -		u16 rgb_565 = le16_to_cpu(*src_pixels);
> -		s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
> -		s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
> -		s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
> +	u16 rgb_565 = le16_to_cpu(*pixels);
> +	s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
> +	s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
> +	s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
>   
> -		out_pixels[x].a = (u16)0xffff;
> -		out_pixels[x].r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio));
> -		out_pixels[x].g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio));
> -		out_pixels[x].b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio));
> -	}
> +	out_pixel->a = (u16)0xffff;
> +	out_pixel->r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio));
> +	out_pixel->g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio));
> +	out_pixel->b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio));
> +}
> +
> +void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
> +{
> +	struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
> +	struct vkms_frame_info *frame_info = plane->frame_info;
> +	u8 *src_pixels = get_packed_src_addr(frame_info, y);
> +	int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
> +
> +	for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp)
> +		plane->pixel_read(src_pixels, &out_pixels[x]);
>   }
>   
>   /*
> @@ -249,7 +224,7 @@ static void argb_u16_to_RGB565(struct vkms_frame_info *frame_info,
>   	}
>   }
>   
> -void *get_frame_to_line_function(u32 format)
> +void *get_pixel_conversion_function(u32 format)
>   {
>   	switch (format) {
>   	case DRM_FORMAT_ARGB8888:
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
> index 43b7c1979018..c5b113495d0c 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.h
> +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> @@ -5,7 +5,7 @@
>   
>   #include "vkms_drv.h"
>   
> -void *get_frame_to_line_function(u32 format);
> +void *get_pixel_conversion_function(u32 format);
>   
>   void *get_line_to_frame_function(u32 format);
>   
> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> index c41cec7dcb70..0a23875900ec 100644
> --- a/drivers/gpu/drm/vkms/vkms_plane.c
> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> @@ -123,7 +123,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
>   	frame_info->offset = fb->offsets[0];
>   	frame_info->pitch = fb->pitches[0];
>   	frame_info->cpp = fb->format->cpp[0];
> -	vkms_plane_state->plane_read = get_frame_to_line_function(fmt);
> +	vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
>   }
>   
>   static int vkms_plane_atomic_check(struct drm_plane *plane,

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

* Re: [PATCH v4 4/6] drm/vkms: add rotate-90 property
  2023-04-18 13:05 ` [PATCH v4 4/6] drm/vkms: add rotate-90 property Maíra Canal
@ 2023-05-07 20:48   ` Melissa Wen
  0 siblings, 0 replies; 11+ messages in thread
From: Melissa Wen @ 2023-05-07 20:48 UTC (permalink / raw)
  To: Maíra Canal
  Cc: Haneen Mohammed, Rodrigo Siqueira, dri-devel, Arthur Grillo,
	Igor Matheus Andrade Torrente

On 04/18, Maíra Canal wrote:
> Currently, vkms only supports the rotate-180, reflect-x and reflect-y
> properties. Therefore, improve the vkms IGT test coverage by adding the
> rotate-90 property to vkms. The rotation was implement by software: rotate
> the way the blending occurs by making the source x axis be the destination
> y axis and the source y axis be the destination x axis.
> 
> Tested with igt@kms_rotation_crc@primary-rotation-90,
> igt@kms_rotation_crc@sprite-rotation-90, and
> igt@kms_rotation_crc@sprite-rotation-90-pos-100-0.

In the same way you did for reflect-x, could you add the link for your
IGT patchset here to avoid misunderstanding between VKMS and IGT tests
status? Double-check if it's necessary for other commits in this series.

Thanks,

Melissa

> 
> Signed-off-by: Maíra Canal <mcanal@igalia.com>
> ---
>  drivers/gpu/drm/vkms/vkms_composer.c | 21 ++++++++++++++++-----
>  drivers/gpu/drm/vkms/vkms_formats.c  |  4 ++++
>  drivers/gpu/drm/vkms/vkms_plane.c    |  2 ++
>  3 files changed, 22 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
> index 6c5ef11b3943..491850ffeac9 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> @@ -57,13 +57,24 @@ static int get_y_pos(struct vkms_frame_info *frame_info, int y)
>  {
>  	if (frame_info->rotation & DRM_MODE_REFLECT_Y)
>  		return drm_rect_height(&frame_info->rotated) - y - 1;
> -	return y;
> +
> +	switch (frame_info->rotation & DRM_MODE_ROTATE_MASK) {
> +	case DRM_MODE_ROTATE_90:
> +		return frame_info->rotated.x2 - y - 1;
> +	default:
> +		return y;
> +	}
>  }
>  
> -static bool check_y_limit(struct vkms_frame_info *frame_info, int y)
> +static bool check_limit(struct vkms_frame_info *frame_info, int pos)
>  {
> -	if (y >= frame_info->rotated.y1 && y < frame_info->rotated.y2)
> -		return true;
> +	if (frame_info->rotation & DRM_MODE_ROTATE_90) {
> +		if (pos >= 0 && pos < drm_rect_width(&frame_info->rotated))
> +			return true;
> +	} else {
> +		if (pos >= frame_info->rotated.y1 && pos < frame_info->rotated.y2)
> +			return true;
> +	}
>  
>  	return false;
>  }
> @@ -106,7 +117,7 @@ static void blend(struct vkms_writeback_job *wb,
>  		for (size_t i = 0; i < n_active_planes; i++) {
>  			y_pos = get_y_pos(plane[i]->frame_info, y);
>  
> -			if (!check_y_limit(plane[i]->frame_info, y_pos))
> +			if (!check_limit(plane[i]->frame_info, y_pos))
>  				continue;
>  
>  			vkms_compose_row(stage_buffer, plane[i], y_pos);
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
> index f59b1c48a563..f56f359e0d2d 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.c
> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> @@ -119,6 +119,10 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state
>  	for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) {
>  		int x_pos = get_x_position(frame_info, limit, x);
>  
> +		if (frame_info->rotation & DRM_MODE_ROTATE_90)
> +			src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1)
> +				+ frame_info->cpp * y;
> +
>  		plane->pixel_read(src_pixels, &out_pixels[x_pos]);
>  	}
>  }
> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> index 904a278e07d7..9e451ce97099 100644
> --- a/drivers/gpu/drm/vkms/vkms_plane.c
> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> @@ -123,6 +123,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
>  	memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
>  	drm_framebuffer_get(frame_info->fb);
>  	frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
> +						     DRM_MODE_ROTATE_90 |
>  						     DRM_MODE_REFLECT_X |
>  						     DRM_MODE_REFLECT_Y);
>  
> @@ -240,6 +241,7 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
>  
>  	drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
>  					   DRM_MODE_ROTATE_0 |
> +					   DRM_MODE_ROTATE_90 |
>  					   DRM_MODE_ROTATE_180 |
>  					   DRM_MODE_REFLECT_X |
>  					   DRM_MODE_REFLECT_Y);
> -- 
> 2.39.2
> 

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

* Re: [PATCH v4 0/6] drm/vkms: introduce plane rotation property
  2023-04-18 13:05 [PATCH v4 0/6] drm/vkms: introduce plane rotation property Maíra Canal
                   ` (5 preceding siblings ...)
  2023-04-18 13:05 ` [PATCH v4 6/6] drm/vkms: drop "Rotation" TODO Maíra Canal
@ 2023-05-07 20:54 ` Melissa Wen
  2023-05-08 13:02   ` Maíra Canal
  6 siblings, 1 reply; 11+ messages in thread
From: Melissa Wen @ 2023-05-07 20:54 UTC (permalink / raw)
  To: Maíra Canal
  Cc: Haneen Mohammed, Rodrigo Siqueira, dri-devel, Arthur Grillo,
	Igor Matheus Andrade Torrente

On 04/18, Maíra Canal wrote:
> This patchset implements all possible rotation value in vkms. All operations
> were implemented by software by changing the way the pixels are read. The way
> the blending is performed can be depicted as:
> 
> - rotate-0:
>     (x) ---->
>     ----------------------
> (y) |                    |
>   | |                    |
>   | |                    |
>   ˇ |                    |
>     ----------------------
> 
> - rotate-90:
>     <---- (y)
>     ----------------------
> (x) |                    |
>   | |                    |
>   | |                    |
>   ˇ |                    |
>     ----------------------
> 
> - rotate-180:
>     <---- (x)
>     ----------------------
> (y) |                    |
>   ^ |                    |
>   | |                    |
>   | |                    |
>     ----------------------
> 
> - rotate-270:
>     (y) ---->
>     ----------------------
> (x) |                    |
>   ^ |                    |
>   | |                    |
>   | |                    |
>     ----------------------
> 
> - reflect-x:
>     <---- (x)
>     ----------------------
> (y) |                    |
>   | |                    |
>   | |                    |
>   ˇ |                    |
>     ----------------------
> 
> - reflect-y:
>     (x) ---->
>     ----------------------
> (y) |                    |
>   ^ |                    |
>   | |                    |
>   | |                    |
>     ----------------------
> 
> The patchset was tested with IGT's kms_rotation_crc tests and also with some
> additional tests [1] for the reflection operations.
> 
> In order to avoid code duplication, I introduced a patch that isolates the
> pixel format convertion and wraps it in a single loop.
> 
> I tried to apply Ville's suggestion to avoid hand rolled coordinate
> calculation stuff. Although I couldn't apply all the code suggested by
> Ville, I was able to remove all the hardcoded code related to the x-offset.
> As VKMS' composition is performed by line, I still need to indicate the
> right pixel, which means that I still have some hardcoded code. Thanks for
> the suggestion, Ville! It really reduced the code complexity. 
> 
> v1 -> v2: https://lore.kernel.org/dri-devel/20230406130138.70752-1-mcanal@igalia.com/T/
> 
> * Add patch to isolate pixel format conversion (Arthur Grillo).
> 
> v2 -> v3: https://lore.kernel.org/dri-devel/20230414135151.75975-1-mcanal@igalia.com/T/
> 
> * Use cpp to calculate pixel size instead of hard-coding (Arthur Grillo).
> * Don't use the x coordinate in the pixel_read functions (Arthur Grillo).
> * Use drm_rotate_simplify() to avoid hard-coding rotate-180 (Ville Syrjälä).
> * Use u8* to input the src_pixels instead of using u16*.
> 
> v3 -> v4: https://lore.kernel.org/dri-devel/20230417121056.63917-1-mcanal@igalia.com/T/
> 
> * Create a original rectangle and a rotated rectangle and use the original
>   rectangle to offset the x-axis (Ville Syrjälä).
> 
> [1] https://patchwork.freedesktop.org/series/116025/

Hi Maíra,

Thanks for adding rotation properties to VKMS!
Overall, LGTM and this series is:

Reviewed-by: Melissa Wen <mwen@igalia.com>

As you already applied the first patch, not a big issue, but I see new
function documentation is missing. Could you send a follow-up patch
documenting "vkms_compose_row()"? Also, would be good to apply the same
improvement for the remaining conversion functions too.

Thanks,

Melissa

> 
> Best Regards,
> - Maíra Canal
> 
> Maíra Canal (6):
>   drm/vkms: isolate pixel conversion functionality
>   drm/vkms: add rotate-0 and reflect-x property
>   drm/vkms: add reflect-y and rotate-180 property
>   drm/vkms: add rotate-90 property
>   drm/vkms: add rotate-270 property
>   drm/vkms: drop "Rotation" TODO
> 
>  Documentation/gpu/vkms.rst           |   2 +-
>  drivers/gpu/drm/vkms/vkms_composer.c |  38 ++++++--
>  drivers/gpu/drm/vkms/vkms_drv.h      |   6 +-
>  drivers/gpu/drm/vkms/vkms_formats.c  | 139 +++++++++++++--------------
>  drivers/gpu/drm/vkms/vkms_formats.h  |   2 +-
>  drivers/gpu/drm/vkms/vkms_plane.c    |  16 ++-
>  6 files changed, 117 insertions(+), 86 deletions(-)
> 
> -- 
> 2.39.2
> 

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

* Re: [PATCH v4 0/6] drm/vkms: introduce plane rotation property
  2023-05-07 20:54 ` [PATCH v4 0/6] drm/vkms: introduce plane rotation property Melissa Wen
@ 2023-05-08 13:02   ` Maíra Canal
  0 siblings, 0 replies; 11+ messages in thread
From: Maíra Canal @ 2023-05-08 13:02 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Haneen Mohammed, Rodrigo Siqueira, dri-devel, Arthur Grillo,
	Igor Matheus Andrade Torrente

On 5/7/23 17:54, Melissa Wen wrote:
> On 04/18, Maíra Canal wrote:
>> This patchset implements all possible rotation value in vkms. All operations
>> were implemented by software by changing the way the pixels are read. The way
>> the blending is performed can be depicted as:
>>
>> - rotate-0:
>>     (x) ---->
>>     ----------------------
>> (y) |                    |
>>   | |                    |
>>   | |                    |
>>   ˇ |                    |
>>     ----------------------
>>
>> - rotate-90:
>>     <---- (y)
>>     ----------------------
>> (x) |                    |
>>   | |                    |
>>   | |                    |
>>   ˇ |                    |
>>     ----------------------
>>
>> - rotate-180:
>>     <---- (x)
>>     ----------------------
>> (y) |                    |
>>   ^ |                    |
>>   | |                    |
>>   | |                    |
>>     ----------------------
>>
>> - rotate-270:
>>     (y) ---->
>>     ----------------------
>> (x) |                    |
>>   ^ |                    |
>>   | |                    |
>>   | |                    |
>>     ----------------------
>>
>> - reflect-x:
>>     <---- (x)
>>     ----------------------
>> (y) |                    |
>>   | |                    |
>>   | |                    |
>>   ˇ |                    |
>>     ----------------------
>>
>> - reflect-y:
>>     (x) ---->
>>     ----------------------
>> (y) |                    |
>>   ^ |                    |
>>   | |                    |
>>   | |                    |
>>     ----------------------
>>
>> The patchset was tested with IGT's kms_rotation_crc tests and also with some
>> additional tests [1] for the reflection operations.
>>
>> In order to avoid code duplication, I introduced a patch that isolates the
>> pixel format convertion and wraps it in a single loop.
>>
>> I tried to apply Ville's suggestion to avoid hand rolled coordinate
>> calculation stuff. Although I couldn't apply all the code suggested by
>> Ville, I was able to remove all the hardcoded code related to the x-offset.
>> As VKMS' composition is performed by line, I still need to indicate the
>> right pixel, which means that I still have some hardcoded code. Thanks for
>> the suggestion, Ville! It really reduced the code complexity.
>> v1 -> v2: https://lore.kernel.org/dri-devel/20230406130138.70752-1-mcanal@igalia.com/T/
>>
>> * Add patch to isolate pixel format conversion (Arthur Grillo).
>>
>> v2 -> v3: https://lore.kernel.org/dri-devel/20230414135151.75975-1-mcanal@igalia.com/T/
>>
>> * Use cpp to calculate pixel size instead of hard-coding (Arthur Grillo).
>> * Don't use the x coordinate in the pixel_read functions (Arthur Grillo).
>> * Use drm_rotate_simplify() to avoid hard-coding rotate-180 (Ville Syrjälä).
>> * Use u8* to input the src_pixels instead of using u16*.
>>
>> v3 -> v4: https://lore.kernel.org/dri-devel/20230417121056.63917-1-mcanal@igalia.com/T/
>>
>> * Create a original rectangle and a rotated rectangle and use the original
>>   rectangle to offset the x-axis (Ville Syrjälä).
>>
>> [1] https://patchwork.freedesktop.org/series/116025/
> 
> Hi Maíra,
> 
> Thanks for adding rotation properties to VKMS!
> Overall, LGTM and this series is:
> 
> Reviewed-by: Melissa Wen <mwen@igalia.com>

Thanks for the review, Melissa! Applied to drm/drm-misc (drm-misc-next).

> 
> As you already applied the first patch, not a big issue, but I see new
> function documentation is missing. Could you send a follow-up patch
> documenting "vkms_compose_row()"? Also, would be good to apply the same
> improvement for the remaining conversion functions too.

I'll try to work on some follow-up patches ASAP.

Best Regards,
- Maíra Canal

> 
> Thanks,
> 
> Melissa
> 
>>
>> Best Regards,
>> - Maíra Canal
>>
>> Maíra Canal (6):
>>   drm/vkms: isolate pixel conversion functionality
>>   drm/vkms: add rotate-0 and reflect-x property
>>   drm/vkms: add reflect-y and rotate-180 property
>>   drm/vkms: add rotate-90 property
>>   drm/vkms: add rotate-270 property
>>   drm/vkms: drop "Rotation" TODO
>>
>>  Documentation/gpu/vkms.rst           |   2 +-
>>  drivers/gpu/drm/vkms/vkms_composer.c |  38 ++++++--
>>  drivers/gpu/drm/vkms/vkms_drv.h      |   6 +-
>>  drivers/gpu/drm/vkms/vkms_formats.c  | 139 +++++++++++++--------------
>>  drivers/gpu/drm/vkms/vkms_formats.h  |   2 +-
>>  drivers/gpu/drm/vkms/vkms_plane.c    |  16 ++-
>>  6 files changed, 117 insertions(+), 86 deletions(-)
>>
>> -- 
>> 2.39.2
>>

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

end of thread, other threads:[~2023-05-08 13:02 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-18 13:05 [PATCH v4 0/6] drm/vkms: introduce plane rotation property Maíra Canal
2023-04-18 13:05 ` [PATCH v4 1/6] drm/vkms: isolate pixel conversion functionality Maíra Canal
2023-04-24 21:22   ` Maíra Canal
2023-04-18 13:05 ` [PATCH v4 2/6] drm/vkms: add rotate-0 and reflect-x property Maíra Canal
2023-04-18 13:05 ` [PATCH v4 3/6] drm/vkms: add reflect-y and rotate-180 property Maíra Canal
2023-04-18 13:05 ` [PATCH v4 4/6] drm/vkms: add rotate-90 property Maíra Canal
2023-05-07 20:48   ` Melissa Wen
2023-04-18 13:05 ` [PATCH v4 5/6] drm/vkms: add rotate-270 property Maíra Canal
2023-04-18 13:05 ` [PATCH v4 6/6] drm/vkms: drop "Rotation" TODO Maíra Canal
2023-05-07 20:54 ` [PATCH v4 0/6] drm/vkms: introduce plane rotation property Melissa Wen
2023-05-08 13:02   ` Maíra Canal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).