Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/tests/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 48 kB image not shown  

Quelle  drm_format_helper_test.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0+

#include <kunit/test.h>

#include <drm/drm_device.h>
#include <drm/drm_drv.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_kunit_helpers.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

#define TEST_USE_DEFAULT_PITCH 0

static unsigned char fmtcnv_state_mem[PAGE_SIZE];
static struct drm_format_conv_state fmtcnv_state =
 DRM_FORMAT_CONV_STATE_INIT_PREALLOCATED(fmtcnv_state_mem, sizeof(fmtcnv_state_mem));

struct convert_to_gray8_result {
 unsigned int dst_pitch;
 const u8 expected[TEST_BUF_SIZE];
};

struct convert_to_rgb332_result {
 unsigned int dst_pitch;
 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_to_xrgb1555_result {
 unsigned int dst_pitch;
 const u16 expected[TEST_BUF_SIZE];
};

struct convert_to_argb1555_result {
 unsigned int dst_pitch;
 const u16 expected[TEST_BUF_SIZE];
};

struct convert_to_rgba5551_result {
 unsigned int dst_pitch;
 const u16 expected[TEST_BUF_SIZE];
};

struct convert_to_rgb888_result {
 unsigned int dst_pitch;
 const u8 expected[TEST_BUF_SIZE];
};

struct convert_to_bgr888_result {
 unsigned int dst_pitch;
 const u8 expected[TEST_BUF_SIZE];
};

struct convert_to_argb8888_result {
 unsigned int dst_pitch;
 const u32 expected[TEST_BUF_SIZE];
};

struct convert_to_xrgb2101010_result {
 unsigned int dst_pitch;
 const u32 expected[TEST_BUF_SIZE];
};

struct convert_to_argb2101010_result {
 unsigned int dst_pitch;
 const u32 expected[TEST_BUF_SIZE];
};

struct convert_to_mono_result {
 unsigned int dst_pitch;
 const u8 expected[TEST_BUF_SIZE];
};

struct fb_swab_result {
 unsigned int dst_pitch;
 const u32 expected[TEST_BUF_SIZE];
};

struct convert_to_xbgr8888_result {
 unsigned int dst_pitch;
 const u32 expected[TEST_BUF_SIZE];
};

struct convert_to_abgr8888_result {
 unsigned int dst_pitch;
 const u32 expected[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_gray8_result gray8_result;
 struct convert_to_rgb332_result rgb332_result;
 struct convert_to_rgb565_result rgb565_result;
 struct convert_to_xrgb1555_result xrgb1555_result;
 struct convert_to_argb1555_result argb1555_result;
 struct convert_to_rgba5551_result rgba5551_result;
 struct convert_to_rgb888_result rgb888_result;
 struct convert_to_bgr888_result bgr888_result;
 struct convert_to_argb8888_result argb8888_result;
 struct convert_to_xrgb2101010_result xrgb2101010_result;
 struct convert_to_argb2101010_result argb2101010_result;
 struct convert_to_mono_result mono_result;
 struct fb_swab_result swab_result;
 struct convert_to_xbgr8888_result xbgr8888_result;
 struct convert_to_abgr8888_result abgr8888_result;
};

static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
 {
  .name = "single_pixel_source_buffer",
  .pitch = 1 * 4,
  .clip = DRM_RECT_INIT(0, 0, 1, 1),
  .xrgb8888 = { 0x01FF0000 },
  .gray8_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0x4C },
  },
  .rgb332_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xE0 },
  },
  .rgb565_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xF800 },
   .expected_swab = { 0x00F8 },
  },
  .xrgb1555_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0x7C00 },
  },
  .argb1555_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFC00 },
  },
  .rgba5551_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xF801 },
  },
  .rgb888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0x00, 0x00, 0xFF },
  },
  .bgr888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFF, 0x00, 0x00 },
  },
  .argb8888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFFFF0000 },
  },
  .xrgb2101010_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0x3FF00000 },
  },
  .argb2101010_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFFF00000 },
  },
  .mono_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = { 0b0 },
  },
  .swab_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = { 0x0000FF01 },
  },
  .xbgr8888_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = { 0x010000FF },
  },
  .abgr8888_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFF0000FF },
  },
 },
 {
  .name = "single_pixel_clip_rectangle",
  .pitch = 2 * 4,
  .clip = DRM_RECT_INIT(1, 1, 1, 1),
  .xrgb8888 = {
   0x00000000, 0x00000000,
   0x00000000, 0x10FF0000,
  },
  .gray8_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0x4C },
  },
  .rgb332_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xE0 },
  },
  .rgb565_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xF800 },
   .expected_swab = { 0x00F8 },
  },
  .xrgb1555_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0x7C00 },
  },
  .argb1555_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFC00 },
  },
  .rgba5551_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xF801 },
  },
  .rgb888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0x00, 0x00, 0xFF },
  },
  .bgr888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFF, 0x00, 0x00 },
  },
  .argb8888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFFFF0000 },
  },
  .xrgb2101010_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0x3FF00000 },
  },
  .argb2101010_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFFF00000 },
  },
  .mono_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = { 0b0 },
  },
  .swab_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = { 0x0000FF10 },
  },
  .xbgr8888_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = { 0x100000FF },
  },
  .abgr8888_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = { 0xFF0000FF },
  },
 },
 {
  /* 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,
  .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,
  },
  .gray8_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFF, 0x00,
    0x4C, 0x95,
    0x1C, 0x69,
    0xE2, 0xB2,
   },
  },
  .rgb332_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFF, 0x00,
    0xE0, 0x1C,
    0x03, 0xE3,
    0xFC, 0x1F,
   },
  },
  .rgb565_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFFFF, 0x0000,
    0xF800, 0x07E0,
    0x001F, 0xF81F,
    0xFFE0, 0x07FF,
   },
   .expected_swab = {
    0xFFFF, 0x0000,
    0x00F8, 0xE007,
    0x1F00, 0x1FF8,
    0xE0FF, 0xFF07,
   },
  },
  .xrgb1555_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0x7FFF, 0x0000,
    0x7C00, 0x03E0,
    0x001F, 0x7C1F,
    0x7FE0, 0x03FF,
   },
  },
  .argb1555_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFFFF, 0x8000,
    0xFC00, 0x83E0,
    0x801F, 0xFC1F,
    0xFFE0, 0x83FF,
   },
  },
  .rgba5551_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFFFF, 0x0001,
    0xF801, 0x07C1,
    0x003F, 0xF83F,
    0xFFC1, 0x07FF,
   },
  },
  .rgb888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00,
    0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF,
    0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
   },
  },
  .bgr888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
    0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00,
    0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
    0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
   },
  },
  .argb8888_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFFFFFFFF, 0xFF000000,
    0xFFFF0000, 0xFF00FF00,
    0xFF0000FF, 0xFFFF00FF,
    0xFFFFFF00, 0xFF00FFFF,
   },
  },
  .xrgb2101010_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0x3FFFFFFF, 0x00000000,
    0x3FF00000, 0x000FFC00,
    0x000003FF, 0x3FF003FF,
    0x3FFFFC00, 0x000FFFFF,
   },
  },
  .argb2101010_result = {
   .dst_pitch = TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFFFFFFFF, 0xC0000000,
    0xFFF00000, 0xC00FFC00,
    0xC00003FF, 0xFFF003FF,
    0xFFFFFC00, 0xC00FFFFF,
   },
  },
  .mono_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = {
    0b01,
    0b10,
    0b00,
    0b11,
   },
  },
  .swab_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFFFFFF11, 0x00000022,
    0x0000FF33, 0x00FF0044,
    0xFF000055, 0xFF00FF66,
    0x00FFFF77, 0xFFFF0088,
   },
  },
  .xbgr8888_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = {
    0x11FFFFFF, 0x22000000,
    0x330000FF, 0x4400FF00,
    0x55FF0000, 0x66FF00FF,
    0x7700FFFF, 0x88FFFF00,
   },
  },
  .abgr8888_result = {
   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
   .expected = {
    0xFFFFFFFF, 0xFF000000,
    0xFF0000FF, 0xFF00FF00,
    0xFFFF0000, 0xFFFF00FF,
    0xFF00FFFF, 0xFFFFFF00,
   },
  },
 },
 {
  /* Randomly picked colors. Full buffer within the clip area. */
  .name = "destination_pitch",
  .pitch = 3 * 4,
  .clip = DRM_RECT_INIT(0, 0, 3, 3),
  .xrgb8888 = {
   0xA10E449C, 0xB1114D05, 0xC1A8F303,
   0xD16CF073, 0xA20E449C, 0xB2114D05,
   0xC2A80303, 0xD26CF073, 0xA30E449C,
  },
  .gray8_result = {
   .dst_pitch = 5,
   .expected = {
    0x3D, 0x32, 0xC1, 0x00, 0x00,
    0xBA, 0x3D, 0x32, 0x00, 0x00,
    0x34, 0xBA, 0x3D, 0x00, 0x00,
   },
  },
  .rgb332_result = {
   .dst_pitch = 5,
   .expected = {
    0x0A, 0x08, 0xBC, 0x00, 0x00,
    0x7D, 0x0A, 0x08, 0x00, 0x00,
    0xA0, 0x7D, 0x0A, 0x00, 0x00,
   },
  },
  .rgb565_result = {
   .dst_pitch = 10,
   .expected = {
    0x0A33, 0x1260, 0xAF80, 0x0000, 0x0000,
    0x6F8E, 0x0A33, 0x1260, 0x0000, 0x0000,
    0xA800, 0x6F8E, 0x0A33, 0x0000, 0x0000,
   },
   .expected_swab = {
    0x330A, 0x6012, 0x80AF, 0x0000, 0x0000,
    0x8E6F, 0x330A, 0x6012, 0x0000, 0x0000,
    0x00A8, 0x8E6F, 0x330A, 0x0000, 0x0000,
   },
  },
  .xrgb1555_result = {
   .dst_pitch = 10,
   .expected = {
    0x0513, 0x0920, 0x57C0, 0x0000, 0x0000,
    0x37CE, 0x0513, 0x0920, 0x0000, 0x0000,
    0x5400, 0x37CE, 0x0513, 0x0000, 0x0000,
   },
  },
  .argb1555_result = {
   .dst_pitch = 10,
   .expected = {
    0x8513, 0x8920, 0xD7C0, 0x0000, 0x0000,
    0xB7CE, 0x8513, 0x8920, 0x0000, 0x0000,
    0xD400, 0xB7CE, 0x8513, 0x0000, 0x0000,
   },
  },
  .rgba5551_result = {
   .dst_pitch = 10,
   .expected = {
    0x0A27, 0x1241, 0xAF81, 0x0000, 0x0000,
    0x6F9D, 0x0A27, 0x1241, 0x0000, 0x0000,
    0xA801, 0x6F9D, 0x0A27, 0x0000, 0x0000,
   },
  },
  .rgb888_result = {
   .dst_pitch = 15,
   .expected = {
    0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 0x03, 0xF3, 0xA8,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x03, 0x03, 0xA8, 0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   },
  },
  .bgr888_result = {
   .dst_pitch = 15,
   .expected = {
    0x0E, 0x44, 0x9C, 0x11, 0x4D, 0x05, 0xA8, 0xF3, 0x03,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x6C, 0xF0, 0x73, 0x0E, 0x44, 0x9C, 0x11, 0x4D, 0x05,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xA8, 0x03, 0x03, 0x6C, 0xF0, 0x73, 0x0E, 0x44, 0x9C,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   },
  },
  .argb8888_result = {
   .dst_pitch = 20,
   .expected = {
    0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
    0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
    0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
   },
  },
  .xrgb2101010_result = {
   .dst_pitch = 20,
   .expected = {
    0x03844672, 0x0444D414, 0x2A2F3C0C, 0x00000000, 0x00000000,
    0x1B1F0DCD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000,
    0x2A20300C, 0x1B1F0DCD, 0x03844672, 0x00000000, 0x00000000,
   },
  },
  .argb2101010_result = {
   .dst_pitch = 20,
   .expected = {
    0xC3844672, 0xC444D414, 0xEA2F3C0C, 0x00000000, 0x00000000,
    0xDB1F0DCD, 0xC3844672, 0xC444D414, 0x00000000, 0x00000000,
    0xEA20300C, 0xDB1F0DCD, 0xC3844672, 0x00000000, 0x00000000,
   },
  },
  .mono_result = {
   .dst_pitch = 2,
   .expected = {
    0b100, 0b000,
    0b001, 0b000,
    0b010, 0b000,
   },
  },
  .swab_result = {
   .dst_pitch =  20,
   .expected = {
    0x9C440EA1, 0x054D11B1, 0x03F3A8C1, 0x00000000, 0x00000000,
    0x73F06CD1, 0x9C440EA2, 0x054D11B2, 0x00000000, 0x00000000,
    0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x00000000, 0x00000000,
   },
  },
  .xbgr8888_result = {
   .dst_pitch =  20,
   .expected = {
    0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x00000000, 0x00000000,
    0xD173F06C, 0xA29C440E, 0xB2054D11, 0x00000000, 0x00000000,
    0xC20303A8, 0xD273F06C, 0xA39C440E, 0x00000000, 0x00000000,
   },
  },
  .abgr8888_result = {
   .dst_pitch =  20,
   .expected = {
    0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x00000000, 0x00000000,
    0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x00000000, 0x00000000,
    0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x00000000, 0x00000000,
   },
  },
 },
};

