diff mbox series

[v2,4/4] drm/format-helper: Add KUnit tests for drm_fb_xrgb8888_to_rgb565()

Message ID 20220709115837.560877-5-jose.exposito89@gmail.com (mailing list archive)
State New, archived
Headers show
Series KUnit tests for RGB565 conversion | expand

Commit Message

José Expósito July 9, 2022, 11:58 a.m. UTC
Extend the existing test cases to test the conversion from XRGB8888 to
RGB565.

The documentation and the color picker available on [1] are useful
resources to understand this patch and validate the values returned by
the conversion function.

Tested-by: Tales L. Aparecida <tales.aparecida@gmail.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Link: http://www.barth-dev.de/online/rgb565-color-picker/ # [1]
---
 .../gpu/drm/tests/drm_format_helper_test.c    | 76 ++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

Comments

David Gow July 16, 2022, 9:32 a.m. UTC | #1
On Sat, Jul 9, 2022 at 7:58 PM José Expósito <jose.exposito89@gmail.com> wrote:
>
> Extend the existing test cases to test the conversion from XRGB8888 to
> RGB565.
>
> The documentation and the color picker available on [1] are useful
> resources to understand this patch and validate the values returned by
> the conversion function.
>
> Tested-by: Tales L. Aparecida <tales.aparecida@gmail.com>
> Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
> Signed-off-by: José Expósito <jose.exposito89@gmail.com>
> Link: http://www.barth-dev.de/online/rgb565-color-picker/ # [1]
> ---

Looks good and passes here.

Reviewed-by: David Gow <davidgow@google.com>

Thanks,
-- David


