* [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading
@ 2024-10-07 16:10 Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 01/15] drm/vkms: Code formatting Louis Chauvet
` (14 more replies)
0 siblings, 15 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen, Maíra Canal
This patchset is the second version of [1]. It is almost a complete
rewrite to use a line-by-line algorithm for the composition.
During the development of this series Pekka and Arthur found an issue in
drm core. The YUV part of this series depend on the fix [9]. I'll let
Arthur extract it and submit a new independant patch.
It can be divided in three parts:
- PATCH 1 to 3: no functional change is intended, only some formatting and
documenting (PATCH 2 is taken from [2])
- PATCH 4 to 7: Some preparation work not directly related to the
line-by-line algorithm
- PATCH 8: main patch for this series, it reintroduce the
line-by-line algorithm
- PATCH 9: Remove useless drm_simplify_rotation
- PATCH 10 to 14: taken from Arthur's series [2], with sometimes
adaptation to use the pixel-by-pixel algorithm.
- PATCH 15: Introduce the support for DRM_FORMAT_R1/2/4/8
The PATCH 8 aims to restore the line-by-line pixel reading algorithm. It
was introduced in 8ba1648567e2 ("drm: vkms: Refactor the plane composer to
accept new formats") but removed in 8ba1648567e2 ("drm: vkms: Refactor the
plane composer to accept new formats") in a over-simplification effort.
At this time, nobody noticed the performance impact of this commit. After
the first iteration of my series, poeple notice performance impact, and it
was the case. Pekka suggested to reimplement the line-by-line algorithm.
Expiriments on my side shown great improvement for the line-by-line
algorithm, and the performances are the same as the original line-by-line
algorithm. I targeted my effort to make the code working for all the
rotations and translations. The usage of helpers from drm_rect_* avoid
reimplementing existing logic.
The only "complex" part remaining is the clipping of the coordinate to
avoid reading/writing outside of src/dst. Thus I added a lot of comments
to help when someone will want to add some features (framebuffer resizing
for example).
The YUV part is not mandatory for this series, but as my first effort was
to help the integration of YUV, I decided to rebase Arthur's series on
mine to help. I took [3], [4], [5] and [6] and adapted them to use the
line-by-line reading. They were also updated to use 32.32 fixed point
values for yuv conversion instead of 8.8 fixed points.
The last patch of this series introduce DRM_FORMAT_R1/2/4/8 to show how
the PATCH 7/16 can be used to manage packed pixel formats.
To properly test the rotation algorithm, I had to implement a new IGT
test [8]. This helped to found one issue in the YUV rotation algortihm.
My series was mainly tested with:
- kms_plane (for color conversions)
- kms_rotation_crc (for a subset of rotation and formats)
- kms_rotation (to test all rotation and formats combinations) [8]
- kms_cursor_crc (for translations)
The benchmark used to measure the improvment was done with
kms_fb_stress [10] with some modifications:
- Fixing the writeback format to XRGB8888
- Using a primary plane with odd dimension to avoid failures due to YUV
alignment
The KMS structure was:
CRTC:
rectangle: 4096x2160+0+0
primary:
format: ABGR16161616
rectangle: 3640x2160+101+0
writeback:
format: XRGB8888
rectangle: 4096x2160+0+0
Results (on my computer):
8356b9790650: drm/test: Add test cases for drm_rect_rotate_inv() (before any regression)
322d716a3e8a: drm/vkms: isolate pixel conversion functionality (first regression)
cc4fd2934d41: drm/vkms: Isolate writeback pixel conversion functions (second regression)
2c3d1bd284c5: drm/panel: simple: Add Microtips Technology MF-103HIEB0GA0 panel (current drm-misc-next)
Used format | This series | 2c3d1bd284c5 | cc4fd2934d41 | 322d716a3e8a | 8356b9790650 |
--------------+-------------+--------------+--------------+--------------+--------------+
XRGB8888 | 13.261666s | 14.289582s | 10.731272s | 9.480001s | 9.277507s |
XRGB16161616 | 13.282479s | 13.918926s | 10.712616s | 9.776903s | 9.291766s |
RGB565 | 136.154163s | 141.646489s | 101.744050s | 103.712164s | 87.860923s |
This is a 5-10% improvment of the performance. More work need to be done
on the writeback to gain more.
[1]: https://lore.kernel.org/all/20240201-yuv-v1-0-3ca376f27632@bootlin.com
[2]: https://lore.kernel.org/all/20240110-vkms-yuv-v2-0-952fcaa5a193@riseup.net/
[3]: https://lore.kernel.org/all/20240110-vkms-yuv-v2-3-952fcaa5a193@riseup.net/
[4]: https://lore.kernel.org/all/20240110-vkms-yuv-v2-5-952fcaa5a193@riseup.net/
[5]: https://lore.kernel.org/all/20240110-vkms-yuv-v2-6-952fcaa5a193@riseup.net/
[6]: https://lore.kernel.org/all/20240110-vkms-yuv-v2-7-952fcaa5a193@riseup.net/
[8]: https://lore.kernel.org/r/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com
[9]: https://lore.kernel.org/dri-devel/20240306-louis-vkms-conv-v1-1-5bfe7d129fdd@riseup.net/
[10]: https://lore.kernel.org/all/20240422-kms_fb_stress-dev-v5-0-0c577163dc88@riseup.net/
To: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
To: Melissa Wen <melissa.srw@gmail.com>
To: Maíra Canal <mairacanal@riseup.net>
To: Haneen Mohammed <hamohammed.sa@gmail.com>
To: Daniel Vetter <daniel@ffwll.ch>
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: Maxime Ripard <mripard@kernel.org>
To: Thomas Zimmermann <tzimmermann@suse.de>
To: David Airlie <airlied@gmail.com>
To: rdunlap@infradead.org
To: arthurgrillo@riseup.net
To: Jonathan Corbet <corbet@lwn.net>
To: pekka.paalanen@haloniitty.fi
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Cc: jeremie.dautheribes@bootlin.com
Cc: miquel.raynal@bootlin.com
Cc: thomas.petazzoni@bootlin.com
Cc: seanpaul@google.com
Cc: marcheu@google.com
Cc: nicolejadeyee@google.com
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Note: after my changes, those tests seems to pass, so [7] may need
updating (I did not check, it was maybe already the case):
- kms_cursor_legacy@flip-vs-cursor-atomic
- kms_pipe_crc_basic@nonblocking-crc
- kms_pipe_crc_basic@nonblocking-crc-frame-sequence
- kms_writeback@writeback-pixel-formats
- kms_writeback@writeback-invalid-parameters
- kms_flip@flip-vs-absolute-wf_vblank-interruptible
And those tests pass, I did not investigate why the runners fails:
- kms_flip@flip-vs-expired-vblank-interruptible
- kms_flip@flip-vs-expired-vblank
- kms_flip@plain-flip-fb-recreate
- kms_flip@plain-flip-fb-recreate-interruptible
- kms_flip@plain-flip-ts-check-interruptible
- kms_cursor_legacy@cursorA-vs-flipA-toggle
- kms_pipe_crc_basic@nonblocking-crc
- kms_prop_blob@invalid-get-prop
- kms_flip@flip-vs-absolute-wf_vblank-interruptible
- kms_invalid_mode@zero-hdisplay
- kms_invalid_mode@bad-vtotal
- kms_cursor_crc.* (everything is SUCCEED or SKIP, except for
rapid_movement)
[7]: https://lore.kernel.org/all/20240201065346.801038-1-vignesh.raman@collabora.com/
Changes in v12:
- Fix documentation issues as suggested by Randy
- Link to v11: https://lore.kernel.org/r/20240930-yuv-v11-0-4b1a26bcfc96@bootlin.com
Changes in v11:
- Remove documentation patch (already merged)
- Fix sparse warning about documentation
- Link to v10: https://lore.kernel.org/r/20240809-yuv-v10-0-1a7c764166f7@bootlin.com
Changes in v10:
- Properly remove the patch introducing dummy read/write functions
- PATCH 8/16: Format fixups
- PATCH 9/16: Format fixups
- PATCH 11/16: Format fixups
- PATCH 14/16: Fix test compilation, add module description
- Link to v9: https://lore.kernel.org/r/20240802-yuv-v9-0-08a706669e16@bootlin.com
Changes in v9:
- PATCH 3/17: Fix docs as Maíra suggested
- PATCH 4,6,10,12,15,17/17: Fix sparse warning about __le16 casting
- Link to v8: https://lore.kernel.org/all/20240516-yuv-v8-0-cf8d6f86430e@bootlin.com/
Changes in v8:
- PATCH 7/17: Update pitch access to use the proper value for block
formats
- PATCH 9/17: Update pitch access to use the proper value for block
formats
- Link to v7: https://lore.kernel.org/r/20240513-yuv-v7-0-380e9ffec502@bootlin.com
Changes in v7:
- Some typos and indent fixes
- Add Review-By, Acked-By
- PATCH 3/17: Clarify src/dst unit
- PATCH 9/17: Clarify documentation
- PATCH 9/17: Restrict conditions for direction
- PATCH 9/17: Rename get_block_step_byte to get_block_step_bytes
- PATCH 10/17: Clarify kernel doc for clamp_line_coordinates, blend_line,
pixel_read_line_t
- PATCH 10/17: Fix the case when src_*_start >= fb->width/height
- PATCH 10/17: Change y in blend to be an int
- PATCH 10/17: Clarify documentation for read functions
- PATCH 12/17: Fix the type of rgb variables in argb_u16_from_yuv888
- PATCH 12/17: Move comments at the right place, remove useless ones
- PATCH 12/17: Add missing const
- PATCH 17/17: Use drm_format_info_bpp and computation to avoid hard-coded
values
- Link to v6: https://lore.kernel.org/r/20240409-yuv-v6-0-de1c5728fd70@bootlin.com
Changes in v6:
- Add Randy
- Add Review-By and Acked-By
- PATCH 2/17: Remove useless newline
- PATCH 3/17: Fix kernel doc
- PATCH 4/17: Fix typo in git commit
- PATCH 4/17: Fix kernel doc and simplify brief description of typedef
- PATCH 5/17: Change black default color to Magenta
- PATCH 5/17: Fix wording in comment
- PATCH 7/17: Fix typo in packed_pixel_offset
- PATCH 7/17: Add WARN_ON for currently not supported formats
- PATCH 8/17: Rename x_limit to pixel_count
- PATCH 8/17: Clarify kernel doc for pre_mul_alpha_blend
- PATCH 9/17: Rename get_step_next_block to get_block_step_bytes
- PATCH 9/17: Change kernel doc order
- PATCH 9/17: Rework the direction_for_rotation function to use drm
helpers
- PATCH 9/17: Add a warn in direction_for_rotation if the result is not
expected
- PATCH 10/17: Reword the comment of pixel color conversion functions
- PATCH 10/17: Refactor the blending function to extract functions
- PATCH 11/17: Remove useless drm_rotation_simplify
- PATCH 12/17: Fix typo in comments
- PATCH 12/17: Remove useless define
- PATCH 12/17: Fix some comments typo and kernel doc
- PATCH 12/17: Add a comma at the end of the vkms_formats list
- PATCH 12/17: Use copy of matrix instead of pointers
- PATCH 12/17: Use 16 bit range for yuv conversion
- PATCH 17/17: Add a comma at the end of the vkms_formats list
- PATCH 17/17: Add assertions
- PATCH 17/17: Fix color conversion... Next time I will read the doc
twice...
- Link to v5: https://lore.kernel.org/r/20240313-yuv-v5-0-e610cbd03f52@bootlin.com
Changes in v5:
- All patches: fix some formatting issues
- PATCH 4/16: Use the correct formatter for 4cc code
- PATCH 7/16: Update the pixel accessors to also return the pixel position
inside a block.
- PATCH 8/16: Fix a temporary bug
- PATCH 9/16: Update the get_step_1x1 to get_step_next_block and update
the documentation
- PATCH 10/16: Update to uses the new pixel accessors
- PATCH 10/16: Reword some comments
- PATCH 11/16: Update to use the new pixel accessors
- PATCH 11/16: Fix a bug in the subsampling offset for inverted reading
(right to left/bottom to top). Found by [8].
- PATCH 11/16: Apply Arthur's modifications (comments, algorithm
clarification)
- PATCH 11/16: Use the correct formatter for 4cc code
- PATCH 11/16: Update to use the new get_step_next_block
- PATCH 14/16: Apply Arthur's modification (comments, compilation issue)
- PATCH 15/16: Add Arthur's patch to explain the kunit tests
- PATCH 16/16: Introduce DRM_FORMAT_R* support.
- Link to v4: https://lore.kernel.org/r/20240304-yuv-v4-0-76beac8e9793@bootlin.com
Changes in v4:
- PATCH 3/14: Update comments for get_pixel_* functions
- PATCH 4/14: Add WARN when trying to get unsupported pixel_* functions
- PATCH 5/14: Create dummy pixel reader/writer to avoid NULL
function pointers and kernel OOPS
- PATCH 6/14: Added the usage of const pointers when needed
- PATCH 7/14: Extraction of pixel accessors modification
- PATCH 8/14: Extraction of the blending function modification
- PATCH 9/14: Extraction of the pixel_read_direction enum
- PATCH 10/14: Update direction_for_rotation documentation
- PATCH 10/14: Rename conversion functions to be explicit
- PATCH 10/14: Replace while(count) by while(out_pixel<end) in read_line
callbacks. It avoid a new variable+addition in the composition hot path.
- PATCH 11/14: Rename conversion functions to be explicit
- PATCH 11/14: Update the documentation for get_subsampling_offset
- PATCH 11/14: Add the matrix_conversion structure to remove a test from
the hot path.
- PATCH 11/14: Upadate matrix values to use 32.32 fixed floats for
conversion
- PATCH 12/14: Update commit message
- PATCH 14/14: Change kunit expected value
- Link to v3: https://lore.kernel.org/r/20240226-yuv-v3-0-ff662f0994db@bootlin.com
Changes in v3:
- Correction of remaining git-rebase artefacts
- Added Pekka in copy of this patch
- Link to v2: https://lore.kernel.org/r/20240223-yuv-v2-0-aa6be2827bb7@bootlin.com
Changes in v2:
- Rebased the series on top of drm-misc/drm-misc-net
- Extract the typedef for pixel_read/pixel_write
- Introduce the line-by-line algorithm per pixel format
- Add some documentation for existing and new code
- Port the series [1] to use line-by-line algorithm
- Link to v1: https://lore.kernel.org/r/20240201-yuv-v1-0-3ca376f27632@bootlin.com
---
Arthur Grillo (6):
drm/vkms: Use drm_frame directly
drm/vkms: Add YUV support
drm/vkms: Add range and encoding properties to the plane
drm/vkms: Drop YUV formats TODO
drm/vkms: Create KUnit tests for YUV conversions
drm/vkms: Add how to run the Kunit tests
Louis Chauvet (9):
drm/vkms: Code formatting
drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions
drm/vkms: Use const for input pointers in pixel_read an pixel_write functions
drm/vkms: Update pixels accessor to support packed and multi-plane formats.
drm/vkms: Avoid computing blending limits inside pre_mul_alpha_blend
drm/vkms: Introduce pixel_read_direction enum
drm/vkms: Re-introduce line-per-line composition algorithm
drm/vkms: Remove useless drm_rotation_simplify
drm/vkms: Add support for DRM_FORMAT_R*
Documentation/gpu/vkms.rst | 14 +-
drivers/gpu/drm/vkms/Kconfig | 15 +
drivers/gpu/drm/vkms/Makefile | 1 +
drivers/gpu/drm/vkms/tests/.kunitconfig | 4 +
drivers/gpu/drm/vkms/tests/Makefile | 3 +
drivers/gpu/drm/vkms/tests/vkms_format_test.c | 232 +++++++
drivers/gpu/drm/vkms/vkms_composer.c | 312 +++++++--
drivers/gpu/drm/vkms/vkms_crtc.c | 6 +-
drivers/gpu/drm/vkms/vkms_drv.c | 3 +-
drivers/gpu/drm/vkms/vkms_drv.h | 73 ++-
drivers/gpu/drm/vkms/vkms_formats.c | 873 ++++++++++++++++++++++----
drivers/gpu/drm/vkms/vkms_formats.h | 13 +-
drivers/gpu/drm/vkms/vkms_plane.c | 46 +-
drivers/gpu/drm/vkms/vkms_writeback.c | 5 -
14 files changed, 1374 insertions(+), 226 deletions(-)
---
base-commit: 82fe69e63d2b5a5e86ea94c7361c833d3848ab69
change-id: 20240201-yuv-1337d90d9576
Best regards,
--
Louis Chauvet <louis.chauvet@bootlin.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v12 01/15] drm/vkms: Code formatting
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 02/15] drm/vkms: Use drm_frame directly Louis Chauvet
` (13 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen, Maíra Canal
Few no-op changes to remove double spaces and fix wrong alignments.
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_composer.c | 10 +++++-----
drivers/gpu/drm/vkms/vkms_crtc.c | 6 ++----
drivers/gpu/drm/vkms/vkms_drv.c | 3 +--
drivers/gpu/drm/vkms/vkms_plane.c | 8 ++++----
4 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 57a5769fc994..931e214b225c 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -96,7 +96,7 @@ static u16 lerp_u16(u16 a, u16 b, s64 t)
s64 a_fp = drm_int2fixp(a);
s64 b_fp = drm_int2fixp(b);
- s64 delta = drm_fixp_mul(b_fp - a_fp, t);
+ s64 delta = drm_fixp_mul(b_fp - a_fp, t);
return drm_fixp2int(a_fp + delta);
}
@@ -309,8 +309,8 @@ static int compose_active_planes(struct vkms_writeback_job *active_wb,
void vkms_composer_worker(struct work_struct *work)
{
struct vkms_crtc_state *crtc_state = container_of(work,
- struct vkms_crtc_state,
- composer_work);
+ struct vkms_crtc_state,
+ composer_work);
struct drm_crtc *crtc = crtc_state->base.crtc;
struct vkms_writeback_job *active_wb = crtc_state->active_writeback;
struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
@@ -335,7 +335,7 @@ void vkms_composer_worker(struct work_struct *work)
crtc_state->gamma_lut.base = (struct drm_color_lut *)crtc->state->gamma_lut->data;
crtc_state->gamma_lut.lut_length =
crtc->state->gamma_lut->length / sizeof(struct drm_color_lut);
- max_lut_index_fp = drm_int2fixp(crtc_state->gamma_lut.lut_length - 1);
+ max_lut_index_fp = drm_int2fixp(crtc_state->gamma_lut.lut_length - 1);
crtc_state->gamma_lut.channel_value2index_ratio = drm_fixp_div(max_lut_index_fp,
u16_max_fp);
@@ -374,7 +374,7 @@ void vkms_composer_worker(struct work_struct *work)
drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32);
}
-static const char * const pipe_crc_sources[] = {"auto"};
+static const char *const pipe_crc_sources[] = { "auto" };
const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
size_t *count)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index a40295c18b48..39bf9d4247fa 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -188,8 +188,7 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
return ret;
drm_for_each_plane_mask(plane, crtc->dev, crtc_state->plane_mask) {
- plane_state = drm_atomic_get_existing_plane_state(crtc_state->state,
- plane);
+ plane_state = drm_atomic_get_existing_plane_state(crtc_state->state, plane);
WARN_ON(!plane_state);
if (!plane_state->visible)
@@ -205,8 +204,7 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
i = 0;
drm_for_each_plane_mask(plane, crtc->dev, crtc_state->plane_mask) {
- plane_state = drm_atomic_get_existing_plane_state(crtc_state->state,
- plane);
+ plane_state = drm_atomic_get_existing_plane_state(crtc_state->state, plane);
if (!plane_state->visible)
continue;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 2d1e95cb66e5..19b7322ce49d 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -82,8 +82,7 @@ static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state)
drm_atomic_helper_wait_for_flip_done(dev, old_state);
for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
- struct vkms_crtc_state *vkms_state =
- to_vkms_crtc_state(old_crtc_state);
+ struct vkms_crtc_state *vkms_state = to_vkms_crtc_state(old_crtc_state);
flush_work(&vkms_state->composer_work);
}
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index e5c625ab8e3e..5a8d295e65f2 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -117,10 +117,10 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
drm_framebuffer_get(frame_info->fb);
frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
- DRM_MODE_ROTATE_90 |
- DRM_MODE_ROTATE_270 |
- DRM_MODE_REFLECT_X |
- DRM_MODE_REFLECT_Y);
+ DRM_MODE_ROTATE_90 |
+ DRM_MODE_ROTATE_270 |
+ DRM_MODE_REFLECT_X |
+ DRM_MODE_REFLECT_Y);
drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
drm_rect_height(&frame_info->rotated), frame_info->rotation);
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 02/15] drm/vkms: Use drm_frame directly
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 01/15] drm/vkms: Code formatting Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 03/15] drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions Louis Chauvet
` (12 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen, Maíra Canal
From: Arthur Grillo <arthurgrillo@riseup.net>
Remove intermidiary variables and access the variables directly from
drm_frame. These changes should be noop.
Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
[Louis Chauvet: Applied review from Maíra]
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_drv.h | 3 ---
drivers/gpu/drm/vkms/vkms_formats.c | 11 ++++++-----
drivers/gpu/drm/vkms/vkms_plane.c | 3 ---
drivers/gpu/drm/vkms/vkms_writeback.c | 5 -----
4 files changed, 6 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 672fe191e239..fcb5a5ff7df7 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -42,9 +42,6 @@ struct vkms_frame_info {
struct drm_rect rotated;
struct iosys_map map[DRM_FORMAT_MAX_PLANES];
unsigned int rotation;
- unsigned int offset;
- unsigned int pitch;
- unsigned int cpp;
};
struct pixel_argb_u16 {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index e8a5cc235ebb..2a0fbe27d8b2 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -23,8 +23,9 @@
*/
static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int y)
{
- return frame_info->offset + (y * frame_info->pitch)
- + (x * frame_info->cpp);
+ struct drm_framebuffer *fb = frame_info->fb;
+
+ return fb->offsets[0] + (y * fb->pitches[0]) + (x * fb->format->cpp[0]);
}
/**
@@ -154,12 +155,12 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state
u8 *src_pixels = get_packed_src_addr(frame_info, y);
int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
- for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) {
+ for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) {
int x_pos = get_x_position(frame_info, limit, x);
if (drm_rotation_90_or_270(frame_info->rotation))
src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1)
- + frame_info->cpp * y;
+ + frame_info->fb->format->cpp[0] * y;
plane->pixel_read(src_pixels, &out_pixels[x_pos]);
}
@@ -253,7 +254,7 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
struct pixel_argb_u16 *in_pixels = src_buffer->pixels;
int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), src_buffer->n_pixels);
- for (size_t x = 0; x < x_limit; x++, dst_pixels += frame_info->cpp)
+ for (size_t x = 0; x < x_limit; x++, dst_pixels += frame_info->fb->format->cpp[0])
wb->pixel_write(dst_pixels, &in_pixels[x]);
}
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 5a8d295e65f2..21b5adfb44aa 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -125,9 +125,6 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
drm_rect_height(&frame_info->rotated), frame_info->rotation);
- frame_info->offset = fb->offsets[0];
- frame_info->pitch = fb->pitches[0];
- frame_info->cpp = fb->format->cpp[0];
vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
}
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c
index bc724cbd5e3a..c8582df1f739 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -149,11 +149,6 @@ static void vkms_wb_atomic_commit(struct drm_connector *conn,
crtc_state->active_writeback = active_wb;
crtc_state->wb_pending = true;
spin_unlock_irq(&output->composer_lock);
-
- wb_frame_info->offset = fb->offsets[0];
- wb_frame_info->pitch = fb->pitches[0];
- wb_frame_info->cpp = fb->format->cpp[0];
-
drm_writeback_queue_job(wb_conn, connector_state);
active_wb->pixel_write = get_pixel_write_function(wb_format);
drm_rect_init(&wb_frame_info->src, 0, 0, crtc_width, crtc_height);
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 03/15] drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 01/15] drm/vkms: Code formatting Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 02/15] drm/vkms: Use drm_frame directly Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 04/15] drm/vkms: Use const for input pointers in pixel_read an " Louis Chauvet
` (11 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen
Introduce two typedefs: pixel_read_t and pixel_write_t. It allows the
compiler to check if the passed functions take the correct arguments.
Such typedefs will help ensuring consistency across the code base in
case of update of these prototypes.
Rename input/output variable in a consistent way between read_line and
write_line.
A warn has been added in get_pixel_*_function to alert when an unsupported
pixel format is requested. As those formats are checked before
atomic_update callbacks, it should never happen.
Document for those typedefs.
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_drv.h | 23 ++++++-
drivers/gpu/drm/vkms/vkms_formats.c | 124 ++++++++++++++++++++----------------
drivers/gpu/drm/vkms/vkms_formats.h | 4 +-
drivers/gpu/drm/vkms/vkms_plane.c | 2 +-
4 files changed, 94 insertions(+), 59 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index fcb5a5ff7df7..e0d46defed83 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -53,12 +53,31 @@ struct line_buffer {
struct pixel_argb_u16 *pixels;
};
+/**
+ * typedef pixel_write_t - These functions are used to read a pixel from a
+ * &struct pixel_argb_u16, convert it in a specific format and write it in the @out_pixel
+ * buffer.
+ *
+ * @out_pixel: destination address to write the pixel
+ * @in_pixel: pixel to write
+ */
+typedef void (*pixel_write_t)(u8 *out_pixel, struct pixel_argb_u16 *in_pixel);
+
struct vkms_writeback_job {
struct iosys_map data[DRM_FORMAT_MAX_PLANES];
struct vkms_frame_info wb_frame_info;
- void (*pixel_write)(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel);
+ pixel_write_t pixel_write;
};
+/**
+ * typedef pixel_read_t - These functions are used to read a pixel in the source frame,
+ * convert it to `struct pixel_argb_u16` and write it to @out_pixel.
+ *
+ * @in_pixel: pointer to the pixel to read
+ * @out_pixel: pointer to write the converted pixel
+ */
+typedef void (*pixel_read_t)(u8 *in_pixel, struct pixel_argb_u16 *out_pixel);
+
/**
* struct vkms_plane_state - Driver specific plane state
* @base: base plane state
@@ -69,7 +88,7 @@ struct vkms_writeback_job {
struct vkms_plane_state {
struct drm_shadow_plane_state base;
struct vkms_frame_info *frame_info;
- void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel);
+ pixel_read_t pixel_read;
};
struct vkms_plane {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index 2a0fbe27d8b2..b9544e67cd4f 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -75,7 +75,7 @@ static int get_x_position(const struct vkms_frame_info *frame_info, int limit, i
* They are used in the vkms_compose_row() function to handle multiple formats.
*/
-static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
/*
* The 257 is the "conversion ratio". This number is obtained by the
@@ -83,48 +83,48 @@ static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixe
* the best color value in a pixel format with more possibilities.
* A similar idea applies to others RGB color conversions.
*/
- out_pixel->a = (u16)src_pixels[3] * 257;
- out_pixel->r = (u16)src_pixels[2] * 257;
- out_pixel->g = (u16)src_pixels[1] * 257;
- out_pixel->b = (u16)src_pixels[0] * 257;
+ out_pixel->a = (u16)in_pixel[3] * 257;
+ out_pixel->r = (u16)in_pixel[2] * 257;
+ out_pixel->g = (u16)in_pixel[1] * 257;
+ out_pixel->b = (u16)in_pixel[0] * 257;
}
-static void XRGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
out_pixel->a = (u16)0xffff;
- out_pixel->r = (u16)src_pixels[2] * 257;
- out_pixel->g = (u16)src_pixels[1] * 257;
- out_pixel->b = (u16)src_pixels[0] * 257;
+ out_pixel->r = (u16)in_pixel[2] * 257;
+ out_pixel->g = (u16)in_pixel[1] * 257;
+ out_pixel->b = (u16)in_pixel[0] * 257;
}
-static void ARGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
- __le16 *pixels = (__force __le16 *)src_pixels;
+ __le16 *pixel = (__le16 *)in_pixel;
- out_pixel->a = le16_to_cpu(pixels[3]);
- out_pixel->r = le16_to_cpu(pixels[2]);
- out_pixel->g = le16_to_cpu(pixels[1]);
- out_pixel->b = le16_to_cpu(pixels[0]);
+ out_pixel->a = le16_to_cpu(pixel[3]);
+ out_pixel->r = le16_to_cpu(pixel[2]);
+ out_pixel->g = le16_to_cpu(pixel[1]);
+ out_pixel->b = le16_to_cpu(pixel[0]);
}
-static void XRGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+static void XRGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
- __le16 *pixels = (__force __le16 *)src_pixels;
+ __le16 *pixel = (__le16 *)in_pixel;
out_pixel->a = (u16)0xffff;
- out_pixel->r = le16_to_cpu(pixels[2]);
- out_pixel->g = le16_to_cpu(pixels[1]);
- out_pixel->b = le16_to_cpu(pixels[0]);
+ out_pixel->r = le16_to_cpu(pixel[2]);
+ out_pixel->g = le16_to_cpu(pixel[1]);
+ out_pixel->b = le16_to_cpu(pixel[0]);
}
-static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+static void RGB565_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
- __le16 *pixels = (__force __le16 *)src_pixels;
+ __le16 *pixel = (__le16 *)in_pixel;
s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
- u16 rgb_565 = le16_to_cpu(*pixels);
+ u16 rgb_565 = le16_to_cpu(*pixel);
s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
@@ -168,12 +168,12 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state
/*
* The following functions take one &struct pixel_argb_u16 and convert it to a specific format.
- * The result is stored in @dst_pixels.
+ * The result is stored in @out_pixel.
*
* They are used in vkms_writeback_row() to convert and store a pixel from the src_buffer to
* the writeback buffer.
*/
-static void argb_u16_to_ARGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_ARGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
{
/*
* This sequence below is important because the format's byte order is
@@ -185,43 +185,43 @@ static void argb_u16_to_ARGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel
* | Addr + 2 | = Red channel
* | Addr + 3 | = Alpha channel
*/
- dst_pixels[3] = DIV_ROUND_CLOSEST(in_pixel->a, 257);
- dst_pixels[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257);
- dst_pixels[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257);
- dst_pixels[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257);
+ out_pixel[3] = DIV_ROUND_CLOSEST(in_pixel->a, 257);
+ out_pixel[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257);
+ out_pixel[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257);
+ out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257);
}
-static void argb_u16_to_XRGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_XRGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
{
- dst_pixels[3] = 0xff;
- dst_pixels[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257);
- dst_pixels[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257);
- dst_pixels[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257);
+ out_pixel[3] = 0xff;
+ out_pixel[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257);
+ out_pixel[1] = DIV_ROUND_CLOSEST(in_pixel->g, 257);
+ out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257);
}
-static void argb_u16_to_ARGB16161616(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_ARGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
{
- __le16 *pixels = (__force __le16 *)dst_pixels;
+ __le16 *pixel = (__le16 *)out_pixel;
- pixels[3] = cpu_to_le16(in_pixel->a);
- pixels[2] = cpu_to_le16(in_pixel->r);
- pixels[1] = cpu_to_le16(in_pixel->g);
- pixels[0] = cpu_to_le16(in_pixel->b);
+ pixel[3] = cpu_to_le16(in_pixel->a);
+ pixel[2] = cpu_to_le16(in_pixel->r);
+ pixel[1] = cpu_to_le16(in_pixel->g);
+ pixel[0] = cpu_to_le16(in_pixel->b);
}
-static void argb_u16_to_XRGB16161616(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_XRGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
{
- __le16 *pixels = (__force __le16 *)dst_pixels;
+ __le16 *pixel = (__le16 *)out_pixel;
- pixels[3] = cpu_to_le16(0xffff);
- pixels[2] = cpu_to_le16(in_pixel->r);
- pixels[1] = cpu_to_le16(in_pixel->g);
- pixels[0] = cpu_to_le16(in_pixel->b);
+ pixel[3] = cpu_to_le16(0xffff);
+ pixel[2] = cpu_to_le16(in_pixel->r);
+ pixel[1] = cpu_to_le16(in_pixel->g);
+ pixel[0] = cpu_to_le16(in_pixel->b);
}
-static void argb_u16_to_RGB565(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_RGB565(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
{
- __le16 *pixels = (__force __le16 *)dst_pixels;
+ __le16 *pixel = (__le16 *)out_pixel;
s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
@@ -234,7 +234,7 @@ static void argb_u16_to_RGB565(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel)
u16 g = drm_fixp2int(drm_fixp_div(fp_g, fp_g_ratio));
u16 b = drm_fixp2int(drm_fixp_div(fp_b, fp_rb_ratio));
- *pixels = cpu_to_le16(r << 11 | g << 5 | b);
+ *pixel = cpu_to_le16(r << 11 | g << 5 | b);
}
/**
@@ -259,13 +259,13 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
}
/**
- * get_pixel_conversion_function() - Retrieve the correct read_pixel function for a specific
+ * get_pixel_read_function() - Retrieve the correct read_pixel function for a specific
* format. The returned pointer is NULL for unsupported pixel formats. The caller must ensure that
* the pointer is valid before using it in a vkms_plane_state.
*
* @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h])
*/
-void *get_pixel_conversion_function(u32 format)
+pixel_read_t get_pixel_read_function(u32 format)
{
switch (format) {
case DRM_FORMAT_ARGB8888:
@@ -279,7 +279,15 @@ void *get_pixel_conversion_function(u32 format)
case DRM_FORMAT_RGB565:
return &RGB565_to_argb_u16;
default:
- return NULL;
+ /*
+ * This is a bug in vkms_plane_atomic_check(). All the supported
+ * format must:
+ * - Be listed in vkms_formats in vkms_plane.c
+ * - Have a pixel_read callback defined here
+ */
+ pr_err("Pixel format %p4cc is not supported by VKMS planes. This is a kernel bug, atomic check must forbid this configuration.\n",
+ &format);
+ BUG();
}
}
@@ -290,7 +298,7 @@ void *get_pixel_conversion_function(u32 format)
*
* @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h])
*/
-void *get_pixel_write_function(u32 format)
+pixel_write_t get_pixel_write_function(u32 format)
{
switch (format) {
case DRM_FORMAT_ARGB8888:
@@ -304,6 +312,14 @@ void *get_pixel_write_function(u32 format)
case DRM_FORMAT_RGB565:
return &argb_u16_to_RGB565;
default:
- return NULL;
+ /*
+ * This is a bug in vkms_writeback_atomic_check. All the supported
+ * format must:
+ * - Be listed in vkms_wb_formats in vkms_writeback.c
+ * - Have a pixel_write callback defined here
+ */
+ pr_err("Pixel format %p4cc is not supported by VKMS writeback. This is a kernel bug, atomic check must forbid this configuration.\n",
+ &format);
+ BUG();
}
}
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
index cf59c2ed8e9a..3ecea4563254 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -5,8 +5,8 @@
#include "vkms_drv.h"
-void *get_pixel_conversion_function(u32 format);
+pixel_read_t get_pixel_read_function(u32 format);
-void *get_pixel_write_function(u32 format);
+pixel_write_t get_pixel_write_function(u32 format);
#endif /* _VKMS_FORMATS_H_ */
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 21b5adfb44aa..10e9b23dab28 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -125,7 +125,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
drm_rect_height(&frame_info->rotated), frame_info->rotation);
- vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
+ vkms_plane_state->pixel_read = get_pixel_read_function(fmt);
}
static int vkms_plane_atomic_check(struct drm_plane *plane,
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 04/15] drm/vkms: Use const for input pointers in pixel_read an pixel_write functions
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (2 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 03/15] drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 05/15] drm/vkms: Update pixels accessor to support packed and multi-plane formats Louis Chauvet
` (10 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen, Maíra Canal
As the pixel_read and pixel_write function should never modify the input
buffer, mark those pointers const.
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_drv.h | 4 ++--
drivers/gpu/drm/vkms/vkms_formats.c | 20 ++++++++++----------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index e0d46defed83..3f45290a0c5d 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -61,7 +61,7 @@ struct line_buffer {
* @out_pixel: destination address to write the pixel
* @in_pixel: pixel to write
*/
-typedef void (*pixel_write_t)(u8 *out_pixel, struct pixel_argb_u16 *in_pixel);
+typedef void (*pixel_write_t)(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel);
struct vkms_writeback_job {
struct iosys_map data[DRM_FORMAT_MAX_PLANES];
@@ -76,7 +76,7 @@ struct vkms_writeback_job {
* @in_pixel: pointer to the pixel to read
* @out_pixel: pointer to write the converted pixel
*/
-typedef void (*pixel_read_t)(u8 *in_pixel, struct pixel_argb_u16 *out_pixel);
+typedef void (*pixel_read_t)(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel);
/**
* struct vkms_plane_state - Driver specific plane state
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index b9544e67cd4f..06aef5162529 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -75,7 +75,7 @@ static int get_x_position(const struct vkms_frame_info *frame_info, int limit, i
* They are used in the vkms_compose_row() function to handle multiple formats.
*/
-static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static void ARGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
/*
* The 257 is the "conversion ratio". This number is obtained by the
@@ -89,7 +89,7 @@ static void ARGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
out_pixel->b = (u16)in_pixel[0] * 257;
}
-static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static void XRGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
out_pixel->a = (u16)0xffff;
out_pixel->r = (u16)in_pixel[2] * 257;
@@ -97,7 +97,7 @@ static void XRGB8888_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
out_pixel->b = (u16)in_pixel[0] * 257;
}
-static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static void ARGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
__le16 *pixel = (__le16 *)in_pixel;
@@ -107,7 +107,7 @@ static void ARGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pi
out_pixel->b = le16_to_cpu(pixel[0]);
}
-static void XRGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static void XRGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
__le16 *pixel = (__le16 *)in_pixel;
@@ -117,7 +117,7 @@ static void XRGB16161616_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pi
out_pixel->b = le16_to_cpu(pixel[0]);
}
-static void RGB565_to_argb_u16(u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
{
__le16 *pixel = (__le16 *)in_pixel;
@@ -173,7 +173,7 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state
* They are used in vkms_writeback_row() to convert and store a pixel from the src_buffer to
* the writeback buffer.
*/
-static void argb_u16_to_ARGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_ARGB8888(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
{
/*
* This sequence below is important because the format's byte order is
@@ -191,7 +191,7 @@ static void argb_u16_to_ARGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257);
}
-static void argb_u16_to_XRGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_XRGB8888(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
{
out_pixel[3] = 0xff;
out_pixel[2] = DIV_ROUND_CLOSEST(in_pixel->r, 257);
@@ -199,7 +199,7 @@ static void argb_u16_to_XRGB8888(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
out_pixel[0] = DIV_ROUND_CLOSEST(in_pixel->b, 257);
}
-static void argb_u16_to_ARGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_ARGB16161616(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
{
__le16 *pixel = (__le16 *)out_pixel;
@@ -209,7 +209,7 @@ static void argb_u16_to_ARGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pi
pixel[0] = cpu_to_le16(in_pixel->b);
}
-static void argb_u16_to_XRGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_XRGB16161616(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
{
__le16 *pixel = (__le16 *)out_pixel;
@@ -219,7 +219,7 @@ static void argb_u16_to_XRGB16161616(u8 *out_pixel, struct pixel_argb_u16 *in_pi
pixel[0] = cpu_to_le16(in_pixel->b);
}
-static void argb_u16_to_RGB565(u8 *out_pixel, struct pixel_argb_u16 *in_pixel)
+static void argb_u16_to_RGB565(u8 *out_pixel, const struct pixel_argb_u16 *in_pixel)
{
__le16 *pixel = (__le16 *)out_pixel;
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 05/15] drm/vkms: Update pixels accessor to support packed and multi-plane formats.
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (3 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 04/15] drm/vkms: Use const for input pointers in pixel_read an " Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 06/15] drm/vkms: Avoid computing blending limits inside pre_mul_alpha_blend Louis Chauvet
` (9 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee
Introduce the usage of block_h/block_w to compute the offset and the
pointer of a pixel. The previous implementation was specialized for
planes with block_h == block_w == 1. To avoid confusion and allow easier
implementation of tiled formats. It also remove the usage of the
deprecated format field `cpp`.
Introduce the plane_index parameter to get an offset/pointer on a
different plane.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_formats.c | 114 ++++++++++++++++++++++++++++--------
1 file changed, 91 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index 06aef5162529..7f932d42394d 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -10,22 +10,46 @@
#include "vkms_formats.h"
/**
- * pixel_offset() - Get the offset of the pixel at coordinates x/y in the first plane
+ * packed_pixels_offset() - Get the offset of the block containing the pixel at coordinates x/y
*
* @frame_info: Buffer metadata
* @x: The x coordinate of the wanted pixel in the buffer
* @y: The y coordinate of the wanted pixel in the buffer
+ * @plane_index: The index of the plane to use
+ * @offset: The returned offset inside the buffer of the block
+ * @rem_x: The returned X coordinate of the requested pixel in the block
+ * @rem_y: The returned Y coordinate of the requested pixel in the block
*
- * The caller must ensure that the framebuffer associated with this request uses a pixel format
- * where block_h == block_w == 1.
- * If this requirement is not fulfilled, the resulting offset can point to an other pixel or
- * outside of the buffer.
+ * As some pixel formats store multiple pixels in a block (DRM_FORMAT_R* for example), some
+ * pixels are not individually addressable. This function return 3 values: the offset of the
+ * whole block, and the coordinate of the requested pixel inside this block.
+ * For example, if the format is DRM_FORMAT_R1 and the requested coordinate is 13,5, the offset
+ * will point to the byte 5*pitches + 13/8 (second byte of the 5th line), and the rem_x/rem_y
+ * coordinates will be (13 % 8, 5 % 1) = (5, 0)
+ *
+ * With this function, the caller just have to extract the correct pixel from the block.
*/
-static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int y)
+static void packed_pixels_offset(const struct vkms_frame_info *frame_info, int x, int y,
+ int plane_index, int *offset, int *rem_x, int *rem_y)
{
struct drm_framebuffer *fb = frame_info->fb;
+ const struct drm_format_info *format = frame_info->fb->format;
+ /* Directly using x and y to multiply pitches and format->ccp is not sufficient because
+ * in some formats a block can represent multiple pixels.
+ *
+ * Dividing x and y by the block size allows to extract the correct offset of the block
+ * containing the pixel.
+ */
- return fb->offsets[0] + (y * fb->pitches[0]) + (x * fb->format->cpp[0]);
+ int block_x = x / drm_format_info_block_width(format, plane_index);
+ int block_y = y / drm_format_info_block_height(format, plane_index);
+ int block_pitch = fb->pitches[plane_index] * drm_format_info_block_height(format,
+ plane_index);
+ *rem_x = x % drm_format_info_block_width(format, plane_index);
+ *rem_y = y % drm_format_info_block_height(format, plane_index);
+ *offset = fb->offsets[plane_index] +
+ block_y * block_pitch +
+ block_x * format->char_per_block[plane_index];
}
/**
@@ -35,30 +59,71 @@ static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int
* @frame_info: Buffer metadata
* @x: The x (width) coordinate inside the plane
* @y: The y (height) coordinate inside the plane
+ * @plane_index: The index of the plane
+ * @addr: The returned pointer
+ * @rem_x: The returned X coordinate of the requested pixel in the block
+ * @rem_y: The returned Y coordinate of the requested pixel in the block
*
- * Takes the information stored in the frame_info, a pair of coordinates, and
- * returns the address of the first color channel.
- * This function assumes the channels are packed together, i.e. a color channel
- * comes immediately after another in the memory. And therefore, this function
- * doesn't work for YUV with chroma subsampling (e.g. YUV420 and NV21).
+ * Takes the information stored in the frame_info, a pair of coordinates, and returns the address
+ * of the block containing this pixel and the pixel position inside this block.
*
- * The caller must ensure that the framebuffer associated with this request uses a pixel format
- * where block_h == block_w == 1, otherwise the returned pointer can be outside the buffer.
+ * See @packed_pixel_offset for details about rem_x/rem_y behavior.
*/
-static void *packed_pixels_addr(const struct vkms_frame_info *frame_info,
- int x, int y)
+static void packed_pixels_addr(const struct vkms_frame_info *frame_info,
+ int x, int y, int plane_index, u8 **addr, int *rem_x,
+ int *rem_y)
{
- size_t offset = pixel_offset(frame_info, x, y);
+ int offset;
- return (u8 *)frame_info->map[0].vaddr + offset;
+ packed_pixels_offset(frame_info, x, y, plane_index, &offset, rem_x, rem_y);
+ *addr = (u8 *)frame_info->map[0].vaddr + offset;
}
-static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y)
+/**
+ * packed_pixels_addr_1x1() - Get the pointer to the block containing the pixel at the given
+ * coordinates
+ *
+ * @frame_info: Buffer metadata
+ * @x: The x (width) coordinate inside the plane
+ * @y: The y (height) coordinate inside the plane
+ * @plane_index: The index of the plane
+ * @addr: The returned pointer
+ *
+ * This function can only be used with format where block_h == block_w == 1.
+ */
+static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info,
+ int x, int y, int plane_index, u8 **addr)
+{
+ int offset, rem_x, rem_y;
+
+ WARN_ONCE(drm_format_info_block_width(frame_info->fb->format,
+ plane_index) != 1,
+ "%s() only support formats with block_w == 1", __func__);
+ WARN_ONCE(drm_format_info_block_height(frame_info->fb->format,
+ plane_index) != 1,
+ "%s() only support formats with block_h == 1", __func__);
+
+ packed_pixels_offset(frame_info, x, y, plane_index, &offset, &rem_x,
+ &rem_y);
+ *addr = (u8 *)frame_info->map[0].vaddr + offset;
+}
+
+static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y,
+ int plane_index)
{
int x_src = frame_info->src.x1 >> 16;
int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16);
+ u8 *addr;
+ int rem_x, rem_y;
+
+ WARN_ONCE(drm_format_info_block_width(frame_info->fb->format, plane_index) != 1,
+ "%s() only support formats with block_w == 1", __func__);
+ WARN_ONCE(drm_format_info_block_height(frame_info->fb->format, plane_index) != 1,
+ "%s() only support formats with block_h == 1", __func__);
- return packed_pixels_addr(frame_info, x_src, y_src);
+ packed_pixels_addr(frame_info, x_src, y_src, plane_index, &addr, &rem_x, &rem_y);
+
+ return addr;
}
static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x)
@@ -152,14 +217,14 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state
{
struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
struct vkms_frame_info *frame_info = plane->frame_info;
- u8 *src_pixels = get_packed_src_addr(frame_info, y);
+ u8 *src_pixels = get_packed_src_addr(frame_info, y, 0);
int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) {
int x_pos = get_x_position(frame_info, limit, x);
if (drm_rotation_90_or_270(frame_info->rotation))
- src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1)
+ src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1, 0)
+ frame_info->fb->format->cpp[0] * y;
plane->pixel_read(src_pixels, &out_pixels[x_pos]);
@@ -250,7 +315,10 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
{
struct vkms_frame_info *frame_info = &wb->wb_frame_info;
int x_dst = frame_info->dst.x1;
- u8 *dst_pixels = packed_pixels_addr(frame_info, x_dst, y);
+ u8 *dst_pixels;
+ int rem_x, rem_y;
+
+ packed_pixels_addr(frame_info, x_dst, y, 0, &dst_pixels, &rem_x, &rem_y);
struct pixel_argb_u16 *in_pixels = src_buffer->pixels;
int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), src_buffer->n_pixels);
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 06/15] drm/vkms: Avoid computing blending limits inside pre_mul_alpha_blend
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (4 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 05/15] drm/vkms: Update pixels accessor to support packed and multi-plane formats Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 07/15] drm/vkms: Introduce pixel_read_direction enum Louis Chauvet
` (8 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen
The pre_mul_alpha_blend is dedicated to blending, so to avoid mixing
different concepts (coordinate calculation and color management), extract
the x_limit and x_dst computation outside of this helper.
It also increases the maintainability by grouping the computation related
to coordinates in the same place: the loop in `blend`.
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_composer.c | 40 +++++++++++++++++-------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 931e214b225c..ecac0bc858a0 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -24,34 +24,30 @@ static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha)
/**
* pre_mul_alpha_blend - alpha blending equation
- * @frame_info: Source framebuffer's metadata
* @stage_buffer: The line with the pixels from src_plane
* @output_buffer: A line buffer that receives all the blends output
+ * @x_start: The start offset
+ * @pixel_count: The number of pixels to blend
*
- * Using the information from the `frame_info`, this blends only the
- * necessary pixels from the `stage_buffer` to the `output_buffer`
- * using premultiplied blend formula.
+ * The pixels [0;@pixel_count) in stage_buffer are blended at [@x_start;@x_start+@pixel_count) in
+ * output_buffer.
*
* The current DRM assumption is that pixel color values have been already
* pre-multiplied with the alpha channel values. See more
* drm_plane_create_blend_mode_property(). Also, this formula assumes a
* completely opaque background.
*/
-static void pre_mul_alpha_blend(struct vkms_frame_info *frame_info,
- struct line_buffer *stage_buffer,
- struct line_buffer *output_buffer)
+static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer,
+ struct line_buffer *output_buffer, int x_start, int pixel_count)
{
- int x_dst = frame_info->dst.x1;
- struct pixel_argb_u16 *out = output_buffer->pixels + x_dst;
- struct pixel_argb_u16 *in = stage_buffer->pixels;
- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
- stage_buffer->n_pixels);
-
- for (int x = 0; x < x_limit; x++) {
- out[x].a = (u16)0xffff;
- out[x].r = pre_mul_blend_channel(in[x].r, out[x].r, in[x].a);
- out[x].g = pre_mul_blend_channel(in[x].g, out[x].g, in[x].a);
- out[x].b = pre_mul_blend_channel(in[x].b, out[x].b, in[x].a);
+ struct pixel_argb_u16 *out = &output_buffer->pixels[x_start];
+ const struct pixel_argb_u16 *in = stage_buffer->pixels;
+
+ for (int i = 0; i < pixel_count; i++) {
+ out[i].a = (u16)0xffff;
+ out[i].r = pre_mul_blend_channel(in[i].r, out[i].r, in[i].a);
+ out[i].g = pre_mul_blend_channel(in[i].g, out[i].g, in[i].a);
+ out[i].b = pre_mul_blend_channel(in[i].b, out[i].b, in[i].a);
}
}
@@ -183,7 +179,7 @@ static void blend(struct vkms_writeback_job *wb,
{
struct vkms_plane_state **plane = crtc_state->active_planes;
u32 n_active_planes = crtc_state->num_active_planes;
- int y_pos;
+ int y_pos, x_dst, pixel_count;
const struct pixel_argb_u16 background_color = { .a = 0xffff };
@@ -201,14 +197,16 @@ static void blend(struct vkms_writeback_job *wb,
/* The active planes are composed associatively in z-order. */
for (size_t i = 0; i < n_active_planes; i++) {
+ x_dst = plane[i]->frame_info->dst.x1;
+ pixel_count = min_t(int, drm_rect_width(&plane[i]->frame_info->dst),
+ (int)stage_buffer->n_pixels);
y_pos = get_y_pos(plane[i]->frame_info, y);
if (!check_limit(plane[i]->frame_info, y_pos))
continue;
vkms_compose_row(stage_buffer, plane[i], y_pos);
- pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer,
- output_buffer);
+ pre_mul_alpha_blend(stage_buffer, output_buffer, x_dst, pixel_count);
}
apply_lut(crtc_state, output_buffer);
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 07/15] drm/vkms: Introduce pixel_read_direction enum
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (5 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 06/15] drm/vkms: Avoid computing blending limits inside pre_mul_alpha_blend Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm Louis Chauvet
` (7 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee
The pixel_read_direction enum is useful to describe the reading direction
in a plane. It avoids using the rotation property of DRM, which not
practical to know the direction of reading.
This patch also introduce two helpers, one to compute the
pixel_read_direction from the DRM rotation property, and one to compute
the step, in byte, between two successive pixel in a specific direction.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_composer.c | 44 ++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_drv.h | 11 +++++++++
drivers/gpu/drm/vkms/vkms_formats.c | 32 ++++++++++++++++++++++++++
3 files changed, 87 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index ecac0bc858a0..601e33431b45 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -159,6 +159,50 @@ static void apply_lut(const struct vkms_crtc_state *crtc_state, struct line_buff
}
}
+/**
+ * direction_for_rotation() - Get the correct reading direction for a given rotation
+ *
+ * @rotation: Rotation to analyze. It correspond the field @frame_info.rotation.
+ *
+ * This function will use the @rotation setting of a source plane to compute the reading
+ * direction in this plane which correspond to a "left to right writing" in the CRTC.
+ * For example, if the buffer is reflected on X axis, the pixel must be read from right to left
+ * to be written from left to right on the CRTC.
+ */
+static enum pixel_read_direction direction_for_rotation(unsigned int rotation)
+{
+ struct drm_rect tmp_a, tmp_b;
+ int x, y;
+
+ /*
+ * Points A and B are depicted as zero-size rectangles on the CRTC.
+ * The CRTC writing direction is from A to B. The plane reading direction
+ * is discovered by inverse-transforming A and B.
+ * The reading direction is computed by rotating the vector AB (top-left to top-right) in a
+ * 1x1 square.
+ */
+
+ tmp_a = DRM_RECT_INIT(0, 0, 0, 0);
+ tmp_b = DRM_RECT_INIT(1, 0, 0, 0);
+ drm_rect_rotate_inv(&tmp_a, 1, 1, rotation);
+ drm_rect_rotate_inv(&tmp_b, 1, 1, rotation);
+
+ x = tmp_b.x1 - tmp_a.x1;
+ y = tmp_b.y1 - tmp_a.y1;
+
+ if (x == 1 && y == 0)
+ return READ_LEFT_TO_RIGHT;
+ else if (x == -1 && y == 0)
+ return READ_RIGHT_TO_LEFT;
+ else if (y == 1 && x == 0)
+ return READ_TOP_TO_BOTTOM;
+ else if (y == -1 && x == 0)
+ return READ_BOTTOM_TO_TOP;
+
+ WARN_ONCE(true, "The inverse of the rotation gives an incorrect direction.");
+ return READ_LEFT_TO_RIGHT;
+}
+
/**
* blend - blend the pixels from all planes and compute crc
* @wb: The writeback frame buffer metadata
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 3f45290a0c5d..777b7bd91f27 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -69,6 +69,17 @@ struct vkms_writeback_job {
pixel_write_t pixel_write;
};
+/**
+ * enum pixel_read_direction - Enum used internaly by VKMS to represent a reading direction in a
+ * plane.
+ */
+enum pixel_read_direction {
+ READ_BOTTOM_TO_TOP,
+ READ_TOP_TO_BOTTOM,
+ READ_RIGHT_TO_LEFT,
+ READ_LEFT_TO_RIGHT
+};
+
/**
* typedef pixel_read_t - These functions are used to read a pixel in the source frame,
* convert it to `struct pixel_argb_u16` and write it to @out_pixel.
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index 7f932d42394d..d0e7dfc1f0d3 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -79,6 +79,38 @@ static void packed_pixels_addr(const struct vkms_frame_info *frame_info,
*addr = (u8 *)frame_info->map[0].vaddr + offset;
}
+/**
+ * get_block_step_bytes() - Common helper to compute the correct step value between each pixel block
+ * to read in a certain direction.
+ *
+ * @fb: Framebuffer to iter on
+ * @direction: Direction of the reading
+ * @plane_index: Plane to get the step from
+ *
+ * As the returned count is the number of bytes between two consecutive blocks in a direction,
+ * the caller may have to read multiple pixels before using the next one (for example, to read from
+ * left to right in a DRM_FORMAT_R1 plane, each block contains 8 pixels, so the step must be used
+ * only every 8 pixels).
+ */
+static int get_block_step_bytes(struct drm_framebuffer *fb, enum pixel_read_direction direction,
+ int plane_index)
+{
+ switch (direction) {
+ case READ_LEFT_TO_RIGHT:
+ return fb->format->char_per_block[plane_index];
+ case READ_RIGHT_TO_LEFT:
+ return -fb->format->char_per_block[plane_index];
+ case READ_TOP_TO_BOTTOM:
+ return (int)fb->pitches[plane_index] * drm_format_info_block_width(fb->format,
+ plane_index);
+ case READ_BOTTOM_TO_TOP:
+ return -(int)fb->pitches[plane_index] * drm_format_info_block_width(fb->format,
+ plane_index);
+ }
+
+ return 0;
+}
+
/**
* packed_pixels_addr_1x1() - Get the pointer to the block containing the pixel at the given
* coordinates
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (6 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 07/15] drm/vkms: Introduce pixel_read_direction enum Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-26 14:26 ` Maíra Canal
2024-10-07 16:10 ` [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify Louis Chauvet
` (6 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen
Re-introduce a line-by-line composition algorithm for each pixel format.
This allows more performance by not requiring an indirection per pixel
read. This patch is focused on readability of the code.
Line-by-line composition was introduced by [1] but rewritten back to
pixel-by-pixel algorithm in [2]. At this time, nobody noticed the impact
on performance, and it was merged.
This patch is almost a revert of [2], but in addition efforts have been
made to increase readability and maintainability of the rotation handling.
The blend function is now divided in two parts:
- Transformation of coordinates from the output referential to the source
referential
- Line conversion and blending
Most of the complexity of the rotation management is avoided by using
drm_rect_* helpers. The remaining complexity is around the clipping, to
avoid reading/writing outside source/destination buffers.
The pixel conversion is now done line-by-line, so the read_pixel_t was
replaced with read_pixel_line_t callback. This way the indirection is only
required once per line and per plane, instead of once per pixel and per
plane.
The read_line_t callbacks are very similar for most pixel format, but it
is required to avoid performance impact. Some helpers for color
conversion were introduced to avoid code repetition:
- *_to_argb_u16: perform colors conversion. They should be inlined by the
compiler, and they are used to avoid repetition between multiple variants
of the same format (argb/xrgb and maybe in the future for formats like
bgr formats).
This new algorithm was tested with:
- kms_plane (for color conversions)
- kms_rotation_crc (for rotations of planes)
- kms_cursor_crc (for translations of planes)
- kms_rotation (for all rotations and formats combinations) [3]
The performance gain was mesured with kms_fb_stress [4] with some
modification to fix the writeback format.
The performance improvement is around 5 to 10%.
[1]: commit 8ba1648567e2 ("drm: vkms: Refactor the plane composer to accept
new formats")
https://lore.kernel.org/all/20220905190811.25024-7-igormtorrente@gmail.com/
[2]: commit 322d716a3e8a ("drm/vkms: isolate pixel conversion
functionality")
https://lore.kernel.org/all/20230418130525.128733-2-mcanal@igalia.com/
[3]: https://lore.kernel.org/igt-dev/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com/
[4]: https://lore.kernel.org/all/20240422-kms_fb_stress-dev-v5-0-0c577163dc88@riseup.net/
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
# Conflicts:
# drivers/gpu/drm/vkms/vkms_composer.c
---
drivers/gpu/drm/vkms/vkms_composer.c | 234 ++++++++++++++++++++++++++++-------
drivers/gpu/drm/vkms/vkms_drv.h | 28 +++--
drivers/gpu/drm/vkms/vkms_formats.c | 224 ++++++++++++++++++++-------------
drivers/gpu/drm/vkms/vkms_formats.h | 2 +-
drivers/gpu/drm/vkms/vkms_plane.c | 5 +-
5 files changed, 344 insertions(+), 149 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 601e33431b45..7a3e47b895a7 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -29,8 +29,8 @@ static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha)
* @x_start: The start offset
* @pixel_count: The number of pixels to blend
*
- * The pixels [0;@pixel_count) in stage_buffer are blended at [@x_start;@x_start+@pixel_count) in
- * output_buffer.
+ * The pixels [@x_start;@x_start+@pixel_count) in stage_buffer are blended at
+ * [@x_start;@x_start+@pixel_count) in output_buffer.
*
* The current DRM assumption is that pixel color values have been already
* pre-multiplied with the alpha channel values. See more
@@ -41,7 +41,7 @@ static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer,
struct line_buffer *output_buffer, int x_start, int pixel_count)
{
struct pixel_argb_u16 *out = &output_buffer->pixels[x_start];
- const struct pixel_argb_u16 *in = stage_buffer->pixels;
+ const struct pixel_argb_u16 *in = &stage_buffer->pixels[x_start];
for (int i = 0; i < pixel_count; i++) {
out[i].a = (u16)0xffff;
@@ -51,33 +51,6 @@ static void pre_mul_alpha_blend(const struct line_buffer *stage_buffer,
}
}
-static int get_y_pos(struct vkms_frame_info *frame_info, int y)
-{
- if (frame_info->rotation & DRM_MODE_REFLECT_Y)
- return drm_rect_height(&frame_info->rotated) - y - 1;
-
- switch (frame_info->rotation & DRM_MODE_ROTATE_MASK) {
- case DRM_MODE_ROTATE_90:
- return frame_info->rotated.x2 - y - 1;
- case DRM_MODE_ROTATE_270:
- return y + frame_info->rotated.x1;
- default:
- return y;
- }
-}
-
-static bool check_limit(struct vkms_frame_info *frame_info, int pos)
-{
- if (drm_rotation_90_or_270(frame_info->rotation)) {
- if (pos >= 0 && pos < drm_rect_width(&frame_info->rotated))
- return true;
- } else {
- if (pos >= frame_info->rotated.y1 && pos < frame_info->rotated.y2)
- return true;
- }
-
- return false;
-}
static void fill_background(const struct pixel_argb_u16 *background_color,
struct line_buffer *output_buffer)
@@ -203,6 +176,182 @@ static enum pixel_read_direction direction_for_rotation(unsigned int rotation)
return READ_LEFT_TO_RIGHT;
}
+/**
+ * clamp_line_coordinates() - Compute and clamp the coordinate to read and write during the blend
+ * process.
+ *
+ * @direction: direction of the reading
+ * @current_plane: current plane blended
+ * @src_line: source line of the reading. Only the top-left coordinate is used. This rectangle
+ * must be rotated and have a shape of 1*pixel_count if @direction is vertical and a shape of
+ * pixel_count*1 if @direction is horizontal.
+ * @src_x_start: x start coordinate for the line reading
+ * @src_y_start: y start coordinate for the line reading
+ * @dst_x_start: x coordinate to blend the read line
+ * @pixel_count: number of pixels to blend
+ *
+ * This function is mainly a safety net to avoid reading outside the source buffer. As the
+ * userspace should never ask to read outside the source plane, all the cases covered here should
+ * be dead code.
+ */
+static void clamp_line_coordinates(enum pixel_read_direction direction,
+ const struct vkms_plane_state *current_plane,
+ const struct drm_rect *src_line, int *src_x_start,
+ int *src_y_start, int *dst_x_start, int *pixel_count)
+{
+ /* By default the start points are correct */
+ *src_x_start = src_line->x1;
+ *src_y_start = src_line->y1;
+ *dst_x_start = current_plane->frame_info->dst.x1;
+
+ /* Get the correct number of pixel to blend, it depends of the direction */
+ switch (direction) {
+ case READ_LEFT_TO_RIGHT:
+ case READ_RIGHT_TO_LEFT:
+ *pixel_count = drm_rect_width(src_line);
+ break;
+ case READ_BOTTOM_TO_TOP:
+ case READ_TOP_TO_BOTTOM:
+ *pixel_count = drm_rect_height(src_line);
+ break;
+ }
+
+ /*
+ * Clamp the coordinates to avoid reading outside the buffer
+ *
+ * This is mainly a security check to avoid reading outside the buffer, the userspace
+ * should never request to read outside the source buffer.
+ */
+ switch (direction) {
+ case READ_LEFT_TO_RIGHT:
+ case READ_RIGHT_TO_LEFT:
+ if (*src_x_start < 0) {
+ *pixel_count += *src_x_start;
+ *dst_x_start -= *src_x_start;
+ *src_x_start = 0;
+ }
+ if (*src_x_start + *pixel_count > current_plane->frame_info->fb->width)
+ *pixel_count = max(0, (int)current_plane->frame_info->fb->width -
+ *src_x_start);
+ break;
+ case READ_BOTTOM_TO_TOP:
+ case READ_TOP_TO_BOTTOM:
+ if (*src_y_start < 0) {
+ *pixel_count += *src_y_start;
+ *dst_x_start -= *src_y_start;
+ *src_y_start = 0;
+ }
+ if (*src_y_start + *pixel_count > current_plane->frame_info->fb->height)
+ *pixel_count = max(0, (int)current_plane->frame_info->fb->height -
+ *src_y_start);
+ break;
+ }
+}
+
+/**
+ * blend_line() - Blend a line from a plane to the output buffer
+ *
+ * @current_plane: current plane to work on
+ * @y: line to write in the output buffer
+ * @crtc_x_limit: width of the output buffer
+ * @stage_buffer: temporary buffer to convert the pixel line from the source buffer
+ * @output_buffer: buffer to blend the read line into.
+ */
+static void blend_line(struct vkms_plane_state *current_plane, int y,
+ int crtc_x_limit, struct line_buffer *stage_buffer,
+ struct line_buffer *output_buffer)
+{
+ int src_x_start, src_y_start, dst_x_start, pixel_count;
+ struct drm_rect dst_line, tmp_src, src_line;
+
+ /* Avoid rendering useless lines */
+ if (y < current_plane->frame_info->dst.y1 ||
+ y >= current_plane->frame_info->dst.y2)
+ return;
+
+ /*
+ * dst_line is the line to copy. The initial coordinates are inside the
+ * destination framebuffer, and then drm_rect_* helpers are used to
+ * compute the correct position into the source framebuffer.
+ */
+ dst_line = DRM_RECT_INIT(current_plane->frame_info->dst.x1, y,
+ drm_rect_width(¤t_plane->frame_info->dst),
+ 1);
+
+ drm_rect_fp_to_int(&tmp_src, ¤t_plane->frame_info->src);
+
+ /*
+ * [1]: Clamping src_line to the crtc_x_limit to avoid writing outside of
+ * the destination buffer
+ */
+ dst_line.x1 = max_t(int, dst_line.x1, 0);
+ dst_line.x2 = min_t(int, dst_line.x2, crtc_x_limit);
+ /* The destination is completely outside of the crtc. */
+ if (dst_line.x2 <= dst_line.x1)
+ return;
+
+ src_line = dst_line;
+
+ /*
+ * Transform the coordinate x/y from the crtc to coordinates into
+ * coordinates for the src buffer.
+ *
+ * - Cancel the offset of the dst buffer.
+ * - Invert the rotation. This assumes that
+ * dst = drm_rect_rotate(src, rotation) (dst and src have the
+ * same size, but can be rotated).
+ * - Apply the offset of the source rectangle to the coordinate.
+ */
+ drm_rect_translate(&src_line, -current_plane->frame_info->dst.x1,
+ -current_plane->frame_info->dst.y1);
+ drm_rect_rotate_inv(&src_line, drm_rect_width(&tmp_src),
+ drm_rect_height(&tmp_src),
+ current_plane->frame_info->rotation);
+ drm_rect_translate(&src_line, tmp_src.x1, tmp_src.y1);
+
+ /* Get the correct reading direction in the source buffer. */
+
+ enum pixel_read_direction direction =
+ direction_for_rotation(current_plane->frame_info->rotation);
+
+ /* [2]: Compute and clamp the number of pixel to read */
+ clamp_line_coordinates(direction, current_plane, &src_line, &src_x_start, &src_y_start,
+ &dst_x_start, &pixel_count);
+
+ if (pixel_count <= 0) {
+ /* Nothing to read, so avoid multiple function calls */
+ return;
+ }
+
+ /*
+ * Modify the starting point to take in account the rotation
+ *
+ * src_line is the top-left corner, so when reading READ_RIGHT_TO_LEFT or
+ * READ_BOTTOM_TO_TOP, it must be changed to the top-right/bottom-left
+ * corner.
+ */
+ if (direction == READ_RIGHT_TO_LEFT) {
+ // src_x_start is now the right point
+ src_x_start += pixel_count - 1;
+ } else if (direction == READ_BOTTOM_TO_TOP) {
+ // src_y_start is now the bottom point
+ src_y_start += pixel_count - 1;
+ }
+
+ /*
+ * Perform the conversion and the blending
+ *
+ * Here we know that the read line (x_start, y_start, pixel_count) is
+ * inside the source buffer [2] and we don't write outside the stage
+ * buffer [1].
+ */
+ current_plane->pixel_read_line(current_plane, src_x_start, src_y_start, direction,
+ pixel_count, &stage_buffer->pixels[dst_x_start]);
+
+ pre_mul_alpha_blend(stage_buffer, output_buffer,
+ dst_x_start, pixel_count);
+}
+
/**
* blend - blend the pixels from all planes and compute crc
* @wb: The writeback frame buffer metadata
@@ -223,34 +372,25 @@ static void blend(struct vkms_writeback_job *wb,
{
struct vkms_plane_state **plane = crtc_state->active_planes;
u32 n_active_planes = crtc_state->num_active_planes;
- int y_pos, x_dst, pixel_count;
const struct pixel_argb_u16 background_color = { .a = 0xffff };
- size_t crtc_y_limit = crtc_state->base.crtc->mode.vdisplay;
+ int crtc_y_limit = crtc_state->base.crtc->mode.vdisplay;
+ int crtc_x_limit = crtc_state->base.crtc->mode.hdisplay;
/*
* The planes are composed line-by-line to avoid heavy memory usage. It is a necessary
* complexity to avoid poor blending performance.
*
- * The function vkms_compose_row() is used to read a line, pixel-by-pixel, into the staging
- * buffer.
+ * The function pixel_read_line callback is used to read a line, using an efficient
+ * algorithm for a specific format, into the staging buffer.
*/
- for (size_t y = 0; y < crtc_y_limit; y++) {
+ for (int y = 0; y < crtc_y_limit; y++) {
fill_background(&background_color, output_buffer);
/* The active planes are composed associatively in z-order. */
for (size_t i = 0; i < n_active_planes; i++) {
- x_dst = plane[i]->frame_info->dst.x1;
- pixel_count = min_t(int, drm_rect_width(&plane[i]->frame_info->dst),
- (int)stage_buffer->n_pixels);
- y_pos = get_y_pos(plane[i]->frame_info, y);
-
- if (!check_limit(plane[i]->frame_info, y_pos))
- continue;
-
- vkms_compose_row(stage_buffer, plane[i], y_pos);
- pre_mul_alpha_blend(stage_buffer, output_buffer, x_dst, pixel_count);
+ blend_line(plane[i], y, crtc_x_limit, stage_buffer, output_buffer);
}
apply_lut(crtc_state, output_buffer);
@@ -258,7 +398,7 @@ static void blend(struct vkms_writeback_job *wb,
*crc32 = crc32_le(*crc32, (void *)output_buffer->pixels, row_size);
if (wb)
- vkms_writeback_row(wb, output_buffer, y_pos);
+ vkms_writeback_row(wb, output_buffer, y);
}
}
@@ -269,7 +409,7 @@ static int check_format_funcs(struct vkms_crtc_state *crtc_state,
u32 n_active_planes = crtc_state->num_active_planes;
for (size_t i = 0; i < n_active_planes; i++)
- if (!planes[i]->pixel_read)
+ if (!planes[i]->pixel_read_line)
return -1;
if (active_wb && !active_wb->pixel_write)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 777b7bd91f27..067a4797f7a0 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -39,7 +39,6 @@
struct vkms_frame_info {
struct drm_framebuffer *fb;
struct drm_rect src, dst;
- struct drm_rect rotated;
struct iosys_map map[DRM_FORMAT_MAX_PLANES];
unsigned int rotation;
};
@@ -80,26 +79,38 @@ enum pixel_read_direction {
READ_LEFT_TO_RIGHT
};
+struct vkms_plane_state;
+
/**
- * typedef pixel_read_t - These functions are used to read a pixel in the source frame,
+ * typedef pixel_read_line_t - These functions are used to read a pixel line in the source frame,
* convert it to `struct pixel_argb_u16` and write it to @out_pixel.
*
- * @in_pixel: pointer to the pixel to read
- * @out_pixel: pointer to write the converted pixel
+ * @plane: plane used as source for the pixel value
+ * @x_start: X (width) coordinate of the first pixel to copy. The caller must ensure that x_start
+ * is non-negative and smaller than @plane->frame_info->fb->width.
+ * @y_start: Y (height) coordinate of the first pixel to copy. The caller must ensure that y_start
+ * is non-negative and smaller than @plane->frame_info->fb->height.
+ * @direction: direction to use for the copy, starting at @x_start/@y_start
+ * @count: number of pixels to copy
+ * @out_pixel: pointer where to write the pixel values. They will be written from @out_pixel[0]
+ * (included) to @out_pixel[@count] (excluded). The caller must ensure that out_pixel have a
+ * length of at least @count.
*/
-typedef void (*pixel_read_t)(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel);
+typedef void (*pixel_read_line_t)(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[]);
/**
* struct vkms_plane_state - Driver specific plane state
* @base: base plane state
* @frame_info: data required for composing computation
- * @pixel_read: function to read a pixel in this plane. The creator of a struct vkms_plane_state
- * must ensure that this pointer is valid
+ * @pixel_read_line: function to read a pixel line in this plane. The creator of a
+ * struct vkms_plane_state must ensure that this pointer is valid
*/
struct vkms_plane_state {
struct drm_shadow_plane_state base;
struct vkms_frame_info *frame_info;
- pixel_read_t pixel_read;
+ pixel_read_line_t pixel_read_line;
};
struct vkms_plane {
@@ -265,7 +276,6 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
/* Composer Support */
void vkms_composer_worker(struct work_struct *work);
void vkms_set_composer(struct vkms_output *out, bool enabled);
-void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y);
void vkms_writeback_row(struct vkms_writeback_job *wb, const struct line_buffer *src_buffer, int y);
/* Writeback */
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index d0e7dfc1f0d3..0f6678420a11 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -140,83 +140,51 @@ static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info,
*addr = (u8 *)frame_info->map[0].vaddr + offset;
}
-static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y,
- int plane_index)
-{
- int x_src = frame_info->src.x1 >> 16;
- int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16);
- u8 *addr;
- int rem_x, rem_y;
-
- WARN_ONCE(drm_format_info_block_width(frame_info->fb->format, plane_index) != 1,
- "%s() only support formats with block_w == 1", __func__);
- WARN_ONCE(drm_format_info_block_height(frame_info->fb->format, plane_index) != 1,
- "%s() only support formats with block_h == 1", __func__);
-
- packed_pixels_addr(frame_info, x_src, y_src, plane_index, &addr, &rem_x, &rem_y);
-
- return addr;
-}
-
-static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x)
-{
- if (frame_info->rotation & (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270))
- return limit - x - 1;
- return x;
-}
-
/*
- * The following functions take pixel data from the buffer and convert them to the format
- * ARGB16161616 in @out_pixel.
+ * The following functions take pixel data (a, r, g, b, pixel, ...) and convert them to
+ * &struct pixel_argb_u16
*
- * They are used in the vkms_compose_row() function to handle multiple formats.
+ * They are used in the `read_line`s functions to avoid duplicate work for some pixel formats.
*/
-static void ARGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static struct pixel_argb_u16 argb_u16_from_u8888(u8 a, u8 r, u8 g, u8 b)
{
+ struct pixel_argb_u16 out_pixel;
/*
* The 257 is the "conversion ratio". This number is obtained by the
* (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
* the best color value in a pixel format with more possibilities.
* A similar idea applies to others RGB color conversions.
*/
- out_pixel->a = (u16)in_pixel[3] * 257;
- out_pixel->r = (u16)in_pixel[2] * 257;
- out_pixel->g = (u16)in_pixel[1] * 257;
- out_pixel->b = (u16)in_pixel[0] * 257;
-}
+ out_pixel.a = (u16)a * 257;
+ out_pixel.r = (u16)r * 257;
+ out_pixel.g = (u16)g * 257;
+ out_pixel.b = (u16)b * 257;
-static void XRGB8888_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
-{
- out_pixel->a = (u16)0xffff;
- out_pixel->r = (u16)in_pixel[2] * 257;
- out_pixel->g = (u16)in_pixel[1] * 257;
- out_pixel->b = (u16)in_pixel[0] * 257;
+ return out_pixel;
}
-static void ARGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static struct pixel_argb_u16 argb_u16_from_u16161616(u16 a, u16 r, u16 g, u16 b)
{
- __le16 *pixel = (__le16 *)in_pixel;
+ struct pixel_argb_u16 out_pixel;
+
+ out_pixel.a = a;
+ out_pixel.r = r;
+ out_pixel.g = g;
+ out_pixel.b = b;
- out_pixel->a = le16_to_cpu(pixel[3]);
- out_pixel->r = le16_to_cpu(pixel[2]);
- out_pixel->g = le16_to_cpu(pixel[1]);
- out_pixel->b = le16_to_cpu(pixel[0]);
+ return out_pixel;
}
-static void XRGB16161616_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static struct pixel_argb_u16 argb_u16_from_le16161616(__le16 a, __le16 r, __le16 g, __le16 b)
{
- __le16 *pixel = (__le16 *)in_pixel;
-
- out_pixel->a = (u16)0xffff;
- out_pixel->r = le16_to_cpu(pixel[2]);
- out_pixel->g = le16_to_cpu(pixel[1]);
- out_pixel->b = le16_to_cpu(pixel[0]);
+ return argb_u16_from_u16161616(le16_to_cpu(a), le16_to_cpu(r), le16_to_cpu(g),
+ le16_to_cpu(b));
}
-static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
+static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
{
- __le16 *pixel = (__le16 *)in_pixel;
+ struct pixel_argb_u16 out_pixel;
s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
@@ -226,40 +194,120 @@ static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pi
s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
- out_pixel->a = (u16)0xffff;
- out_pixel->r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
- out_pixel->g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
- out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
+ out_pixel.a = (u16)0xffff;
+ out_pixel.r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
+ out_pixel.g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
+ out_pixel.b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
+
+ return out_pixel;
}
-/**
- * vkms_compose_row - compose a single row of a plane
- * @stage_buffer: output line with the composed pixels
- * @plane: state of the plane that is being composed
- * @y: y coordinate of the row
+/*
+ * The following functions are read_line function for each pixel format supported by VKMS.
+ *
+ * They read a line starting at the point @x_start,@y_start following the @direction. The result
+ * is stored in @out_pixel and in the format ARGB16161616.
+ *
+ * These functions are very repetitive, but the innermost pixel loops must be kept inside these
+ * functions for performance reasons. Some benchmarking was done in [1] where having the innermost
+ * loop factored out of these functions showed a slowdown by a factor of three.
*
- * This function composes a single row of a plane. It gets the source pixels
- * through the y coordinate (see get_packed_src_addr()) and goes linearly
- * through the source pixel, reading the pixels and converting it to
- * ARGB16161616 (see the pixel_read() callback). For rotate-90 and rotate-270,
- * the source pixels are not traversed linearly. The source pixels are queried
- * on each iteration in order to traverse the pixels vertically.
+ * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
*/
-void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
+
+static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
+ enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
{
- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
- struct vkms_frame_info *frame_info = plane->frame_info;
- u8 *src_pixels = get_packed_src_addr(frame_info, y, 0);
- int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
+ struct pixel_argb_u16 *end = out_pixel + count;
+ u8 *src_pixels;
+
+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
+
+ int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
+
+ while (out_pixel < end) {
+ u8 *px = (u8 *)src_pixels;
+ *out_pixel = argb_u16_from_u8888(px[3], px[2], px[1], px[0]);
+ out_pixel += 1;
+ src_pixels += step;
+ }
+}
+
+static void XRGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
+ enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ struct pixel_argb_u16 *end = out_pixel + count;
+ u8 *src_pixels;
+
+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
+
+ int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
+
+ while (out_pixel < end) {
+ u8 *px = (u8 *)src_pixels;
+ *out_pixel = argb_u16_from_u8888(255, px[2], px[1], px[0]);
+ out_pixel += 1;
+ src_pixels += step;
+ }
+}
+
+static void ARGB16161616_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ struct pixel_argb_u16 *end = out_pixel + count;
+ u8 *src_pixels;
+
+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
+
+ int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
+
+ while (out_pixel < end) {
+ u16 *px = (u16 *)src_pixels;
+ *out_pixel = argb_u16_from_u16161616(px[3], px[2], px[1], px[0]);
+ out_pixel += 1;
+ src_pixels += step;
+ }
+}
+
+static void XRGB16161616_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ struct pixel_argb_u16 *end = out_pixel + count;
+ u8 *src_pixels;
+
+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
+
+ int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
+
+ while (out_pixel < end) {
+ __le16 *px = (__le16 *)src_pixels;
+ *out_pixel = argb_u16_from_le16161616(cpu_to_le16(0xFFFF), px[2], px[1], px[0]);
+ out_pixel += 1;
+ src_pixels += step;
+ }
+}
+
+static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ struct pixel_argb_u16 *end = out_pixel + count;
+ u8 *src_pixels;
+
+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
- for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) {
- int x_pos = get_x_position(frame_info, limit, x);
+ int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
- if (drm_rotation_90_or_270(frame_info->rotation))
- src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1, 0)
- + frame_info->fb->format->cpp[0] * y;
+ while (out_pixel < end) {
+ __le16 *px = (__le16 *)src_pixels;
- plane->pixel_read(src_pixels, &out_pixels[x_pos]);
+ *out_pixel = argb_u16_from_RGB565(px);
+ out_pixel += 1;
+ src_pixels += step;
}
}
@@ -359,25 +407,25 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
}
/**
- * get_pixel_read_function() - Retrieve the correct read_pixel function for a specific
+ * get_pixel_read_line_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
* the pointer is valid before using it in a vkms_plane_state.
*
* @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h])
*/
-pixel_read_t get_pixel_read_function(u32 format)
+pixel_read_line_t get_pixel_read_line_function(u32 format)
{
switch (format) {
case DRM_FORMAT_ARGB8888:
- return &ARGB8888_to_argb_u16;
+ return &ARGB8888_read_line;
case DRM_FORMAT_XRGB8888:
- return &XRGB8888_to_argb_u16;
+ return &XRGB8888_read_line;
case DRM_FORMAT_ARGB16161616:
- return &ARGB16161616_to_argb_u16;
+ return &ARGB16161616_read_line;
case DRM_FORMAT_XRGB16161616:
- return &XRGB16161616_to_argb_u16;
+ return &XRGB16161616_read_line;
case DRM_FORMAT_RGB565:
- return &RGB565_to_argb_u16;
+ return &RGB565_read_line;
default:
/*
* This is a bug in vkms_plane_atomic_check(). All the supported
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
index 3ecea4563254..8d2bef95ff79 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -5,7 +5,7 @@
#include "vkms_drv.h"
-pixel_read_t get_pixel_read_function(u32 format);
+pixel_read_line_t get_pixel_read_line_function(u32 format);
pixel_write_t get_pixel_write_function(u32 format);
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 10e9b23dab28..8875bed76410 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -112,7 +112,6 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
frame_info = vkms_plane_state->frame_info;
memcpy(&frame_info->src, &new_state->src, sizeof(struct drm_rect));
memcpy(&frame_info->dst, &new_state->dst, sizeof(struct drm_rect));
- memcpy(&frame_info->rotated, &new_state->dst, sizeof(struct drm_rect));
frame_info->fb = fb;
memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
drm_framebuffer_get(frame_info->fb);
@@ -122,10 +121,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
DRM_MODE_REFLECT_X |
DRM_MODE_REFLECT_Y);
- drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
- drm_rect_height(&frame_info->rotated), frame_info->rotation);
- vkms_plane_state->pixel_read = get_pixel_read_function(fmt);
+ vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
}
static int vkms_plane_atomic_check(struct drm_plane *plane,
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (7 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-11 9:36 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 10/15] drm/vkms: Add YUV support Louis Chauvet
` (5 subsequent siblings)
14 siblings, 1 reply; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee
As all the rotation are now supported by VKMS, this simplification does
not make sense anymore, so remove it.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 8875bed76410..5a028ee96c91 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
frame_info->fb = fb;
memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
drm_framebuffer_get(frame_info->fb);
- frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
- DRM_MODE_ROTATE_90 |
- DRM_MODE_ROTATE_270 |
- DRM_MODE_REFLECT_X |
- DRM_MODE_REFLECT_Y);
-
+ frame_info->rotation = new_state->rotation;
vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
}
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 10/15] drm/vkms: Add YUV support
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (8 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 11/15] drm/vkms: Add range and encoding properties to the plane Louis Chauvet
` (4 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee
From: Arthur Grillo <arthurgrillo@riseup.net>
Add support to the YUV formats bellow:
- NV12/NV16/NV24
- NV21/NV61/NV42
- YUV420/YUV422/YUV444
- YVU420/YVU422/YVU444
The conversion from yuv to rgb is done with fixed-point arithmetic, using
32.32 fixed-point numbers and the drm_fixed helpers.
To do the conversion, a specific matrix must be used for each color range
(DRM_COLOR_*_RANGE) and encoding (DRM_COLOR_*). This matrix is stored in
the `conversion_matrix` struct, along with the specific y_offset needed.
This matrix is queried only once, in `vkms_plane_atomic_update` and
stored in a `vkms_plane_state`. Those conversion matrices of each
encoding and range were obtained by rounding the values of the original
conversion matrices multiplied by 2^32. This is done to avoid the use of
floating point operations.
The same reading function is used for YUV and YVU formats. As the only
difference between those two category of formats is the order of field, a
simple swap in conversion matrix columns allows using the same function.
Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
[Louis Chauvet:
- Adapted Arthur's work
- Implemented the read_line_t callbacks for yuv
- add struct conversion_matrix
- store the whole conversion_matrix in the plane state
- remove struct pixel_yuv_u8
- update the commit message
- Merge the modifications from Arthur]
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_drv.h | 18 ++
drivers/gpu/drm/vkms/vkms_formats.c | 353 ++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_formats.h | 4 +
drivers/gpu/drm/vkms/vkms_plane.c | 16 +-
4 files changed, 390 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 067a4797f7a0..337ca3f39cd2 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -100,17 +100,35 @@ typedef void (*pixel_read_line_t)(const struct vkms_plane_state *plane, int x_st
int y_start, enum pixel_read_direction direction, int count,
struct pixel_argb_u16 out_pixel[]);
+/**
+ * struct conversion_matrix - Matrix to use for a specific encoding and range
+ *
+ * @matrix: Conversion matrix from yuv to rgb. The matrix is stored in a row-major manner and is
+ * used to compute rgb values from yuv values:
+ * [[r],[g],[b]] = @matrix * [[y],[u],[v]]
+ * OR for yvu formats:
+ * [[r],[g],[b]] = @matrix * [[y],[v],[u]]
+ * The values of the matrix are signed fixed-point values with 32 bits fractional part.
+ * @y_offset: Offset to apply on the y value.
+ */
+struct conversion_matrix {
+ s64 matrix[3][3];
+ int y_offset;
+};
+
/**
* struct vkms_plane_state - Driver specific plane state
* @base: base plane state
* @frame_info: data required for composing computation
* @pixel_read_line: function to read a pixel line in this plane. The creator of a
* struct vkms_plane_state must ensure that this pointer is valid
+ * @conversion_matrix: matrix used for yuv formats to convert to rgb
*/
struct vkms_plane_state {
struct drm_shadow_plane_state base;
struct vkms_frame_info *frame_info;
pixel_read_line_t pixel_read_line;
+ struct conversion_matrix conversion_matrix;
};
struct vkms_plane {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index 0f6678420a11..adb1228e5201 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -140,6 +140,51 @@ static void packed_pixels_addr_1x1(const struct vkms_frame_info *frame_info,
*addr = (u8 *)frame_info->map[0].vaddr + offset;
}
+/**
+ * get_subsampling() - Get the subsampling divisor value on a specific direction
+ *
+ * @format: format to extarct the subsampling from
+ * @direction: direction of the subsampling requested
+ */
+static int get_subsampling(const struct drm_format_info *format,
+ enum pixel_read_direction direction)
+{
+ switch (direction) {
+ case READ_BOTTOM_TO_TOP:
+ case READ_TOP_TO_BOTTOM:
+ return format->vsub;
+ case READ_RIGHT_TO_LEFT:
+ case READ_LEFT_TO_RIGHT:
+ return format->hsub;
+ }
+ WARN_ONCE(true, "Invalid direction for pixel reading: %d\n", direction);
+ return 1;
+}
+
+/**
+ * get_subsampling_offset() - An offset for keeping the chroma siting consistent regardless of
+ * x_start and y_start values
+ *
+ * @direction: direction of the reading to properly compute this offset
+ * @x_start: x coordinate of the starting point of the readed line
+ * @y_start: y coordinate of the starting point of the readed line
+ */
+static int get_subsampling_offset(enum pixel_read_direction direction, int x_start, int y_start)
+{
+ switch (direction) {
+ case READ_BOTTOM_TO_TOP:
+ return -y_start - 1;
+ case READ_TOP_TO_BOTTOM:
+ return y_start;
+ case READ_RIGHT_TO_LEFT:
+ return -x_start - 1;
+ case READ_LEFT_TO_RIGHT:
+ return x_start;
+ }
+ WARN_ONCE(true, "Invalid direction for pixel reading: %d\n", direction);
+ return 0;
+}
+
/*
* The following functions take pixel data (a, r, g, b, pixel, ...) and convert them to
* &struct pixel_argb_u16
@@ -202,6 +247,38 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
return out_pixel;
}
+static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
+ const struct conversion_matrix *matrix)
+{
+ u16 r, g, b;
+ s64 fp_y, fp_channel_1, fp_channel_2;
+ s64 fp_r, fp_g, fp_b;
+
+ fp_y = drm_int2fixp(((int)y - matrix->y_offset) * 257);
+ fp_channel_1 = drm_int2fixp(((int)channel_1 - 128) * 257);
+ fp_channel_2 = drm_int2fixp(((int)channel_2 - 128) * 257);
+
+ fp_r = drm_fixp_mul(matrix->matrix[0][0], fp_y) +
+ drm_fixp_mul(matrix->matrix[0][1], fp_channel_1) +
+ drm_fixp_mul(matrix->matrix[0][2], fp_channel_2);
+ fp_g = drm_fixp_mul(matrix->matrix[1][0], fp_y) +
+ drm_fixp_mul(matrix->matrix[1][1], fp_channel_1) +
+ drm_fixp_mul(matrix->matrix[1][2], fp_channel_2);
+ fp_b = drm_fixp_mul(matrix->matrix[2][0], fp_y) +
+ drm_fixp_mul(matrix->matrix[2][1], fp_channel_1) +
+ drm_fixp_mul(matrix->matrix[2][2], fp_channel_2);
+
+ fp_r = drm_fixp2int_round(fp_r);
+ fp_g = drm_fixp2int_round(fp_g);
+ fp_b = drm_fixp2int_round(fp_b);
+
+ r = clamp(fp_r, 0, 0xffff);
+ g = clamp(fp_g, 0, 0xffff);
+ b = clamp(fp_b, 0, 0xffff);
+
+ return argb_u16_from_u16161616(0xffff, r, g, b);
+}
+
/*
* The following functions are read_line function for each pixel format supported by VKMS.
*
@@ -311,6 +388,92 @@ static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start,
}
}
+/*
+ * This callback can be used for YUV formats where U and V values are
+ * stored in the same plane (often called semi-planar formats). It will
+ * correctly handle subsampling as described in the drm_format_info of the plane.
+ *
+ * The conversion matrix stored in the @plane is used to:
+ * - Apply the correct color range and encoding
+ * - Convert YUV and YVU with the same function (a column swap is needed when setting up
+ * plane->conversion_matrix)
+ */
+static void semi_planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ u8 *y_plane;
+ u8 *uv_plane;
+
+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0,
+ &y_plane);
+ packed_pixels_addr_1x1(plane->frame_info,
+ x_start / plane->frame_info->fb->format->hsub,
+ y_start / plane->frame_info->fb->format->vsub, 1,
+ &uv_plane);
+ int step_y = get_block_step_bytes(plane->frame_info->fb, direction, 0);
+ int step_uv = get_block_step_bytes(plane->frame_info->fb, direction, 1);
+ int subsampling = get_subsampling(plane->frame_info->fb->format, direction);
+ int subsampling_offset = get_subsampling_offset(direction, x_start, y_start);
+ const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix;
+
+ for (int i = 0; i < count; i++) {
+ *out_pixel = argb_u16_from_yuv888(y_plane[0], uv_plane[0], uv_plane[1],
+ conversion_matrix);
+ out_pixel += 1;
+ y_plane += step_y;
+ if ((i + subsampling_offset + 1) % subsampling == 0)
+ uv_plane += step_uv;
+ }
+}
+
+/*
+ * This callback can be used for YUV format where each color component is
+ * stored in a different plane (often called planar formats). It will
+ * correctly handle subsampling as described in the drm_format_info of the plane.
+ *
+ * The conversion matrix stored in the @plane is used to:
+ * - Apply the correct color range and encoding
+ * - Convert YUV and YVU with the same function (a column swap is needed when setting up
+ * plane->conversion_matrix)
+ */
+static void planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ u8 *y_plane;
+ u8 *channel_1_plane;
+ u8 *channel_2_plane;
+
+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0,
+ &y_plane);
+ packed_pixels_addr_1x1(plane->frame_info,
+ x_start / plane->frame_info->fb->format->hsub,
+ y_start / plane->frame_info->fb->format->vsub, 1,
+ &channel_1_plane);
+ packed_pixels_addr_1x1(plane->frame_info,
+ x_start / plane->frame_info->fb->format->hsub,
+ y_start / plane->frame_info->fb->format->vsub, 2,
+ &channel_2_plane);
+ int step_y = get_block_step_bytes(plane->frame_info->fb, direction, 0);
+ int step_channel_1 = get_block_step_bytes(plane->frame_info->fb, direction, 1);
+ int step_channel_2 = get_block_step_bytes(plane->frame_info->fb, direction, 2);
+ int subsampling = get_subsampling(plane->frame_info->fb->format, direction);
+ int subsampling_offset = get_subsampling_offset(direction, x_start, y_start);
+ const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix;
+
+ for (int i = 0; i < count; i++) {
+ *out_pixel = argb_u16_from_yuv888(*y_plane, *channel_1_plane, *channel_2_plane,
+ conversion_matrix);
+ out_pixel += 1;
+ y_plane += step_y;
+ if ((i + subsampling_offset + 1) % subsampling == 0) {
+ channel_1_plane += step_channel_1;
+ channel_2_plane += step_channel_2;
+ }
+ }
+}
+
/*
* The following functions take one &struct pixel_argb_u16 and convert it to a specific format.
* The result is stored in @out_pixel.
@@ -426,6 +589,20 @@ pixel_read_line_t get_pixel_read_line_function(u32 format)
return &XRGB16161616_read_line;
case DRM_FORMAT_RGB565:
return &RGB565_read_line;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV42:
+ return &semi_planar_yuv_read_line;
+ case DRM_FORMAT_YUV420:
+ case DRM_FORMAT_YUV422:
+ case DRM_FORMAT_YUV444:
+ case DRM_FORMAT_YVU420:
+ case DRM_FORMAT_YVU422:
+ case DRM_FORMAT_YVU444:
+ return &planar_yuv_read_line;
default:
/*
* This is a bug in vkms_plane_atomic_check(). All the supported
@@ -439,6 +616,182 @@ pixel_read_line_t get_pixel_read_line_function(u32 format)
}
}
+/*
+ * Those matrices were generated using the colour python framework
+ *
+ * Below are the function calls used to generate each matrix, go to
+ * https://colour.readthedocs.io/en/develop/generated/colour.matrix_YCbCr.html
+ * for more info:
+ *
+ * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
+ * is_legal = False,
+ * bits = 8) * 2**32).astype(int)
+ */
+static const struct conversion_matrix no_operation = {
+ .matrix = {
+ { 4294967296, 0, 0, },
+ { 0, 4294967296, 0, },
+ { 0, 0, 4294967296, },
+ },
+ .y_offset = 0,
+};
+
+static const struct conversion_matrix yuv_bt601_full = {
+ .matrix = {
+ { 4294967296, 0, 6021544149 },
+ { 4294967296, -1478054095, -3067191994 },
+ { 4294967296, 7610682049, 0 },
+ },
+ .y_offset = 0,
+};
+
+/*
+ * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
+ * is_legal = True,
+ * bits = 8) * 2**32).astype(int)
+ */
+static const struct conversion_matrix yuv_bt601_limited = {
+ .matrix = {
+ { 5020601039, 0, 6881764740 },
+ { 5020601039, -1689204679, -3505362278 },
+ { 5020601039, 8697922339, 0 },
+ },
+ .y_offset = 16,
+};
+
+/*
+ * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.709"],
+ * is_legal = False,
+ * bits = 8) * 2**32).astype(int)
+ */
+static const struct conversion_matrix yuv_bt709_full = {
+ .matrix = {
+ { 4294967296, 0, 6763714498 },
+ { 4294967296, -804551626, -2010578443 },
+ { 4294967296, 7969741314, 0 },
+ },
+ .y_offset = 0,
+};
+
+/*
+ * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.709"],
+ * is_legal = True,
+ * bits = 8) * 2**32).astype(int)
+ */
+static const struct conversion_matrix yuv_bt709_limited = {
+ .matrix = {
+ { 5020601039, 0, 7729959424 },
+ { 5020601039, -919487572, -2297803934 },
+ { 5020601039, 9108275786, 0 },
+ },
+ .y_offset = 16,
+};
+
+/*
+ * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"],
+ * is_legal = False,
+ * bits = 8) * 2**32).astype(int)
+ */
+static const struct conversion_matrix yuv_bt2020_full = {
+ .matrix = {
+ { 4294967296, 0, 6333358775 },
+ { 4294967296, -706750298, -2453942994 },
+ { 4294967296, 8080551471, 0 },
+ },
+ .y_offset = 0,
+};
+
+/*
+ * numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"],
+ * is_legal = True,
+ * bits = 8) * 2**32).astype(int)
+ */
+static const struct conversion_matrix yuv_bt2020_limited = {
+ .matrix = {
+ { 5020601039, 0, 7238124312 },
+ { 5020601039, -807714626, -2804506279 },
+ { 5020601039, 9234915964, 0 },
+ },
+ .y_offset = 16,
+};
+
+/**
+ * swap_uv_columns() - Swap u and v column of a given matrix
+ *
+ * @matrix: Matrix in which column are swapped
+ */
+static void swap_uv_columns(struct conversion_matrix *matrix)
+{
+ swap(matrix->matrix[0][2], matrix->matrix[0][1]);
+ swap(matrix->matrix[1][2], matrix->matrix[1][1]);
+ swap(matrix->matrix[2][2], matrix->matrix[2][1]);
+}
+
+/**
+ * get_conversion_matrix_to_argb_u16() - Retrieve the correct yuv to rgb conversion matrix for a
+ * given encoding and range.
+ *
+ * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h])
+ * @encoding: DRM_COLOR_* value for which to obtain a conversion matrix
+ * @range: DRM_COLOR_*_RANGE value for which to obtain a conversion matrix
+ * @matrix: Pointer to store the value into
+ */
+void get_conversion_matrix_to_argb_u16(u32 format,
+ enum drm_color_encoding encoding,
+ enum drm_color_range range,
+ struct conversion_matrix *matrix)
+{
+ const struct conversion_matrix *matrix_to_copy;
+ bool limited_range;
+
+ switch (range) {
+ case DRM_COLOR_YCBCR_LIMITED_RANGE:
+ limited_range = true;
+ break;
+ case DRM_COLOR_YCBCR_FULL_RANGE:
+ limited_range = false;
+ break;
+ case DRM_COLOR_RANGE_MAX:
+ limited_range = false;
+ WARN_ONCE(true, "The requested range is not supported.");
+ break;
+ }
+
+ switch (encoding) {
+ case DRM_COLOR_YCBCR_BT601:
+ matrix_to_copy = limited_range ? &yuv_bt601_limited :
+ &yuv_bt601_full;
+ break;
+ case DRM_COLOR_YCBCR_BT709:
+ matrix_to_copy = limited_range ? &yuv_bt709_limited :
+ &yuv_bt709_full;
+ break;
+ case DRM_COLOR_YCBCR_BT2020:
+ matrix_to_copy = limited_range ? &yuv_bt2020_limited :
+ &yuv_bt2020_full;
+ break;
+ case DRM_COLOR_ENCODING_MAX:
+ matrix_to_copy = &no_operation;
+ WARN_ONCE(true, "The requested encoding is not supported.");
+ break;
+ }
+
+ memcpy(matrix, matrix_to_copy, sizeof(*matrix_to_copy));
+
+ switch (format) {
+ case DRM_FORMAT_YVU420:
+ case DRM_FORMAT_YVU422:
+ case DRM_FORMAT_YVU444:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV42:
+ swap_uv_columns(matrix);
+ break;
+ default:
+ break;
+ }
+}
+
/**
* get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format.
* The returned pointer is NULL for unsupported pixel formats. The caller must ensure that the
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
index 8d2bef95ff79..d583855cb320 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -9,4 +9,8 @@ pixel_read_line_t get_pixel_read_line_function(u32 format);
pixel_write_t get_pixel_write_function(u32 format);
+void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encoding,
+ enum drm_color_range range,
+ struct conversion_matrix *matrix);
+
#endif /* _VKMS_FORMATS_H_ */
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 5a028ee96c91..d4e375913122 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -17,7 +17,19 @@ static const u32 vkms_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_XRGB16161616,
DRM_FORMAT_ARGB16161616,
- DRM_FORMAT_RGB565
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV42,
+ DRM_FORMAT_YUV420,
+ DRM_FORMAT_YUV422,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YVU420,
+ DRM_FORMAT_YVU422,
+ DRM_FORMAT_YVU444,
};
static struct drm_plane_state *
@@ -118,6 +130,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
frame_info->rotation = new_state->rotation;
vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
+ get_conversion_matrix_to_argb_u16(fmt, new_state->color_encoding, new_state->color_range,
+ &vkms_plane_state->conversion_matrix);
}
static int vkms_plane_atomic_check(struct drm_plane *plane,
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 11/15] drm/vkms: Add range and encoding properties to the plane
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (9 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 10/15] drm/vkms: Add YUV support Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 12/15] drm/vkms: Drop YUV formats TODO Louis Chauvet
` (3 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen
From: Arthur Grillo <arthurgrillo@riseup.net>
Now that the driver internally handles these quantization ranges and YUV
encoding matrices, expose the UAPI for setting them.
Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
[Louis Chauvet: retained only relevant parts, updated the commit message]
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_plane.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index d4e375913122..8f764a108b00 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -218,5 +218,14 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
+ drm_plane_create_color_properties(&plane->base,
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020),
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+ DRM_COLOR_YCBCR_BT601,
+ DRM_COLOR_YCBCR_FULL_RANGE);
+
return plane;
}
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 12/15] drm/vkms: Drop YUV formats TODO
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (10 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 11/15] drm/vkms: Add range and encoding properties to the plane Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions Louis Chauvet
` (2 subsequent siblings)
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee
From: Arthur Grillo <arthurgrillo@riseup.net>
VKMS has support for YUV formats now. Remove the task from the TODO
list.
Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index ba04ac7c2167..13b866c3617c 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -122,8 +122,7 @@ There's lots of plane features we could add support for:
- Scaling.
-- Additional buffer formats, especially YUV formats for video like NV12.
- Low/high bpp RGB formats would also be interesting.
+- Additional buffer formats. Low/high bpp RGB formats would be interesting.
- Async updates (currently only possible on cursor plane using the legacy
cursor api).
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (11 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 12/15] drm/vkms: Drop YUV formats TODO Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-08 7:53 ` Maxime Ripard
` (2 more replies)
2024-10-07 16:10 ` [PATCH v12 14/15] drm/vkms: Add how to run the Kunit tests Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 15/15] drm/vkms: Add support for DRM_FORMAT_R* Louis Chauvet
14 siblings, 3 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen
From: Arthur Grillo <arthurgrillo@riseup.net>
Create KUnit tests to test the conversion between YUV and RGB. Test each
conversion and range combination with some common colors.
The code used to compute the expected result can be found in comment.
[Louis Chauvet:
- fix minor formating issues (whitespace, double line)
- change expected alpha from 0x0000 to 0xffff
- adapt to the new get_conversion_matrix usage
- apply the changes from Arthur
- move struct pixel_yuv_u8 to the test itself]
Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/Kconfig | 15 ++
drivers/gpu/drm/vkms/Makefile | 1 +
drivers/gpu/drm/vkms/tests/.kunitconfig | 4 +
drivers/gpu/drm/vkms/tests/Makefile | 3 +
drivers/gpu/drm/vkms/tests/vkms_format_test.c | 232 ++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_formats.c | 7 +-
drivers/gpu/drm/vkms/vkms_formats.h | 5 +
7 files changed, 265 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
index 9def079f685b..98ecfce929f3 100644
--- a/drivers/gpu/drm/vkms/Kconfig
+++ b/drivers/gpu/drm/vkms/Kconfig
@@ -14,3 +14,18 @@ config DRM_VKMS
a VKMS.
If M is selected the module will be called vkms.
+
+config DRM_VKMS_KUNIT_TESTS
+ tristate "KUnit tests for VKMS." if !KUNIT_ALL_TESTS
+ depends on DRM_VKMS=y && KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ This builds unit tests for VKMS. This option is not useful for
+ distributions or general kernels, but only for kernel
+ developers working on VKMS.
+
+ For more information on KUnit and unit tests in general,
+ please refer to the KUnit documentation in
+ Documentation/dev-tools/kunit/.
+
+ If in doubt, say "N".
diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
index 1b28a6a32948..8d3e46dde635 100644
--- a/drivers/gpu/drm/vkms/Makefile
+++ b/drivers/gpu/drm/vkms/Makefile
@@ -9,3 +9,4 @@ vkms-y := \
vkms_writeback.o
obj-$(CONFIG_DRM_VKMS) += vkms.o
+obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += tests/
diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig b/drivers/gpu/drm/vkms/tests/.kunitconfig
new file mode 100644
index 000000000000..70e378228cbd
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
@@ -0,0 +1,4 @@
+CONFIG_KUNIT=y
+CONFIG_DRM=y
+CONFIG_DRM_VKMS=y
+CONFIG_DRM_VKMS_KUNIT_TESTS=y
diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile
new file mode 100644
index 000000000000..2d1df668569e
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += vkms_format_test.o
diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
new file mode 100644
index 000000000000..351409897ca3
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <kunit/test.h>
+
+#include <drm/drm_fixed.h>
+#include <drm/drm_fourcc.h>
+
+#include "../../drm_crtc_internal.h"
+
+#include "../vkms_formats.h"
+
+#define TEST_BUFF_SIZE 50
+
+MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
+
+struct pixel_yuv_u8 {
+ u8 y, u, v;
+};
+
+struct yuv_u8_to_argb_u16_case {
+ enum drm_color_encoding encoding;
+ enum drm_color_range range;
+ size_t n_colors;
+ struct format_pair {
+ char *name;
+ struct pixel_yuv_u8 yuv;
+ struct pixel_argb_u16 argb;
+ } colors[TEST_BUFF_SIZE];
+};
+
+/*
+ * The YUV color representation were acquired via the colour python framework.
+ * Below are the function calls used for generating each case.
+ *
+ * For more information got to the docs:
+ * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html
+ */
+static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
+ /*
+ * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
+ * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
+ * in_bits = 16,
+ * in_legal = False,
+ * in_int = True,
+ * out_bits = 8,
+ * out_legal = False,
+ * out_int = True)
+ */
+ {
+ .encoding = DRM_COLOR_YCBCR_BT601,
+ .range = DRM_COLOR_YCBCR_FULL_RANGE,
+ .n_colors = 6,
+ .colors = {
+ { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }},
+ { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }},
+ { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }},
+ { "red", { 0x4c, 0x55, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }},
+ { "green", { 0x96, 0x2c, 0x15 }, { 0xffff, 0x0000, 0xffff, 0x0000 }},
+ { "blue", { 0x1d, 0xff, 0x6b }, { 0xffff, 0x0000, 0x0000, 0xffff }},
+ },
+ },
+ /*
+ * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
+ * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
+ * in_bits = 16,
+ * in_legal = False,
+ * in_int = True,
+ * out_bits = 8,
+ * out_legal = True,
+ * out_int = True)
+ */
+ {
+ .encoding = DRM_COLOR_YCBCR_BT601,
+ .range = DRM_COLOR_YCBCR_LIMITED_RANGE,
+ .n_colors = 6,
+ .colors = {
+ { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }},
+ { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }},
+ { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }},
+ { "red", { 0x51, 0x5a, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }},
+ { "green", { 0x91, 0x36, 0x22 }, { 0xffff, 0x0000, 0xffff, 0x0000 }},
+ { "blue", { 0x29, 0xf0, 0x6e }, { 0xffff, 0x0000, 0x0000, 0xffff }},
+ },
+ },
+ /*
+ * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
+ * K=colour.WEIGHTS_YCBCR["ITU-R BT.709"],
+ * in_bits = 16,
+ * in_legal = False,
+ * in_int = True,
+ * out_bits = 8,
+ * out_legal = False,
+ * out_int = True)
+ */
+ {
+ .encoding = DRM_COLOR_YCBCR_BT709,
+ .range = DRM_COLOR_YCBCR_FULL_RANGE,
+ .n_colors = 4,
+ .colors = {
+ { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }},
+ { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }},
+ { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }},
+ { "red", { 0x36, 0x63, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }},
+ { "green", { 0xb6, 0x1e, 0x0c }, { 0xffff, 0x0000, 0xffff, 0x0000 }},
+ { "blue", { 0x12, 0xff, 0x74 }, { 0xffff, 0x0000, 0x0000, 0xffff }},
+ },
+ },
+ /*
+ * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
+ * K=colour.WEIGHTS_YCBCR["ITU-R BT.709"],
+ * in_bits = 16,
+ * int_legal = False,
+ * in_int = True,
+ * out_bits = 8,
+ * out_legal = True,
+ * out_int = True)
+ */
+ {
+ .encoding = DRM_COLOR_YCBCR_BT709,
+ .range = DRM_COLOR_YCBCR_LIMITED_RANGE,
+ .n_colors = 4,
+ .colors = {
+ { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }},
+ { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }},
+ { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }},
+ { "red", { 0x3f, 0x66, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }},
+ { "green", { 0xad, 0x2a, 0x1a }, { 0xffff, 0x0000, 0xffff, 0x0000 }},
+ { "blue", { 0x20, 0xf0, 0x76 }, { 0xffff, 0x0000, 0x0000, 0xffff }},
+ },
+ },
+ /*
+ * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
+ * K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"],
+ * in_bits = 16,
+ * in_legal = False,
+ * in_int = True,
+ * out_bits = 8,
+ * out_legal = False,
+ * out_int = True)
+ */
+ {
+ .encoding = DRM_COLOR_YCBCR_BT2020,
+ .range = DRM_COLOR_YCBCR_FULL_RANGE,
+ .n_colors = 4,
+ .colors = {
+ { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }},
+ { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }},
+ { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }},
+ { "red", { 0x43, 0x5c, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }},
+ { "green", { 0xad, 0x24, 0x0b }, { 0xffff, 0x0000, 0xffff, 0x0000 }},
+ { "blue", { 0x0f, 0xff, 0x76 }, { 0xffff, 0x0000, 0x0000, 0xffff }},
+ },
+ },
+ /*
+ * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
+ * K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"],
+ * in_bits = 16,
+ * in_legal = False,
+ * in_int = True,
+ * out_bits = 8,
+ * out_legal = True,
+ * out_int = True)
+ */
+ {
+ .encoding = DRM_COLOR_YCBCR_BT2020,
+ .range = DRM_COLOR_YCBCR_LIMITED_RANGE,
+ .n_colors = 4,
+ .colors = {
+ { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }},
+ { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }},
+ { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }},
+ { "red", { 0x4a, 0x61, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }},
+ { "green", { 0xa4, 0x2f, 0x19 }, { 0xffff, 0x0000, 0xffff, 0x0000 }},
+ { "blue", { 0x1d, 0xf0, 0x77 }, { 0xffff, 0x0000, 0x0000, 0xffff }},
+ },
+ },
+};
+
+static void vkms_format_test_yuv_u8_to_argb_u16(struct kunit *test)
+{
+ const struct yuv_u8_to_argb_u16_case *param = test->param_value;
+ struct pixel_argb_u16 argb;
+
+ for (size_t i = 0; i < param->n_colors; i++) {
+ const struct format_pair *color = ¶m->colors[i];
+ struct conversion_matrix matrix;
+
+ get_conversion_matrix_to_argb_u16
+ (DRM_FORMAT_NV12, param->encoding, param->range, &matrix);
+
+ argb = argb_u16_from_yuv888(color->yuv.y, color->yuv.u, color->yuv.v, &matrix);
+
+ KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.a, color->argb.a), 257,
+ "On the A channel of the color %s expected 0x%04x, got 0x%04x",
+ color->name, color->argb.a, argb.a);
+ KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.r, color->argb.r), 257,
+ "On the R channel of the color %s expected 0x%04x, got 0x%04x",
+ color->name, color->argb.r, argb.r);
+ KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.g, color->argb.g), 257,
+ "On the G channel of the color %s expected 0x%04x, got 0x%04x",
+ color->name, color->argb.g, argb.g);
+ KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.b, color->argb.b), 257,
+ "On the B channel of the color %s expected 0x%04x, got 0x%04x",
+ color->name, color->argb.b, argb.b);
+ }
+}
+
+static void vkms_format_test_yuv_u8_to_argb_u16_case_desc(struct yuv_u8_to_argb_u16_case *t,
+ char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s - %s",
+ drm_get_color_encoding_name(t->encoding), drm_get_color_range_name(t->range));
+}
+
+KUNIT_ARRAY_PARAM(yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_cases,
+ vkms_format_test_yuv_u8_to_argb_u16_case_desc
+);
+
+static struct kunit_case vkms_format_test_cases[] = {
+ KUNIT_CASE_PARAM(vkms_format_test_yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_gen_params),
+ {}
+};
+
+static struct kunit_suite vkms_format_test_suite = {
+ .name = "vkms-format",
+ .test_cases = vkms_format_test_cases,
+};
+
+kunit_test_suite(vkms_format_test_suite);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Kunit test for vkms format conversion");
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index adb1228e5201..0b201185eae7 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -7,6 +7,8 @@
#include <drm/drm_rect.h>
#include <drm/drm_fixed.h>
+#include <kunit/visibility.h>
+
#include "vkms_formats.h"
/**
@@ -247,8 +249,8 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
return out_pixel;
}
-static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
- const struct conversion_matrix *matrix)
+VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
+ const struct conversion_matrix *matrix)
{
u16 r, g, b;
s64 fp_y, fp_channel_1, fp_channel_2;
@@ -278,6 +280,7 @@ static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel
return argb_u16_from_u16161616(0xffff, r, g, b);
}
+EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888);
/*
* The following functions are read_line function for each pixel format supported by VKMS.
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
index d583855cb320..b4fe62ab9c65 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -13,4 +13,9 @@ void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encod
enum drm_color_range range,
struct conversion_matrix *matrix);
+#if IS_ENABLED(CONFIG_KUNIT)
+struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
+ const struct conversion_matrix *matrix);
+#endif
+
#endif /* _VKMS_FORMATS_H_ */
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 14/15] drm/vkms: Add how to run the Kunit tests
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (12 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 15/15] drm/vkms: Add support for DRM_FORMAT_R* Louis Chauvet
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee
From: Arthur Grillo <arthurgrillo@riseup.net>
Now that we have KUnit tests, add instructions on how to run them.
Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 13b866c3617c..5ef5ef2e6a21 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -89,6 +89,17 @@ You can also run subtests if you do not want to run the entire test::
sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device "sys:/sys/devices/platform/vkms"
sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip --run-subtest basic-plain-flip
+Testing With KUnit
+==================
+
+KUnit (Kernel unit testing framework) provides a common framework for unit tests
+within the Linux kernel.
+More information in ../dev-tools/kunit/index.rst .
+
+To run the VKMS KUnit tests::
+
+ tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/vkms/tests
+
TODO
====
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v12 15/15] drm/vkms: Add support for DRM_FORMAT_R*
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
` (13 preceding siblings ...)
2024-10-07 16:10 ` [PATCH v12 14/15] drm/vkms: Add how to run the Kunit tests Louis Chauvet
@ 2024-10-07 16:10 ` Louis Chauvet
14 siblings, 0 replies; 36+ messages in thread
From: Louis Chauvet @ 2024-10-07 16:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Louis Chauvet, Simona Vetter, rdunlap,
arthurgrillo, pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen
This add the support for:
- R1/R2/R4/R8
R1 format was tested with [1] and [2].
[1]: https://lore.kernel.org/r/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com
[2]: https://lore.kernel.org/igt-dev/20240306-b4-kms_tests-v1-0-8fe451efd2ac@bootlin.com/
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_formats.c | 110 +++++++++++++++++++++++++++++++++++-
drivers/gpu/drm/vkms/vkms_plane.c | 4 ++
2 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index 0b201185eae7..f9841b8000c4 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -249,6 +249,16 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
return out_pixel;
}
+static struct pixel_argb_u16 argb_u16_from_gray8(u16 gray)
+{
+ return argb_u16_from_u8888(255, gray, gray, gray);
+}
+
+static struct pixel_argb_u16 argb_u16_from_grayu16(u16 gray)
+{
+ return argb_u16_from_u16161616(0xFFFF, gray, gray, gray);
+}
+
VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
const struct conversion_matrix *matrix)
{
@@ -286,7 +296,7 @@ EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888);
* The following functions are read_line function for each pixel format supported by VKMS.
*
* They read a line starting at the point @x_start,@y_start following the @direction. The result
- * is stored in @out_pixel and in the format ARGB16161616.
+ * is stored in @out_pixel and in a 64 bits format, see struct pixel_argb_u16.
*
* These functions are very repetitive, but the innermost pixel loops must be kept inside these
* functions for performance reasons. Some benchmarking was done in [1] where having the innermost
@@ -295,6 +305,96 @@ EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888);
* [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
*/
+static void Rx_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ struct pixel_argb_u16 *end = out_pixel + count;
+ int bits_per_pixel = drm_format_info_bpp(plane->frame_info->fb->format, 0);
+ u8 *src_pixels;
+ int rem_x, rem_y;
+
+ WARN_ONCE(drm_format_info_block_height(plane->frame_info->fb->format, 0) != 1,
+ "%s() only support formats with block_h == 1", __func__);
+
+ packed_pixels_addr(plane->frame_info, x_start, y_start, 0, &src_pixels, &rem_x, &rem_y);
+ int bit_offset = (8 - bits_per_pixel) - rem_x * bits_per_pixel;
+ int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
+ int mask = (0x1 << bits_per_pixel) - 1;
+ int lum_per_level = 0xFFFF / mask;
+
+ if (direction == READ_LEFT_TO_RIGHT || direction == READ_RIGHT_TO_LEFT) {
+ int restart_bit_offset;
+ int step_bit_offset;
+
+ if (direction == READ_LEFT_TO_RIGHT) {
+ restart_bit_offset = 8 - bits_per_pixel;
+ step_bit_offset = -bits_per_pixel;
+ } else {
+ restart_bit_offset = 0;
+ step_bit_offset = bits_per_pixel;
+ }
+
+ while (out_pixel < end) {
+ u8 val = ((*src_pixels) >> bit_offset) & mask;
+
+ *out_pixel = argb_u16_from_grayu16((int)val * lum_per_level);
+
+ bit_offset += step_bit_offset;
+ if (bit_offset < 0 || 8 <= bit_offset) {
+ bit_offset = restart_bit_offset;
+ src_pixels += step;
+ }
+ out_pixel += 1;
+ }
+ } else if (direction == READ_TOP_TO_BOTTOM || direction == READ_BOTTOM_TO_TOP) {
+ while (out_pixel < end) {
+ u8 val = (*src_pixels >> bit_offset) & mask;
+ *out_pixel = argb_u16_from_grayu16((int)val * lum_per_level);
+ src_pixels += step;
+ out_pixel += 1;
+ }
+ }
+}
+
+static void R1_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ Rx_read_line(plane, x_start, y_start, direction, count, out_pixel);
+}
+
+static void R2_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ Rx_read_line(plane, x_start, y_start, direction, count, out_pixel);
+}
+
+static void R4_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ Rx_read_line(plane, x_start, y_start, direction, count, out_pixel);
+}
+
+static void R8_read_line(const struct vkms_plane_state *plane, int x_start,
+ int y_start, enum pixel_read_direction direction, int count,
+ struct pixel_argb_u16 out_pixel[])
+{
+ struct pixel_argb_u16 *end = out_pixel + count;
+ u8 *src_pixels;
+ int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
+
+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
+
+ while (out_pixel < end) {
+ *out_pixel = argb_u16_from_gray8(*src_pixels);
+ src_pixels += step;
+ out_pixel += 1;
+ }
+}
+
static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
enum pixel_read_direction direction, int count,
struct pixel_argb_u16 out_pixel[])
@@ -606,6 +706,14 @@ pixel_read_line_t get_pixel_read_line_function(u32 format)
case DRM_FORMAT_YVU422:
case DRM_FORMAT_YVU444:
return &planar_yuv_read_line;
+ case DRM_FORMAT_R1:
+ return &R1_read_line;
+ case DRM_FORMAT_R2:
+ return &R2_read_line;
+ case DRM_FORMAT_R4:
+ return &R4_read_line;
+ case DRM_FORMAT_R8:
+ return &R8_read_line;
default:
/*
* This is a bug in vkms_plane_atomic_check(). All the supported
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 8f764a108b00..67f891e7ac58 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -30,6 +30,10 @@ static const u32 vkms_formats[] = {
DRM_FORMAT_YVU420,
DRM_FORMAT_YVU422,
DRM_FORMAT_YVU444,
+ DRM_FORMAT_R1,
+ DRM_FORMAT_R2,
+ DRM_FORMAT_R4,
+ DRM_FORMAT_R8,
};
static struct drm_plane_state *
--
2.46.2
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-07 16:10 ` [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions Louis Chauvet
@ 2024-10-08 7:53 ` Maxime Ripard
2024-10-08 9:23 ` Louis Chauvet
2024-10-10 20:35 ` kernel test robot
2024-10-26 14:49 ` Maíra Canal
2 siblings, 1 reply; 36+ messages in thread
From: Maxime Ripard @ 2024-10-08 7:53 UTC (permalink / raw)
To: Louis Chauvet
Cc: Rodrigo Siqueira, Melissa Wen, Maíra Canal, Haneen Mohammed,
Maarten Lankhorst, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Simona Vetter, rdunlap, arthurgrillo,
pekka.paalanen, Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
[-- Attachment #1: Type: text/plain, Size: 5012 bytes --]
Hi,
On Mon, Oct 07, 2024 at 06:10:47PM GMT, Louis Chauvet wrote:
> From: Arthur Grillo <arthurgrillo@riseup.net>
>
> Create KUnit tests to test the conversion between YUV and RGB. Test each
> conversion and range combination with some common colors.
>
> The code used to compute the expected result can be found in comment.
>
> [Louis Chauvet:
> - fix minor formating issues (whitespace, double line)
> - change expected alpha from 0x0000 to 0xffff
> - adapt to the new get_conversion_matrix usage
> - apply the changes from Arthur
> - move struct pixel_yuv_u8 to the test itself]
>
> Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
> Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/Kconfig | 15 ++
> drivers/gpu/drm/vkms/Makefile | 1 +
> drivers/gpu/drm/vkms/tests/.kunitconfig | 4 +
> drivers/gpu/drm/vkms/tests/Makefile | 3 +
> drivers/gpu/drm/vkms/tests/vkms_format_test.c | 232 ++++++++++++++++++++++++++
> drivers/gpu/drm/vkms/vkms_formats.c | 7 +-
> drivers/gpu/drm/vkms/vkms_formats.h | 5 +
> 7 files changed, 265 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
> index 9def079f685b..98ecfce929f3 100644
> --- a/drivers/gpu/drm/vkms/Kconfig
> +++ b/drivers/gpu/drm/vkms/Kconfig
> @@ -14,3 +14,18 @@ config DRM_VKMS
> a VKMS.
>
> If M is selected the module will be called vkms.
> +
> +config DRM_VKMS_KUNIT_TESTS
> + tristate "KUnit tests for VKMS." if !KUNIT_ALL_TESTS
> + depends on DRM_VKMS=y && KUNIT
> + default KUNIT_ALL_TESTS
> + help
> + This builds unit tests for VKMS. This option is not useful for
> + distributions or general kernels, but only for kernel
> + developers working on VKMS.
> +
> + For more information on KUnit and unit tests in general,
> + please refer to the KUnit documentation in
> + Documentation/dev-tools/kunit/.
> +
> + If in doubt, say "N".
> diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
> index 1b28a6a32948..8d3e46dde635 100644
> --- a/drivers/gpu/drm/vkms/Makefile
> +++ b/drivers/gpu/drm/vkms/Makefile
> @@ -9,3 +9,4 @@ vkms-y := \
> vkms_writeback.o
>
> obj-$(CONFIG_DRM_VKMS) += vkms.o
> +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += tests/
> diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig b/drivers/gpu/drm/vkms/tests/.kunitconfig
> new file mode 100644
> index 000000000000..70e378228cbd
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
> @@ -0,0 +1,4 @@
> +CONFIG_KUNIT=y
> +CONFIG_DRM=y
> +CONFIG_DRM_VKMS=y
> +CONFIG_DRM_VKMS_KUNIT_TESTS=y
> diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile
> new file mode 100644
> index 000000000000..2d1df668569e
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += vkms_format_test.o
> diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
> new file mode 100644
> index 000000000000..351409897ca3
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
> @@ -0,0 +1,232 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <kunit/test.h>
> +
> +#include <drm/drm_fixed.h>
> +#include <drm/drm_fourcc.h>
> +
> +#include "../../drm_crtc_internal.h"
> +
> +#include "../vkms_formats.h"
> +
> +#define TEST_BUFF_SIZE 50
> +
> +MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
> +
> +struct pixel_yuv_u8 {
> + u8 y, u, v;
> +};
> +
> +struct yuv_u8_to_argb_u16_case {
> + enum drm_color_encoding encoding;
> + enum drm_color_range range;
> + size_t n_colors;
> + struct format_pair {
> + char *name;
> + struct pixel_yuv_u8 yuv;
> + struct pixel_argb_u16 argb;
> + } colors[TEST_BUFF_SIZE];
> +};
> +
> +/*
> + * The YUV color representation were acquired via the colour python framework.
> + * Below are the function calls used for generating each case.
> + *
> + * For more information got to the docs:
> + * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html
> + */
> +static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
> + /*
> + * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
> + * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
> + * in_bits = 16,
> + * in_legal = False,
> + * in_int = True,
> + * out_bits = 8,
> + * out_legal = False,
> + * out_int = True)
> + */
We should really detail what the intent and expected outcome is supposed
to be here. Relying on a third-party python library call for
documentation isn't great.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-08 7:53 ` Maxime Ripard
@ 2024-10-08 9:23 ` Louis Chauvet
2024-10-11 10:49 ` Maxime Ripard
0 siblings, 1 reply; 36+ messages in thread
From: Louis Chauvet @ 2024-10-08 9:23 UTC (permalink / raw)
To: Maxime Ripard
Cc: Rodrigo Siqueira, Melissa Wen, Maaara Canal, Haneen Mohammed,
Maarten Lankhorst, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Simona Vetter, rdunlap, arthurgrillo,
pekka.paalanen, Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
Hi,
> > + * The YUV color representation were acquired via the colour python framework.
> > + * Below are the function calls used for generating each case.
> > + *
> > + * For more information got to the docs:
> > + * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html
> > + */
> > +static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
> > + /*
> > + * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
> > + * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
> > + * in_bits = 16,
> > + * in_legal = False,
> > + * in_int = True,
> > + * out_bits = 8,
> > + * out_legal = False,
> > + * out_int = True)
> > + */
>
> We should really detail what the intent and expected outcome is supposed
> to be here. Relying on a third-party python library call for
> documentation isn't great.
>
> Maxime
This was requested by Pekka in the [v2] of this series.
I can add something like this before each tests, but I think having the
exact python code used may help people to understand what should be the
behavior, and refering to the python code to understand the conversion.
I can add something like this before each tests to clarify the tested
case:
Test cases for conversion between YUV BT601 limited range and
RGB using the ITU-R BT.601 weights.
Or maybe just documenting the structure yuv_u8_to_argb_u16_case:
@encoding: Encoding used to convert RGB to YUV
@range: Range used to convert RGB to YUV
@n_colors: Count of test colors in this case
@format_pair.name: Name used for this color conversion, used to
clarify the test results
@format_pair.rgb: RGB color tested
@format_pair.yuv: Same color as @format_pair.rgb, but converted to
YUV using @encoding and @range.
What do you think?
Thanks,
Louis Chauvet
[v2]:https://lore.kernel.org/all/20240229141238.51891cad.pekka.paalanen@collabora.com/
[v5]:https://lore.kernel.org/all/20240328152631.63af0e8c.pekka.paalanen@collabora.com/
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-07 16:10 ` [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions Louis Chauvet
2024-10-08 7:53 ` Maxime Ripard
@ 2024-10-10 20:35 ` kernel test robot
2024-10-26 14:49 ` Maíra Canal
2 siblings, 0 replies; 36+ messages in thread
From: kernel test robot @ 2024-10-10 20:35 UTC (permalink / raw)
To: Louis Chauvet, Rodrigo Siqueira, Melissa Wen, Maíra Canal,
Haneen Mohammed, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Jonathan Corbet, Simona Vetter,
rdunlap, arthurgrillo, pekka.paalanen
Cc: oe-kbuild-all, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
Hi Louis,
kernel test robot noticed the following build errors:
[auto build test ERROR on 82fe69e63d2b5a5e86ea94c7361c833d3848ab69]
url: https://github.com/intel-lab-lkp/linux/commits/Louis-Chauvet/drm-vkms-Code-formatting/20241008-001316
base: 82fe69e63d2b5a5e86ea94c7361c833d3848ab69
patch link: https://lore.kernel.org/r/20241007-yuv-v12-13-01c1ada6fec8%40bootlin.com
patch subject: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
config: i386-randconfig-013-20241010 (https://download.01.org/0day-ci/archive/20241011/202410110407.EHvadSaF-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241011/202410110407.EHvadSaF-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410110407.EHvadSaF-lkp@intel.com/
All errors (new ones prefixed by >>, old ones prefixed by <<):
WARNING: modpost: missing MODULE_DESCRIPTION() in lib/slub_kunit.o
>> ERROR: modpost: "drm_get_color_range_name" [drivers/gpu/drm/vkms/tests/vkms_format_test.ko] undefined!
>> ERROR: modpost: "drm_get_color_encoding_name" [drivers/gpu/drm/vkms/tests/vkms_format_test.ko] undefined!
>> ERROR: modpost: "get_conversion_matrix_to_argb_u16" [drivers/gpu/drm/vkms/tests/vkms_format_test.ko] undefined!
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for GET_FREE_REGION
Depends on [n]: SPARSEMEM [=n]
Selected by [m]:
- RESOURCE_KUNIT_TEST [=m] && RUNTIME_TESTING_MENU [=y] && KUNIT [=y]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-07 16:10 ` [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify Louis Chauvet
@ 2024-10-11 9:36 ` Louis Chauvet
2024-10-11 13:53 ` Maira Canal
0 siblings, 1 reply; 36+ messages in thread
From: Louis Chauvet @ 2024-10-11 9:36 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maaara Canal, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Simona Vetter, rdunlap, arthurgrillo,
pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee
Hi all,
Until this point, this series has not received any major comments since
v9. I will commit patches 1-9 next week if there are no further comments.
For patches 10-15, I am currently waiting for feedback from Maxime to
send the next iteration with a fix for kunit tests.
Thanks,
Louis Chauvet
On 07/10/24 - 18:10, Louis Chauvet wrote:
> As all the rotation are now supported by VKMS, this simplification does
> not make sense anymore, so remove it.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
> 1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> index 8875bed76410..5a028ee96c91 100644
> --- a/drivers/gpu/drm/vkms/vkms_plane.c
> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
> frame_info->fb = fb;
> memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
> drm_framebuffer_get(frame_info->fb);
> - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
> - DRM_MODE_ROTATE_90 |
> - DRM_MODE_ROTATE_270 |
> - DRM_MODE_REFLECT_X |
> - DRM_MODE_REFLECT_Y);
> -
> + frame_info->rotation = new_state->rotation;
>
> vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
> }
>
> --
> 2.46.2
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-08 9:23 ` Louis Chauvet
@ 2024-10-11 10:49 ` Maxime Ripard
2024-10-11 14:29 ` Louis Chauvet
0 siblings, 1 reply; 36+ messages in thread
From: Maxime Ripard @ 2024-10-11 10:49 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maaara Canal, Haneen Mohammed,
Maarten Lankhorst, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Simona Vetter, rdunlap, arthurgrillo,
pekka.paalanen, Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
[-- Attachment #1: Type: text/plain, Size: 2571 bytes --]
On Tue, Oct 08, 2024 at 11:23:22AM GMT, Louis Chauvet wrote:
>
> Hi,
>
> > > + * The YUV color representation were acquired via the colour python framework.
> > > + * Below are the function calls used for generating each case.
> > > + *
> > > + * For more information got to the docs:
> > > + * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html
> > > + */
> > > +static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
> > > + /*
> > > + * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
> > > + * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
> > > + * in_bits = 16,
> > > + * in_legal = False,
> > > + * in_int = True,
> > > + * out_bits = 8,
> > > + * out_legal = False,
> > > + * out_int = True)
> > > + */
> >
> > We should really detail what the intent and expected outcome is supposed
> > to be here. Relying on a third-party python library call for
> > documentation isn't great.
>
> This was requested by Pekka in the [v2] of this series.
Ok.
> I can add something like this before each tests, but I think having the
> exact python code used may help people to understand what should be the
> behavior, and refering to the python code to understand the conversion.
Help, sure. Be the *only* documentation, absolutely not.
Let's turn this around. You run kunit, one of these tests fail:
- It adds cognitive load to try to identify and make sense of an
unknown lib.
- How can we check that the arguments you provided there are the one
you actually wanted to provide, and you didn't make a typo?
> I can add something like this before each tests to clarify the tested
> case:
>
> Test cases for conversion between YUV BT601 limited range and
> RGB using the ITU-R BT.601 weights.
>
> Or maybe just documenting the structure yuv_u8_to_argb_u16_case:
>
> @encoding: Encoding used to convert RGB to YUV
> @range: Range used to convert RGB to YUV
> @n_colors: Count of test colors in this case
> @format_pair.name: Name used for this color conversion, used to
> clarify the test results
> @format_pair.rgb: RGB color tested
> @format_pair.yuv: Same color as @format_pair.rgb, but converted to
> YUV using @encoding and @range.
>
> What do you think?
That it's welcome, but it still doesn't allow to figure out what your
intent was with this test 2 years from now.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-11 9:36 ` Louis Chauvet
@ 2024-10-11 13:53 ` Maira Canal
2024-10-11 14:14 ` Maxime Ripard
2024-10-14 8:39 ` Louis Chauvet
0 siblings, 2 replies; 36+ messages in thread
From: Maira Canal @ 2024-10-11 13:53 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee
Hi Louis,
On 10/11/24 06:36, Louis Chauvet wrote:
>
> Hi all,
>
> Until this point, this series has not received any major comments since
> v9. I will commit patches 1-9 next week if there are no further comments.
>
Although we are maintainers of VKMS, it isn't recommended that we push
our own changes without even the Ack of another person. Please, read the
"drm-misc Committer Guidelines" [1].
I can ack patches 05/15, 07/15, and 09/15, but it would be more
beneficial for the community if you ask for an ack (from me or from the
DRM maintainers, which are always around), instead of saying that you
are going to commit the patches without any review.
[1]
https://drm.pages.freedesktop.org/maintainer-tools/committer/committer-drm-misc.html
Best Regards,
- Maíra
> For patches 10-15, I am currently waiting for feedback from Maxime to
> send the next iteration with a fix for kunit tests.
>
> Thanks,
> Louis Chauvet
>
> On 07/10/24 - 18:10, Louis Chauvet wrote:
>> As all the rotation are now supported by VKMS, this simplification does
>> not make sense anymore, so remove it.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> ---
>> drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
>> 1 file changed, 1 insertion(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
>> index 8875bed76410..5a028ee96c91 100644
>> --- a/drivers/gpu/drm/vkms/vkms_plane.c
>> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
>> @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
>> frame_info->fb = fb;
>> memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
>> drm_framebuffer_get(frame_info->fb);
>> - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
>> - DRM_MODE_ROTATE_90 |
>> - DRM_MODE_ROTATE_270 |
>> - DRM_MODE_REFLECT_X |
>> - DRM_MODE_REFLECT_Y);
>> -
>> + frame_info->rotation = new_state->rotation;
>>
>> vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
>> }
>>
>> --
>> 2.46.2
>>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-11 13:53 ` Maira Canal
@ 2024-10-11 14:14 ` Maxime Ripard
2024-10-14 8:39 ` Louis Chauvet
1 sibling, 0 replies; 36+ messages in thread
From: Maxime Ripard @ 2024-10-11 14:14 UTC (permalink / raw)
To: Maira Canal
Cc: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Maarten Lankhorst,
Thomas Zimmermann, David Airlie, Jonathan Corbet, Simona Vetter,
rdunlap, arthurgrillo, pekka.paalanen, Simona Vetter, dri-devel,
linux-kernel, linux-doc, thomas.petazzoni, jeremie.dautheribes,
miquel.raynal, seanpaul, marcheu, nicolejadeyee
[-- Attachment #1: Type: text/plain, Size: 583 bytes --]
On Fri, Oct 11, 2024 at 10:53:52AM GMT, Maira Canal wrote:
> Hi Louis,
>
> On 10/11/24 06:36, Louis Chauvet wrote:
> >
> > Hi all,
> >
> > Until this point, this series has not received any major comments since
> > v9. I will commit patches 1-9 next week if there are no further comments.
> >
>
> Although we are maintainers of VKMS, it isn't recommended that we push
> our own changes without even the Ack of another person. Please, read the
> "drm-misc Committer Guidelines" [1].
It's not that it's not recommended, it's that you shouldn't, really.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-11 10:49 ` Maxime Ripard
@ 2024-10-11 14:29 ` Louis Chauvet
2024-10-24 14:06 ` Maxime Ripard
0 siblings, 1 reply; 36+ messages in thread
From: Louis Chauvet @ 2024-10-11 14:29 UTC (permalink / raw)
To: Maxime Ripard
Cc: Rodrigo Siqueira, Melissa Wen, Maaara Canal, Haneen Mohammed,
Maarten Lankhorst, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Simona Vetter, rdunlap, arthurgrillo,
pekka.paalanen, Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
On 11/10/24 - 12:49, Maxime Ripard wrote:
> On Tue, Oct 08, 2024 at 11:23:22AM GMT, Louis Chauvet wrote:
> >
> > Hi,
> >
> > > > + * The YUV color representation were acquired via the colour python framework.
> > > > + * Below are the function calls used for generating each case.
> > > > + *
> > > > + * For more information got to the docs:
> > > > + * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html
> > > > + */
> > > > +static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
> > > > + /*
> > > > + * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
> > > > + * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
> > > > + * in_bits = 16,
> > > > + * in_legal = False,
> > > > + * in_int = True,
> > > > + * out_bits = 8,
> > > > + * out_legal = False,
> > > > + * out_int = True)
> > > > + */
> > >
> > > We should really detail what the intent and expected outcome is supposed
> > > to be here. Relying on a third-party python library call for
> > > documentation isn't great.
> >
> > This was requested by Pekka in the [v2] of this series.
>
> Ok.
>
> > I can add something like this before each tests, but I think having the
> > exact python code used may help people to understand what should be the
> > behavior, and refering to the python code to understand the conversion.
>
> Help, sure. Be the *only* documentation, absolutely not.
>
> Let's turn this around. You run kunit, one of these tests fail:
>
> - It adds cognitive load to try to identify and make sense of an
> unknown lib.
>
> - How can we check that the arguments you provided there are the one
> you actually wanted to provide, and you didn't make a typo?
>
> > I can add something like this before each tests to clarify the tested
> > case:
> >
> > Test cases for conversion between YUV BT601 limited range and
> > RGB using the ITU-R BT.601 weights.
> >
> > Or maybe just documenting the structure yuv_u8_to_argb_u16_case:
> >
> > @encoding: Encoding used to convert RGB to YUV
> > @range: Range used to convert RGB to YUV
> > @n_colors: Count of test colors in this case
> > @format_pair.name: Name used for this color conversion, used to
> > clarify the test results
> > @format_pair.rgb: RGB color tested
> > @format_pair.yuv: Same color as @format_pair.rgb, but converted to
> > YUV using @encoding and @range.
> >
> > What do you think?
>
> That it's welcome, but it still doesn't allow to figure out what your
> intent was with this test 2 years from now.
I don't really understand what you want to add. Can you explain what you
expect here? Did you mean you want a description like this above the test
function?
/*
* vkms_format_test_yuv_u8_to_argb_u16 - Testing the conversion between YUV
* colors to ARGB colors in VKMS
*
* This test will use the functions get_conversion_matrix_to_argb_u16 and
* argb_u16_from_yuv888 to convert YUV colors (stored in
* yuv_u8_to_argb_u16_cases) into ARGB colors.
*
* As there is a different range between YUV input (8 bits) and RGB output (16
* bits), the values are not checked exactly but ensured that they are within
* the uncertainty range.
*/
Thanks,
Louis Chauvet
> Maxime
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-11 13:53 ` Maira Canal
2024-10-11 14:14 ` Maxime Ripard
@ 2024-10-14 8:39 ` Louis Chauvet
2024-10-26 12:10 ` Maíra Canal
1 sibling, 1 reply; 36+ messages in thread
From: Louis Chauvet @ 2024-10-14 8:39 UTC (permalink / raw)
To: Maira Canal
Cc: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee
On 11/10/24 - 10:53, Maira Canal wrote:
> Hi Louis,
>
> On 10/11/24 06:36, Louis Chauvet wrote:
> >
> > Hi all,
> >
> > Until this point, this series has not received any major comments since
> > v9. I will commit patches 1-9 next week if there are no further comments.
> >
>
> Although we are maintainers of VKMS, it isn't recommended that we push
> our own changes without even the Ack of another person. Please, read the
> "drm-misc Committer Guidelines" [1].
Hi Maíra, Maxime,
I apologize for this rushed commit request. I sent the initial email with
a delay before the commit action because I was not sure about the
procedure and wanted to give others a chance to raise any concerns.
Unfortunately, I overlooked the need to collect an Ack/Review for each
patch, even when there hadn't been any responses for several months. I'm
sorry for this oversight.
> I can ack patches 05/15, 07/15, and 09/15, but it would be more
> beneficial for the community if you ask for an ack (from me or from the
> DRM maintainers, which are always around), instead of saying that you
> are going to commit the patches without any review.
I will be happy to ask for acknowledgments if needed, but as you mentioned
multiple times: nobody is paid to maintain VKMS. Since you did not comment
these series since July, when you told me you would review my patches, I
assumed it was either okay or you no longer had the time to maintain
(which I completely understand).
So, I hereby formally request reviews/ACKs for the following series:
[this series]:https://lore.kernel.org/all/20241007-yuv-v12-0-01c1ada6fec8@bootlin.com/
[2]:https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-0-d47da50d4674@bootlin.com/
[3]:https://lore.kernel.org/all/20240516-writeback_line_by_line-v1-0-7b2e3bf9f1c9@bootlin.com/
(I have to send a v2 for [3] because of rebase conflict, but nothing else
changed)
Thanks a lot,
Louis Chauvet
> [1] https://drm.pages.freedesktop.org/maintainer-tools/committer/committer-drm-misc.html
>
> Best Regards,
> - Maíra
>
> > For patches 10-15, I am currently waiting for feedback from Maxime to
> > send the next iteration with a fix for kunit tests.
> >
> > Thanks,
> > Louis Chauvet
> >
> > On 07/10/24 - 18:10, Louis Chauvet wrote:
> > > As all the rotation are now supported by VKMS, this simplification does
> > > not make sense anymore, so remove it.
> > >
> > > Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> > > ---
> > > drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
> > > 1 file changed, 1 insertion(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> > > index 8875bed76410..5a028ee96c91 100644
> > > --- a/drivers/gpu/drm/vkms/vkms_plane.c
> > > +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> > > @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
> > > frame_info->fb = fb;
> > > memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
> > > drm_framebuffer_get(frame_info->fb);
> > > - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
> > > - DRM_MODE_ROTATE_90 |
> > > - DRM_MODE_ROTATE_270 |
> > > - DRM_MODE_REFLECT_X |
> > > - DRM_MODE_REFLECT_Y);
> > > -
> > > + frame_info->rotation = new_state->rotation;
> > > vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
> > > }
> > >
> > > --
> > > 2.46.2
> > >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-11 14:29 ` Louis Chauvet
@ 2024-10-24 14:06 ` Maxime Ripard
0 siblings, 0 replies; 36+ messages in thread
From: Maxime Ripard @ 2024-10-24 14:06 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Maaara Canal, Haneen Mohammed,
Maarten Lankhorst, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Simona Vetter, rdunlap, arthurgrillo,
pekka.paalanen, Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
[-- Attachment #1: Type: text/plain, Size: 3851 bytes --]
On Fri, Oct 11, 2024 at 04:29:25PM +0200, Louis Chauvet wrote:
> On 11/10/24 - 12:49, Maxime Ripard wrote:
> > On Tue, Oct 08, 2024 at 11:23:22AM GMT, Louis Chauvet wrote:
> > >
> > > Hi,
> > >
> > > > > + * The YUV color representation were acquired via the colour python framework.
> > > > > + * Below are the function calls used for generating each case.
> > > > > + *
> > > > > + * For more information got to the docs:
> > > > > + * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html
> > > > > + */
> > > > > +static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
> > > > > + /*
> > > > > + * colour.RGB_to_YCbCr(<rgb color in 16 bit form>,
> > > > > + * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
> > > > > + * in_bits = 16,
> > > > > + * in_legal = False,
> > > > > + * in_int = True,
> > > > > + * out_bits = 8,
> > > > > + * out_legal = False,
> > > > > + * out_int = True)
> > > > > + */
> > > >
> > > > We should really detail what the intent and expected outcome is supposed
> > > > to be here. Relying on a third-party python library call for
> > > > documentation isn't great.
> > >
> > > This was requested by Pekka in the [v2] of this series.
> >
> > Ok.
> >
> > > I can add something like this before each tests, but I think having the
> > > exact python code used may help people to understand what should be the
> > > behavior, and refering to the python code to understand the conversion.
> >
> > Help, sure. Be the *only* documentation, absolutely not.
> >
> > Let's turn this around. You run kunit, one of these tests fail:
> >
> > - It adds cognitive load to try to identify and make sense of an
> > unknown lib.
> >
> > - How can we check that the arguments you provided there are the one
> > you actually wanted to provide, and you didn't make a typo?
> >
> > > I can add something like this before each tests to clarify the tested
> > > case:
> > >
> > > Test cases for conversion between YUV BT601 limited range and
> > > RGB using the ITU-R BT.601 weights.
> > >
> > > Or maybe just documenting the structure yuv_u8_to_argb_u16_case:
> > >
> > > @encoding: Encoding used to convert RGB to YUV
> > > @range: Range used to convert RGB to YUV
> > > @n_colors: Count of test colors in this case
> > > @format_pair.name: Name used for this color conversion, used to
> > > clarify the test results
> > > @format_pair.rgb: RGB color tested
> > > @format_pair.yuv: Same color as @format_pair.rgb, but converted to
> > > YUV using @encoding and @range.
> > >
> > > What do you think?
> >
> > That it's welcome, but it still doesn't allow to figure out what your
> > intent was with this test 2 years from now.
>
> I don't really understand what you want to add. Can you explain what you
> expect here? Did you mean you want a description like this above the test
> function?
I want, for each test case, to have a documentation of what case it's
testing and what the test should expect.
So, for the first one, something like:
/*
* Test the conversion of full range, BT601-encoded, YUVXXX pixel to
* ARGBXXXX, for various colors. This has been generated using:
*
* colour.RGB_to_YCbCR(...)
*/
And there's other things you need to document. Like, it seems that you
sometimes pass different values for in_legal and out_legal, and that's
not clear to me.
It also that you uses a matrix for NV12 but are converting a different
format. This needs to be documented.
Finally, You should be documented why you are checking that the colors
difference is less than 257, and not exactly equal.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-14 8:39 ` Louis Chauvet
@ 2024-10-26 12:10 ` Maíra Canal
2024-10-28 9:50 ` Louis Chauvet
0 siblings, 1 reply; 36+ messages in thread
From: Maíra Canal @ 2024-10-26 12:10 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee
Hi Louis,
On 14/10/24 05:39, Louis Chauvet wrote:
> On 11/10/24 - 10:53, Maira Canal wrote:
>> Hi Louis,
>>
>> On 10/11/24 06:36, Louis Chauvet wrote:
>>>
>>> Hi all,
>>>
>>> Until this point, this series has not received any major comments since
>>> v9. I will commit patches 1-9 next week if there are no further comments.
>>>
>>
>> Although we are maintainers of VKMS, it isn't recommended that we push
>> our own changes without even the Ack of another person. Please, read the
>> "drm-misc Committer Guidelines" [1].
>
> Hi Maíra, Maxime,
>
> I apologize for this rushed commit request. I sent the initial email with
> a delay before the commit action because I was not sure about the
> procedure and wanted to give others a chance to raise any concerns.
> Unfortunately, I overlooked the need to collect an Ack/Review for each
> patch, even when there hadn't been any responses for several months. I'm
> sorry for this oversight.
>
>> I can ack patches 05/15, 07/15, and 09/15, but it would be more
>> beneficial for the community if you ask for an ack (from me or from the
>> DRM maintainers, which are always around), instead of saying that you
>> are going to commit the patches without any review.
>
> I will be happy to ask for acknowledgments if needed, but as you mentioned
> multiple times: nobody is paid to maintain VKMS. Since you did not comment
> these series since July, when you told me you would review my patches, I
> assumed it was either okay or you no longer had the time to maintain
> (which I completely understand).
Yeah, I'm a volunteer and no longer have time to maintain VKMS. A couple
of weeks ago I sent a patch removing myself as VKMS maintainer. This
doesn't imply that patches can be pushed without review.
We are a community with several active developers. Although I don't have
time to properly review your patches, you can try to gather other
developers to review your patches. You can try to use #dri-devel to get
reviewers.
That said, you can add my ACK to patches 05/15, 07/15, and 09/15 and
push the patches. I won't ack the YUV patches as I don't feel
comfortable reviewing/acking those.
Acked-by: Maíra Canal <mairacanal@riseup.net>
BTW if the patches are fixing IGT tests, please update the list of fails
and skips on DRM CI.
Best Regards,
- Maíra
>
> So, I hereby formally request reviews/ACKs for the following series:
>
> [this series]:https://lore.kernel.org/all/20241007-yuv-v12-0-01c1ada6fec8@bootlin.com/
> [2]:https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-0-d47da50d4674@bootlin.com/
> [3]:https://lore.kernel.org/all/20240516-writeback_line_by_line-v1-0-7b2e3bf9f1c9@bootlin.com/
>
> (I have to send a v2 for [3] because of rebase conflict, but nothing else
> changed)
>
> Thanks a lot,
> Louis Chauvet
>
>> [1] https://drm.pages.freedesktop.org/maintainer-tools/committer/committer-drm-misc.html
>>
>> Best Regards,
>> - Maíra
>>
>>> For patches 10-15, I am currently waiting for feedback from Maxime to
>>> send the next iteration with a fix for kunit tests.
>>>
>>> Thanks,
>>> Louis Chauvet
>>>
>>> On 07/10/24 - 18:10, Louis Chauvet wrote:
>>>> As all the rotation are now supported by VKMS, this simplification does
>>>> not make sense anymore, so remove it.
>>>>
>>>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>>>> ---
>>>> drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
>>>> 1 file changed, 1 insertion(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
>>>> index 8875bed76410..5a028ee96c91 100644
>>>> --- a/drivers/gpu/drm/vkms/vkms_plane.c
>>>> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
>>>> @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
>>>> frame_info->fb = fb;
>>>> memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
>>>> drm_framebuffer_get(frame_info->fb);
>>>> - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
>>>> - DRM_MODE_ROTATE_90 |
>>>> - DRM_MODE_ROTATE_270 |
>>>> - DRM_MODE_REFLECT_X |
>>>> - DRM_MODE_REFLECT_Y);
>>>> -
>>>> + frame_info->rotation = new_state->rotation;
>>>> vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
>>>> }
>>>>
>>>> --
>>>> 2.46.2
>>>>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm
2024-10-07 16:10 ` [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm Louis Chauvet
@ 2024-10-26 14:26 ` Maíra Canal
2024-10-28 9:50 ` Louis Chauvet
0 siblings, 1 reply; 36+ messages in thread
From: Maíra Canal @ 2024-10-26 14:26 UTC (permalink / raw)
To: Louis Chauvet, Rodrigo Siqueira, Melissa Wen, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Simona Vetter, rdunlap, arthurgrillo,
pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen
Hi Louis,
On 07/10/24 13:10, Louis Chauvet wrote:
> Re-introduce a line-by-line composition algorithm for each pixel format.
> This allows more performance by not requiring an indirection per pixel
> read. This patch is focused on readability of the code.
>
> Line-by-line composition was introduced by [1] but rewritten back to
> pixel-by-pixel algorithm in [2]. At this time, nobody noticed the impact
> on performance, and it was merged.
>
> This patch is almost a revert of [2], but in addition efforts have been
> made to increase readability and maintainability of the rotation handling.
> The blend function is now divided in two parts:
> - Transformation of coordinates from the output referential to the source
> referential
> - Line conversion and blending
>
> Most of the complexity of the rotation management is avoided by using
> drm_rect_* helpers. The remaining complexity is around the clipping, to
> avoid reading/writing outside source/destination buffers.
>
> The pixel conversion is now done line-by-line, so the read_pixel_t was
> replaced with read_pixel_line_t callback. This way the indirection is only
> required once per line and per plane, instead of once per pixel and per
> plane.
>
> The read_line_t callbacks are very similar for most pixel format, but it
> is required to avoid performance impact. Some helpers for color
> conversion were introduced to avoid code repetition:
> - *_to_argb_u16: perform colors conversion. They should be inlined by the
> compiler, and they are used to avoid repetition between multiple variants
> of the same format (argb/xrgb and maybe in the future for formats like
> bgr formats).
>
> This new algorithm was tested with:
> - kms_plane (for color conversions)
> - kms_rotation_crc (for rotations of planes)
> - kms_cursor_crc (for translations of planes)
> - kms_rotation (for all rotations and formats combinations) [3]
> The performance gain was mesured with kms_fb_stress [4] with some
> modification to fix the writeback format.
>
> The performance improvement is around 5 to 10%.
>
> [1]: commit 8ba1648567e2 ("drm: vkms: Refactor the plane composer to accept
> new formats")
> https://lore.kernel.org/all/20220905190811.25024-7-igormtorrente@gmail.com/
> [2]: commit 322d716a3e8a ("drm/vkms: isolate pixel conversion
> functionality")
> https://lore.kernel.org/all/20230418130525.128733-2-mcanal@igalia.com/
> [3]: https://lore.kernel.org/igt-dev/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com/
> [4]: https://lore.kernel.org/all/20240422-kms_fb_stress-dev-v5-0-0c577163dc88@riseup.net/
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
>
> # Conflicts:
> # drivers/gpu/drm/vkms/vkms_composer.c
> ---
> drivers/gpu/drm/vkms/vkms_composer.c | 234 ++++++++++++++++++++++++++++-------
> drivers/gpu/drm/vkms/vkms_drv.h | 28 +++--
> drivers/gpu/drm/vkms/vkms_formats.c | 224 ++++++++++++++++++++-------------
> drivers/gpu/drm/vkms/vkms_formats.h | 2 +-
> drivers/gpu/drm/vkms/vkms_plane.c | 5 +-
> 5 files changed, 344 insertions(+), 149 deletions(-)
>
[...]
>
> -static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
> +static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
> {
> - __le16 *pixel = (__le16 *)in_pixel;
> + struct pixel_argb_u16 out_pixel;
>
> s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
> s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
> @@ -226,40 +194,120 @@ static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pi
> s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
> s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
>
> - out_pixel->a = (u16)0xffff;
> - out_pixel->r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
> - out_pixel->g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
> - out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
> + out_pixel.a = (u16)0xffff;
> + out_pixel.r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
> + out_pixel.g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
> + out_pixel.b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
> +
> + return out_pixel;
> }
>
> -/**
> - * vkms_compose_row - compose a single row of a plane
> - * @stage_buffer: output line with the composed pixels
> - * @plane: state of the plane that is being composed
> - * @y: y coordinate of the row
> +/*
> + * The following functions are read_line function for each pixel format supported by VKMS.
> + *
> + * They read a line starting at the point @x_start,@y_start following the @direction. The result
> + * is stored in @out_pixel and in the format ARGB16161616.
> + *
> + * These functions are very repetitive, but the innermost pixel loops must be kept inside these
> + * functions for performance reasons. Some benchmarking was done in [1] where having the innermost
> + * loop factored out of these functions showed a slowdown by a factor of three.
> *
> - * This function composes a single row of a plane. It gets the source pixels
> - * through the y coordinate (see get_packed_src_addr()) and goes linearly
> - * through the source pixel, reading the pixels and converting it to
> - * ARGB16161616 (see the pixel_read() callback). For rotate-90 and rotate-270,
> - * the source pixels are not traversed linearly. The source pixels are queried
> - * on each iteration in order to traverse the pixels vertically.
> + * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
> */
> -void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
> +
> +static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
> + enum pixel_read_direction direction, int count,
> + struct pixel_argb_u16 out_pixel[])
> {
> - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
> - struct vkms_frame_info *frame_info = plane->frame_info;
> - u8 *src_pixels = get_packed_src_addr(frame_info, y, 0);
> - int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
> + struct pixel_argb_u16 *end = out_pixel + count;
> + u8 *src_pixels;
> +
> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> +
> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> +
> + while (out_pixel < end) {
> + u8 *px = (u8 *)src_pixels;
Why are you converting u8* to u8*? There are repetitions of this pattern
in this patch.
> + *out_pixel = argb_u16_from_u8888(px[3], px[2], px[1], px[0]);
> + out_pixel += 1;
> + src_pixels += step;
> + }
> +}
> +
> +static void XRGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
> + enum pixel_read_direction direction, int count,
> + struct pixel_argb_u16 out_pixel[])
> +{
> + struct pixel_argb_u16 *end = out_pixel + count;
> + u8 *src_pixels;
> +
> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> +
> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> +
> + while (out_pixel < end) {
> + u8 *px = (u8 *)src_pixels;
> + *out_pixel = argb_u16_from_u8888(255, px[2], px[1], px[0]);
> + out_pixel += 1;
> + src_pixels += step;
> + }
> +}
> +
> +static void ARGB16161616_read_line(const struct vkms_plane_state *plane, int x_start,
> + int y_start, enum pixel_read_direction direction, int count,
> + struct pixel_argb_u16 out_pixel[])
> +{
> + struct pixel_argb_u16 *end = out_pixel + count;
> + u8 *src_pixels;
> +
> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> +
> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> +
> + while (out_pixel < end) {
> + u16 *px = (u16 *)src_pixels;
> + *out_pixel = argb_u16_from_u16161616(px[3], px[2], px[1], px[0]);
> + out_pixel += 1;
> + src_pixels += step;
> + }
> +}
> +
> +static void XRGB16161616_read_line(const struct vkms_plane_state *plane, int x_start,
> + int y_start, enum pixel_read_direction direction, int count,
> + struct pixel_argb_u16 out_pixel[])
> +{
> + struct pixel_argb_u16 *end = out_pixel + count;
> + u8 *src_pixels;
> +
> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> +
> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> +
> + while (out_pixel < end) {
> + __le16 *px = (__le16 *)src_pixels;
> + *out_pixel = argb_u16_from_le16161616(cpu_to_le16(0xFFFF), px[2], px[1], px[0]);
> + out_pixel += 1;
> + src_pixels += step;
> + }
> +}
> +
> +static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start,
> + int y_start, enum pixel_read_direction direction, int count,
> + struct pixel_argb_u16 out_pixel[])
> +{
> + struct pixel_argb_u16 *end = out_pixel + count;
> + u8 *src_pixels;
> +
> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
>
> - for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) {
> - int x_pos = get_x_position(frame_info, limit, x);
> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
>
> - if (drm_rotation_90_or_270(frame_info->rotation))
> - src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1, 0)
> - + frame_info->fb->format->cpp[0] * y;
> + while (out_pixel < end) {
> + __le16 *px = (__le16 *)src_pixels;
>
> - plane->pixel_read(src_pixels, &out_pixels[x_pos]);
> + *out_pixel = argb_u16_from_RGB565(px);
> + out_pixel += 1;
> + src_pixels += step;
> }
> }
>
> @@ -359,25 +407,25 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
> }
>
> /**
> - * get_pixel_read_function() - Retrieve the correct read_pixel function for a specific
> + * get_pixel_read_line_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
> * the pointer is valid before using it in a vkms_plane_state.
> *
> * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h])
> */
> -pixel_read_t get_pixel_read_function(u32 format)
> +pixel_read_line_t get_pixel_read_line_function(u32 format)
> {
> switch (format) {
> case DRM_FORMAT_ARGB8888:
> - return &ARGB8888_to_argb_u16;
> + return &ARGB8888_read_line;
> case DRM_FORMAT_XRGB8888:
> - return &XRGB8888_to_argb_u16;
> + return &XRGB8888_read_line;
> case DRM_FORMAT_ARGB16161616:
> - return &ARGB16161616_to_argb_u16;
> + return &ARGB16161616_read_line;
> case DRM_FORMAT_XRGB16161616:
> - return &XRGB16161616_to_argb_u16;
> + return &XRGB16161616_read_line;
> case DRM_FORMAT_RGB565:
> - return &RGB565_to_argb_u16;
> + return &RGB565_read_line;
> default:
> /*
> * This is a bug in vkms_plane_atomic_check(). All the supported
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
> index 3ecea4563254..8d2bef95ff79 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.h
> +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> @@ -5,7 +5,7 @@
>
> #include "vkms_drv.h"
>
> -pixel_read_t get_pixel_read_function(u32 format);
> +pixel_read_line_t get_pixel_read_line_function(u32 format);
>
> pixel_write_t get_pixel_write_function(u32 format);
>
> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> index 10e9b23dab28..8875bed76410 100644
> --- a/drivers/gpu/drm/vkms/vkms_plane.c
> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> @@ -112,7 +112,6 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
> frame_info = vkms_plane_state->frame_info;
> memcpy(&frame_info->src, &new_state->src, sizeof(struct drm_rect));
> memcpy(&frame_info->dst, &new_state->dst, sizeof(struct drm_rect));
> - memcpy(&frame_info->rotated, &new_state->dst, sizeof(struct drm_rect));
If you won't use rotated anymore, delete it from the struct.
Best Regards,
- Maíra
> frame_info->fb = fb;
> memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
> drm_framebuffer_get(frame_info->fb);
> @@ -122,10 +121,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
> DRM_MODE_REFLECT_X |
> DRM_MODE_REFLECT_Y);
>
> - drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
> - drm_rect_height(&frame_info->rotated), frame_info->rotation);
>
> - vkms_plane_state->pixel_read = get_pixel_read_function(fmt);
> + vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
> }
>
> static int vkms_plane_atomic_check(struct drm_plane *plane,
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-07 16:10 ` [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions Louis Chauvet
2024-10-08 7:53 ` Maxime Ripard
2024-10-10 20:35 ` kernel test robot
@ 2024-10-26 14:49 ` Maíra Canal
2024-10-28 9:50 ` Louis Chauvet
2 siblings, 1 reply; 36+ messages in thread
From: Maíra Canal @ 2024-10-26 14:49 UTC (permalink / raw)
To: Louis Chauvet, Rodrigo Siqueira, Melissa Wen, Haneen Mohammed,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Jonathan Corbet, Simona Vetter, rdunlap, arthurgrillo,
pekka.paalanen, Simona Vetter
Cc: dri-devel, linux-kernel, linux-doc, thomas.petazzoni,
jeremie.dautheribes, miquel.raynal, seanpaul, marcheu,
nicolejadeyee, Pekka Paalanen
Hi Louis,
On 07/10/24 13:10, Louis Chauvet wrote:
> From: Arthur Grillo <arthurgrillo@riseup.net>
>
> Create KUnit tests to test the conversion between YUV and RGB. Test each
> conversion and range combination with some common colors.
>
> The code used to compute the expected result can be found in comment.
>
> [Louis Chauvet:
> - fix minor formating issues (whitespace, double line)
> - change expected alpha from 0x0000 to 0xffff
> - adapt to the new get_conversion_matrix usage
> - apply the changes from Arthur
> - move struct pixel_yuv_u8 to the test itself]
>
> Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
> Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/Kconfig | 15 ++
> drivers/gpu/drm/vkms/Makefile | 1 +
> drivers/gpu/drm/vkms/tests/.kunitconfig | 4 +
> drivers/gpu/drm/vkms/tests/Makefile | 3 +
> drivers/gpu/drm/vkms/tests/vkms_format_test.c | 232 ++++++++++++++++++++++++++
> drivers/gpu/drm/vkms/vkms_formats.c | 7 +-
> drivers/gpu/drm/vkms/vkms_formats.h | 5 +
> 7 files changed, 265 insertions(+), 2 deletions(-)
>
[...]
> +
> +static void vkms_format_test_yuv_u8_to_argb_u16(struct kunit *test)
> +{
> + const struct yuv_u8_to_argb_u16_case *param = test->param_value;
> + struct pixel_argb_u16 argb;
> +
> + for (size_t i = 0; i < param->n_colors; i++) {
> + const struct format_pair *color = ¶m->colors[i];
> + struct conversion_matrix matrix;
> +
> + get_conversion_matrix_to_argb_u16
> + (DRM_FORMAT_NV12, param->encoding, param->range, &matrix);
> +
> + argb = argb_u16_from_yuv888(color->yuv.y, color->yuv.u, color->yuv.v, &matrix);
This should be `argb_u16_from_yuv161616` as you fixed in [1].
[1]
https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-5-d47da50d4674@bootlin.com/
Best Regards,
- Maíra
> +
> + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.a, color->argb.a), 257,
> + "On the A channel of the color %s expected 0x%04x, got 0x%04x",
> + color->name, color->argb.a, argb.a);
> + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.r, color->argb.r), 257,
> + "On the R channel of the color %s expected 0x%04x, got 0x%04x",
> + color->name, color->argb.r, argb.r);
> + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.g, color->argb.g), 257,
> + "On the G channel of the color %s expected 0x%04x, got 0x%04x",
> + color->name, color->argb.g, argb.g);
> + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.b, color->argb.b), 257,
> + "On the B channel of the color %s expected 0x%04x, got 0x%04x",
> + color->name, color->argb.b, argb.b);
> + }
> +}
> +
> +static void vkms_format_test_yuv_u8_to_argb_u16_case_desc(struct yuv_u8_to_argb_u16_case *t,
> + char *desc)
> +{
> + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s - %s",
> + drm_get_color_encoding_name(t->encoding), drm_get_color_range_name(t->range));
> +}
> +
> +KUNIT_ARRAY_PARAM(yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_cases,
> + vkms_format_test_yuv_u8_to_argb_u16_case_desc
> +);
> +
> +static struct kunit_case vkms_format_test_cases[] = {
> + KUNIT_CASE_PARAM(vkms_format_test_yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_gen_params),
> + {}
> +};
> +
> +static struct kunit_suite vkms_format_test_suite = {
> + .name = "vkms-format",
> + .test_cases = vkms_format_test_cases,
> +};
> +
> +kunit_test_suite(vkms_format_test_suite);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Kunit test for vkms format conversion");
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
> index adb1228e5201..0b201185eae7 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.c
> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> @@ -7,6 +7,8 @@
> #include <drm/drm_rect.h>
> #include <drm/drm_fixed.h>
>
> +#include <kunit/visibility.h>
> +
> #include "vkms_formats.h"
>
> /**
> @@ -247,8 +249,8 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
> return out_pixel;
> }
>
> -static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
> - const struct conversion_matrix *matrix)
> +VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
> + const struct conversion_matrix *matrix)
> {
> u16 r, g, b;
> s64 fp_y, fp_channel_1, fp_channel_2;
> @@ -278,6 +280,7 @@ static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel
>
> return argb_u16_from_u16161616(0xffff, r, g, b);
> }
> +EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888);
>
> /*
> * The following functions are read_line function for each pixel format supported by VKMS.
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
> index d583855cb320..b4fe62ab9c65 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.h
> +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> @@ -13,4 +13,9 @@ void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encod
> enum drm_color_range range,
> struct conversion_matrix *matrix);
>
> +#if IS_ENABLED(CONFIG_KUNIT)
> +struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
> + const struct conversion_matrix *matrix);
> +#endif
> +
> #endif /* _VKMS_FORMATS_H_ */
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-26 12:10 ` Maíra Canal
@ 2024-10-28 9:50 ` Louis Chauvet
2024-10-28 10:17 ` Maíra Canal
0 siblings, 1 reply; 36+ 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, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee
On 26/10/24 - 09:10, Maíra Canal wrote:
> Hi Louis,
>
> On 14/10/24 05:39, Louis Chauvet wrote:
> > On 11/10/24 - 10:53, Maira Canal wrote:
> > > Hi Louis,
> > >
> > > On 10/11/24 06:36, Louis Chauvet wrote:
> > > >
> > > > Hi all,
> > > >
> > > > Until this point, this series has not received any major comments since
> > > > v9. I will commit patches 1-9 next week if there are no further comments.
> > > >
> > >
> > > Although we are maintainers of VKMS, it isn't recommended that we push
> > > our own changes without even the Ack of another person. Please, read the
> > > "drm-misc Committer Guidelines" [1].
> >
> > Hi Maíra, Maxime,
> >
> > I apologize for this rushed commit request. I sent the initial email with
> > a delay before the commit action because I was not sure about the
> > procedure and wanted to give others a chance to raise any concerns.
> > Unfortunately, I overlooked the need to collect an Ack/Review for each
> > patch, even when there hadn't been any responses for several months. I'm
> > sorry for this oversight.
> >
> > > I can ack patches 05/15, 07/15, and 09/15, but it would be more
> > > beneficial for the community if you ask for an ack (from me or from the
> > > DRM maintainers, which are always around), instead of saying that you
> > > are going to commit the patches without any review.
> >
> > I will be happy to ask for acknowledgments if needed, but as you mentioned
> > multiple times: nobody is paid to maintain VKMS. Since you did not comment
> > these series since July, when you told me you would review my patches, I
> > assumed it was either okay or you no longer had the time to maintain
> > (which I completely understand).
>
> Yeah, I'm a volunteer and no longer have time to maintain VKMS. A couple
> of weeks ago I sent a patch removing myself as VKMS maintainer. This
> doesn't imply that patches can be pushed without review.
I will acked-by and push your patch, it will be an easy "first commit". If
I do something wrong during the process, please tell me.
Thanks for this precision, I understood this, and I will not push without
reviews, don't worry!
Thanks a lot for all your reviews!
> We are a community with several active developers. Although I don't have
> time to properly review your patches, you can try to gather other
> developers to review your patches. You can try to use #dri-devel to get
> reviewers.
Thanks for the tip, I will do this!
> That said, you can add my ACK to patches 05/15, 07/15, and 09/15 and
> push the patches. I won't ack the YUV patches as I don't feel
> comfortable reviewing/acking those.
Perfect for the patches 1..9, it will be a very nice step forward and will
reduce my conflicts a lot with the rest of my work!
> Acked-by: Maíra Canal <mairacanal@riseup.net>
>
> BTW if the patches are fixing IGT tests, please update the list of fails
> and skips on DRM CI.
For this, how should I do? Commit the series and wait for the bot results?
Run tests on my computer (I only have a x86 VM)? Is there some doc
somewhere?
Thanks a lot,
Louis Chauvet
> Best Regards,
> - Maíra
>
> >
> > So, I hereby formally request reviews/ACKs for the following series:
> >
> > [this series]:https://lore.kernel.org/all/20241007-yuv-v12-0-01c1ada6fec8@bootlin.com/
> > [2]:https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-0-d47da50d4674@bootlin.com/
> > [3]:https://lore.kernel.org/all/20240516-writeback_line_by_line-v1-0-7b2e3bf9f1c9@bootlin.com/
> >
> > (I have to send a v2 for [3] because of rebase conflict, but nothing else
> > changed)
> >
> > Thanks a lot,
> > Louis Chauvet
> > > [1] https://drm.pages.freedesktop.org/maintainer-tools/committer/committer-drm-misc.html
> > >
> > > Best Regards,
> > > - Maíra
> > >
> > > > For patches 10-15, I am currently waiting for feedback from Maxime to
> > > > send the next iteration with a fix for kunit tests.
> > > >
> > > > Thanks,
> > > > Louis Chauvet
> > > >
> > > > On 07/10/24 - 18:10, Louis Chauvet wrote:
> > > > > As all the rotation are now supported by VKMS, this simplification does
> > > > > not make sense anymore, so remove it.
> > > > >
> > > > > Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> > > > > ---
> > > > > drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
> > > > > 1 file changed, 1 insertion(+), 6 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> > > > > index 8875bed76410..5a028ee96c91 100644
> > > > > --- a/drivers/gpu/drm/vkms/vkms_plane.c
> > > > > +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> > > > > @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
> > > > > frame_info->fb = fb;
> > > > > memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
> > > > > drm_framebuffer_get(frame_info->fb);
> > > > > - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
> > > > > - DRM_MODE_ROTATE_90 |
> > > > > - DRM_MODE_ROTATE_270 |
> > > > > - DRM_MODE_REFLECT_X |
> > > > > - DRM_MODE_REFLECT_Y);
> > > > > -
> > > > > + frame_info->rotation = new_state->rotation;
> > > > > vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
> > > > > }
> > > > >
> > > > > --
> > > > > 2.46.2
> > > > >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions
2024-10-26 14:49 ` Maíra Canal
@ 2024-10-28 9:50 ` Louis Chauvet
0 siblings, 0 replies; 36+ 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, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
On 26/10/24 - 11:49, Maíra Canal wrote:
> Hi Louis,
>
> On 07/10/24 13:10, Louis Chauvet wrote:
> > From: Arthur Grillo <arthurgrillo@riseup.net>
> >
> > Create KUnit tests to test the conversion between YUV and RGB. Test each
> > conversion and range combination with some common colors.
> >
> > The code used to compute the expected result can be found in comment.
> >
> > [Louis Chauvet:
> > - fix minor formating issues (whitespace, double line)
> > - change expected alpha from 0x0000 to 0xffff
> > - adapt to the new get_conversion_matrix usage
> > - apply the changes from Arthur
> > - move struct pixel_yuv_u8 to the test itself]
> >
> > Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
> > Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
> > Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> > ---
> > drivers/gpu/drm/vkms/Kconfig | 15 ++
> > drivers/gpu/drm/vkms/Makefile | 1 +
> > drivers/gpu/drm/vkms/tests/.kunitconfig | 4 +
> > drivers/gpu/drm/vkms/tests/Makefile | 3 +
> > drivers/gpu/drm/vkms/tests/vkms_format_test.c | 232 ++++++++++++++++++++++++++
> > drivers/gpu/drm/vkms/vkms_formats.c | 7 +-
> > drivers/gpu/drm/vkms/vkms_formats.h | 5 +
> > 7 files changed, 265 insertions(+), 2 deletions(-)
> >
>
> [...]
>
> > +
> > +static void vkms_format_test_yuv_u8_to_argb_u16(struct kunit *test)
> > +{
> > + const struct yuv_u8_to_argb_u16_case *param = test->param_value;
> > + struct pixel_argb_u16 argb;
> > +
> > + for (size_t i = 0; i < param->n_colors; i++) {
> > + const struct format_pair *color = ¶m->colors[i];
> > + struct conversion_matrix matrix;
> > +
> > + get_conversion_matrix_to_argb_u16
> > + (DRM_FORMAT_NV12, param->encoding, param->range, &matrix);
> > +
> > + argb = argb_u16_from_yuv888(color->yuv.y, color->yuv.u, color->yuv.v, &matrix);
>
> This should be `argb_u16_from_yuv161616` as you fixed in [1].
(I suppose you talk about [2]?)
I understand that I change this function in a future series, but [2] is
not Acked-By yet. I prefer to have the opportunity to merge this
first series (with yuv888) quickly and to work on [2] later (I have less
conflicts between [2] and the rest of my work on configFS).
If I get a Acked-by on [2], I can merge the two commits and directly use
yuv161616 conversion functions.
Thanks,
Louis Chauvet
[2]:https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-6-d47da50d4674@bootlin.com/
> [1] https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-5-d47da50d4674@bootlin.com/
>
> Best Regards,
> - Maíra
>
> > +
> > + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.a, color->argb.a), 257,
> > + "On the A channel of the color %s expected 0x%04x, got 0x%04x",
> > + color->name, color->argb.a, argb.a);
> > + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.r, color->argb.r), 257,
> > + "On the R channel of the color %s expected 0x%04x, got 0x%04x",
> > + color->name, color->argb.r, argb.r);
> > + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.g, color->argb.g), 257,
> > + "On the G channel of the color %s expected 0x%04x, got 0x%04x",
> > + color->name, color->argb.g, argb.g);
> > + KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.b, color->argb.b), 257,
> > + "On the B channel of the color %s expected 0x%04x, got 0x%04x",
> > + color->name, color->argb.b, argb.b);
> > + }
> > +}
> > +
> > +static void vkms_format_test_yuv_u8_to_argb_u16_case_desc(struct yuv_u8_to_argb_u16_case *t,
> > + char *desc)
> > +{
> > + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s - %s",
> > + drm_get_color_encoding_name(t->encoding), drm_get_color_range_name(t->range));
> > +}
> > +
> > +KUNIT_ARRAY_PARAM(yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_cases,
> > + vkms_format_test_yuv_u8_to_argb_u16_case_desc
> > +);
> > +
> > +static struct kunit_case vkms_format_test_cases[] = {
> > + KUNIT_CASE_PARAM(vkms_format_test_yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_gen_params),
> > + {}
> > +};
> > +
> > +static struct kunit_suite vkms_format_test_suite = {
> > + .name = "vkms-format",
> > + .test_cases = vkms_format_test_cases,
> > +};
> > +
> > +kunit_test_suite(vkms_format_test_suite);
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_DESCRIPTION("Kunit test for vkms format conversion");
> > diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
> > index adb1228e5201..0b201185eae7 100644
> > --- a/drivers/gpu/drm/vkms/vkms_formats.c
> > +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> > @@ -7,6 +7,8 @@
> > #include <drm/drm_rect.h>
> > #include <drm/drm_fixed.h>
> > +#include <kunit/visibility.h>
> > +
> > #include "vkms_formats.h"
> > /**
> > @@ -247,8 +249,8 @@ static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
> > return out_pixel;
> > }
> > -static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
> > - const struct conversion_matrix *matrix)
> > +VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
> > + const struct conversion_matrix *matrix)
> > {
> > u16 r, g, b;
> > s64 fp_y, fp_channel_1, fp_channel_2;
> > @@ -278,6 +280,7 @@ static struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel
> > return argb_u16_from_u16161616(0xffff, r, g, b);
> > }
> > +EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888);
> > /*
> > * The following functions are read_line function for each pixel format supported by VKMS.
> > diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
> > index d583855cb320..b4fe62ab9c65 100644
> > --- a/drivers/gpu/drm/vkms/vkms_formats.h
> > +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> > @@ -13,4 +13,9 @@ void get_conversion_matrix_to_argb_u16(u32 format, enum drm_color_encoding encod
> > enum drm_color_range range,
> > struct conversion_matrix *matrix);
> > +#if IS_ENABLED(CONFIG_KUNIT)
> > +struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2,
> > + const struct conversion_matrix *matrix);
> > +#endif
> > +
> > #endif /* _VKMS_FORMATS_H_ */
> >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm
2024-10-26 14:26 ` Maíra Canal
@ 2024-10-28 9:50 ` Louis Chauvet
2024-10-28 10:13 ` Maíra Canal
0 siblings, 1 reply; 36+ 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, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
On 26/10/24 - 11:26, Maíra Canal wrote:
> Hi Louis,
>
> On 07/10/24 13:10, Louis Chauvet wrote:
> > Re-introduce a line-by-line composition algorithm for each pixel format.
> > This allows more performance by not requiring an indirection per pixel
> > read. This patch is focused on readability of the code.
> >
> > Line-by-line composition was introduced by [1] but rewritten back to
> > pixel-by-pixel algorithm in [2]. At this time, nobody noticed the impact
> > on performance, and it was merged.
> >
> > This patch is almost a revert of [2], but in addition efforts have been
> > made to increase readability and maintainability of the rotation handling.
> > The blend function is now divided in two parts:
> > - Transformation of coordinates from the output referential to the source
> > referential
> > - Line conversion and blending
> >
> > Most of the complexity of the rotation management is avoided by using
> > drm_rect_* helpers. The remaining complexity is around the clipping, to
> > avoid reading/writing outside source/destination buffers.
> >
> > The pixel conversion is now done line-by-line, so the read_pixel_t was
> > replaced with read_pixel_line_t callback. This way the indirection is only
> > required once per line and per plane, instead of once per pixel and per
> > plane.
> >
> > The read_line_t callbacks are very similar for most pixel format, but it
> > is required to avoid performance impact. Some helpers for color
> > conversion were introduced to avoid code repetition:
> > - *_to_argb_u16: perform colors conversion. They should be inlined by the
> > compiler, and they are used to avoid repetition between multiple variants
> > of the same format (argb/xrgb and maybe in the future for formats like
> > bgr formats).
> >
> > This new algorithm was tested with:
> > - kms_plane (for color conversions)
> > - kms_rotation_crc (for rotations of planes)
> > - kms_cursor_crc (for translations of planes)
> > - kms_rotation (for all rotations and formats combinations) [3]
> > The performance gain was mesured with kms_fb_stress [4] with some
> > modification to fix the writeback format.
> >
> > The performance improvement is around 5 to 10%.
> >
> > [1]: commit 8ba1648567e2 ("drm: vkms: Refactor the plane composer to accept
> > new formats")
> > https://lore.kernel.org/all/20220905190811.25024-7-igormtorrente@gmail.com/
> > [2]: commit 322d716a3e8a ("drm/vkms: isolate pixel conversion
> > functionality")
> > https://lore.kernel.org/all/20230418130525.128733-2-mcanal@igalia.com/
> > [3]: https://lore.kernel.org/igt-dev/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com/
> > [4]: https://lore.kernel.org/all/20240422-kms_fb_stress-dev-v5-0-0c577163dc88@riseup.net/
> >
> > Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> > Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
> >
> > # Conflicts:
> > # drivers/gpu/drm/vkms/vkms_composer.c
I jut noticed this, I will remove it...
> > ---
> > drivers/gpu/drm/vkms/vkms_composer.c | 234 ++++++++++++++++++++++++++++-------
> > drivers/gpu/drm/vkms/vkms_drv.h | 28 +++--
> > drivers/gpu/drm/vkms/vkms_formats.c | 224 ++++++++++++++++++++-------------
> > drivers/gpu/drm/vkms/vkms_formats.h | 2 +-
> > drivers/gpu/drm/vkms/vkms_plane.c | 5 +-
> > 5 files changed, 344 insertions(+), 149 deletions(-)
> >
>
> [...]
>
> > -static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
> > +static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
> > {
> > - __le16 *pixel = (__le16 *)in_pixel;
> > + struct pixel_argb_u16 out_pixel;
> > s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
> > s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
> > @@ -226,40 +194,120 @@ static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pi
> > s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
> > s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
> > - out_pixel->a = (u16)0xffff;
> > - out_pixel->r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
> > - out_pixel->g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
> > - out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
> > + out_pixel.a = (u16)0xffff;
> > + out_pixel.r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
> > + out_pixel.g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
> > + out_pixel.b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
> > +
> > + return out_pixel;
> > }
> > -/**
> > - * vkms_compose_row - compose a single row of a plane
> > - * @stage_buffer: output line with the composed pixels
> > - * @plane: state of the plane that is being composed
> > - * @y: y coordinate of the row
> > +/*
> > + * The following functions are read_line function for each pixel format supported by VKMS.
> > + *
> > + * They read a line starting at the point @x_start,@y_start following the @direction. The result
> > + * is stored in @out_pixel and in the format ARGB16161616.
> > + *
> > + * These functions are very repetitive, but the innermost pixel loops must be kept inside these
> > + * functions for performance reasons. Some benchmarking was done in [1] where having the innermost
> > + * loop factored out of these functions showed a slowdown by a factor of three.
> > *
> > - * This function composes a single row of a plane. It gets the source pixels
> > - * through the y coordinate (see get_packed_src_addr()) and goes linearly
> > - * through the source pixel, reading the pixels and converting it to
> > - * ARGB16161616 (see the pixel_read() callback). For rotate-90 and rotate-270,
> > - * the source pixels are not traversed linearly. The source pixels are queried
> > - * on each iteration in order to traverse the pixels vertically.
> > + * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
> > */
> > -void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
> > +
> > +static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
> > + enum pixel_read_direction direction, int count,
> > + struct pixel_argb_u16 out_pixel[])
> > {
> > - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
> > - struct vkms_frame_info *frame_info = plane->frame_info;
> > - u8 *src_pixels = get_packed_src_addr(frame_info, y, 0);
> > - int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
> > + struct pixel_argb_u16 *end = out_pixel + count;
> > + u8 *src_pixels;
> > +
> > + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> > +
> > + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> > +
> > + while (out_pixel < end) {
> > + u8 *px = (u8 *)src_pixels;
>
> Why are you converting u8* to u8*? There are repetitions of this pattern
> in this patch.
I think it was to be consistent between all the conversion functions. They
are exactly the same, so having the casting (even useless one) at the same
place may help to understand the code.
I will remove this cast if you prefer.
> > + *out_pixel = argb_u16_from_u8888(px[3], px[2], px[1], px[0]);
> > + out_pixel += 1;
> > + src_pixels += step;
> > + }
> > +}
> > +
> > +static void XRGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
> > + enum pixel_read_direction direction, int count,
> > + struct pixel_argb_u16 out_pixel[])
> > +{
> > + struct pixel_argb_u16 *end = out_pixel + count;
> > + u8 *src_pixels;
> > +
> > + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> > +
> > + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> > +
> > + while (out_pixel < end) {
> > + u8 *px = (u8 *)src_pixels;
> > + *out_pixel = argb_u16_from_u8888(255, px[2], px[1], px[0]);
> > + out_pixel += 1;
> > + src_pixels += step;
> > + }
> > +}
> > +
> > +static void ARGB16161616_read_line(const struct vkms_plane_state *plane, int x_start,
> > + int y_start, enum pixel_read_direction direction, int count,
> > + struct pixel_argb_u16 out_pixel[])
> > +{
> > + struct pixel_argb_u16 *end = out_pixel + count;
> > + u8 *src_pixels;
> > +
> > + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> > +
> > + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> > +
> > + while (out_pixel < end) {
> > + u16 *px = (u16 *)src_pixels;
> > + *out_pixel = argb_u16_from_u16161616(px[3], px[2], px[1], px[0]);
> > + out_pixel += 1;
> > + src_pixels += step;
> > + }
> > +}
> > +
> > +static void XRGB16161616_read_line(const struct vkms_plane_state *plane, int x_start,
> > + int y_start, enum pixel_read_direction direction, int count,
> > + struct pixel_argb_u16 out_pixel[])
> > +{
> > + struct pixel_argb_u16 *end = out_pixel + count;
> > + u8 *src_pixels;
> > +
> > + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> > +
> > + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> > +
> > + while (out_pixel < end) {
> > + __le16 *px = (__le16 *)src_pixels;
> > + *out_pixel = argb_u16_from_le16161616(cpu_to_le16(0xFFFF), px[2], px[1], px[0]);
> > + out_pixel += 1;
> > + src_pixels += step;
> > + }
> > +}
> > +
> > +static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start,
> > + int y_start, enum pixel_read_direction direction, int count,
> > + struct pixel_argb_u16 out_pixel[])
> > +{
> > + struct pixel_argb_u16 *end = out_pixel + count;
> > + u8 *src_pixels;
> > +
> > + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
> > - for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) {
> > - int x_pos = get_x_position(frame_info, limit, x);
> > + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
> > - if (drm_rotation_90_or_270(frame_info->rotation))
> > - src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1, 0)
> > - + frame_info->fb->format->cpp[0] * y;
> > + while (out_pixel < end) {
> > + __le16 *px = (__le16 *)src_pixels;
> > - plane->pixel_read(src_pixels, &out_pixels[x_pos]);
> > + *out_pixel = argb_u16_from_RGB565(px);
> > + out_pixel += 1;
> > + src_pixels += step;
> > }
> > }
> > @@ -359,25 +407,25 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
> > }
> > /**
> > - * get_pixel_read_function() - Retrieve the correct read_pixel function for a specific
> > + * get_pixel_read_line_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
> > * the pointer is valid before using it in a vkms_plane_state.
> > *
> > * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h])
> > */
> > -pixel_read_t get_pixel_read_function(u32 format)
> > +pixel_read_line_t get_pixel_read_line_function(u32 format)
> > {
> > switch (format) {
> > case DRM_FORMAT_ARGB8888:
> > - return &ARGB8888_to_argb_u16;
> > + return &ARGB8888_read_line;
> > case DRM_FORMAT_XRGB8888:
> > - return &XRGB8888_to_argb_u16;
> > + return &XRGB8888_read_line;
> > case DRM_FORMAT_ARGB16161616:
> > - return &ARGB16161616_to_argb_u16;
> > + return &ARGB16161616_read_line;
> > case DRM_FORMAT_XRGB16161616:
> > - return &XRGB16161616_to_argb_u16;
> > + return &XRGB16161616_read_line;
> > case DRM_FORMAT_RGB565:
> > - return &RGB565_to_argb_u16;
> > + return &RGB565_read_line;
> > default:
> > /*
> > * This is a bug in vkms_plane_atomic_check(). All the supported
> > diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
> > index 3ecea4563254..8d2bef95ff79 100644
> > --- a/drivers/gpu/drm/vkms/vkms_formats.h
> > +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> > @@ -5,7 +5,7 @@
> > #include "vkms_drv.h"
> > -pixel_read_t get_pixel_read_function(u32 format);
> > +pixel_read_line_t get_pixel_read_line_function(u32 format);
> > pixel_write_t get_pixel_write_function(u32 format);
> > diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> > index 10e9b23dab28..8875bed76410 100644
> > --- a/drivers/gpu/drm/vkms/vkms_plane.c
> > +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> > @@ -112,7 +112,6 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
> > frame_info = vkms_plane_state->frame_info;
> > memcpy(&frame_info->src, &new_state->src, sizeof(struct drm_rect));
> > memcpy(&frame_info->dst, &new_state->dst, sizeof(struct drm_rect));
> > - memcpy(&frame_info->rotated, &new_state->dst, sizeof(struct drm_rect));
>
> If you won't use rotated anymore, delete it from the struct.
It is already done in this patch.
Thanks for your reviews,
Louis Chauvet
> Best Regards,
> - Maíra
>
> > frame_info->fb = fb;
> > memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
> > drm_framebuffer_get(frame_info->fb);
> > @@ -122,10 +121,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
> > DRM_MODE_REFLECT_X |
> > DRM_MODE_REFLECT_Y);
> > - drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
> > - drm_rect_height(&frame_info->rotated), frame_info->rotation);
> > - vkms_plane_state->pixel_read = get_pixel_read_function(fmt);
> > + vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
> > }
> > static int vkms_plane_atomic_check(struct drm_plane *plane,
> >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm
2024-10-28 9:50 ` Louis Chauvet
@ 2024-10-28 10:13 ` Maíra Canal
0 siblings, 0 replies; 36+ messages in thread
From: Maíra Canal @ 2024-10-28 10:13 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee, Pekka Paalanen
Hi Louis,
On 28/10/24 06:50, Louis Chauvet wrote:
> On 26/10/24 - 11:26, Maíra Canal wrote:
>> Hi Louis,
>>
>> On 07/10/24 13:10, Louis Chauvet wrote:
>>> Re-introduce a line-by-line composition algorithm for each pixel format.
>>> This allows more performance by not requiring an indirection per pixel
>>> read. This patch is focused on readability of the code.
>>>
>>> Line-by-line composition was introduced by [1] but rewritten back to
>>> pixel-by-pixel algorithm in [2]. At this time, nobody noticed the impact
>>> on performance, and it was merged.
>>>
>>> This patch is almost a revert of [2], but in addition efforts have been
>>> made to increase readability and maintainability of the rotation handling.
>>> The blend function is now divided in two parts:
>>> - Transformation of coordinates from the output referential to the source
>>> referential
>>> - Line conversion and blending
>>>
>>> Most of the complexity of the rotation management is avoided by using
>>> drm_rect_* helpers. The remaining complexity is around the clipping, to
>>> avoid reading/writing outside source/destination buffers.
>>>
>>> The pixel conversion is now done line-by-line, so the read_pixel_t was
>>> replaced with read_pixel_line_t callback. This way the indirection is only
>>> required once per line and per plane, instead of once per pixel and per
>>> plane.
>>>
>>> The read_line_t callbacks are very similar for most pixel format, but it
>>> is required to avoid performance impact. Some helpers for color
>>> conversion were introduced to avoid code repetition:
>>> - *_to_argb_u16: perform colors conversion. They should be inlined by the
>>> compiler, and they are used to avoid repetition between multiple variants
>>> of the same format (argb/xrgb and maybe in the future for formats like
>>> bgr formats).
>>>
>>> This new algorithm was tested with:
>>> - kms_plane (for color conversions)
>>> - kms_rotation_crc (for rotations of planes)
>>> - kms_cursor_crc (for translations of planes)
>>> - kms_rotation (for all rotations and formats combinations) [3]
>>> The performance gain was mesured with kms_fb_stress [4] with some
>>> modification to fix the writeback format.
>>>
>>> The performance improvement is around 5 to 10%.
>>>
>>> [1]: commit 8ba1648567e2 ("drm: vkms: Refactor the plane composer to accept
>>> new formats")
>>> https://lore.kernel.org/all/20220905190811.25024-7-igormtorrente@gmail.com/
>>> [2]: commit 322d716a3e8a ("drm/vkms: isolate pixel conversion
>>> functionality")
>>> https://lore.kernel.org/all/20230418130525.128733-2-mcanal@igalia.com/
>>> [3]: https://lore.kernel.org/igt-dev/20240313-new_rotation-v2-0-6230fd5cae59@bootlin.com/
>>> [4]: https://lore.kernel.org/all/20240422-kms_fb_stress-dev-v5-0-0c577163dc88@riseup.net/
>>>
>>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>>> Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
>>>
>>> # Conflicts:
>>> # drivers/gpu/drm/vkms/vkms_composer.c
>
> I jut noticed this, I will remove it...
>
>>> ---
>>> drivers/gpu/drm/vkms/vkms_composer.c | 234 ++++++++++++++++++++++++++++-------
>>> drivers/gpu/drm/vkms/vkms_drv.h | 28 +++--
>>> drivers/gpu/drm/vkms/vkms_formats.c | 224 ++++++++++++++++++++-------------
>>> drivers/gpu/drm/vkms/vkms_formats.h | 2 +-
>>> drivers/gpu/drm/vkms/vkms_plane.c | 5 +-
>>> 5 files changed, 344 insertions(+), 149 deletions(-)
>>>
>>
>> [...]
>>
>>> -static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pixel)
>>> +static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
>>> {
>>> - __le16 *pixel = (__le16 *)in_pixel;
>>> + struct pixel_argb_u16 out_pixel;
>>> s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
>>> s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
>>> @@ -226,40 +194,120 @@ static void RGB565_to_argb_u16(const u8 *in_pixel, struct pixel_argb_u16 *out_pi
>>> s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
>>> s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
>>> - out_pixel->a = (u16)0xffff;
>>> - out_pixel->r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
>>> - out_pixel->g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
>>> - out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
>>> + out_pixel.a = (u16)0xffff;
>>> + out_pixel.r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
>>> + out_pixel.g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
>>> + out_pixel.b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
>>> +
>>> + return out_pixel;
>>> }
>>> -/**
>>> - * vkms_compose_row - compose a single row of a plane
>>> - * @stage_buffer: output line with the composed pixels
>>> - * @plane: state of the plane that is being composed
>>> - * @y: y coordinate of the row
>>> +/*
>>> + * The following functions are read_line function for each pixel format supported by VKMS.
>>> + *
>>> + * They read a line starting at the point @x_start,@y_start following the @direction. The result
>>> + * is stored in @out_pixel and in the format ARGB16161616.
>>> + *
>>> + * These functions are very repetitive, but the innermost pixel loops must be kept inside these
>>> + * functions for performance reasons. Some benchmarking was done in [1] where having the innermost
>>> + * loop factored out of these functions showed a slowdown by a factor of three.
>>> *
>>> - * This function composes a single row of a plane. It gets the source pixels
>>> - * through the y coordinate (see get_packed_src_addr()) and goes linearly
>>> - * through the source pixel, reading the pixels and converting it to
>>> - * ARGB16161616 (see the pixel_read() callback). For rotate-90 and rotate-270,
>>> - * the source pixels are not traversed linearly. The source pixels are queried
>>> - * on each iteration in order to traverse the pixels vertically.
>>> + * [1]: https://lore.kernel.org/dri-devel/d258c8dc-78e9-4509-9037-a98f7f33b3a3@riseup.net/
>>> */
>>> -void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
>>> +
>>> +static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
>>> + enum pixel_read_direction direction, int count,
>>> + struct pixel_argb_u16 out_pixel[])
>>> {
>>> - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
>>> - struct vkms_frame_info *frame_info = plane->frame_info;
>>> - u8 *src_pixels = get_packed_src_addr(frame_info, y, 0);
>>> - int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
>>> + struct pixel_argb_u16 *end = out_pixel + count;
>>> + u8 *src_pixels;
>>> +
>>> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
>>> +
>>> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
>>> +
>>> + while (out_pixel < end) {
>>> + u8 *px = (u8 *)src_pixels;
>>
>> Why are you converting u8* to u8*? There are repetitions of this pattern
>> in this patch.
>
> I think it was to be consistent between all the conversion functions. They
> are exactly the same, so having the casting (even useless one) at the same
> place may help to understand the code.
>
> I will remove this cast if you prefer.
I only suggested to remove as we are going to delete this function when
we push [1]. So, I believe it's better to add as little code as
possible.
[1]
https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-0-d47da50d4674@bootlin.com/
Best Regards,
- Maíra
>
>>> + *out_pixel = argb_u16_from_u8888(px[3], px[2], px[1], px[0]);
>>> + out_pixel += 1;
>>> + src_pixels += step;
>>> + }
>>> +}
>>> +
>>> +static void XRGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start,
>>> + enum pixel_read_direction direction, int count,
>>> + struct pixel_argb_u16 out_pixel[])
>>> +{
>>> + struct pixel_argb_u16 *end = out_pixel + count;
>>> + u8 *src_pixels;
>>> +
>>> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
>>> +
>>> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
>>> +
>>> + while (out_pixel < end) {
>>> + u8 *px = (u8 *)src_pixels;
>>> + *out_pixel = argb_u16_from_u8888(255, px[2], px[1], px[0]);
>>> + out_pixel += 1;
>>> + src_pixels += step;
>>> + }
>>> +}
>>> +
>>> +static void ARGB16161616_read_line(const struct vkms_plane_state *plane, int x_start,
>>> + int y_start, enum pixel_read_direction direction, int count,
>>> + struct pixel_argb_u16 out_pixel[])
>>> +{
>>> + struct pixel_argb_u16 *end = out_pixel + count;
>>> + u8 *src_pixels;
>>> +
>>> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
>>> +
>>> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
>>> +
>>> + while (out_pixel < end) {
>>> + u16 *px = (u16 *)src_pixels;
>>> + *out_pixel = argb_u16_from_u16161616(px[3], px[2], px[1], px[0]);
>>> + out_pixel += 1;
>>> + src_pixels += step;
>>> + }
>>> +}
>>> +
>>> +static void XRGB16161616_read_line(const struct vkms_plane_state *plane, int x_start,
>>> + int y_start, enum pixel_read_direction direction, int count,
>>> + struct pixel_argb_u16 out_pixel[])
>>> +{
>>> + struct pixel_argb_u16 *end = out_pixel + count;
>>> + u8 *src_pixels;
>>> +
>>> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
>>> +
>>> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
>>> +
>>> + while (out_pixel < end) {
>>> + __le16 *px = (__le16 *)src_pixels;
>>> + *out_pixel = argb_u16_from_le16161616(cpu_to_le16(0xFFFF), px[2], px[1], px[0]);
>>> + out_pixel += 1;
>>> + src_pixels += step;
>>> + }
>>> +}
>>> +
>>> +static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start,
>>> + int y_start, enum pixel_read_direction direction, int count,
>>> + struct pixel_argb_u16 out_pixel[])
>>> +{
>>> + struct pixel_argb_u16 *end = out_pixel + count;
>>> + u8 *src_pixels;
>>> +
>>> + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels);
>>> - for (size_t x = 0; x < limit; x++, src_pixels += frame_info->fb->format->cpp[0]) {
>>> - int x_pos = get_x_position(frame_info, limit, x);
>>> + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0);
>>> - if (drm_rotation_90_or_270(frame_info->rotation))
>>> - src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1, 0)
>>> - + frame_info->fb->format->cpp[0] * y;
>>> + while (out_pixel < end) {
>>> + __le16 *px = (__le16 *)src_pixels;
>>> - plane->pixel_read(src_pixels, &out_pixels[x_pos]);
>>> + *out_pixel = argb_u16_from_RGB565(px);
>>> + out_pixel += 1;
>>> + src_pixels += step;
>>> }
>>> }
>>> @@ -359,25 +407,25 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
>>> }
>>> /**
>>> - * get_pixel_read_function() - Retrieve the correct read_pixel function for a specific
>>> + * get_pixel_read_line_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
>>> * the pointer is valid before using it in a vkms_plane_state.
>>> *
>>> * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h])
>>> */
>>> -pixel_read_t get_pixel_read_function(u32 format)
>>> +pixel_read_line_t get_pixel_read_line_function(u32 format)
>>> {
>>> switch (format) {
>>> case DRM_FORMAT_ARGB8888:
>>> - return &ARGB8888_to_argb_u16;
>>> + return &ARGB8888_read_line;
>>> case DRM_FORMAT_XRGB8888:
>>> - return &XRGB8888_to_argb_u16;
>>> + return &XRGB8888_read_line;
>>> case DRM_FORMAT_ARGB16161616:
>>> - return &ARGB16161616_to_argb_u16;
>>> + return &ARGB16161616_read_line;
>>> case DRM_FORMAT_XRGB16161616:
>>> - return &XRGB16161616_to_argb_u16;
>>> + return &XRGB16161616_read_line;
>>> case DRM_FORMAT_RGB565:
>>> - return &RGB565_to_argb_u16;
>>> + return &RGB565_read_line;
>>> default:
>>> /*
>>> * This is a bug in vkms_plane_atomic_check(). All the supported
>>> diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
>>> index 3ecea4563254..8d2bef95ff79 100644
>>> --- a/drivers/gpu/drm/vkms/vkms_formats.h
>>> +++ b/drivers/gpu/drm/vkms/vkms_formats.h
>>> @@ -5,7 +5,7 @@
>>> #include "vkms_drv.h"
>>> -pixel_read_t get_pixel_read_function(u32 format);
>>> +pixel_read_line_t get_pixel_read_line_function(u32 format);
>>> pixel_write_t get_pixel_write_function(u32 format);
>>> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
>>> index 10e9b23dab28..8875bed76410 100644
>>> --- a/drivers/gpu/drm/vkms/vkms_plane.c
>>> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
>>> @@ -112,7 +112,6 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
>>> frame_info = vkms_plane_state->frame_info;
>>> memcpy(&frame_info->src, &new_state->src, sizeof(struct drm_rect));
>>> memcpy(&frame_info->dst, &new_state->dst, sizeof(struct drm_rect));
>>> - memcpy(&frame_info->rotated, &new_state->dst, sizeof(struct drm_rect));
>>
>> If you won't use rotated anymore, delete it from the struct.
>
> It is already done in this patch.
>
> Thanks for your reviews,
> Louis Chauvet
>
>> Best Regards,
>> - Maíra
>>
>>> frame_info->fb = fb;
>>> memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
>>> drm_framebuffer_get(frame_info->fb);
>>> @@ -122,10 +121,8 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
>>> DRM_MODE_REFLECT_X |
>>> DRM_MODE_REFLECT_Y);
>>> - drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
>>> - drm_rect_height(&frame_info->rotated), frame_info->rotation);
>>> - vkms_plane_state->pixel_read = get_pixel_read_function(fmt);
>>> + vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
>>> }
>>> static int vkms_plane_atomic_check(struct drm_plane *plane,
>>>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-28 9:50 ` Louis Chauvet
@ 2024-10-28 10:17 ` Maíra Canal
2024-10-28 11:01 ` Louis Chauvet
0 siblings, 1 reply; 36+ messages in thread
From: Maíra Canal @ 2024-10-28 10:17 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee
Hi Louis,
On 28/10/24 06:50, Louis Chauvet wrote:
> On 26/10/24 - 09:10, Maíra Canal wrote:
>> Hi Louis,
>>
>> On 14/10/24 05:39, Louis Chauvet wrote:
>>> On 11/10/24 - 10:53, Maira Canal wrote:
>>>> Hi Louis,
>>>>
>>>> On 10/11/24 06:36, Louis Chauvet wrote:
>>>>>
>>>>> Hi all,
>>>>>
>>>>> Until this point, this series has not received any major comments since
>>>>> v9. I will commit patches 1-9 next week if there are no further comments.
>>>>>
>>>>
>>>> Although we are maintainers of VKMS, it isn't recommended that we push
>>>> our own changes without even the Ack of another person. Please, read the
>>>> "drm-misc Committer Guidelines" [1].
>>>
>>> Hi Maíra, Maxime,
>>>
>>> I apologize for this rushed commit request. I sent the initial email with
>>> a delay before the commit action because I was not sure about the
>>> procedure and wanted to give others a chance to raise any concerns.
>>> Unfortunately, I overlooked the need to collect an Ack/Review for each
>>> patch, even when there hadn't been any responses for several months. I'm
>>> sorry for this oversight.
>>>
>>>> I can ack patches 05/15, 07/15, and 09/15, but it would be more
>>>> beneficial for the community if you ask for an ack (from me or from the
>>>> DRM maintainers, which are always around), instead of saying that you
>>>> are going to commit the patches without any review.
>>>
>>> I will be happy to ask for acknowledgments if needed, but as you mentioned
>>> multiple times: nobody is paid to maintain VKMS. Since you did not comment
>>> these series since July, when you told me you would review my patches, I
>>> assumed it was either okay or you no longer had the time to maintain
>>> (which I completely understand).
>>
>> Yeah, I'm a volunteer and no longer have time to maintain VKMS. A couple
>> of weeks ago I sent a patch removing myself as VKMS maintainer. This
>> doesn't imply that patches can be pushed without review.
>
> I will acked-by and push your patch, it will be an easy "first commit". If
> I do something wrong during the process, please tell me.
>
> Thanks for this precision, I understood this, and I will not push without
> reviews, don't worry!
>
> Thanks a lot for all your reviews!
>
>> We are a community with several active developers. Although I don't have
>> time to properly review your patches, you can try to gather other
>> developers to review your patches. You can try to use #dri-devel to get
>> reviewers.
>
> Thanks for the tip, I will do this!
>
>> That said, you can add my ACK to patches 05/15, 07/15, and 09/15 and
>> push the patches. I won't ack the YUV patches as I don't feel
>> comfortable reviewing/acking those.
>
> Perfect for the patches 1..9, it will be a very nice step forward and will
> reduce my conflicts a lot with the rest of my work!
> >> Acked-by: Maíra Canal <mairacanal@riseup.net>
>>
>> BTW if the patches are fixing IGT tests, please update the list of fails
>> and skips on DRM CI.
>
> For this, how should I do? Commit the series and wait for the bot results?
> Run tests on my computer (I only have a x86 VM)? Is there some doc
> somewhere?
Check [1] for instructions on how to run the CI on GitLab.
[1] https://docs.kernel.org/gpu/automated_testing.html
Best Regards,
- Maíra
>
> Thanks a lot,
> Louis Chauvet
>
>> Best Regards,
>> - Maíra
>>
>>>
>>> So, I hereby formally request reviews/ACKs for the following series:
>>>
>>> [this series]:https://lore.kernel.org/all/20241007-yuv-v12-0-01c1ada6fec8@bootlin.com/
>>> [2]:https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-0-d47da50d4674@bootlin.com/
>>> [3]:https://lore.kernel.org/all/20240516-writeback_line_by_line-v1-0-7b2e3bf9f1c9@bootlin.com/
>>>
>>> (I have to send a v2 for [3] because of rebase conflict, but nothing else
>>> changed)
>>>
>>> Thanks a lot,
>>> Louis Chauvet
>>>> [1] https://drm.pages.freedesktop.org/maintainer-tools/committer/committer-drm-misc.html
>>>>
>>>> Best Regards,
>>>> - Maíra
>>>>
>>>>> For patches 10-15, I am currently waiting for feedback from Maxime to
>>>>> send the next iteration with a fix for kunit tests.
>>>>>
>>>>> Thanks,
>>>>> Louis Chauvet
>>>>>
>>>>> On 07/10/24 - 18:10, Louis Chauvet wrote:
>>>>>> As all the rotation are now supported by VKMS, this simplification does
>>>>>> not make sense anymore, so remove it.
>>>>>>
>>>>>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>>>>>> ---
>>>>>> drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
>>>>>> 1 file changed, 1 insertion(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
>>>>>> index 8875bed76410..5a028ee96c91 100644
>>>>>> --- a/drivers/gpu/drm/vkms/vkms_plane.c
>>>>>> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
>>>>>> @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
>>>>>> frame_info->fb = fb;
>>>>>> memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
>>>>>> drm_framebuffer_get(frame_info->fb);
>>>>>> - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
>>>>>> - DRM_MODE_ROTATE_90 |
>>>>>> - DRM_MODE_ROTATE_270 |
>>>>>> - DRM_MODE_REFLECT_X |
>>>>>> - DRM_MODE_REFLECT_Y);
>>>>>> -
>>>>>> + frame_info->rotation = new_state->rotation;
>>>>>> vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
>>>>>> }
>>>>>>
>>>>>> --
>>>>>> 2.46.2
>>>>>>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-28 10:17 ` Maíra Canal
@ 2024-10-28 11:01 ` Louis Chauvet
2024-10-28 19:31 ` Maíra Canal
0 siblings, 1 reply; 36+ messages in thread
From: Louis Chauvet @ 2024-10-28 11:01 UTC (permalink / raw)
To: Maíra Canal
Cc: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee
On 28/10/24 - 07:17, Maíra Canal wrote:
> Hi Louis,
>
> On 28/10/24 06:50, Louis Chauvet wrote:
> > On 26/10/24 - 09:10, Maíra Canal wrote:
> > > Hi Louis,
> > >
> > > On 14/10/24 05:39, Louis Chauvet wrote:
> > > > On 11/10/24 - 10:53, Maira Canal wrote:
> > > > > Hi Louis,
> > > > >
> > > > > On 10/11/24 06:36, Louis Chauvet wrote:
> > > > > >
> > > > > > Hi all,
> > > > > >
> > > > > > Until this point, this series has not received any major comments since
> > > > > > v9. I will commit patches 1-9 next week if there are no further comments.
> > > > > >
> > > > >
> > > > > Although we are maintainers of VKMS, it isn't recommended that we push
> > > > > our own changes without even the Ack of another person. Please, read the
> > > > > "drm-misc Committer Guidelines" [1].
> > > >
> > > > Hi Maíra, Maxime,
> > > >
> > > > I apologize for this rushed commit request. I sent the initial email with
> > > > a delay before the commit action because I was not sure about the
> > > > procedure and wanted to give others a chance to raise any concerns.
> > > > Unfortunately, I overlooked the need to collect an Ack/Review for each
> > > > patch, even when there hadn't been any responses for several months. I'm
> > > > sorry for this oversight.
> > > >
> > > > > I can ack patches 05/15, 07/15, and 09/15, but it would be more
> > > > > beneficial for the community if you ask for an ack (from me or from the
> > > > > DRM maintainers, which are always around), instead of saying that you
> > > > > are going to commit the patches without any review.
> > > >
> > > > I will be happy to ask for acknowledgments if needed, but as you mentioned
> > > > multiple times: nobody is paid to maintain VKMS. Since you did not comment
> > > > these series since July, when you told me you would review my patches, I
> > > > assumed it was either okay or you no longer had the time to maintain
> > > > (which I completely understand).
> > >
> > > Yeah, I'm a volunteer and no longer have time to maintain VKMS. A couple
> > > of weeks ago I sent a patch removing myself as VKMS maintainer. This
> > > doesn't imply that patches can be pushed without review.
> >
> > I will acked-by and push your patch, it will be an easy "first commit". If
> > I do something wrong during the process, please tell me.
> >
> > Thanks for this precision, I understood this, and I will not push without
> > reviews, don't worry!
> >
> > Thanks a lot for all your reviews!
> > > We are a community with several active developers. Although I don't have
> > > time to properly review your patches, you can try to gather other
> > > developers to review your patches. You can try to use #dri-devel to get
> > > reviewers.
> >
> > Thanks for the tip, I will do this!
> >
> > > That said, you can add my ACK to patches 05/15, 07/15, and 09/15 and
> > > push the patches. I won't ack the YUV patches as I don't feel
> > > comfortable reviewing/acking those.
> >
> > Perfect for the patches 1..9, it will be a very nice step forward and will
> > reduce my conflicts a lot with the rest of my work!
> > >> Acked-by: Maíra Canal <mairacanal@riseup.net>
> > >
> > > BTW if the patches are fixing IGT tests, please update the list of fails
> > > and skips on DRM CI.
> >
> > For this, how should I do? Commit the series and wait for the bot results?
> > Run tests on my computer (I only have a x86 VM)? Is there some doc
> > somewhere?
>
> Check [1] for instructions on how to run the CI on GitLab.
>
> [1] https://docs.kernel.org/gpu/automated_testing.html
Thanks for the link!
I am stuck at the first step, do I need to ask some right to create a repo
on git.freedesktop.org? I don't see any button to create a repo, and I
can't fork any existing kernel repo.
I also asked the access to CI-OK.
Thanks,
Louis Chauvet
> Best Regards,
> - Maíra
>
> >
> > Thanks a lot,
> > Louis Chauvet
> >
> > > Best Regards,
> > > - Maíra
> > >
> > > >
> > > > So, I hereby formally request reviews/ACKs for the following series:
> > > >
> > > > [this series]:https://lore.kernel.org/all/20241007-yuv-v12-0-01c1ada6fec8@bootlin.com/
> > > > [2]:https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-0-d47da50d4674@bootlin.com/
> > > > [3]:https://lore.kernel.org/all/20240516-writeback_line_by_line-v1-0-7b2e3bf9f1c9@bootlin.com/
> > > >
> > > > (I have to send a v2 for [3] because of rebase conflict, but nothing else
> > > > changed)
> > > >
> > > > Thanks a lot,
> > > > Louis Chauvet
> > > > > [1] https://drm.pages.freedesktop.org/maintainer-tools/committer/committer-drm-misc.html
> > > > >
> > > > > Best Regards,
> > > > > - Maíra
> > > > >
> > > > > > For patches 10-15, I am currently waiting for feedback from Maxime to
> > > > > > send the next iteration with a fix for kunit tests.
> > > > > >
> > > > > > Thanks,
> > > > > > Louis Chauvet
> > > > > >
> > > > > > On 07/10/24 - 18:10, Louis Chauvet wrote:
> > > > > > > As all the rotation are now supported by VKMS, this simplification does
> > > > > > > not make sense anymore, so remove it.
> > > > > > >
> > > > > > > Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> > > > > > > ---
> > > > > > > drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
> > > > > > > 1 file changed, 1 insertion(+), 6 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> > > > > > > index 8875bed76410..5a028ee96c91 100644
> > > > > > > --- a/drivers/gpu/drm/vkms/vkms_plane.c
> > > > > > > +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> > > > > > > @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
> > > > > > > frame_info->fb = fb;
> > > > > > > memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
> > > > > > > drm_framebuffer_get(frame_info->fb);
> > > > > > > - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
> > > > > > > - DRM_MODE_ROTATE_90 |
> > > > > > > - DRM_MODE_ROTATE_270 |
> > > > > > > - DRM_MODE_REFLECT_X |
> > > > > > > - DRM_MODE_REFLECT_Y);
> > > > > > > -
> > > > > > > + frame_info->rotation = new_state->rotation;
> > > > > > > vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
> > > > > > > }
> > > > > > >
> > > > > > > --
> > > > > > > 2.46.2
> > > > > > >
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify
2024-10-28 11:01 ` Louis Chauvet
@ 2024-10-28 19:31 ` Maíra Canal
0 siblings, 0 replies; 36+ messages in thread
From: Maíra Canal @ 2024-10-28 19:31 UTC (permalink / raw)
To: Rodrigo Siqueira, Melissa Wen, Haneen Mohammed, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
Simona Vetter, rdunlap, arthurgrillo, pekka.paalanen,
Simona Vetter, dri-devel, linux-kernel, linux-doc,
thomas.petazzoni, jeremie.dautheribes, miquel.raynal, seanpaul,
marcheu, nicolejadeyee
Hi Louis,
On 28/10/24 08:01, Louis Chauvet wrote:
> On 28/10/24 - 07:17, Maíra Canal wrote:
>> Hi Louis,
>>
>> On 28/10/24 06:50, Louis Chauvet wrote:
>>> On 26/10/24 - 09:10, Maíra Canal wrote:
>>>> Hi Louis,
>>>>
>>>> On 14/10/24 05:39, Louis Chauvet wrote:
>>>>> On 11/10/24 - 10:53, Maira Canal wrote:
>>>>>> Hi Louis,
>>>>>>
>>>>>> On 10/11/24 06:36, Louis Chauvet wrote:
>>>>>>>
>>>>>>> Hi all,
>>>>>>>
>>>>>>> Until this point, this series has not received any major comments since
>>>>>>> v9. I will commit patches 1-9 next week if there are no further comments.
>>>>>>>
>>>>>>
>>>>>> Although we are maintainers of VKMS, it isn't recommended that we push
>>>>>> our own changes without even the Ack of another person. Please, read the
>>>>>> "drm-misc Committer Guidelines" [1].
>>>>>
>>>>> Hi Maíra, Maxime,
>>>>>
>>>>> I apologize for this rushed commit request. I sent the initial email with
>>>>> a delay before the commit action because I was not sure about the
>>>>> procedure and wanted to give others a chance to raise any concerns.
>>>>> Unfortunately, I overlooked the need to collect an Ack/Review for each
>>>>> patch, even when there hadn't been any responses for several months. I'm
>>>>> sorry for this oversight.
>>>>>
>>>>>> I can ack patches 05/15, 07/15, and 09/15, but it would be more
>>>>>> beneficial for the community if you ask for an ack (from me or from the
>>>>>> DRM maintainers, which are always around), instead of saying that you
>>>>>> are going to commit the patches without any review.
>>>>>
>>>>> I will be happy to ask for acknowledgments if needed, but as you mentioned
>>>>> multiple times: nobody is paid to maintain VKMS. Since you did not comment
>>>>> these series since July, when you told me you would review my patches, I
>>>>> assumed it was either okay or you no longer had the time to maintain
>>>>> (which I completely understand).
>>>>
>>>> Yeah, I'm a volunteer and no longer have time to maintain VKMS. A couple
>>>> of weeks ago I sent a patch removing myself as VKMS maintainer. This
>>>> doesn't imply that patches can be pushed without review.
>>>
>>> I will acked-by and push your patch, it will be an easy "first commit". If
>>> I do something wrong during the process, please tell me.
>>>
>>> Thanks for this precision, I understood this, and I will not push without
>>> reviews, don't worry!
>>>
>>> Thanks a lot for all your reviews!
>>>> We are a community with several active developers. Although I don't have
>>>> time to properly review your patches, you can try to gather other
>>>> developers to review your patches. You can try to use #dri-devel to get
>>>> reviewers.
>>>
>>> Thanks for the tip, I will do this!
>>>
>>>> That said, you can add my ACK to patches 05/15, 07/15, and 09/15 and
>>>> push the patches. I won't ack the YUV patches as I don't feel
>>>> comfortable reviewing/acking those.
>>>
>>> Perfect for the patches 1..9, it will be a very nice step forward and will
>>> reduce my conflicts a lot with the rest of my work!
>>>>> Acked-by: Maíra Canal <mairacanal@riseup.net>
>>>>
>>>> BTW if the patches are fixing IGT tests, please update the list of fails
>>>> and skips on DRM CI.
>>>
>>> For this, how should I do? Commit the series and wait for the bot results?
>>> Run tests on my computer (I only have a x86 VM)? Is there some doc
>>> somewhere?
>>
>> Check [1] for instructions on how to run the CI on GitLab.
>>
>> [1] https://docs.kernel.org/gpu/automated_testing.html
>
> Thanks for the link!
>
> I am stuck at the first step, do I need to ask some right to create a repo
> on git.freedesktop.org? I don't see any button to create a repo, and I
> can't fork any existing kernel repo.
Check [1]. For more fd.o infra questions, you can ask on #freedesktop
(the answer will probably be quicker).
[1] https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home
Best Regards,
- Maíra
>
> I also asked the access to CI-OK.
>
> Thanks,
> Louis Chauvet
>
>> Best Regards,
>> - Maíra
>>
>>>
>>> Thanks a lot,
>>> Louis Chauvet
>>>
>>>> Best Regards,
>>>> - Maíra
>>>>
>>>>>
>>>>> So, I hereby formally request reviews/ACKs for the following series:
>>>>>
>>>>> [this series]:https://lore.kernel.org/all/20241007-yuv-v12-0-01c1ada6fec8@bootlin.com/
>>>>> [2]:https://lore.kernel.org/all/20241007-b4-new-color-formats-v2-0-d47da50d4674@bootlin.com/
>>>>> [3]:https://lore.kernel.org/all/20240516-writeback_line_by_line-v1-0-7b2e3bf9f1c9@bootlin.com/
>>>>>
>>>>> (I have to send a v2 for [3] because of rebase conflict, but nothing else
>>>>> changed)
>>>>>
>>>>> Thanks a lot,
>>>>> Louis Chauvet
>>>>>> [1] https://drm.pages.freedesktop.org/maintainer-tools/committer/committer-drm-misc.html
>>>>>>
>>>>>> Best Regards,
>>>>>> - Maíra
>>>>>>
>>>>>>> For patches 10-15, I am currently waiting for feedback from Maxime to
>>>>>>> send the next iteration with a fix for kunit tests.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Louis Chauvet
>>>>>>>
>>>>>>> On 07/10/24 - 18:10, Louis Chauvet wrote:
>>>>>>>> As all the rotation are now supported by VKMS, this simplification does
>>>>>>>> not make sense anymore, so remove it.
>>>>>>>>
>>>>>>>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>>>>>>>> ---
>>>>>>>> drivers/gpu/drm/vkms/vkms_plane.c | 7 +------
>>>>>>>> 1 file changed, 1 insertion(+), 6 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
>>>>>>>> index 8875bed76410..5a028ee96c91 100644
>>>>>>>> --- a/drivers/gpu/drm/vkms/vkms_plane.c
>>>>>>>> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
>>>>>>>> @@ -115,12 +115,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
>>>>>>>> frame_info->fb = fb;
>>>>>>>> memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
>>>>>>>> drm_framebuffer_get(frame_info->fb);
>>>>>>>> - frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
>>>>>>>> - DRM_MODE_ROTATE_90 |
>>>>>>>> - DRM_MODE_ROTATE_270 |
>>>>>>>> - DRM_MODE_REFLECT_X |
>>>>>>>> - DRM_MODE_REFLECT_Y);
>>>>>>>> -
>>>>>>>> + frame_info->rotation = new_state->rotation;
>>>>>>>> vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt);
>>>>>>>> }
>>>>>>>>
>>>>>>>> --
>>>>>>>> 2.46.2
>>>>>>>>
>>
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2024-10-28 19:31 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-07 16:10 [PATCH v12 00/15] drm/vkms: Reimplement line-per-line pixel conversion for plane reading Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 01/15] drm/vkms: Code formatting Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 02/15] drm/vkms: Use drm_frame directly Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 03/15] drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 04/15] drm/vkms: Use const for input pointers in pixel_read an " Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 05/15] drm/vkms: Update pixels accessor to support packed and multi-plane formats Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 06/15] drm/vkms: Avoid computing blending limits inside pre_mul_alpha_blend Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 07/15] drm/vkms: Introduce pixel_read_direction enum Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 08/15] drm/vkms: Re-introduce line-per-line composition algorithm Louis Chauvet
2024-10-26 14:26 ` Maíra Canal
2024-10-28 9:50 ` Louis Chauvet
2024-10-28 10:13 ` Maíra Canal
2024-10-07 16:10 ` [PATCH v12 09/15] drm/vkms: Remove useless drm_rotation_simplify Louis Chauvet
2024-10-11 9:36 ` Louis Chauvet
2024-10-11 13:53 ` Maira Canal
2024-10-11 14:14 ` Maxime Ripard
2024-10-14 8:39 ` Louis Chauvet
2024-10-26 12:10 ` Maíra Canal
2024-10-28 9:50 ` Louis Chauvet
2024-10-28 10:17 ` Maíra Canal
2024-10-28 11:01 ` Louis Chauvet
2024-10-28 19:31 ` Maíra Canal
2024-10-07 16:10 ` [PATCH v12 10/15] drm/vkms: Add YUV support Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 11/15] drm/vkms: Add range and encoding properties to the plane Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 12/15] drm/vkms: Drop YUV formats TODO Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 13/15] drm/vkms: Create KUnit tests for YUV conversions Louis Chauvet
2024-10-08 7:53 ` Maxime Ripard
2024-10-08 9:23 ` Louis Chauvet
2024-10-11 10:49 ` Maxime Ripard
2024-10-11 14:29 ` Louis Chauvet
2024-10-24 14:06 ` Maxime Ripard
2024-10-10 20:35 ` kernel test robot
2024-10-26 14:49 ` Maíra Canal
2024-10-28 9:50 ` Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 14/15] drm/vkms: Add how to run the Kunit tests Louis Chauvet
2024-10-07 16:10 ` [PATCH v12 15/15] drm/vkms: Add support for DRM_FORMAT_R* Louis Chauvet
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).