Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Test cases for the drm_plane_helper functions
0004  */
0005 
0006 #define pr_fmt(fmt) "drm_plane_helper: " fmt
0007 
0008 #include <drm/drm_atomic_helper.h>
0009 #include <drm/drm_framebuffer.h>
0010 #include <drm/drm_plane_helper.h>
0011 #include <drm/drm_modes.h>
0012 
0013 #include "test-drm_modeset_common.h"
0014 
0015 static void set_src(struct drm_plane_state *plane_state,
0016             unsigned src_x, unsigned src_y,
0017             unsigned src_w, unsigned src_h)
0018 {
0019     plane_state->src_x = src_x;
0020     plane_state->src_y = src_y;
0021     plane_state->src_w = src_w;
0022     plane_state->src_h = src_h;
0023 }
0024 
0025 static bool check_src_eq(struct drm_plane_state *plane_state,
0026              unsigned src_x, unsigned src_y,
0027              unsigned src_w, unsigned src_h)
0028 {
0029     if (plane_state->src.x1 < 0) {
0030         pr_err("src x coordinate %x should never be below 0.\n", plane_state->src.x1);
0031         drm_rect_debug_print("src: ", &plane_state->src, true);
0032         return false;
0033     }
0034     if (plane_state->src.y1 < 0) {
0035         pr_err("src y coordinate %x should never be below 0.\n", plane_state->src.y1);
0036         drm_rect_debug_print("src: ", &plane_state->src, true);
0037         return false;
0038     }
0039 
0040     if (plane_state->src.x1 != src_x ||
0041         plane_state->src.y1 != src_y ||
0042         drm_rect_width(&plane_state->src) != src_w ||
0043         drm_rect_height(&plane_state->src) != src_h) {
0044         drm_rect_debug_print("src: ", &plane_state->src, true);
0045         return false;
0046     }
0047 
0048     return true;
0049 }
0050 
0051 static void set_crtc(struct drm_plane_state *plane_state,
0052              int crtc_x, int crtc_y,
0053              unsigned crtc_w, unsigned crtc_h)
0054 {
0055     plane_state->crtc_x = crtc_x;
0056     plane_state->crtc_y = crtc_y;
0057     plane_state->crtc_w = crtc_w;
0058     plane_state->crtc_h = crtc_h;
0059 }
0060 
0061 static bool check_crtc_eq(struct drm_plane_state *plane_state,
0062               int crtc_x, int crtc_y,
0063               unsigned crtc_w, unsigned crtc_h)
0064 {
0065     if (plane_state->dst.x1 != crtc_x ||
0066         plane_state->dst.y1 != crtc_y ||
0067         drm_rect_width(&plane_state->dst) != crtc_w ||
0068         drm_rect_height(&plane_state->dst) != crtc_h) {
0069         drm_rect_debug_print("dst: ", &plane_state->dst, false);
0070 
0071         return false;
0072     }
0073 
0074     return true;
0075 }
0076 
0077 int igt_check_plane_state(void *ignored)
0078 {
0079     int ret;
0080 
0081     static const struct drm_crtc_state crtc_state = {
0082         .crtc = ZERO_SIZE_PTR,
0083         .enable = true,
0084         .active = true,
0085         .mode = {
0086             DRM_MODE("1024x768", 0, 65000, 1024, 1048,
0087                 1184, 1344, 0, 768, 771, 777, 806, 0,
0088                 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
0089         },
0090     };
0091     static struct drm_plane plane = {
0092         .dev = NULL
0093     };
0094     static struct drm_framebuffer fb = {
0095         .width = 2048,
0096         .height = 2048
0097     };
0098     static struct drm_plane_state plane_state = {
0099         .plane = &plane,
0100         .crtc = ZERO_SIZE_PTR,
0101         .fb = &fb,
0102         .rotation = DRM_MODE_ROTATE_0
0103     };
0104 
0105     /* Simple clipping, no scaling. */
0106     set_src(&plane_state, 0, 0, fb.width << 16, fb.height << 16);
0107     set_crtc(&plane_state, 0, 0, fb.width, fb.height);
0108     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0109                           DRM_PLANE_HELPER_NO_SCALING,
0110                           DRM_PLANE_HELPER_NO_SCALING,
0111                           false, false);
0112     FAIL(ret < 0, "Simple clipping check should pass\n");
0113     FAIL_ON(!plane_state.visible);
0114     FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1024 << 16, 768 << 16));
0115     FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
0116 
0117     /* Rotated clipping + reflection, no scaling. */
0118     plane_state.rotation = DRM_MODE_ROTATE_90 | DRM_MODE_REFLECT_X;
0119     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0120                           DRM_PLANE_HELPER_NO_SCALING,
0121                           DRM_PLANE_HELPER_NO_SCALING,
0122                           false, false);
0123     FAIL(ret < 0, "Rotated clipping check should pass\n");
0124     FAIL_ON(!plane_state.visible);
0125     FAIL_ON(!check_src_eq(&plane_state, 0, 0, 768 << 16, 1024 << 16));
0126     FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
0127     plane_state.rotation = DRM_MODE_ROTATE_0;
0128 
0129     /* Check whether positioning works correctly. */
0130     set_src(&plane_state, 0, 0, 1023 << 16, 767 << 16);
0131     set_crtc(&plane_state, 0, 0, 1023, 767);
0132     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0133                           DRM_PLANE_HELPER_NO_SCALING,
0134                           DRM_PLANE_HELPER_NO_SCALING,
0135                           false, false);
0136     FAIL(!ret, "Should not be able to position on the crtc with can_position=false\n");
0137 
0138     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0139                           DRM_PLANE_HELPER_NO_SCALING,
0140                           DRM_PLANE_HELPER_NO_SCALING,
0141                           true, false);
0142     FAIL(ret < 0, "Simple positioning should work\n");
0143     FAIL_ON(!plane_state.visible);
0144     FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1023 << 16, 767 << 16));
0145     FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1023, 767));
0146 
0147     /* Simple scaling tests. */
0148     set_src(&plane_state, 0, 0, 512 << 16, 384 << 16);
0149     set_crtc(&plane_state, 0, 0, 1024, 768);
0150     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0151                           0x8001,
0152                           DRM_PLANE_HELPER_NO_SCALING,
0153                           false, false);
0154     FAIL(!ret, "Upscaling out of range should fail.\n");
0155     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0156                           0x8000,
0157                           DRM_PLANE_HELPER_NO_SCALING,
0158                           false, false);
0159     FAIL(ret < 0, "Upscaling exactly 2x should work\n");
0160     FAIL_ON(!plane_state.visible);
0161     FAIL_ON(!check_src_eq(&plane_state, 0, 0, 512 << 16, 384 << 16));
0162     FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
0163 
0164     set_src(&plane_state, 0, 0, 2048 << 16, 1536 << 16);
0165     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0166                           DRM_PLANE_HELPER_NO_SCALING,
0167                           0x1ffff, false, false);
0168     FAIL(!ret, "Downscaling out of range should fail.\n");
0169     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0170                           DRM_PLANE_HELPER_NO_SCALING,
0171                           0x20000, false, false);
0172     FAIL(ret < 0, "Should succeed with exact scaling limit\n");
0173     FAIL_ON(!plane_state.visible);
0174     FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2048 << 16, 1536 << 16));
0175     FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
0176 
0177     /* Testing rounding errors. */
0178     set_src(&plane_state, 0, 0, 0x40001, 0x40001);
0179     set_crtc(&plane_state, 1022, 766, 4, 4);
0180     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0181                           DRM_PLANE_HELPER_NO_SCALING,
0182                           0x10001,
0183                           true, false);
0184     FAIL(ret < 0, "Should succeed by clipping to exact multiple");
0185     FAIL_ON(!plane_state.visible);
0186     FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16));
0187     FAIL_ON(!check_crtc_eq(&plane_state, 1022, 766, 2, 2));
0188 
0189     set_src(&plane_state, 0x20001, 0x20001, 0x4040001, 0x3040001);
0190     set_crtc(&plane_state, -2, -2, 1028, 772);
0191     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0192                           DRM_PLANE_HELPER_NO_SCALING,
0193                           0x10001,
0194                           false, false);
0195     FAIL(ret < 0, "Should succeed by clipping to exact multiple");
0196     FAIL_ON(!plane_state.visible);
0197     FAIL_ON(!check_src_eq(&plane_state, 0x40002, 0x40002, 1024 << 16, 768 << 16));
0198     FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
0199 
0200     set_src(&plane_state, 0, 0, 0x3ffff, 0x3ffff);
0201     set_crtc(&plane_state, 1022, 766, 4, 4);
0202     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0203                           0xffff,
0204                           DRM_PLANE_HELPER_NO_SCALING,
0205                           true, false);
0206     FAIL(ret < 0, "Should succeed by clipping to exact multiple");
0207     FAIL_ON(!plane_state.visible);
0208     /* Should not be rounded to 0x20001, which would be upscaling. */
0209     FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16));
0210     FAIL_ON(!check_crtc_eq(&plane_state, 1022, 766, 2, 2));
0211 
0212     set_src(&plane_state, 0x1ffff, 0x1ffff, 0x403ffff, 0x303ffff);
0213     set_crtc(&plane_state, -2, -2, 1028, 772);
0214     ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
0215                           0xffff,
0216                           DRM_PLANE_HELPER_NO_SCALING,
0217                           false, false);
0218     FAIL(ret < 0, "Should succeed by clipping to exact multiple");
0219     FAIL_ON(!plane_state.visible);
0220     FAIL_ON(!check_src_eq(&plane_state, 0x3fffe, 0x3fffe, 1024 << 16, 768 << 16));
0221     FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
0222 
0223     return 0;
0224 }