>  .../gpu/drm/tests/drm_format_helper_test.c    | 76 ++++++++++++++++++-
>  1 file changed, 75 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c
> index 0a490ad4fd32..c0592c1235cf 100644
> --- a/drivers/gpu/drm/tests/drm_format_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
> @@ -21,12 +21,19 @@ struct convert_to_rgb332_result {
>         const u8 expected[TEST_BUF_SIZE];
>  };
>
> +struct convert_to_rgb565_result {
> +       unsigned int dst_pitch;
> +       const u16 expected[TEST_BUF_SIZE];
> +       const u16 expected_swab[TEST_BUF_SIZE];
> +};
> +
>  struct convert_xrgb8888_case {
>         const char *name;
>         unsigned int pitch;
>         struct drm_rect clip;
>         const u32 xrgb8888[TEST_BUF_SIZE];
>         struct convert_to_rgb332_result rgb332_result;
> +       struct convert_to_rgb565_result rgb565_result;
>  };
>
>  static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
> @@ -39,6 +46,11 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
>                         .dst_pitch = 0,
>                         .expected = { 0xE0 },
>                 },
> +               .rgb565_result = {
> +                       .dst_pitch = 0,
> +                       .expected = { 0xF800 },
> +                       .expected_swab = { 0x00F8 },
> +               },
>         },
>         {
>                 .name = "single_pixel_clip_rectangle",
> @@ -52,6 +64,11 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
>                         .dst_pitch = 0,
>                         .expected = { 0xE0 },
>                 },
> +               .rgb565_result = {
> +                       .dst_pitch = 0,
> +                       .expected = { 0xF800 },
> +                       .expected_swab = { 0x00F8 },
> +               },
>         },
>         {
>                 /* Well known colors: White, black, red, green, blue, magenta,
> @@ -77,6 +94,21 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
>                                 0xFC, 0x1F,
>                         },
>                 },
> +               .rgb565_result = {
> +                       .dst_pitch = 0,
> +                       .expected = {
> +                               0xFFFF, 0x0000,
> +                               0xF800, 0x07E0,
> +                               0x001F, 0xF81F,
> +                               0xFFE0, 0x07FF,
> +                       },
> +                       .expected_swab = {
> +                               0xFFFF, 0x0000,
> +                               0x00F8, 0xE007,
> +                               0x1F00, 0x1FF8,
> +                               0xE0FF, 0xFF07,
> +                       },
> +               },
>         },
>         {
>                 /* Randomly picked colors. Full buffer within the clip area. */
> @@ -96,6 +128,19 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
>                                 0xA0, 0x6D, 0x0A, 0x00, 0x00,
>                         },
>                 },
> +               .rgb565_result = {
> +                       .dst_pitch = 10,
> +                       .expected = {
> +                               0x0A33, 0x1260, 0xA800, 0x0000, 0x0000,
> +                               0x6B8E, 0x0A33, 0x1260, 0x0000, 0x0000,
> +                               0xA800, 0x6B8E, 0x0A33, 0x0000, 0x0000,
> +                       },
> +                       .expected_swab = {
> +                               0x330A, 0x6012, 0x00A8, 0x0000, 0x0000,
> +                               0x8E6B, 0x330A, 0x6012, 0x0000, 0x0000,
> +                               0x00A8, 0x8E6B, 0x330A, 0x0000, 0x0000,
> +                       },
> +               },
>         },
>  };
>
> @@ -120,7 +165,7 @@ static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
>         if (!dst_pitch)
>                 dst_pitch = drm_rect_width(clip) * dst_fi->cpp[0];
>
> -       return dst_pitch * drm_rect_height(clip);
> +       return (dst_pitch * drm_rect_height(clip)) / (dst_fi->depth / 8);
>  }
>
>  static u32 *le32buf_to_cpu(struct kunit *test, const u32 *buf, size_t buf_size)
> @@ -175,8 +220,37 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)
>         KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected, dst_size), 0);
>  }
>
> +static void xrgb8888_to_rgb565_test(struct kunit *test)
> +{
> +       const struct convert_xrgb8888_case *params = test->param_value;
> +       const struct convert_to_rgb565_result *result = &params->rgb565_result;
> +       size_t dst_size;
> +       __u16 *dst = NULL;
> +
> +       struct drm_framebuffer fb = {
> +               .format = drm_format_info(DRM_FORMAT_XRGB8888),
> +               .pitches = { params->pitch, 0, 0 },
> +       };
> +
> +       dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
> +                                      &params->clip);
> +       KUNIT_ASSERT_GT(test, dst_size, 0);
> +
> +       dst = kunit_kzalloc(test, dst_size, GFP_KERNEL);
> +       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dst);
> +
> +       drm_fb_xrgb8888_to_rgb565(dst, result->dst_pitch, params->xrgb8888, &fb,
> +                                 &params->clip, false);
> +       KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected, dst_size), 0);
> +
> +       drm_fb_xrgb8888_to_rgb565(dst, result->dst_pitch, params->xrgb8888, &fb,
> +                                 &params->clip, true);
> +       KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected_swab, dst_size), 0);
> +}
> +
>  static struct kunit_case drm_format_helper_test_cases[] = {
>         KUNIT_CASE_PARAM(xrgb8888_to_rgb332_test, convert_xrgb8888_gen_params),
> +       KUNIT_CASE_PARAM(xrgb8888_to_rgb565_test, convert_xrgb8888_gen_params),
>         {}
>  };
>
> --
> 2.25.1
>
José Expósito July 17, 2022, 4:55 p.m. UTC | #2
Hi David,

On Sat, Jul 16, 2022 at 05:32:51PM +0800, David Gow wrote:
> On Sat, Jul 9, 2022 at 7:58 PM José Expósito <jose.exposito89@gmail.com> wrote:
> >
> > Extend the existing test cases to test the conversion from XRGB8888 to
> > RGB565.
> >
> > The documentation and the color picker available on [1] are useful
> > resources to understand this patch and validate the values returned by
> > the conversion function.
> >
> > Tested-by: Tales L. Aparecida <tales.aparecida@gmail.com>
> > Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
> > Signed-off-by: José Expósito <jose.exposito89@gmail.com>
> > Link: http://www.barth-dev.de/online/rgb565-color-picker/ # [1]
> > ---
> 
> Looks good and passes here.
> 
> Reviewed-by: David Gow <davidgow@google.com>
> 
> Thanks,
> -- David

Thanks a lot for reviewing the series and for pointing out the Sparse
warning. 

