drm/format-helper: Add KUnit tests for drm_fb_xrgb8888_to_rgb332()

Test the conversion from XRGB8888 to RGB332.

What is tested?

 - Different values for the X in XRGB8888 to make sure it is ignored
 - Different clip values: Single pixel and full and partial buffer
 - Well known colors: White, black, red, green, blue, magenta, yellow
   and cyan
 - Other colors: Randomly picked
 - Destination pitch

How to run the tests?

 $ ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/tests \
         --kconfig_add CONFIG_VIRTIO_UML=y \
         --kconfig_add CONFIG_UML_PCI_OVER_VIRTIO=y

Suggested-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: David Gow <davidgow@google.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220620160640.3790-3-jose.exposito89@gmail.com
This commit is contained in:
José Expósito 2022-06-20 18:06:39 +02:00
parent 84509eede6
commit 8f45610491
5 changed files with 184 additions and 0 deletions

View File

@ -70,6 +70,22 @@ config DRM_DEBUG_SELFTEST
If in doubt, say "N".
config DRM_KUNIT_TEST
tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
depends on DRM && KUNIT=y
select DRM_KMS_HELPER
default KUNIT_ALL_TESTS
help
This builds unit tests for DRM. This option is not useful for
distributions or general kernels, but only for kernel
developers working on DRM and associated drivers.
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".
config DRM_KMS_HELPER
tristate
depends on DRM

View File

@ -76,6 +76,7 @@ obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
#
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
obj-$(CONFIG_DRM_KUNIT_TEST) += tests/
obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o
obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o

View File

@ -0,0 +1,3 @@
CONFIG_KUNIT=y
CONFIG_DRM=y
CONFIG_DRM_KUNIT_TEST=y

View File

@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_DRM_KUNIT_TEST) += drm_format_helper_test.o

View File

@ -0,0 +1,161 @@
// SPDX-License-Identifier: GPL-2.0+
#include <kunit/test.h>
#include <drm/drm_device.h>
#include <drm/drm_file.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_mode.h>
#include <drm/drm_print.h>
#include <drm/drm_rect.h>
#include "../drm_crtc_internal.h"
#define TEST_BUF_SIZE 50
struct xrgb8888_to_rgb332_case {
const char *name;
unsigned int pitch;
unsigned int dst_pitch;
struct drm_rect clip;
const u32 xrgb8888[TEST_BUF_SIZE];
const u8 expected[4 * TEST_BUF_SIZE];
};
static struct xrgb8888_to_rgb332_case xrgb8888_to_rgb332_cases[] = {
{
.name = "single_pixel_source_buffer",
.pitch = 1 * 4,
.dst_pitch = 0,
.clip = DRM_RECT_INIT(0, 0, 1, 1),
.xrgb8888 = { 0x01FF0000 },
.expected = { 0xE0 },
},
{
.name = "single_pixel_clip_rectangle",
.pitch = 2 * 4,
.dst_pitch = 0,
.clip = DRM_RECT_INIT(1, 1, 1, 1),
.xrgb8888 = {
0x00000000, 0x00000000,
0x00000000, 0x10FF0000,
},
.expected = { 0xE0 },
},
{
/* Well known colors: White, black, red, green, blue, magenta,
* yellow and cyan. Different values for the X in XRGB8888 to
* make sure it is ignored. Partial clip area.
*/
.name = "well_known_colors",
.pitch = 4 * 4,
.dst_pitch = 0,
.clip = DRM_RECT_INIT(1, 1, 2, 4),
.xrgb8888 = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
},
.expected = {
0xFF, 0x00,
0xE0, 0x1C,
0x03, 0xE3,
0xFC, 0x1F,
},
},
{
/* Randomly picked colors. Full buffer within the clip area. */
.name = "destination_pitch",
.pitch = 3 * 4,
.dst_pitch = 5,
.clip = DRM_RECT_INIT(0, 0, 3, 3),
.xrgb8888 = {
0xA10E449C, 0xB1114D05, 0xC1A80303,
0xD16C7073, 0xA20E449C, 0xB2114D05,
0xC2A80303, 0xD26C7073, 0xA30E449C,
},
.expected = {
0x0A, 0x08, 0xA0, 0x00, 0x00,
0x6D, 0x0A, 0x08, 0x00, 0x00,
0xA0, 0x6D, 0x0A, 0x00, 0x00,
},
},
};
/*
* conversion_buf_size - Return the destination buffer size required to convert
* between formats.
* @dst_format: destination buffer pixel format (DRM_FORMAT_*)
* @dst_pitch: Number of bytes between two consecutive scanlines within dst
* @clip: Clip rectangle area to convert
*
* Returns:
* The size of the destination buffer or negative value on error.
*/
static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
const struct drm_rect *clip)
{
const struct drm_format_info *dst_fi = drm_format_info(dst_format);
if (!dst_fi)
return -EINVAL;
if (!dst_pitch)
dst_pitch = drm_rect_width(clip) * dst_fi->cpp[0];
return dst_pitch * drm_rect_height(clip);
}
static void xrgb8888_to_rgb332_case_desc(struct xrgb8888_to_rgb332_case *t,
char *desc)
{
strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
}
KUNIT_ARRAY_PARAM(xrgb8888_to_rgb332, xrgb8888_to_rgb332_cases,
xrgb8888_to_rgb332_case_desc);
static void xrgb8888_to_rgb332_test(struct kunit *test)
{
const struct xrgb8888_to_rgb332_case *params = test->param_value;
size_t dst_size;
__u8 *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_RGB332, params->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_rgb332(dst, params->dst_pitch, params->xrgb8888,
&fb, &params->clip);
KUNIT_EXPECT_EQ(test, memcmp(dst, params->expected, dst_size), 0);
}
static struct kunit_case drm_format_helper_test_cases[] = {
KUNIT_CASE_PARAM(xrgb8888_to_rgb332_test,
xrgb8888_to_rgb332_gen_params),
{}
};
static struct kunit_suite drm_format_helper_test_suite = {
.name = "drm_format_helper_test",
.test_cases = drm_format_helper_test_cases,
};
kunit_test_suite(drm_format_helper_test_suite);
MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");