FILE
vkms_color_test.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/vkms/tests/vkms_color_test.c
1// SPDX-License-Identifier: GPL-2.0+ 2 3#include <kunit/test.h> 4 5#include <drm/drm_fixed.h> 6#include <drm/drm_mode.h> 7#include "../vkms_composer.h" 8#include "../vkms_drv.h" 9#include "../vkms_luts.h" 10 11#define TEST_LUT_SIZE 16 12 13MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); 14 15static struct drm_color_lut test_linear_array[TEST_LUT_SIZE] = { 16 { 0x0, 0x0, 0x0, 0 }, 17 { 0x1111, 0x1111, 0x1111, 0 }, 18 { 0x2222, 0x2222, 0x2222, 0 }, 19 { 0x3333, 0x3333, 0x3333, 0 }, 20 { 0x4444, 0x4444, 0x4444, 0 }, 21 { 0x5555, 0x5555, 0x5555, 0 }, 22 { 0x6666, 0x6666, 0x6666, 0 }, 23 { 0x7777, 0x7777, 0x7777, 0 }, 24 { 0x8888, 0x8888, 0x8888, 0 }, 25 { 0x9999, 0x9999, 0x9999, 0 }, 26 { 0xaaaa, 0xaaaa, 0xaaaa, 0 }, 27 { 0xbbbb, 0xbbbb, 0xbbbb, 0 }, 28 { 0xcccc, 0xcccc, 0xcccc, 0 }, 29 { 0xdddd, 0xdddd, 0xdddd, 0 }, 30 { 0xeeee, 0xeeee, 0xeeee, 0 }, 31 { 0xffff, 0xffff, 0xffff, 0 }, 32}; 33 34/* lerp test parameters */ 35struct vkms_color_test_lerp_params { 36 s64 t; 37 __u16 a; 38 __u16 b; 39 __u16 expected; 40}; 41 42/* lerp test cases */ 43static const struct vkms_color_test_lerp_params color_test_lerp_cases[] = { 44 /* Half-way round down */ 45 { 0x80000000 - 1, 0x0, 0x10, 0x8 }, 46 { 0x80000000 - 1, 0x1, 0x10, 0x8 }, /* Odd a */ 47 { 0x80000000 - 1, 0x1, 0xf, 0x8 }, /* Odd b */ 48 { 0x80000000 - 1, 0x10, 0x10, 0x10 }, /* b = a */ 49 { 0x80000000 - 1, 0x10, 0x11, 0x10 }, /* b = a + 1*/ 50 /* Half-way round up */ 51 { 0x80000000, 0x0, 0x10, 0x8 }, 52 { 0x80000000, 0x1, 0x10, 0x9 }, /* Odd a */ 53 { 0x80000000, 0x1, 0xf, 0x8 }, /* Odd b */ 54 { 0x80000000, 0x10, 0x10, 0x10 }, /* b = a */ 55 { 0x80000000, 0x10, 0x11, 0x11 }, /* b = a + 1*/ 56 /* t = 0.0 */ 57 { 0x0, 0x0, 0x10, 0x0 }, 58 { 0x0, 0x1, 0x10, 0x1 }, /* Odd a */ 59 { 0x0, 0x1, 0xf, 0x1 }, /* Odd b */ 60 { 0x0, 0x10, 0x10, 0x10 }, /* b = a */ 61 { 0x0, 0x10, 0x11, 0x10 }, /* b = a + 1*/ 62 /* t = 1.0 */ 63 { 0x100000000, 0x0, 0x10, 0x10 }, 64 { 0x100000000, 0x1, 0x10, 0x10 }, /* Odd a */ 65 { 0x100000000, 0x1, 0xf, 0xf }, /* Odd b */ 66 { 0x100000000, 0x10, 0x10, 0x10 }, /* b = a */ 67 { 0x100000000, 0x10, 0x11, 0x11 }, /* b = a + 1*/ 68 /* t = 0.0 + 1 */ 69 { 0x0 + 1, 0x0, 0x10, 0x0 }, 70 { 0x0 + 1, 0x1, 0x10, 0x1 }, /* Odd a */ 71 { 0x0 + 1, 0x1, 0xf, 0x1 }, /* Odd b */ 72 { 0x0 + 1, 0x10, 0x10, 0x10 }, /* b = a */ 73 { 0x0 + 1, 0x10, 0x11, 0x10 }, /* b = a + 1*/ 74 /* t = 1.0 - 1 */ 75 { 0x100000000 - 1, 0x0, 0x10, 0x10 }, 76 { 0x100000000 - 1, 0x1, 0x10, 0x10 }, /* Odd a */ 77 { 0x100000000 - 1, 0x1, 0xf, 0xf }, /* Odd b */ 78 { 0x100000000 - 1, 0x10, 0x10, 0x10 }, /* b = a */ 79 { 0x100000000 - 1, 0x10, 0x11, 0x11 }, /* b = a + 1*/ 80 /* t chosen to verify the flipping point of result a (or b) to a+1 (or b-1) */ 81 { 0x80000000 - 1, 0x0, 0x1, 0x0 }, 82 { 0x80000000, 0x0, 0x1, 0x1 }, 83}; 84 85static const struct vkms_color_lut test_linear_lut = { 86 .base = test_linear_array, 87 .lut_length = TEST_LUT_SIZE, 88 .channel_value2index_ratio = 0xf000fll 89}; 90 91static void vkms_color_test_get_lut_index(struct kunit *test) 92{ 93 s64 lut_index; 94 int i; 95 96 lut_index = get_lut_index(&test_linear_lut, test_linear_array[0].red); 97 KUNIT_EXPECT_EQ(test, drm_fixp2int(lut_index), 0); 98 99 for (i = 0; i < TEST_LUT_SIZE; i++) { 100 lut_index = get_lut_index(&test_linear_lut, test_linear_array[i].red); 101 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(lut_index), i); 102 } 103 104 KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(&srgb_eotf, 0x0)), 0x0); 105 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x0)), 0x0); 106 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x101)), 0x1); 107 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x202)), 0x2); 108 109 KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(&srgb_inv_eotf, 0x0)), 0x0); 110 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x0)), 0x0); 111 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x101)), 0x1); 112 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x202)), 0x2); 113 114 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0xfefe)), 0xfe); 115 KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0xffff)), 0xff); 116} 117 118static void vkms_color_test_lerp(struct kunit *test) 119{ 120 int i; 121 122 for (i = 0; i < ARRAY_SIZE(color_test_lerp_cases); i++) { 123 const struct vkms_color_test_lerp_params *params = &color_test_lerp_cases[i]; 124 125 KUNIT_EXPECT_EQ(test, lerp_u16(params->a, params->b, params->t), params->expected); 126 } 127} 128 129static void vkms_color_test_linear(struct kunit *test) 130{ 131 for (int i = 0; i < LUT_SIZE; i++) { 132 int linear = apply_lut_to_channel_value(&linear_eotf, i * 0x101, LUT_RED); 133 134 KUNIT_EXPECT_EQ(test, DIV_ROUND_CLOSEST(linear, 0x101), i); 135 } 136} 137 138static void vkms_color_srgb_inv_srgb(struct kunit *test) 139{ 140 u16 srgb, final; 141 142 for (int i = 0; i < LUT_SIZE; i++) { 143 srgb = apply_lut_to_channel_value(&srgb_eotf, i * 0x101, LUT_RED); 144 final = apply_lut_to_channel_value(&srgb_inv_eotf, srgb, LUT_RED); 145 146 KUNIT_EXPECT_GE(test, final / 0x101, i - 1); 147 KUNIT_EXPECT_LE(test, final / 0x101, i + 1); 148 } 149} 150 151#define FIXPT_HALF (DRM_FIXED_ONE >> 1) 152#define FIXPT_QUARTER (DRM_FIXED_ONE >> 2) 153 154static const struct drm_color_ctm_3x4 test_matrix_3x4_50_desat = { { 155 FIXPT_HALF, FIXPT_QUARTER, FIXPT_QUARTER, 0, 156 FIXPT_QUARTER, FIXPT_HALF, FIXPT_QUARTER, 0, 157 FIXPT_QUARTER, FIXPT_QUARTER, FIXPT_HALF, 0 158} }; 159 160static void vkms_color_ctm_3x4_50_desat(struct kunit *test) 161{ 162 struct pixel_argb_s32 ref, out; 163 164 /* full white */ 165 ref.a = 0xffff; 166 ref.r = 0xffff; 167 ref.g = 0xffff; 168 ref.b = 0xffff; 169 170 memcpy(&out, &ref, sizeof(out)); 171 apply_3x4_matrix(&out, &test_matrix_3x4_50_desat); 172 173 KUNIT_EXPECT_MEMEQ(test, &ref, &out, sizeof(out)); 174 175 /* full black */ 176 ref.a = 0xffff; 177 ref.r = 0x0; 178 ref.g = 0x0; 179 ref.b = 0x0; 180 181 memcpy(&out, &ref, sizeof(out)); 182 apply_3x4_matrix(&out, &test_matrix_3x4_50_desat); 183 184 KUNIT_EXPECT_MEMEQ(test, &ref, &out, sizeof(out)); 185 186 /* 50% grey */ 187 ref.a = 0xffff; 188 ref.r = 0x8000; 189 ref.g = 0x8000; 190 ref.b = 0x8000; 191 192 memcpy(&out, &ref, sizeof(out)); 193 apply_3x4_matrix(&out, &test_matrix_3x4_50_desat); 194 195 KUNIT_EXPECT_MEMEQ(test, &ref, &out, sizeof(out)); 196 197 /* full red to 50% desat */ 198 ref.a = 0xffff; 199 ref.r = 0x8000; 200 ref.g = 0x4000; 201 ref.b = 0x4000; 202 203 out.a = 0xffff; 204 out.r = 0xffff; 205 out.g = 0x0; 206 out.b = 0x0; 207 208 apply_3x4_matrix(&out, &test_matrix_3x4_50_desat); 209 210 KUNIT_EXPECT_MEMEQ(test, &ref, &out, sizeof(out)); 211} 212 213/* 214 * BT.709 encoding matrix 215 * 216 * Values printed from within IGT when converting 217 * igt_matrix_3x4_bt709_enc to the fixed-point format expected 218 * by DRM/KMS. 219 */ 220static const struct drm_color_ctm_3x4 test_matrix_3x4_bt709_enc = { { 221 0x00000000366cf400ull, 0x00000000b7175900ull, 0x0000000127bb300ull, 0, 222 0x800000001993b3a0ull, 0x800000005609fe80ull, 0x000000006f9db200ull, 0, 223 0x000000009d70a400ull, 0x800000008f011100ull, 0x800000000e6f9330ull, 0 224} }; 225 226static void vkms_color_ctm_3x4_bt709(struct kunit *test) 227{ 228 struct pixel_argb_s32 out; 229 230 /* full white to bt709 */ 231 out.a = 0xffff; 232 out.r = 0xffff; 233 out.g = 0xffff; 234 out.b = 0xffff; 235 236 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 237 238 /* Y 255 */ 239 KUNIT_EXPECT_GT(test, out.r, 0xfe00); 240 KUNIT_EXPECT_LT(test, out.r, 0x10000); 241 242 /* U 0 */ 243 KUNIT_EXPECT_LT(test, out.g, 0x0100); 244 245 /* V 0 */ 246 KUNIT_EXPECT_LT(test, out.b, 0x0100); 247 248 /* full black to bt709 */ 249 out.a = 0xffff; 250 out.r = 0x0; 251 out.g = 0x0; 252 out.b = 0x0; 253 254 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 255 256 /* Y 0 */ 257 KUNIT_EXPECT_LT(test, out.r, 0x100); 258 259 /* U 0 */ 260 KUNIT_EXPECT_LT(test, out.g, 0x0100); 261 262 /* V 0 */ 263 KUNIT_EXPECT_LT(test, out.b, 0x0100); 264 265 /* gray to bt709 */ 266 out.a = 0xffff; 267 out.r = 0x7fff; 268 out.g = 0x7fff; 269 out.b = 0x7fff; 270 271 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 272 273 /* Y 127 */ 274 KUNIT_EXPECT_GT(test, out.r, 0x7e00); 275 KUNIT_EXPECT_LT(test, out.r, 0x8000); 276 277 /* U 0 */ 278 KUNIT_EXPECT_LT(test, out.g, 0x0100); 279 280 /* V 0 */ 281 KUNIT_EXPECT_LT(test, out.b, 0x0100); 282 283 /* == red 255 - bt709 enc == */ 284 out.a = 0xffff; 285 out.r = 0xffff; 286 out.g = 0x0; 287 out.b = 0x0; 288 289 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 290 291 /* Y 54 */ 292 KUNIT_EXPECT_GT(test, out.r, 0x3500); 293 KUNIT_EXPECT_LT(test, out.r, 0x3700); 294 295 /* U 0 */ 296 KUNIT_EXPECT_LT(test, out.g, 0x0100); 297 298 /* V 157 */ 299 KUNIT_EXPECT_GT(test, out.b, 0x9C00); 300 KUNIT_EXPECT_LT(test, out.b, 0x9E00); 301 302 /* == green 255 - bt709 enc == */ 303 out.a = 0xffff; 304 out.r = 0x0; 305 out.g = 0xffff; 306 out.b = 0x0; 307 308 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 309 310 /* Y 182 */ 311 KUNIT_EXPECT_GT(test, out.r, 0xB500); 312 KUNIT_EXPECT_LT(test, out.r, 0xB780); /* laxed by half*/ 313 314 /* U 0 */ 315 KUNIT_EXPECT_LT(test, out.g, 0x0100); 316 317 /* V 0 */ 318 KUNIT_EXPECT_LT(test, out.b, 0x0100); 319 320 /* == blue 255 - bt709 enc == */ 321 out.a = 0xffff; 322 out.r = 0x0; 323 out.g = 0x0; 324 out.b = 0xffff; 325 326 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 327 328 /* Y 18 */ 329 KUNIT_EXPECT_GT(test, out.r, 0x1100); 330 KUNIT_EXPECT_LT(test, out.r, 0x1300); 331 332 /* U 111 */ 333 KUNIT_EXPECT_GT(test, out.g, 0x6E00); 334 KUNIT_EXPECT_LT(test, out.g, 0x7000); 335 336 /* V 0 */ 337 KUNIT_EXPECT_LT(test, out.b, 0x0100); 338 339 /* == red 140 - bt709 enc == */ 340 out.a = 0xffff; 341 out.r = 0x8c8c; 342 out.g = 0x0; 343 out.b = 0x0; 344 345 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 346 347 /* Y 30 */ 348 KUNIT_EXPECT_GT(test, out.r, 0x1D00); 349 KUNIT_EXPECT_LT(test, out.r, 0x1F00); 350 351 /* U 0 */ 352 KUNIT_EXPECT_LT(test, out.g, 0x100); 353 354 /* V 87 */ 355 KUNIT_EXPECT_GT(test, out.b, 0x5600); 356 KUNIT_EXPECT_LT(test, out.b, 0x5800); 357 358 /* == green 140 - bt709 enc == */ 359 out.a = 0xffff; 360 out.r = 0x0; 361 out.g = 0x8c8c; 362 out.b = 0x0; 363 364 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 365 366 /* Y 30 */ 367 KUNIT_EXPECT_GT(test, out.r, 0x6400); 368 KUNIT_EXPECT_LT(test, out.r, 0x6600); 369 370 /* U 0 */ 371 KUNIT_EXPECT_LT(test, out.g, 0x100); 372 373 /* V 0 */ 374 KUNIT_EXPECT_LT(test, out.b, 0x100); 375 376 /* == blue 140 - bt709 enc == */ 377 out.a = 0xffff; 378 out.r = 0x0; 379 out.g = 0x0; 380 out.b = 0x8c8c; 381 382 apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc); 383 384 /* Y 30 */ 385 KUNIT_EXPECT_GT(test, out.r, 0x900); 386 KUNIT_EXPECT_LT(test, out.r, 0xB00); 387 388 /* U 61 */ 389 KUNIT_EXPECT_GT(test, out.g, 0x3C00); 390 KUNIT_EXPECT_LT(test, out.g, 0x3E00); 391 392 /* V 0 */ 393 KUNIT_EXPECT_LT(test, out.b, 0x100); 394} 395 396static struct kunit_case vkms_color_test_cases[] = { 397 KUNIT_CASE(vkms_color_test_get_lut_index), 398 KUNIT_CASE(vkms_color_test_lerp), 399 KUNIT_CASE(vkms_color_test_linear), 400 KUNIT_CASE(vkms_color_srgb_inv_srgb), 401 KUNIT_CASE(vkms_color_ctm_3x4_50_desat), 402 KUNIT_CASE(vkms_color_ctm_3x4_bt709), 403 {} 404}; 405 406static struct kunit_suite vkms_color_test_suite = { 407 .name = "vkms-color", 408 .test_cases = vkms_color_test_cases, 409}; 410 411kunit_test_suite(vkms_color_test_suite); 412 413MODULE_DESCRIPTION("Kunit test for VKMS LUT handling"); 414MODULE_LICENSE("GPL");
~/
Read-only file preview.