Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/selftests: Add drm_rect selftests

Add selftests for drm_rect. A few basic ones for clipped and unclipped
cases, and a few special ones for specific bugs we had in the code.

I'm too lazy to think of more corner cases to check at this time.
Maybe later.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191122175623.13565-5-ville.syrjala@linux.intel.com
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@st.com>

+238 -1
+2 -1
drivers/gpu/drm/selftests/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ 3 3 test-drm_format.o test-drm_framebuffer.o \ 4 - test-drm_damage_helper.o test-drm_dp_mst_helper.o 4 + test-drm_damage_helper.o test-drm_dp_mst_helper.o \ 5 + test-drm_rect.o 5 6 6 7 obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o test-drm_cmdline_parser.o
+4
drivers/gpu/drm/selftests/drm_modeset_selftests.h
··· 6 6 * 7 7 * Tests are executed in order by igt/drm_selftests_helper 8 8 */ 9 + selftest(drm_rect_clip_scaled_div_by_zero, igt_drm_rect_clip_scaled_div_by_zero) 10 + selftest(drm_rect_clip_scaled_not_clipped, igt_drm_rect_clip_scaled_not_clipped) 11 + selftest(drm_rect_clip_scaled_clipped, igt_drm_rect_clip_scaled_clipped) 12 + selftest(drm_rect_clip_scaled_signed_vs_unsigned, igt_drm_rect_clip_scaled_signed_vs_unsigned) 9 13 selftest(check_plane_state, igt_check_plane_state) 10 14 selftest(check_drm_format_block_width, igt_check_drm_format_block_width) 11 15 selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
+7
drivers/gpu/drm/selftests/test-drm_modeset_common.h
··· 3 3 #ifndef __TEST_DRM_MODESET_COMMON_H__ 4 4 #define __TEST_DRM_MODESET_COMMON_H__ 5 5 6 + #include <linux/errno.h> 7 + #include <linux/printk.h> 8 + 6 9 #define FAIL(test, msg, ...) \ 7 10 do { \ 8 11 if (test) { \ ··· 16 13 17 14 #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") 18 15 16 + int igt_drm_rect_clip_scaled_div_by_zero(void *ignored); 17 + int igt_drm_rect_clip_scaled_not_clipped(void *ignored); 18 + int igt_drm_rect_clip_scaled_clipped(void *ignored); 19 + int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored); 19 20 int igt_check_plane_state(void *ignored); 20 21 int igt_check_drm_format_block_width(void *ignored); 21 22 int igt_check_drm_format_block_height(void *ignored);
+223
drivers/gpu/drm/selftests/test-drm_rect.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Test cases for the drm_rect functions 4 + */ 5 + 6 + #define pr_fmt(fmt) "drm_rect: " fmt 7 + 8 + #include <linux/limits.h> 9 + 10 + #include <drm/drm_rect.h> 11 + 12 + #include "test-drm_modeset_common.h" 13 + 14 + int igt_drm_rect_clip_scaled_div_by_zero(void *ignored) 15 + { 16 + struct drm_rect src, dst, clip; 17 + bool visible; 18 + 19 + /* 20 + * Make sure we don't divide by zero when dst 21 + * width/height is zero and dst and clip do not intersect. 22 + */ 23 + drm_rect_init(&src, 0, 0, 0, 0); 24 + drm_rect_init(&dst, 0, 0, 0, 0); 25 + drm_rect_init(&clip, 1, 1, 1, 1); 26 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 27 + FAIL(visible, "Destination not be visible\n"); 28 + FAIL(drm_rect_visible(&src), "Source should not be visible\n"); 29 + 30 + drm_rect_init(&src, 0, 0, 0, 0); 31 + drm_rect_init(&dst, 3, 3, 0, 0); 32 + drm_rect_init(&clip, 1, 1, 1, 1); 33 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 34 + FAIL(visible, "Destination not be visible\n"); 35 + FAIL(drm_rect_visible(&src), "Source should not be visible\n"); 36 + 37 + return 0; 38 + } 39 + 40 + int igt_drm_rect_clip_scaled_not_clipped(void *ignored) 41 + { 42 + struct drm_rect src, dst, clip; 43 + bool visible; 44 + 45 + /* 1:1 scaling */ 46 + drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); 47 + drm_rect_init(&dst, 0, 0, 1, 1); 48 + drm_rect_init(&clip, 0, 0, 1, 1); 49 + 50 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 51 + 52 + FAIL(src.x1 != 0 || src.x2 != 1 << 16 || 53 + src.y1 != 0 || src.y2 != 1 << 16, 54 + "Source badly clipped\n"); 55 + FAIL(dst.x1 != 0 || dst.x2 != 1 || 56 + dst.y1 != 0 || dst.y2 != 1, 57 + "Destination badly clipped\n"); 58 + FAIL(!visible, "Destination should be visible\n"); 59 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 60 + 61 + /* 2:1 scaling */ 62 + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 63 + drm_rect_init(&dst, 0, 0, 1, 1); 64 + drm_rect_init(&clip, 0, 0, 1, 1); 65 + 66 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 67 + 68 + FAIL(src.x1 != 0 || src.x2 != 2 << 16 || 69 + src.y1 != 0 || src.y2 != 2 << 16, 70 + "Source badly clipped\n"); 71 + FAIL(dst.x1 != 0 || dst.x2 != 1 || 72 + dst.y1 != 0 || dst.y2 != 1, 73 + "Destination badly clipped\n"); 74 + FAIL(!visible, "Destination should be visible\n"); 75 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 76 + 77 + /* 1:2 scaling */ 78 + drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); 79 + drm_rect_init(&dst, 0, 0, 2, 2); 80 + drm_rect_init(&clip, 0, 0, 2, 2); 81 + 82 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 83 + 84 + FAIL(src.x1 != 0 || src.x2 != 1 << 16 || 85 + src.y1 != 0 || src.y2 != 1 << 16, 86 + "Source badly clipped\n"); 87 + FAIL(dst.x1 != 0 || dst.x2 != 2 || 88 + dst.y1 != 0 || dst.y2 != 2, 89 + "Destination badly clipped\n"); 90 + FAIL(!visible, "Destination should be visible\n"); 91 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 92 + 93 + return 0; 94 + } 95 + 96 + int igt_drm_rect_clip_scaled_clipped(void *ignored) 97 + { 98 + struct drm_rect src, dst, clip; 99 + bool visible; 100 + 101 + /* 1:1 scaling top/left clip */ 102 + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 103 + drm_rect_init(&dst, 0, 0, 2, 2); 104 + drm_rect_init(&clip, 0, 0, 1, 1); 105 + 106 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 107 + 108 + FAIL(src.x1 != 0 || src.x2 != 1 << 16 || 109 + src.y1 != 0 || src.y2 != 1 << 16, 110 + "Source badly clipped\n"); 111 + FAIL(dst.x1 != 0 || dst.x2 != 1 || 112 + dst.y1 != 0 || dst.y2 != 1, 113 + "Destination badly clipped\n"); 114 + FAIL(!visible, "Destination should be visible\n"); 115 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 116 + 117 + /* 1:1 scaling bottom/right clip */ 118 + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 119 + drm_rect_init(&dst, 0, 0, 2, 2); 120 + drm_rect_init(&clip, 1, 1, 1, 1); 121 + 122 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 123 + 124 + FAIL(src.x1 != 1 << 16 || src.x2 != 2 << 16 || 125 + src.y1 != 1 << 16 || src.y2 != 2 << 16, 126 + "Source badly clipped\n"); 127 + FAIL(dst.x1 != 1 || dst.x2 != 2 || 128 + dst.y1 != 1 || dst.y2 != 2, 129 + "Destination badly clipped\n"); 130 + FAIL(!visible, "Destination should be visible\n"); 131 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 132 + 133 + /* 2:1 scaling top/left clip */ 134 + drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); 135 + drm_rect_init(&dst, 0, 0, 2, 2); 136 + drm_rect_init(&clip, 0, 0, 1, 1); 137 + 138 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 139 + 140 + FAIL(src.x1 != 0 || src.x2 != 2 << 16 || 141 + src.y1 != 0 || src.y2 != 2 << 16, 142 + "Source badly clipped\n"); 143 + FAIL(dst.x1 != 0 || dst.x2 != 1 || 144 + dst.y1 != 0 || dst.y2 != 1, 145 + "Destination badly clipped\n"); 146 + FAIL(!visible, "Destination should be visible\n"); 147 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 148 + 149 + /* 2:1 scaling bottom/right clip */ 150 + drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); 151 + drm_rect_init(&dst, 0, 0, 2, 2); 152 + drm_rect_init(&clip, 1, 1, 1, 1); 153 + 154 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 155 + 156 + FAIL(src.x1 != 2 << 16 || src.x2 != 4 << 16 || 157 + src.y1 != 2 << 16 || src.y2 != 4 << 16, 158 + "Source badly clipped\n"); 159 + FAIL(dst.x1 != 1 || dst.x2 != 2 || 160 + dst.y1 != 1 || dst.y2 != 2, 161 + "Destination badly clipped\n"); 162 + FAIL(!visible, "Destination should be visible\n"); 163 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 164 + 165 + /* 1:2 scaling top/left clip */ 166 + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 167 + drm_rect_init(&dst, 0, 0, 4, 4); 168 + drm_rect_init(&clip, 0, 0, 2, 2); 169 + 170 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 171 + 172 + FAIL(src.x1 != 0 || src.x2 != 1 << 16 || 173 + src.y1 != 0 || src.y2 != 1 << 16, 174 + "Source badly clipped\n"); 175 + FAIL(dst.x1 != 0 || dst.x2 != 2 || 176 + dst.y1 != 0 || dst.y2 != 2, 177 + "Destination badly clipped\n"); 178 + FAIL(!visible, "Destination should be visible\n"); 179 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 180 + 181 + /* 1:2 scaling bottom/right clip */ 182 + drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 183 + drm_rect_init(&dst, 0, 0, 4, 4); 184 + drm_rect_init(&clip, 2, 2, 2, 2); 185 + 186 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 187 + 188 + FAIL(src.x1 != 1 << 16 || src.x2 != 2 << 16 || 189 + src.y1 != 1 << 16 || src.y2 != 2 << 16, 190 + "Source badly clipped\n"); 191 + FAIL(dst.x1 != 2 || dst.x2 != 4 || 192 + dst.y1 != 2 || dst.y2 != 4, 193 + "Destination badly clipped\n"); 194 + FAIL(!visible, "Destination should be visible\n"); 195 + FAIL(!drm_rect_visible(&src), "Source should be visible\n"); 196 + 197 + return 0; 198 + } 199 + 200 + int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored) 201 + { 202 + struct drm_rect src, dst, clip; 203 + bool visible; 204 + 205 + /* 206 + * 'clip.x2 - dst.x1 >= dst width' could result a negative 207 + * src rectangle width which is no longer expected by the 208 + * code as it's using unsigned types. This could lead to 209 + * the clipped source rectangle appering visible when it 210 + * should have been fully clipped. Make sure both rectangles 211 + * end up invisible. 212 + */ 213 + drm_rect_init(&src, 0, 0, INT_MAX, INT_MAX); 214 + drm_rect_init(&dst, 0, 0, 2, 2); 215 + drm_rect_init(&clip, 3, 3, 1, 1); 216 + 217 + visible = drm_rect_clip_scaled(&src, &dst, &clip); 218 + 219 + FAIL(visible, "Destination should not be visible\n"); 220 + FAIL(drm_rect_visible(&src), "Source should not be visible\n"); 221 + 222 + return 0; 223 + }
+2
include/drm/drm_rect.h
··· 24 24 #ifndef DRM_RECT_H 25 25 #define DRM_RECT_H 26 26 27 + #include <linux/types.h> 28 + 27 29 /** 28 30 * DOC: rect utils 29 31 *