I already fixed the warning and added the reviewed by tags, however, I
noticed that rebasing the series on the latest drm-misc-next show this
error:

    [18:49:32] ============================================================
    [18:49:33] =========== drm_format_helper_test (2 subtests) ============
    [18:49:33] ================= xrgb8888_to_rgb332_test ==================
    [18:49:33] [ERROR] Test: xrgb8888_to_rgb332_test: missing subtest result line!
    [18:49:33] [ERROR] Test: xrgb8888_to_rgb332_test: 0 tests run!
    [18:49:33] ========== [NO TESTS RUN] xrgb8888_to_rgb332_test ==========
    [18:49:33] [ERROR] Test: drm_format_helper_test: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: drm_format_helper_test: missing subtest result line!
    [18:49:33] # Subtest: drm_format_helper_test
    [18:49:33] 1..2
    [18:49:33] ============= [CRASHED] drm_format_helper_test =============
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] [ERROR] Test: main: missing expected subtest!
    [18:49:33] [CRASHED] 
    [18:49:33] ============================================================
    [18:49:33] Testing complete. Ran 10 tests: crashed: 10, errors: 13

I bisected drm-misc-next to find out that the first bad commit is:
e23a5e14aa278858c2e3d81ec34e83aa9a4177c5

Not very usefull, because that commit merges v5.19-rc6 into misc.

I tested on the latest kselftest-master branch and the error is not
present.

Are you aware of any change that could cause this issue?

Jose

 
> >  .../gpu/drm/tests/drm_format_helper_test.c    | 76 ++++++++++++++++++-
> >  1 file changed, 75 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c
> > index 0a490ad4fd32..c0592c1235cf 100644
> > --- a/drivers/gpu/drm/tests/drm_format_helper_test.c
> > +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
> > @@ -21,12 +21,19 @@ struct convert_to_rgb332_result {
> >         const u8 expected[TEST_BUF_SIZE];
> >  };
> >
> > +struct convert_to_rgb565_result {
> > +       unsigned int dst_pitch;
> > +       const u16 expected[TEST_BUF_SIZE];
> > +       const u16 expected_swab[TEST_BUF_SIZE];
> > +};
> > +
> >  struct convert_xrgb8888_case {
> >         const char *name;
> >         unsigned int pitch;
> >         struct drm_rect clip;
> >         const u32 xrgb8888[TEST_BUF_SIZE];
> >         struct convert_to_rgb332_result rgb332_result;
> > +       struct convert_to_rgb565_result rgb565_result;
> >  };
> >
> >  static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
> > @@ -39,6 +46,11 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
> >                         .dst_pitch = 0,
> >                         .expected = { 0xE0 },
> >                 },
> > +               .rgb565_result = {
> > +                       .dst_pitch = 0,
> > +                       .expected = { 0xF800 },
> > +                       .expected_swab = { 0x00F8 },
> > +               },
> >         },
> >         {
> >                 .name = "single_pixel_clip_rectangle",
> > @@ -52,6 +64,11 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
> >                         .dst_pitch = 0,
> >                         .expected = { 0xE0 },
> >                 },
> > +               .rgb565_result = {
> > +                       .dst_pitch = 0,
> > +                       .expected = { 0xF800 },
> > +                       .expected_swab = { 0x00F8 },
> > +               },
> >         },
> >         {
> >                 /* Well known colors: White, black, red, green, blue, magenta,
> > @@ -77,6 +94,21 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
> >                                 0xFC, 0x1F,
> >                         },
> >                 },
> > +               .rgb565_result = {
> > +                       .dst_pitch = 0,
> > +                       .expected = {
> > +                               0xFFFF, 0x0000,
> > +                               0xF800, 0x07E0,
> > +                               0x001F, 0xF81F,
> > +                               0xFFE0, 0x07FF,
> > +                       },
> > +                       .expected_swab = {
> > +                               0xFFFF, 0x0000,
> > +                               0x00F8, 0xE007,
> > +                               0x1F00, 0x1FF8,
> > +                               0xE0FF, 0xFF07,
> > +                       },
> > +               },
> >         },
> >         {
> >                 /* Randomly picked colors. Full buffer within the clip area. */
> > @@ -96,6 +128,19 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
> >                                 0xA0, 0x6D, 0x0A, 0x00, 0x00,
> >                         },
> >                 },
> > +               .rgb565_result = {
> > +                       .dst_pitch = 10,
> > +                       .expected = {
> > +                               0x0A33, 0x1260, 0xA800, 0x0000, 0x0000,
> > +                               0x6B8E, 0x0A33, 0x1260, 0x0000, 0x0000,
> > +                               0xA800, 0x6B8E, 0x0A33, 0x0000, 0x0000,
> > +                       },
> > +                       .expected_swab = {
> > +                               0x330A, 0x6012, 0x00A8, 0x0000, 0x0000,
> > +                               0x8E6B, 0x330A, 0x6012, 0x0000, 0x0000,
> > +                               0x00A8, 0x8E6B, 0x330A, 0x0000, 0x0000,
> > +                       },
> > +               },
> >         },
> >  };
> >
> > @@ -120,7 +165,7 @@ static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
> >         if (!dst_pitch)
> >                 dst_pitch = drm_rect_width(clip) * dst_fi->cpp[0];
> >
> > -       return dst_pitch * drm_rect_height(clip);
> > +       return (dst_pitch * drm_rect_height(clip)) / (dst_fi->depth / 8);
> >  }
> >
> >  static u32 *le32buf_to_cpu(struct kunit *test, const u32 *buf, size_t buf_size)
> > @@ -175,8 +220,37 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)
> >         KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected, dst_size), 0);
> >  }
> >
> > +static void xrgb8888_to_rgb565_test(struct kunit *test)
> > +{
> > +       const struct convert_xrgb8888_case *params = test->param_value;
> > +       const struct convert_to_rgb565_result *result = &params->rgb565_result;
> > +       size_t dst_size;
> > +       __u16 *dst = NULL;
> > +
> > +       struct drm_framebuffer fb = {
> > +               .format = drm_format_info(DRM_FORMAT_XRGB8888),
> > +               .pitches = { params->pitch, 0, 0 },
> > +       };
> > +
> > +       dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
> > +                                      &params->clip);
> > +       KUNIT_ASSERT_GT(test, dst_size, 0);
> > +
> > +       dst = kunit_kzalloc(test, dst_size, GFP_KERNEL);
> > +       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dst);
> > +
> > +       drm_fb_xrgb8888_to_rgb565(dst, result->dst_pitch, params->xrgb8888, &fb,
> > +                                 &params->clip, false);
> > +       KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected, dst_size), 0);
> > +
> > +       drm_fb_xrgb8888_to_rgb565(dst, result->dst_pitch, params->xrgb8888, &fb,
> > +                                 &params->clip, true);
> > +       KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected_swab, dst_size), 0);
> > +}
> > +
> >  static struct kunit_case drm_format_helper_test_cases[] = {
> >         KUNIT_CASE_PARAM(xrgb8888_to_rgb332_test, convert_xrgb8888_gen_params),
> > +       KUNIT_CASE_PARAM(xrgb8888_to_rgb565_test, convert_xrgb8888_gen_params),
> >         {}
> >  };
> >
> > --
> > 2.25.1
> >
José Expósito July 17, 2022, 5 p.m. UTC | #3
José Expósito <jose.exposito89@gmail.com> wrote:
> I already fixed the warning and added the reviewed by tags, however, I
> noticed that rebasing the series on the latest drm-misc-next show this
> error:
> [...]