/*
 * 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, int plane)
{
 const struct drm_format_info *dst_fi = drm_format_info(dst_format);

 if (!dst_fi)
  return -EINVAL;

 if (!dst_pitch)
  dst_pitch = drm_format_info_min_pitch(dst_fi, plane, drm_rect_width(clip));

 return dst_pitch * drm_rect_height(clip);
}

static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size)
{
 u16 *dst = NULL;
 int n;

 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
 if (!dst)
  return NULL;

 for (n = 0; n < buf_size; n++)
  dst[n] = le16_to_cpu(buf[n]);

 return dst;
}

static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size)
{
 u32 *dst = NULL;
 int n;

 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
 if (!dst)
  return NULL;

 for (n = 0; n < buf_size; n++)
  dst[n] = le32_to_cpu((__force __le32)buf[n]);

 return dst;
}

static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size)
{
 __le32 *dst = NULL;
 int n;

 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
 if (!dst)
  return NULL;

 for (n = 0; n < buf_size; n++)
  dst[n] = cpu_to_le32(buf[n]);

 return dst;
}

static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
           char *desc)
{
 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
}

KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
    convert_xrgb8888_case_desc);

static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_gray8_result *result = ¶ms->gray8_result;
 size_t dst_size;
 u8 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
           ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_gray8(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_rgb332_result *result = ¶ms->rgb332_result;
 size_t dst_size;
 u8 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
           ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_rgb332(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_rgb565_result *result = ¶ms->rgb565_result;
 size_t dst_size;
 u16 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 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,
           ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, ¶ms->clip,
      &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 drm_fb_xrgb8888_to_rgb565be(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip,
        &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);

 buf = dst.vaddr;
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, ¶ms->clip,
      &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_xrgb1555_result *result = ¶ms->xrgb1555_result;
 size_t dst_size;
 u16 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
           ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_argb1555_result *result = ¶ms->argb1555_result;
 size_t dst_size;
 u16 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
           ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_rgba5551_result *result = ¶ms->rgba5551_result;
 size_t dst_size;
 u16 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
           ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_rgb888_result *result = ¶ms->rgb888_result;
 size_t dst_size;
 u8 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
           ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 /*
 * RGB888 expected results are already in little-endian
 * order, so there's no need to convert the test output.
 */

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_bgr888(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_bgr888_result *result = ¶ms->bgr888_result;
 size_t dst_size;
 u8 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_BGR888, result->dst_pitch,
           ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 /*
 * BGR888 expected results are already in little-endian
 * order, so there's no need to convert the test output.
 */

 drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip,
      &fmtcnv_state);
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip,
      &fmtcnv_state);
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_argb8888_result *result = ¶ms->argb8888_result;
 size_t dst_size;
 u32 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
           result->dst_pitch, ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_xrgb2101010_result *result = ¶ms->xrgb2101010_result;
 size_t dst_size;
 u32 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
           result->dst_pitch, ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_argb2101010_result *result = ¶ms->argb2101010_result;
 size_t dst_size;
 u32 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
           result->dst_pitch, ¶ms->clip, 0);
 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_mono_result *result = ¶ms->mono_result;
 size_t dst_size;
 u8 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, ¶ms->clip, 0);

 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_mono(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_swab(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct fb_swab_result *result = ¶ms->swab_result;
 size_t dst_size;
 u32 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_XRGB8888, result->dst_pitch, ¶ms->clip, 0);

 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_swab(&dst, dst_pitch, &src, &fb, ¶ms->clip, false, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr; /* restore original value of buf */
 memset(buf, 0, dst_size);

 drm_fb_swab(&dst, dst_pitch, &src, &fb, ¶ms->clip, false, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr;
 memset(buf, 0, dst_size);

 drm_fb_xrgb8888_to_bgrx8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);

 buf = dst.vaddr;
 memset(buf, 0, dst_size);

 struct drm_format_info mock_format = *fb.format;

 mock_format.format |= DRM_FORMAT_BIG_ENDIAN;
 fb.format = &mock_format;

 drm_fb_swab(&dst, dst_pitch, &src, &fb, ¶ms->clip, false, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_abgr8888_result *result = ¶ms->abgr8888_result;
 size_t dst_size;
 u32 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, ¶ms->clip, 0);

 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_abgr8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)
{
 const struct convert_xrgb8888_case *params = test->param_value;
 const struct convert_to_xbgr8888_result *result = ¶ms->xbgr8888_result;
 size_t dst_size;
 u32 *buf = NULL;
 __le32 *xrgb8888 = NULL;
 struct iosys_map dst, src;

 struct drm_framebuffer fb = {
  .format = drm_format_info(DRM_FORMAT_XRGB8888),
  .pitches = { params->pitch, 0, 0 },
 };

 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, ¶ms->clip, 0);

 KUNIT_ASSERT_GT(test, dst_size, 0);

 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 iosys_map_set_vaddr(&dst, buf);

 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
 iosys_map_set_vaddr(&src, xrgb8888);

 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
  NULL : &result->dst_pitch;

 drm_fb_xrgb8888_to_xbgr8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
}

