2018-10-16 13:46:08 -07:00
// SPDX-License-Identifier: GPL-2.0
2018-05-03 13:22:17 +02:00
/*
2018-10-16 13:46:08 -07:00
* Test cases for the drm_plane_helper functions
2022-07-08 17:30:48 -03:00
*
* Copyright ( c ) 2022 Maíra Canal < mairacanal @ riseup . net >
2018-05-03 13:22:17 +02:00
*/
2022-07-08 17:30:48 -03:00
# include <kunit/test.h>
2018-05-03 13:22:17 +02:00
# include <drm/drm_atomic_helper.h>
2022-06-14 12:54:49 +03:00
# include <drm/drm_framebuffer.h>
2018-05-03 13:22:17 +02:00
# include <drm/drm_modes.h>
2022-10-20 10:21:34 +02:00
# include <drm/drm_rect.h>
2018-05-03 13:22:17 +02:00
static void set_src ( struct drm_plane_state * plane_state ,
2022-07-08 17:30:48 -03:00
unsigned int src_x , unsigned int src_y ,
unsigned int src_w , unsigned int src_h )
2018-05-03 13:22:17 +02:00
{
plane_state - > src_x = src_x ;
plane_state - > src_y = src_y ;
plane_state - > src_w = src_w ;
plane_state - > src_h = src_h ;
}
2022-10-20 10:21:34 +02:00
static bool check_src_eq ( struct kunit * test , struct drm_plane_state * plane_state ,
2022-07-08 17:30:48 -03:00
unsigned int src_x , unsigned int src_y ,
unsigned int src_w , unsigned int src_h )
2018-05-03 13:22:17 +02:00
{
2022-10-20 10:21:34 +02:00
struct drm_rect expected = DRM_RECT_INIT ( src_x , src_y , src_w , src_h ) ;
2018-05-03 13:22:17 +02:00
if ( plane_state - > src . x1 < 0 ) {
2022-10-20 10:21:34 +02:00
kunit_err ( test ,
" src x coordinate %x should never be below 0, src: " DRM_RECT_FP_FMT ,
plane_state - > src . x1 , DRM_RECT_FP_ARG ( & plane_state - > src ) ) ;
2018-05-03 13:22:17 +02:00
return false ;
}
if ( plane_state - > src . y1 < 0 ) {
2022-10-20 10:21:34 +02:00
kunit_err ( test ,
" src y coordinate %x should never be below 0, src: " DRM_RECT_FP_FMT ,
plane_state - > src . y1 , DRM_RECT_FP_ARG ( & plane_state - > src ) ) ;
2018-05-03 13:22:17 +02:00
return false ;
}
2022-10-20 10:21:34 +02:00
if ( plane_state - > src . x1 ! = expected . x1 | |
plane_state - > src . y1 ! = expected . y1 | |
drm_rect_width ( & plane_state - > src ) ! = drm_rect_width ( & expected ) | |
drm_rect_height ( & plane_state - > src ) ! = drm_rect_height ( & expected ) ) {
kunit_err ( test , " src: " DRM_RECT_FP_FMT " , expected: " DRM_RECT_FP_FMT ,
DRM_RECT_FP_ARG ( & plane_state - > src ) , DRM_RECT_FP_ARG ( & expected ) ) ;
2018-05-03 13:22:17 +02:00
return false ;
}
return true ;
}
static void set_crtc ( struct drm_plane_state * plane_state ,
int crtc_x , int crtc_y ,
2022-07-08 17:30:48 -03:00
unsigned int crtc_w , unsigned int crtc_h )
2018-05-03 13:22:17 +02:00
{
plane_state - > crtc_x = crtc_x ;
plane_state - > crtc_y = crtc_y ;
plane_state - > crtc_w = crtc_w ;
plane_state - > crtc_h = crtc_h ;
}
2022-10-20 10:21:34 +02:00
static bool check_crtc_eq ( struct kunit * test , struct drm_plane_state * plane_state ,
2018-05-03 13:22:17 +02:00
int crtc_x , int crtc_y ,
2022-07-08 17:30:48 -03:00
unsigned int crtc_w , unsigned int crtc_h )
2018-05-03 13:22:17 +02:00
{
2022-10-20 10:21:34 +02:00
struct drm_rect expected = DRM_RECT_INIT ( crtc_x , crtc_y , crtc_w , crtc_h ) ;
if ( plane_state - > dst . x1 ! = expected . x1 | |
plane_state - > dst . y1 ! = expected . y1 | |
drm_rect_width ( & plane_state - > dst ) ! = drm_rect_width ( & expected ) | |
drm_rect_height ( & plane_state - > dst ) ! = drm_rect_height ( & expected ) ) {
kunit_err ( test , " dst: " DRM_RECT_FMT " , expected: " DRM_RECT_FMT ,
DRM_RECT_ARG ( & plane_state - > dst ) , DRM_RECT_ARG ( & expected ) ) ;
2018-05-03 13:22:17 +02:00
return false ;
}
return true ;
}
2022-09-11 16:17:56 -03:00
static void drm_test_check_plane_state ( struct kunit * test )
2018-05-03 13:22:17 +02:00
{
int ret ;
2022-03-02 16:59:09 -07:00
static const struct drm_crtc_state crtc_state = {
2018-05-03 13:22:17 +02:00
. crtc = ZERO_SIZE_PTR ,
. enable = true ,
. active = true ,
. mode = {
2022-07-08 17:30:48 -03:00
DRM_MODE ( " 1024x768 " , 0 , 65000 , 1024 , 1048 , 1184 , 1344 , 0 , 768 , 771 ,
777 , 806 , 0 , DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC )
2018-05-03 13:22:17 +02:00
} ,
} ;
2022-03-02 16:59:09 -07:00
static struct drm_plane plane = {
2021-12-02 10:49:49 +01:00
. dev = NULL
} ;
2022-03-02 16:59:09 -07:00
static struct drm_framebuffer fb = {
2018-05-03 13:22:17 +02:00
. width = 2048 ,
. height = 2048
} ;
2022-03-02 16:59:09 -07:00
static struct drm_plane_state plane_state = {
2021-12-02 10:49:49 +01:00
. plane = & plane ,
2018-05-03 13:22:17 +02:00
. crtc = ZERO_SIZE_PTR ,
. fb = & fb ,
. rotation = DRM_MODE_ROTATE_0
} ;
/* Simple clipping, no scaling. */
set_src ( & plane_state , 0 , 0 , fb . width < < 16 , fb . height < < 16 ) ;
set_crtc ( & plane_state , 0 , 0 , fb . width , fb . height ) ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Simple clipping check should pass \n " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0 , 0 , 1024 < < 16 , 768 < < 16 ) ) ;
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 0 , 0 , 1024 , 768 ) ) ;
2018-05-03 13:22:17 +02:00
/* Rotated clipping + reflection, no scaling. */
plane_state . rotation = DRM_MODE_ROTATE_90 | DRM_MODE_REFLECT_X ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Rotated clipping check should pass \n " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0 , 0 , 768 < < 16 , 1024 < < 16 ) ) ;
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 0 , 0 , 1024 , 768 ) ) ;
2018-05-03 13:22:17 +02:00
plane_state . rotation = DRM_MODE_ROTATE_0 ;
/* Check whether positioning works correctly. */
set_src ( & plane_state , 0 , 0 , 1023 < < 16 , 767 < < 16 ) ;
set_crtc ( & plane_state , 0 , 0 , 1023 , 767 ) ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_TRUE_MSG ( test , ret ,
" Should not be able to position on the crtc with can_position=false \n " ) ;
2018-05-03 13:22:17 +02:00
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
true , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Simple positioning should work \n " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0 , 0 , 1023 < < 16 , 767 < < 16 ) ) ;
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 0 , 0 , 1023 , 767 ) ) ;
2018-05-03 13:22:17 +02:00
/* Simple scaling tests. */
set_src ( & plane_state , 0 , 0 , 512 < < 16 , 384 < < 16 ) ;
set_crtc ( & plane_state , 0 , 0 , 1024 , 768 ) ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
0x8001 ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_TRUE_MSG ( test , ret , " Upscaling out of range should fail. \n " ) ;
2018-05-03 13:22:17 +02:00
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
0x8000 ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Upscaling exactly 2x should work \n " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0 , 0 , 512 < < 16 , 384 < < 16 ) ) ;
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 0 , 0 , 1024 , 768 ) ) ;
2018-05-03 13:22:17 +02:00
set_src ( & plane_state , 0 , 0 , 2048 < < 16 , 1536 < < 16 ) ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
0x1ffff , false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_TRUE_MSG ( test , ret , " Downscaling out of range should fail. \n " ) ;
2018-05-03 13:22:17 +02:00
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
0x20000 , false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Should succeed with exact scaling limit \n " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0 , 0 , 2048 < < 16 , 1536 < < 16 ) ) ;
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 0 , 0 , 1024 , 768 ) ) ;
2018-05-03 13:22:17 +02:00
/* Testing rounding errors. */
set_src ( & plane_state , 0 , 0 , 0x40001 , 0x40001 ) ;
set_crtc ( & plane_state , 1022 , 766 , 4 , 4 ) ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
0x10001 ,
true , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Should succeed by clipping to exact multiple " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0 , 0 , 2 < < 16 , 2 < < 16 ) ) ;
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 1022 , 766 , 2 , 2 ) ) ;
2018-05-03 13:22:17 +02:00
set_src ( & plane_state , 0x20001 , 0x20001 , 0x4040001 , 0x3040001 ) ;
set_crtc ( & plane_state , - 2 , - 2 , 1028 , 772 ) ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
0x10001 ,
false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Should succeed by clipping to exact multiple " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0x40002 , 0x40002 ,
2022-07-08 17:30:48 -03:00
1024 < < 16 , 768 < < 16 ) ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 0 , 0 , 1024 , 768 ) ) ;
2018-05-03 13:22:17 +02:00
set_src ( & plane_state , 0 , 0 , 0x3ffff , 0x3ffff ) ;
set_crtc ( & plane_state , 1022 , 766 , 4 , 4 ) ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
0xffff ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
true , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Should succeed by clipping to exact multiple " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2018-05-03 13:22:17 +02:00
/* Should not be rounded to 0x20001, which would be upscaling. */
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0 , 0 , 2 < < 16 , 2 < < 16 ) ) ;
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 1022 , 766 , 2 , 2 ) ) ;
2018-05-03 13:22:17 +02:00
set_src ( & plane_state , 0x1ffff , 0x1ffff , 0x403ffff , 0x303ffff ) ;
set_crtc ( & plane_state , - 2 , - 2 , 1028 , 772 ) ;
ret = drm_atomic_helper_check_plane_state ( & plane_state , & crtc_state ,
0xffff ,
2022-07-20 10:30:54 +02:00
DRM_PLANE_NO_SCALING ,
2018-05-03 13:22:17 +02:00
false , false ) ;
2022-07-08 17:30:48 -03:00
KUNIT_EXPECT_FALSE_MSG ( test , ret , 0 , " Should succeed by clipping to exact multiple " ) ;
KUNIT_EXPECT_TRUE ( test , plane_state . visible ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_src_eq ( test , & plane_state , 0x3fffe , 0x3fffe ,
2022-07-08 17:30:48 -03:00
1024 < < 16 , 768 < < 16 ) ) ;
2022-10-20 10:21:34 +02:00
KUNIT_EXPECT_TRUE ( test , check_crtc_eq ( test , & plane_state , 0 , 0 , 1024 , 768 ) ) ;
2018-05-03 13:22:17 +02:00
}
2022-07-08 17:30:48 -03:00
static struct kunit_case drm_plane_helper_test [ ] = {
2022-09-11 16:17:56 -03:00
KUNIT_CASE ( drm_test_check_plane_state ) ,
2022-07-08 17:30:48 -03:00
{ }
} ;
static struct kunit_suite drm_plane_helper_test_suite = {
. name = " drm_plane_helper " ,
. test_cases = drm_plane_helper_test ,
} ;
kunit_test_suite ( drm_plane_helper_test_suite ) ;
MODULE_LICENSE ( " GPL " ) ;