Sorry for the extra email. I forgot to mention that the error is only
present in UML. Running in other architectures works as expected.
Tested on x86_64 and PowerPC.

Jose
Daniel Vetter Aug. 10, 2022, 4:31 p.m. UTC | #4
On Sun, Jul 17, 2022 at 07:00:54PM +0200, José Expósito wrote:
> José Expósito <jose.exposito89@gmail.com> wrote:
> > I already fixed the warning and added the reviewed by tags, however, I
> > noticed that rebasing the series on the latest drm-misc-next show this
> > error:
> > [...]
> 
> Sorry for the extra email. I forgot to mention that the error is only
> present in UML. Running in other architectures works as expected.
> Tested on x86_64 and PowerPC.

Maybe a regression in the kunit infrastructure? Just guessing here ...
-Daniel
Daniel Latypov Aug. 10, 2022, 4:41 p.m. UTC | #5
On Sun, Jul 17, 2022 at 10:01 AM José Expósito
<jose.exposito89@gmail.com> wrote:
>
> José Expósito <jose.exposito89@gmail.com> wrote:
> > I already fixed the warning and added the reviewed by tags, however, I
> > noticed that rebasing the series on the latest drm-misc-next show this
> > error:
> > [...]
>
> Sorry for the extra email. I forgot to mention that the error is only
> present in UML. Running in other architectures works as expected.
> Tested on x86_64 and PowerPC.