struct clip_offset_case {
 const char *name;
 unsigned int pitch;
 u32 format;
 struct drm_rect clip;
 unsigned int expected_offset;
};

static struct clip_offset_case clip_offset_cases[] = {
 {
  .name = "pass through",
  .pitch = TEST_USE_DEFAULT_PITCH,
  .format = DRM_FORMAT_XRGB8888,
  .clip = DRM_RECT_INIT(0, 0, 3, 3),
  .expected_offset = 0
 },
 {
  .name = "horizontal offset",
  .pitch = TEST_USE_DEFAULT_PITCH,
  .format = DRM_FORMAT_XRGB8888,
  .clip = DRM_RECT_INIT(1, 0, 3, 3),
  .expected_offset = 4,
 },
 {
  .name = "vertical offset",
  .pitch = TEST_USE_DEFAULT_PITCH,
  .format = DRM_FORMAT_XRGB8888,
  .clip = DRM_RECT_INIT(0, 1, 3, 3),
  .expected_offset = 12,
 },
 {
  .name = "horizontal and vertical offset",
  .pitch = TEST_USE_DEFAULT_PITCH,
  .format = DRM_FORMAT_XRGB8888,
  .clip = DRM_RECT_INIT(1, 1, 3, 3),
  .expected_offset = 16,
 },
 {
  .name = "horizontal offset (custom pitch)",
  .pitch = 20,
  .format = DRM_FORMAT_XRGB8888,
  .clip = DRM_RECT_INIT(1, 0, 3, 3),
  .expected_offset = 4,
 },
 {
  .name = "vertical offset (custom pitch)",
  .pitch = 20,
  .format = DRM_FORMAT_XRGB8888,
  .clip = DRM_RECT_INIT(0, 1, 3, 3),
  .expected_offset = 20,
 },
 {
  .name = "horizontal and vertical offset (custom pitch)",
  .pitch = 20,
  .format = DRM_FORMAT_XRGB8888,
  .clip = DRM_RECT_INIT(1, 1, 3, 3),
  .expected_offset = 24,
 },
};

