Commit cb500b4c authored by Harry Wentland's avatar Harry Wentland Committed by Simon Ser
Browse files

drm/vkms: Add kunit tests for linear and sRGB LUTs



Two tests are added to VKMS LUT handling:
- linear
- inv_srgb

Reviewed-by: default avatarLouis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: default avatarAlex Hung <alex.hung@amd.com>
Signed-off-by: default avatarHarry Wentland <harry.wentland@amd.com>
Reviewed-by: default avatarDaniel Stone <daniels@collabora.com>
Signed-off-by: default avatarSimon Ser <contact@emersion.fr>
Link: https://patch.msgid.link/20251115000237.3561250-18-alex.hung@amd.com
parent 9b5c7e8b
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <drm/drm_mode.h>
#include "../vkms_composer.h"
#include "../vkms_drv.h"
#include "../vkms_luts.h"

#define TEST_LUT_SIZE 16

@@ -99,6 +100,19 @@ static void vkms_color_test_get_lut_index(struct kunit *test)
		lut_index = get_lut_index(&test_linear_lut, test_linear_array[i].red);
		KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(lut_index), i);
	}

	KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(&srgb_eotf, 0x0)), 0x0);
	KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x0)), 0x0);
	KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x101)), 0x1);
	KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x202)), 0x2);

	KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(&srgb_inv_eotf, 0x0)), 0x0);
	KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x0)), 0x0);
	KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x101)), 0x1);
	KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x202)), 0x2);

	KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0xfefe)), 0xfe);
	KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0xffff)), 0xff);
}

static void vkms_color_test_lerp(struct kunit *test)
@@ -112,9 +126,33 @@ static void vkms_color_test_lerp(struct kunit *test)
	}
}

static void vkms_color_test_linear(struct kunit *test)
{
	for (int i = 0; i < LUT_SIZE; i++) {
		int linear = apply_lut_to_channel_value(&linear_eotf, i * 0x101, LUT_RED);

		KUNIT_EXPECT_EQ(test, DIV_ROUND_CLOSEST(linear, 0x101), i);
	}
}

static void vkms_color_srgb_inv_srgb(struct kunit *test)
{
	u16 srgb, final;

	for (int i = 0; i < LUT_SIZE; i++) {
		srgb = apply_lut_to_channel_value(&srgb_eotf, i * 0x101, LUT_RED);
		final = apply_lut_to_channel_value(&srgb_inv_eotf, srgb, LUT_RED);

		KUNIT_EXPECT_GE(test, final / 0x101, i - 1);
		KUNIT_EXPECT_LE(test, final / 0x101, i + 1);
	}
}

static struct kunit_case vkms_color_test_cases[] = {
	KUNIT_CASE(vkms_color_test_get_lut_index),
	KUNIT_CASE(vkms_color_test_lerp),
	KUNIT_CASE(vkms_color_test_linear),
	KUNIT_CASE(vkms_color_srgb_inv_srgb),
	{}
};

+4 −13
Original line number Diff line number Diff line
@@ -82,18 +82,7 @@ VISIBLE_IF_KUNIT s64 get_lut_index(const struct vkms_color_lut *lut, u16 channel
}
EXPORT_SYMBOL_IF_KUNIT(get_lut_index);

/*
 * This enum is related to the positions of the variables inside
 * `struct drm_color_lut`, so the order of both needs to be the same.
 */
enum lut_channel {
	LUT_RED = 0,
	LUT_GREEN,
	LUT_BLUE,
	LUT_RESERVED
};

static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 channel_value,
VISIBLE_IF_KUNIT u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 channel_value,
						enum lut_channel channel)
{
	s64 lut_index = get_lut_index(lut, channel_value);
@@ -119,6 +108,8 @@ static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 chan
	return lerp_u16(floor_channel_value, ceil_channel_value,
			lut_index & DRM_FIXED_DECIMAL_MASK);
}
EXPORT_SYMBOL_IF_KUNIT(apply_lut_to_channel_value);


static void apply_lut(const struct vkms_crtc_state *crtc_state, struct line_buffer *output_buffer)
{
+13 −0
Original line number Diff line number Diff line
@@ -6,9 +6,22 @@
#include <kunit/visibility.h>
#include "vkms_drv.h"

/*
 * This enum is related to the positions of the variables inside
 * `struct drm_color_lut`, so the order of both needs to be the same.
 */
enum lut_channel {
	LUT_RED = 0,
	LUT_GREEN,
	LUT_BLUE,
	LUT_RESERVED
};

#if IS_ENABLED(CONFIG_KUNIT)
u16 lerp_u16(u16 a, u16 b, s64 t);
s64 get_lut_index(const struct vkms_color_lut *lut, u16 channel_value);
u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 channel_value,
			       enum lut_channel channel);
#endif

#endif /* _VKMS_COMPOSER_H_ */