root/drivers/gpu/drm/selftests/test-drm_plane_helper.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_src
  2. check_src_eq
  3. set_crtc
  4. check_crtc_eq
  5. igt_check_plane_state

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Test cases for the drm_plane_helper functions
   4  */
   5 
   6 #define pr_fmt(fmt) "drm_plane_helper: " fmt
   7 
   8 #include <drm/drm_atomic_helper.h>
   9 #include <drm/drm_plane_helper.h>
  10 #include <drm/drm_modes.h>
  11 
  12 #include "test-drm_modeset_common.h"
  13 
  14 static void set_src(struct drm_plane_state *plane_state,
  15                     unsigned src_x, unsigned src_y,
  16                     unsigned src_w, unsigned src_h)
  17 {
  18         plane_state->src_x = src_x;
  19         plane_state->src_y = src_y;
  20         plane_state->src_w = src_w;
  21         plane_state->src_h = src_h;
  22 }
  23 
  24 static bool check_src_eq(struct drm_plane_state *plane_state,
  25                          unsigned src_x, unsigned src_y,
  26                          unsigned src_w, unsigned src_h)
  27 {
  28         if (plane_state->src.x1 < 0) {
  29                 pr_err("src x coordinate %x should never be below 0.\n", plane_state->src.x1);
  30                 drm_rect_debug_print("src: ", &plane_state->src, true);
  31                 return false;
  32         }
  33         if (plane_state->src.y1 < 0) {
  34                 pr_err("src y coordinate %x should never be below 0.\n", plane_state->src.y1);
  35                 drm_rect_debug_print("src: ", &plane_state->src, true);
  36                 return false;
  37         }
  38 
  39         if (plane_state->src.x1 != src_x ||
  40             plane_state->src.y1 != src_y ||
  41             drm_rect_width(&plane_state->src) != src_w ||
  42             drm_rect_height(&plane_state->src) != src_h) {
  43                 drm_rect_debug_print("src: ", &plane_state->src, true);
  44                 return false;
  45         }
  46 
  47         return true;
  48 }
  49 
  50 static void set_crtc(struct drm_plane_state *plane_state,
  51                      int crtc_x, int crtc_y,
  52                      unsigned crtc_w, unsigned crtc_h)
  53 {
  54         plane_state->crtc_x = crtc_x;
  55         plane_state->crtc_y = crtc_y;
  56         plane_state->crtc_w = crtc_w;
  57         plane_state->crtc_h = crtc_h;
  58 }
  59 
  60 static bool check_crtc_eq(struct drm_plane_state *plane_state,
  61                           int crtc_x, int crtc_y,
  62                           unsigned crtc_w, unsigned crtc_h)
  63 {
  64         if (plane_state->dst.x1 != crtc_x ||
  65             plane_state->dst.y1 != crtc_y ||
  66             drm_rect_width(&plane_state->dst) != crtc_w ||
  67             drm_rect_height(&plane_state->dst) != crtc_h) {
  68                 drm_rect_debug_print("dst: ", &plane_state->dst, false);
  69 
  70                 return false;
  71         }
  72 
  73         return true;
  74 }
  75 
  76 int igt_check_plane_state(void *ignored)
  77 {
  78         int ret;
  79 
  80         const struct drm_crtc_state crtc_state = {
  81                 .crtc = ZERO_SIZE_PTR,
  82                 .enable = true,
  83                 .active = true,
  84                 .mode = {
  85                         DRM_MODE("1024x768", 0, 65000, 1024, 1048,
  86                                 1184, 1344, 0, 768, 771, 777, 806, 0,
  87                                 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
  88                 },
  89         };
  90         struct drm_framebuffer fb = {
  91                 .width = 2048,
  92                 .height = 2048
  93         };
  94         struct drm_plane_state plane_state = {
  95                 .crtc = ZERO_SIZE_PTR,
  96                 .fb = &fb,
  97                 .rotation = DRM_MODE_ROTATE_0
  98         };
  99 
 100         /* Simple clipping, no scaling. */
 101         set_src(&plane_state, 0, 0, fb.width << 16, fb.height << 16);
 102         set_crtc(&plane_state, 0, 0, fb.width, fb.height);
 103         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 104                                                   DRM_PLANE_HELPER_NO_SCALING,
 105                                                   DRM_PLANE_HELPER_NO_SCALING,
 106                                                   false, false);
 107         FAIL(ret < 0, "Simple clipping check should pass\n");
 108         FAIL_ON(!plane_state.visible);
 109         FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1024 << 16, 768 << 16));
 110         FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
 111 
 112         /* Rotated clipping + reflection, no scaling. */
 113         plane_state.rotation = DRM_MODE_ROTATE_90 | DRM_MODE_REFLECT_X;
 114         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 115                                                   DRM_PLANE_HELPER_NO_SCALING,
 116                                                   DRM_PLANE_HELPER_NO_SCALING,
 117                                                   false, false);
 118         FAIL(ret < 0, "Rotated clipping check should pass\n");
 119         FAIL_ON(!plane_state.visible);
 120         FAIL_ON(!check_src_eq(&plane_state, 0, 0, 768 << 16, 1024 << 16));
 121         FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
 122         plane_state.rotation = DRM_MODE_ROTATE_0;
 123 
 124         /* Check whether positioning works correctly. */
 125         set_src(&plane_state, 0, 0, 1023 << 16, 767 << 16);
 126         set_crtc(&plane_state, 0, 0, 1023, 767);
 127         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 128                                                   DRM_PLANE_HELPER_NO_SCALING,
 129                                                   DRM_PLANE_HELPER_NO_SCALING,
 130                                                   false, false);
 131         FAIL(!ret, "Should not be able to position on the crtc with can_position=false\n");
 132 
 133         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 134                                                   DRM_PLANE_HELPER_NO_SCALING,
 135                                                   DRM_PLANE_HELPER_NO_SCALING,
 136                                                   true, false);
 137         FAIL(ret < 0, "Simple positioning should work\n");
 138         FAIL_ON(!plane_state.visible);
 139         FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1023 << 16, 767 << 16));
 140         FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1023, 767));
 141 
 142         /* Simple scaling tests. */
 143         set_src(&plane_state, 0, 0, 512 << 16, 384 << 16);
 144         set_crtc(&plane_state, 0, 0, 1024, 768);
 145         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 146                                                   0x8001,
 147                                                   DRM_PLANE_HELPER_NO_SCALING,
 148                                                   false, false);
 149         FAIL(!ret, "Upscaling out of range should fail.\n");
 150         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 151                                                   0x8000,
 152                                                   DRM_PLANE_HELPER_NO_SCALING,
 153                                                   false, false);
 154         FAIL(ret < 0, "Upscaling exactly 2x should work\n");
 155         FAIL_ON(!plane_state.visible);
 156         FAIL_ON(!check_src_eq(&plane_state, 0, 0, 512 << 16, 384 << 16));
 157         FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
 158 
 159         set_src(&plane_state, 0, 0, 2048 << 16, 1536 << 16);
 160         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 161                                                   DRM_PLANE_HELPER_NO_SCALING,
 162                                                   0x1ffff, false, false);
 163         FAIL(!ret, "Downscaling out of range should fail.\n");
 164         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 165                                                   DRM_PLANE_HELPER_NO_SCALING,
 166                                                   0x20000, false, false);
 167         FAIL(ret < 0, "Should succeed with exact scaling limit\n");
 168         FAIL_ON(!plane_state.visible);
 169         FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2048 << 16, 1536 << 16));
 170         FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
 171 
 172         /* Testing rounding errors. */
 173         set_src(&plane_state, 0, 0, 0x40001, 0x40001);
 174         set_crtc(&plane_state, 1022, 766, 4, 4);
 175         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 176                                                   DRM_PLANE_HELPER_NO_SCALING,
 177                                                   0x10001,
 178                                                   true, false);
 179         FAIL(ret < 0, "Should succeed by clipping to exact multiple");
 180         FAIL_ON(!plane_state.visible);
 181         FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16));
 182         FAIL_ON(!check_crtc_eq(&plane_state, 1022, 766, 2, 2));
 183 
 184         set_src(&plane_state, 0x20001, 0x20001, 0x4040001, 0x3040001);
 185         set_crtc(&plane_state, -2, -2, 1028, 772);
 186         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 187                                                   DRM_PLANE_HELPER_NO_SCALING,
 188                                                   0x10001,
 189                                                   false, false);
 190         FAIL(ret < 0, "Should succeed by clipping to exact multiple");
 191         FAIL_ON(!plane_state.visible);
 192         FAIL_ON(!check_src_eq(&plane_state, 0x40002, 0x40002, 1024 << 16, 768 << 16));
 193         FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
 194 
 195         set_src(&plane_state, 0, 0, 0x3ffff, 0x3ffff);
 196         set_crtc(&plane_state, 1022, 766, 4, 4);
 197         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 198                                                   0xffff,
 199                                                   DRM_PLANE_HELPER_NO_SCALING,
 200                                                   true, false);
 201         FAIL(ret < 0, "Should succeed by clipping to exact multiple");
 202         FAIL_ON(!plane_state.visible);
 203         /* Should not be rounded to 0x20001, which would be upscaling. */
 204         FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16));
 205         FAIL_ON(!check_crtc_eq(&plane_state, 1022, 766, 2, 2));
 206 
 207         set_src(&plane_state, 0x1ffff, 0x1ffff, 0x403ffff, 0x303ffff);
 208         set_crtc(&plane_state, -2, -2, 1028, 772);
 209         ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
 210                                                   0xffff,
 211                                                   DRM_PLANE_HELPER_NO_SCALING,
 212                                                   false, false);
 213         FAIL(ret < 0, "Should succeed by clipping to exact multiple");
 214         FAIL_ON(!plane_state.visible);
 215         FAIL_ON(!check_src_eq(&plane_state, 0x3fffe, 0x3fffe, 1024 << 16, 768 << 16));
 216         FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768));
 217 
 218         return 0;
 219 }

/* [<][>][^][v][top][bottom][index][help] */