static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
{
 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
}

KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);

static void drm_test_fb_clip_offset(struct kunit *test)
{
 const struct clip_offset_case *params = test->param_value;
 const struct drm_format_info *format_info = drm_format_info(params->format);

 unsigned int offset;
 unsigned int pitch = params->pitch;

 if (pitch == TEST_USE_DEFAULT_PITCH)
  pitch = drm_format_info_min_pitch(format_info, 0,
        drm_rect_width(¶ms->clip));

 /*
 * Assure that the pitch is not zero, because this will inevitable cause the
 * wrong expected result
 */

 KUNIT_ASSERT_NE(test, pitch, 0);

 offset = drm_fb_clip_offset(pitch, format_info, ¶ms->clip);

 KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
}

struct fb_memcpy_case {
 const char *name;
 u32 format;
 struct drm_rect clip;
 unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
 const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
 unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
 const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
};

/* The `src` and `expected` buffers are u32 arrays. To deal with planes that
 * have a cpp != 4 the values are stored together on the same u32 number in a
 * way so the order in memory is correct in a little-endian machine.
 *
 * Because of that, on some occasions, parts of a u32 will not be part of the
 * test, to make this explicit the 0xFF byte is used on those parts.
 */


static struct fb_memcpy_case fb_memcpy_cases[] = {
 {
  .name = "single_pixel_source_buffer",
  .format = DRM_FORMAT_XRGB8888,
  .clip = DRM_RECT_INIT(0, 0, 1, 1),
  .src_pitches = { 1 * 4 },
  .src = {{ 0x01020304 }},
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {{ 0x01020304 }},
 },
 {
  .name = "single_pixel_source_buffer",
  .format = DRM_FORMAT_XRGB8888_A8,
  .clip = DRM_RECT_INIT(0, 0, 1, 1),
  .src_pitches = { 1 * 4, 1 },
  .src = {
   { 0x01020304 },
   { 0xFFFFFF01 },
  },
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {
   { 0x01020304 },
   { 0x00000001 },
  },
 },
 {
  .name = "single_pixel_source_buffer",
  .format = DRM_FORMAT_YUV444,
  .clip = DRM_RECT_INIT(0, 0, 1, 1),
  .src_pitches = { 1, 1, 1 },
  .src = {
   { 0xFFFFFF01 },
   { 0xFFFFFF01 },
   { 0xFFFFFF01 },
  },
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {
   { 0x00000001 },
   { 0x00000001 },
   { 0x00000001 },
  },
 },
 {
  .name = "single_pixel_clip_rectangle",
  .format = DRM_FORMAT_XBGR8888,
  .clip = DRM_RECT_INIT(1, 1, 1, 1),
  .src_pitches = { 2 * 4 },
  .src = {
   {
    0x00000000, 0x00000000,
    0x00000000, 0x01020304,
   },
  },
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {
   { 0x01020304 },
  },
 },
 {
  .name = "single_pixel_clip_rectangle",
  .format = DRM_FORMAT_XRGB8888_A8,
  .clip = DRM_RECT_INIT(1, 1, 1, 1),
  .src_pitches = { 2 * 4, 2 * 1 },
  .src = {
   {
    0x00000000, 0x00000000,
    0x00000000, 0x01020304,
   },
   { 0x01000000 },
  },
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {
   { 0x01020304 },
   { 0x00000001 },
  },
 },
 {
  .name = "single_pixel_clip_rectangle",
  .format = DRM_FORMAT_YUV444,
  .clip = DRM_RECT_INIT(1, 1, 1, 1),
  .src_pitches = { 2 * 1, 2 * 1, 2 * 1 },
  .src = {
   { 0x01000000 },
   { 0x01000000 },
   { 0x01000000 },
  },
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {
   { 0x00000001 },
   { 0x00000001 },
   { 0x00000001 },
  },
 },
 {
  .name = "well_known_colors",
  .format = DRM_FORMAT_XBGR8888,
  .clip = DRM_RECT_INIT(1, 1, 2, 4),
  .src_pitches = { 4 * 4 },
  .src = {
   {
    0x00000000, 0x00000000, 0x00000000, 0x00000000,
    0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
    0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
    0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
    0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
   },
  },
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {
   {
    0x11FFFFFF, 0x22000000,
    0x33FF0000, 0x4400FF00,
    0x550000FF, 0x66FF00FF,
    0x77FFFF00, 0x8800FFFF,
   },
  },
 },
 {
  .name = "well_known_colors",
  .format = DRM_FORMAT_XRGB8888_A8,
  .clip = DRM_RECT_INIT(1, 1, 2, 4),
  .src_pitches = { 4 * 4, 4 * 1 },
  .src = {
   {
    0x00000000, 0x00000000, 0x00000000, 0x00000000,
    0x00000000, 0xFFFFFFFF, 0xFF000000, 0x00000000,
    0x00000000, 0xFFFF0000, 0xFF00FF00, 0x00000000,
    0x00000000, 0xFF0000FF, 0xFFFF00FF, 0x00000000,
    0x00000000, 0xFFFFFF00, 0xFF00FFFF, 0x00000000,
   },
   {
    0x00000000,
    0x00221100,
    0x00443300,
    0x00665500,
    0x00887700,
   },
  },
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {
   {
    0xFFFFFFFF, 0xFF000000,
    0xFFFF0000, 0xFF00FF00,
    0xFF0000FF, 0xFFFF00FF,
    0xFFFFFF00, 0xFF00FFFF,
   },
   {
    0x44332211,
    0x88776655,
   },
  },
 },
 {
  .name = "well_known_colors",
  .format = DRM_FORMAT_YUV444,
  .clip = DRM_RECT_INIT(1, 1, 2, 4),
  .src_pitches = { 4 * 1, 4 * 1, 4 * 1 },
  .src = {
   {
    0x00000000,
    0x0000FF00,
    0x00954C00,
    0x00691D00,
    0x00B2E100,
   },
   {
    0x00000000,
    0x00000000,
    0x00BEDE00,
    0x00436500,
    0x00229B00,
   },
   {
    0x00000000,
    0x00000000,
    0x007E9C00,
    0x0083E700,
    0x00641A00,
   },
  },
  .dst_pitches = { TEST_USE_DEFAULT_PITCH },
  .expected = {
   {
    0x954C00FF,
    0xB2E1691D,
   },
   {
    0xBEDE0000,
    0x229B4365,
   },
   {
    0x7E9C0000,
    0x641A83E7,
   },
  },
 },
 {
  .name = "destination_pitch",
  .format = DRM_FORMAT_XBGR8888,
  .clip = DRM_RECT_INIT(0, 0, 3, 3),
  .src_pitches = { 3 * 4 },
  .src = {
   {
    0xA10E449C, 0xB1114D05, 0xC1A8F303,
    0xD16CF073, 0xA20E449C, 0xB2114D05,
    0xC2A80303, 0xD26CF073, 0xA30E449C,
   },
  },
  .dst_pitches = { 5 * 4 },
  .expected = {
   {
    0xA10E449C, 0xB1114D05, 0xC1A8F303, 0x00000000, 0x00000000,
    0xD16CF073, 0xA20E449C, 0xB2114D05, 0x00000000, 0x00000000,
    0xC2A80303, 0xD26CF073, 0xA30E449C, 0x00000000, 0x00000000,
   },
  },
 },
 {
  .name = "destination_pitch",
  .format = DRM_FORMAT_XRGB8888_A8,
  .clip = DRM_RECT_INIT(0, 0, 3, 3),
  .src_pitches = { 3 * 4, 3 * 1 },
  .src = {
   {
    0xFF0E449C, 0xFF114D05, 0xFFA8F303,
    0xFF6CF073, 0xFF0E449C, 0xFF114D05,
    0xFFA80303, 0xFF6CF073, 0xFF0E449C,
   },
   {
    0xB2C1B1A1,
    0xD2A3D1A2,
    0xFFFFFFC2,
   },
  },
  .dst_pitches = { 5 * 4, 5 * 1 },
  .expected = {
   {
    0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
    0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
    0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
   },
   {
    0x00C1B1A1,
    0xD1A2B200,
    0xD2A30000,
    0xFF0000C2,
   },
  },
 },
 {
  .name = "destination_pitch",
  .format = DRM_FORMAT_YUV444,
  .clip = DRM_RECT_INIT(0, 0, 3, 3),
  .src_pitches = { 3 * 1, 3 * 1, 3 * 1 },
  .src = {
   {
    0xBAC1323D,
    0xBA34323D,
    0xFFFFFF3D,
   },
   {
    0xE1ABEC2A,
    0xE1EAEC2A,
    0xFFFFFF2A,
   },
   {
    0xBCEBE4D7,
    0xBC65E4D7,
    0xFFFFFFD7,
   },
  },
  .dst_pitches = { 5 * 1, 5 * 1, 5 * 1 },
  .expected = {
   {
    0x00C1323D,
    0x323DBA00,
    0xBA340000,
    0xFF00003D,
   },
   {
    0x00ABEC2A,
    0xEC2AE100,
    0xE1EA0000,
    0xFF00002A,
   },
   {
    0x00EBE4D7,
    0xE4D7BC00,
    0xBC650000,
    0xFF0000D7,
   },
  },
 },
};