Can you take a look at the raw output?

It would be .kunit/test.log (or replace .kunit with w/e --build_dir
you're using).
You could also run the test with --raw_output to have kunit.py print
that out instead.
We might want to compare the output on UML vs x86 and see what looks suspicious.

These errors
  [ERROR] Test: xrgb8888_to_rgb332_test: missing subtest result line!
means that kunit.py can't parse the KTAP output.

It could be that the output is mangled for some reason.
I recall running into a UML-specific issue with output mangling on an
old kernel fork. I doubt it's related to this one, but it shows that
it's possible there could be something going on.

-Daniel
Daniel Latypov Aug. 10, 2022, 4:45 p.m. UTC | #6
On Wed, Aug 10, 2022 at 9:31 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>
> On Sun, Jul 17, 2022 at 07:00:54PM +0200, José Expósito wrote:
> > José Expósito <jose.exposito89@gmail.com> wrote:
> > > I already fixed the warning and added the reviewed by tags, however, I
> > > noticed that rebasing the series on the latest drm-misc-next show this
> > > error:
> > > [...]
> >
> > Sorry for the extra email. I forgot to mention that the error is only
> > present in UML. Running in other architectures works as expected.
> > Tested on x86_64 and PowerPC.
>
> Maybe a regression in the kunit infrastructure? Just guessing here ...
> -Daniel

As noted elsewhere on the thread, these errors means that kunit.py
can't parse the KTAP output coming from the kernel.
There shouldn't be any recent changes in either the python-side parser
or the kernel-side output logic.

So I can't think of a kunit-specific change that would trigger this.
There could be some other issue causing output mangling.

We'd want to look at what output the UML kernel produces (stored in
.kunit/test.log, or visible via kunit.py run --raw_output).

-A different Daniel
José Expósito Aug. 13, 2022, 10:36 a.m. UTC | #7
On Wed, Aug 10, 2022 at 09:41:18AM -0700, Daniel Latypov wrote:
> On Sun, Jul 17, 2022 at 10:01 AM José Expósito
> <jose.exposito89@gmail.com> wrote:
> >
> > José Expósito <jose.exposito89@gmail.com> wrote:
> > > I already fixed the warning and added the reviewed by tags, however, I
> > > noticed that rebasing the series on the latest drm-misc-next show this
> > > error:
> > > [...]
> >
> > Sorry for the extra email. I forgot to mention that the error is only
> > present in UML. Running in other architectures works as expected.
> > Tested on x86_64 and PowerPC.
> 
> Can you take a look at the raw output?
> 
> It would be .kunit/test.log (or replace .kunit with w/e --build_dir
> you're using).
> You could also run the test with --raw_output to have kunit.py print
> that out instead.
> We might want to compare the output on UML vs x86 and see what looks suspicious.
> 
> These errors
>   [ERROR] Test: xrgb8888_to_rgb332_test: missing subtest result line!
> means that kunit.py can't parse the KTAP output.
> 
> It could be that the output is mangled for some reason.
> I recall running into a UML-specific issue with output mangling on an
> old kernel fork. I doubt it's related to this one, but it shows that
> it's possible there could be something going on.
> 
> -Daniel

Hi!

Sorry for not clarifying the error in this thread.
I fixed it in v3 (already merged).

The issue was in my implementation. I was overwriting a few bytes of
memory due to an out of bounds bug. Thanks to the crash I mentioned,
I detected it before the code got merged.

Thanks a lot for the pointers Daniel, the next time I'll check
.kunit/test.log for usefull information.

Jose
diff mbox series

Patch

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 0a490ad4fd32..c0592c1235cf 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -21,12 +21,19 @@  struct convert_to_rgb332_result {
 	const u8 expected[TEST_BUF_SIZE];
 };
 
+struct convert_to_rgb565_result {
+	unsigned int dst_pitch;
+	const u16 expected[TEST_BUF_SIZE];
+	const u16 expected_swab[TEST_BUF_SIZE];
+};
+
 struct convert_xrgb8888_case {
 	const char *name;
 	unsigned int pitch;
 	struct drm_rect clip;
 	const u32 xrgb8888[TEST_BUF_SIZE];
 	struct convert_to_rgb332_result rgb332_result;
+	struct convert_to_rgb565_result rgb565_result;
 };
 
 static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
@@ -39,6 +46,11 @@  static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
 			.dst_pitch = 0,
 			.expected = { 0xE0 },
 		},
