brintos

brintos / linux-shallow public Read only

0
0
Text · 9.5 KiB · 7e975a3 Raw
320 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Test cases for the drm_plane_helper functions4 *5 * Copyright (c) 2022 Maíra Canal <mairacanal@riseup.net>6 */7 8#include <kunit/test.h>9 10#include <drm/drm_atomic_helper.h>11#include <drm/drm_framebuffer.h>12#include <drm/drm_modes.h>13#include <drm/drm_rect.h>14 15static const struct drm_crtc_state crtc_state = {16	.crtc = ZERO_SIZE_PTR,17	.enable = true,18	.active = true,19	.mode = {20		DRM_MODE("1024x768", 0, 65000, 1024, 1048,21			 1184, 1344, 0, 768, 771, 777, 806, 0,22			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)23	},24};25 26struct drm_check_plane_state_test {27	const char *name;28	const char *msg;29	struct {30		unsigned int x;31		unsigned int y;32		unsigned int w;33		unsigned int h;34	} src, src_expected;35	struct {36		int x;37		int y;38		unsigned int w;39		unsigned int h;40	} crtc, crtc_expected;41	unsigned int rotation;42	int min_scale;43	int max_scale;44	bool can_position;45};46 47static int drm_plane_helper_init(struct kunit *test)48{49	const struct drm_check_plane_state_test *params = test->param_value;50	struct drm_plane *plane;51	struct drm_framebuffer *fb;52	struct drm_plane_state *mock;53 54	plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL);55	KUNIT_ASSERT_NOT_NULL(test, plane);56 57	fb = kunit_kzalloc(test, sizeof(*fb), GFP_KERNEL);58	KUNIT_ASSERT_NOT_NULL(test, fb);59	fb->width = 2048;60	fb->height = 2048;61 62	mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL);63	KUNIT_ASSERT_NOT_NULL(test, mock);64	mock->plane = plane;65	mock->crtc = ZERO_SIZE_PTR;66	mock->fb = fb;67	mock->rotation = params->rotation;68	mock->src_x = params->src.x;69	mock->src_y = params->src.y;70	mock->src_w = params->src.w;71	mock->src_h = params->src.h;72	mock->crtc_x = params->crtc.x;73	mock->crtc_y = params->crtc.y;74	mock->crtc_w = params->crtc.w;75	mock->crtc_h = params->crtc.h;76 77	test->priv = mock;78 79	return 0;80}81 82static void check_src_eq(struct kunit *test, struct drm_plane_state *plane_state,83			 unsigned int src_x, unsigned int src_y,84			 unsigned int src_w, unsigned int src_h)85{86	struct drm_rect expected = DRM_RECT_INIT(src_x, src_y, src_w, src_h);87 88	KUNIT_ASSERT_GE_MSG(test, plane_state->src.x1, 0,89			    "src x coordinate %x should never be below 0, src: " DRM_RECT_FP_FMT,90			    plane_state->src.x1, DRM_RECT_FP_ARG(&plane_state->src));91 92	KUNIT_ASSERT_GE_MSG(test, plane_state->src.y1, 0,93			    "src y coordinate %x should never be below 0, src: " DRM_RECT_FP_FMT,94			    plane_state->src.y1, DRM_RECT_FP_ARG(&plane_state->src));95 96	KUNIT_EXPECT_TRUE_MSG(test, drm_rect_equals(&plane_state->src, &expected),97			      "dst: " DRM_RECT_FP_FMT ", expected: " DRM_RECT_FP_FMT,98			      DRM_RECT_FP_ARG(&plane_state->src), DRM_RECT_FP_ARG(&expected));99}100 101static void check_crtc_eq(struct kunit *test, struct drm_plane_state *plane_state,102			  int crtc_x, int crtc_y,103			  unsigned int crtc_w, unsigned int crtc_h)104{105	struct drm_rect expected = DRM_RECT_INIT(crtc_x, crtc_y, crtc_w, crtc_h);106 107	KUNIT_EXPECT_TRUE_MSG(test, drm_rect_equals(&plane_state->dst, &expected),108			      "dst: " DRM_RECT_FMT ", expected: " DRM_RECT_FMT,109			      DRM_RECT_ARG(&plane_state->dst), DRM_RECT_ARG(&expected));110}111 112static void drm_test_check_plane_state(struct kunit *test)113{114	const struct drm_check_plane_state_test *params = test->param_value;115	struct drm_plane_state *plane_state = test->priv;116 117	KUNIT_ASSERT_EQ_MSG(test,118			    drm_atomic_helper_check_plane_state(plane_state, &crtc_state,119								params->min_scale,120								params->max_scale,121								params->can_position, false),122			    0, params->msg);123	KUNIT_EXPECT_TRUE(test, plane_state->visible);124	check_src_eq(test, plane_state, params->src_expected.x, params->src_expected.y,125		     params->src_expected.w, params->src_expected.h);126	check_crtc_eq(test, plane_state, params->crtc_expected.x, params->crtc_expected.y,127		      params->crtc_expected.w, params->crtc_expected.h);128}129 130static void drm_check_plane_state_desc(const struct drm_check_plane_state_test *t,131				       char *desc)132{133	sprintf(desc, "%s", t->name);134}135 136static const struct drm_check_plane_state_test drm_check_plane_state_tests[] = {137	{138		.name = "clipping_simple",139		.msg = "Simple clipping check should pass",140		.src = { 0, 0,141			 2048 << 16,142			 2048 << 16 },143		.crtc = { 0, 0, 2048, 2048 },144		.rotation = DRM_MODE_ROTATE_0,145		.min_scale = DRM_PLANE_NO_SCALING,146		.max_scale = DRM_PLANE_NO_SCALING,147		.can_position = false,148		.src_expected = { 0, 0, 1024 << 16, 768 << 16 },149		.crtc_expected = { 0, 0, 1024, 768 },150	},151	{152		.name = "clipping_rotate_reflect",153		.msg = "Rotated clipping check should pass",154		.src = { 0, 0,155			 2048 << 16,156			 2048 << 16 },157		.crtc = { 0, 0, 2048, 2048 },158		.rotation = DRM_MODE_ROTATE_90 | DRM_MODE_REFLECT_X,159		.min_scale = DRM_PLANE_NO_SCALING,160		.max_scale = DRM_PLANE_NO_SCALING,161		.can_position = false,162		.src_expected = { 0, 0, 768 << 16, 1024 << 16 },163		.crtc_expected = { 0, 0, 1024, 768 },164	},165	{166		.name = "positioning_simple",167		.msg = "Simple positioning should work",168		.src = { 0, 0, 1023 << 16, 767 << 16 },169		.crtc = { 0, 0, 1023, 767 },170		.rotation = DRM_MODE_ROTATE_0,171		.min_scale = DRM_PLANE_NO_SCALING,172		.max_scale = DRM_PLANE_NO_SCALING,173		.can_position = true,174		.src_expected = { 0, 0, 1023 << 16, 767 << 16 },175		.crtc_expected = { 0, 0, 1023, 767 },176	},177	{178		.name = "upscaling",179		.msg = "Upscaling exactly 2x should work",180		.src = { 0, 0, 512 << 16, 384 << 16 },181		.crtc = { 0, 0, 1024, 768 },182		.rotation = DRM_MODE_ROTATE_0,183		.min_scale = 0x8000,184		.max_scale = DRM_PLANE_NO_SCALING,185		.can_position = false,186		.src_expected = { 0, 0, 512 << 16, 384 << 16 },187		.crtc_expected = { 0, 0, 1024, 768 },188	},189	{190		.name = "downscaling",191		.msg = "Should succeed with exact scaling limit",192		.src = { 0, 0, 2048 << 16, 1536 << 16 },193		.crtc = { 0, 0, 1024, 768 },194		.rotation = DRM_MODE_ROTATE_0,195		.min_scale = DRM_PLANE_NO_SCALING,196		.max_scale = 0x20000,197		.can_position = false,198		.src_expected = { 0, 0, 2048 << 16, 1536 << 16 },199		.crtc_expected = { 0, 0, 1024, 768 },200	},201	{202		.name = "rounding1",203		.msg = "Should succeed by clipping to exact multiple",204		.src = { 0, 0, 0x40001, 0x40001 },205		.crtc = { 1022, 766, 4, 4 },206		.rotation = DRM_MODE_ROTATE_0,207		.min_scale = DRM_PLANE_NO_SCALING,208		.max_scale = 0x10001,209		.can_position = true,210		.src_expected = { 0, 0, 2 << 16, 2 << 16 },211		.crtc_expected = { 1022, 766, 2, 2 },212	},213	{214		.name = "rounding2",215		.msg = "Should succeed by clipping to exact multiple",216		.src = { 0x20001, 0x20001, 0x4040001, 0x3040001 },217		.crtc = { -2, -2, 1028, 772 },218		.rotation = DRM_MODE_ROTATE_0,219		.min_scale = DRM_PLANE_NO_SCALING,220		.max_scale = 0x10001,221		.can_position = false,222		.src_expected = { 0x40002, 0x40002, 1024 << 16, 768 << 16 },223		.crtc_expected = { 0, 0, 1024, 768 },224	},225	{226		.name = "rounding3",227		.msg = "Should succeed by clipping to exact multiple",228		.src = { 0, 0, 0x3ffff, 0x3ffff },229		.crtc = { 1022, 766, 4, 4 },230		.rotation = DRM_MODE_ROTATE_0,231		.min_scale = 0xffff,232		.max_scale = DRM_PLANE_NO_SCALING,233		.can_position = true,234		/* Should not be rounded to 0x20001, which would be upscaling. */235		.src_expected = { 0, 0, 2 << 16, 2 << 16 },236		.crtc_expected = { 1022, 766, 2, 2 },237	},238	{239		.name = "rounding4",240		.msg = "Should succeed by clipping to exact multiple",241		.src = { 0x1ffff, 0x1ffff, 0x403ffff, 0x303ffff },242		.crtc = { -2, -2, 1028, 772 },243		.rotation = DRM_MODE_ROTATE_0,244		.min_scale = 0xffff,245		.max_scale = DRM_PLANE_NO_SCALING,246		.can_position = false,247		.src_expected = { 0x3fffe, 0x3fffe, 1024 << 16, 768 << 16 },248		.crtc_expected = { 0, 0, 1024, 768 },249	},250};251 252KUNIT_ARRAY_PARAM(drm_check_plane_state, drm_check_plane_state_tests, drm_check_plane_state_desc);253 254static void drm_test_check_invalid_plane_state(struct kunit *test)255{256	const struct drm_check_plane_state_test *params = test->param_value;257	struct drm_plane_state *plane_state = test->priv;258 259	KUNIT_ASSERT_LT_MSG(test,260			    drm_atomic_helper_check_plane_state(plane_state, &crtc_state,261								params->min_scale,262								params->max_scale,263								params->can_position, false),264			    0, params->msg);265}266 267static const struct drm_check_plane_state_test drm_check_invalid_plane_state_tests[] = {268	{269		.name = "positioning_invalid",270		.msg = "Should not be able to position on the crtc with can_position=false",271		.src = { 0, 0, 1023 << 16, 767 << 16 },272		.crtc = { 0, 0, 1023, 767 },273		.rotation = DRM_MODE_ROTATE_0,274		.min_scale = DRM_PLANE_NO_SCALING,275		.max_scale = DRM_PLANE_NO_SCALING,276		.can_position = false,277	},278	{279		.name = "upscaling_invalid",280		.msg = "Upscaling out of range should fail",281		.src = { 0, 0, 512 << 16, 384 << 16 },282		.crtc = { 0, 0, 1024, 768 },283		.rotation = DRM_MODE_ROTATE_0,284		.min_scale = 0x8001,285		.max_scale = DRM_PLANE_NO_SCALING,286		.can_position = false,287	},288	{289		.name = "downscaling_invalid",290		.msg = "Downscaling out of range should fail",291		.src = { 0, 0, 2048 << 16, 1536 << 16 },292		.crtc = { 0, 0, 1024, 768 },293		.rotation = DRM_MODE_ROTATE_0,294		.min_scale = DRM_PLANE_NO_SCALING,295		.max_scale = 0x1ffff,296		.can_position = false,297	},298};299 300KUNIT_ARRAY_PARAM(drm_check_invalid_plane_state, drm_check_invalid_plane_state_tests,301		  drm_check_plane_state_desc);302 303static struct kunit_case drm_plane_helper_test[] = {304	KUNIT_CASE_PARAM(drm_test_check_plane_state, drm_check_plane_state_gen_params),305	KUNIT_CASE_PARAM(drm_test_check_invalid_plane_state,306			 drm_check_invalid_plane_state_gen_params),307	{}308};309 310static struct kunit_suite drm_plane_helper_test_suite = {311	.name = "drm_plane_helper",312	.init = drm_plane_helper_init,313	.test_cases = drm_plane_helper_test,314};315 316kunit_test_suite(drm_plane_helper_test_suite);317 318MODULE_DESCRIPTION("Test cases for the drm_plane_helper functions");319MODULE_LICENSE("GPL");320