static void fb_memcpy_case_desc(struct fb_memcpy_case *t, char *desc)
{
 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s: %p4cc", t->name, &t->format);
}

KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);

static void drm_test_fb_memcpy(struct kunit *test)
{
 const struct fb_memcpy_case *params = test->param_value;
 size_t dst_size[DRM_FORMAT_MAX_PLANES] = { 0 };
 u32 *buf[DRM_FORMAT_MAX_PLANES] = { 0 };
 __le32 *src_cp[DRM_FORMAT_MAX_PLANES] = { 0 };
 __le32 *expected[DRM_FORMAT_MAX_PLANES] = { 0 };
 struct iosys_map dst[DRM_FORMAT_MAX_PLANES];
 struct iosys_map src[DRM_FORMAT_MAX_PLANES];

 struct drm_framebuffer fb = {
  .format = drm_format_info(params->format),
 };

 memcpy(fb.pitches, params->src_pitches, DRM_FORMAT_MAX_PLANES * sizeof(int));

 for (size_t i = 0; i < fb.format->num_planes; i++) {
  dst_size[i] = conversion_buf_size(params->format, params->dst_pitches[i],
        ¶ms->clip, i);
  KUNIT_ASSERT_GT(test, dst_size[i], 0);

  buf[i] = kunit_kzalloc(test, dst_size[i], GFP_KERNEL);
  KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf[i]);
  iosys_map_set_vaddr(&dst[i], buf[i]);

  src_cp[i] = cpubuf_to_le32(test, params->src[i], TEST_BUF_SIZE);
  iosys_map_set_vaddr(&src[i], src_cp[i]);
 }

 const unsigned int *dst_pitches = params->dst_pitches[0] == TEST_USE_DEFAULT_PITCH ? NULL :
  params->dst_pitches;

 drm_fb_memcpy(dst, dst_pitches, src, &fb, ¶ms->clip);

 for (size_t i = 0; i < fb.format->num_planes; i++) {
  expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
  KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
           "Failed expectation on plane %zu", i);

  memset(buf[i], 0, dst_size[i]);
 }

 drm_fb_memcpy(dst, dst_pitches, src, &fb, ¶ms->clip);

 for (size_t i = 0; i < fb.format->num_planes; i++) {
  expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
  KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
           "Failed expectation on plane %zu", i);
 }
}

static struct kunit_case drm_format_helper_test_cases[] = {
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_bgr888, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_mono, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
 KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_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 ");

Messung V0.5
C=96 H=93 G=94

¤ Dauer der Verarbeitung: 0.12 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.