+		.rgb565_result = {
+			.dst_pitch = 0,
+			.expected = { 0xF800 },
+			.expected_swab = { 0x00F8 },
+		},
 	},
 	{
 		.name = "single_pixel_clip_rectangle",
@@ -52,6 +64,11 @@  static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
 			.dst_pitch = 0,
 			.expected = { 0xE0 },
 		},
+		.rgb565_result = {
+			.dst_pitch = 0,
+			.expected = { 0xF800 },
+			.expected_swab = { 0x00F8 },
+		},
 	},
 	{
 		/* Well known colors: White, black, red, green, blue, magenta,
@@ -77,6 +94,21 @@  static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
 				0xFC, 0x1F,
 			},
 		},
+		.rgb565_result = {
+			.dst_pitch = 0,
+			.expected = {
+				0xFFFF, 0x0000,
+				0xF800, 0x07E0,
+				0x001F, 0xF81F,
+				0xFFE0, 0x07FF,
+			},
+			.expected_swab = {
+				0xFFFF, 0x0000,
+				0x00F8, 0xE007,
+				0x1F00, 0x1FF8,
+				0xE0FF, 0xFF07,
+			},
+		},
 	},
 	{
 		/* Randomly picked colors. Full buffer within the clip area. */
@@ -96,6 +128,19 @@  static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
 				0xA0, 0x6D, 0x0A, 0x00, 0x00,
 			},
 		},
+		.rgb565_result = {
+			.dst_pitch = 10,
+			.expected = {
+				0x0A33, 0x1260, 0xA800, 0x0000, 0x0000,
+				0x6B8E, 0x0A33, 0x1260, 0x0000, 0x0000,
+				0xA800, 0x6B8E, 0x0A33, 0x0000, 0x0000,
+			},
+			.expected_swab = {
+				0x330A, 0x6012, 0x00A8, 0x0000, 0x0000,
+				0x8E6B, 0x330A, 0x6012, 0x0000, 0x0000,
+				0x00A8, 0x8E6B, 0x330A, 0x0000, 0x0000,
+			},
+		},
 	},
 };
 
@@ -120,7 +165,7 @@  static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
 	if (!dst_pitch)
 		dst_pitch = drm_rect_width(clip) * dst_fi->cpp[0];
 
-	return dst_pitch * drm_rect_height(clip);
+	return (dst_pitch * drm_rect_height(clip)) / (dst_fi->depth / 8);
 }
 
 static u32 *le32buf_to_cpu(struct kunit *test, const u32 *buf, size_t buf_size)
@@ -175,8 +220,37 @@  static void xrgb8888_to_rgb332_test(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected, dst_size), 0);
 }
 
+static void xrgb8888_to_rgb565_test(struct kunit *test)
+{
+	const struct convert_xrgb8888_case *params = test->param_value;
+	const struct convert_to_rgb565_result *result = &params->rgb565_result;
+	size_t dst_size;
+	__u16 *dst = NULL;
+
+	struct drm_framebuffer fb = {
+		.format = drm_format_info(DRM_FORMAT_XRGB8888),
+		.pitches = { params->pitch, 0, 0 },
+	};
+
+	dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
+				       &params->clip);
+	KUNIT_ASSERT_GT(test, dst_size, 0);
+
+	dst = kunit_kzalloc(test, dst_size, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dst);
+
+	drm_fb_xrgb8888_to_rgb565(dst, result->dst_pitch, params->xrgb8888, &fb,
+				  &params->clip, false);
+	KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected, dst_size), 0);
+
+	drm_fb_xrgb8888_to_rgb565(dst, result->dst_pitch, params->xrgb8888, &fb,
+				  &params->clip, true);
+	KUNIT_EXPECT_EQ(test, memcmp(dst, result->expected_swab, dst_size), 0);
+}
+
 static struct kunit_case drm_format_helper_test_cases[] = {
 	KUNIT_CASE_PARAM(xrgb8888_to_rgb332_test, convert_xrgb8888_gen_params),
+	KUNIT_CASE_PARAM(xrgb8888_to_rgb565_test, convert_xrgb8888_gen_params),
 	{}
 };