1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Test cases for the drm_framebuffer functions |
4 | * |
5 | * Copyright (c) 2022 MaĆra Canal <mairacanal@riseup.net> |
6 | */ |
7 | |
8 | #include <kunit/test.h> |
9 | |
10 | #include <drm/drm_device.h> |
11 | #include <drm/drm_mode.h> |
12 | #include <drm/drm_fourcc.h> |
13 | #include <drm/drm_print.h> |
14 | |
15 | #include "../drm_crtc_internal.h" |
16 | |
17 | #define MIN_WIDTH 4 |
18 | #define MAX_WIDTH 4096 |
19 | #define MIN_HEIGHT 4 |
20 | #define MAX_HEIGHT 4096 |
21 | |
22 | struct drm_framebuffer_test { |
23 | int buffer_created; |
24 | struct drm_mode_fb_cmd2 cmd; |
25 | const char *name; |
26 | }; |
27 | |
28 | static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { |
29 | { .buffer_created = 1, .name = "ABGR8888 normal sizes" , |
30 | .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_ABGR8888, |
31 | .handles = { 1, 0, 0 }, .pitches = { 4 * 600, 0, 0 }, |
32 | } |
33 | }, |
34 | { .buffer_created = 1, .name = "ABGR8888 max sizes" , |
35 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
36 | .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, |
37 | } |
38 | }, |
39 | { .buffer_created = 1, .name = "ABGR8888 pitch greater than min required" , |
40 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
41 | .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH + 1, 0, 0 }, |
42 | } |
43 | }, |
44 | { .buffer_created = 0, .name = "ABGR8888 pitch less than min required" , |
45 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
46 | .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH - 1, 0, 0 }, |
47 | } |
48 | }, |
49 | { .buffer_created = 0, .name = "ABGR8888 Invalid width" , |
50 | .cmd = { .width = MAX_WIDTH + 1, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
51 | .handles = { 1, 0, 0 }, .pitches = { 4 * (MAX_WIDTH + 1), 0, 0 }, |
52 | } |
53 | }, |
54 | { .buffer_created = 0, .name = "ABGR8888 Invalid buffer handle" , |
55 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
56 | .handles = { 0, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, |
57 | } |
58 | }, |
59 | { .buffer_created = 0, .name = "No pixel format" , |
60 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = 0, |
61 | .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, |
62 | } |
63 | }, |
64 | { .buffer_created = 0, .name = "ABGR8888 Width 0" , |
65 | .cmd = { .width = 0, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
66 | .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, |
67 | } |
68 | }, |
69 | { .buffer_created = 0, .name = "ABGR8888 Height 0" , |
70 | .cmd = { .width = MAX_WIDTH, .height = 0, .pixel_format = DRM_FORMAT_ABGR8888, |
71 | .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, |
72 | } |
73 | }, |
74 | { .buffer_created = 0, .name = "ABGR8888 Out of bound height * pitch combination" , |
75 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
76 | .handles = { 1, 0, 0 }, .offsets = { UINT_MAX - 1, 0, 0 }, |
77 | .pitches = { 4 * MAX_WIDTH, 0, 0 }, |
78 | } |
79 | }, |
80 | { .buffer_created = 1, .name = "ABGR8888 Large buffer offset" , |
81 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
82 | .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, |
83 | .pitches = { 4 * MAX_WIDTH, 0, 0 }, |
84 | } |
85 | }, |
86 | { .buffer_created = 1, .name = "ABGR8888 Set DRM_MODE_FB_MODIFIERS without modifiers" , |
87 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
88 | .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, |
89 | .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
90 | } |
91 | }, |
92 | { .buffer_created = 1, .name = "ABGR8888 Valid buffer modifier" , |
93 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
94 | .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, |
95 | .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
96 | .modifier = { AFBC_FORMAT_MOD_YTR, 0, 0 }, |
97 | } |
98 | }, |
99 | { .buffer_created = 0, |
100 | .name = "ABGR8888 Invalid buffer modifier(DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)" , |
101 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
102 | .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, |
103 | .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
104 | .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 }, |
105 | } |
106 | }, |
107 | { .buffer_created = 1, .name = "ABGR8888 Extra pitches without DRM_MODE_FB_MODIFIERS" , |
108 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
109 | .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, |
110 | .pitches = { 4 * MAX_WIDTH, 4 * MAX_WIDTH, 0 }, |
111 | } |
112 | }, |
113 | { .buffer_created = 0, .name = "ABGR8888 Extra pitches with DRM_MODE_FB_MODIFIERS" , |
114 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, |
115 | .handles = { 1, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
116 | .pitches = { 4 * MAX_WIDTH, 4 * MAX_WIDTH, 0 }, |
117 | } |
118 | }, |
119 | { .buffer_created = 1, .name = "NV12 Normal sizes" , |
120 | .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_NV12, |
121 | .handles = { 1, 1, 0 }, .pitches = { 600, 600, 0 }, |
122 | } |
123 | }, |
124 | { .buffer_created = 1, .name = "NV12 Max sizes" , |
125 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, |
126 | .handles = { 1, 1, 0 }, .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, |
127 | } |
128 | }, |
129 | { .buffer_created = 0, .name = "NV12 Invalid pitch" , |
130 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, |
131 | .handles = { 1, 1, 0 }, .pitches = { MAX_WIDTH, MAX_WIDTH - 1, 0 }, |
132 | } |
133 | }, |
134 | { .buffer_created = 0, .name = "NV12 Invalid modifier/missing DRM_MODE_FB_MODIFIERS flag" , |
135 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, |
136 | .handles = { 1, 1, 0 }, .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 }, |
137 | .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, |
138 | } |
139 | }, |
140 | { .buffer_created = 0, .name = "NV12 different modifier per-plane" , |
141 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, |
142 | .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
143 | .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 }, |
144 | .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, |
145 | } |
146 | }, |
147 | { .buffer_created = 1, .name = "NV12 with DRM_FORMAT_MOD_SAMSUNG_64_32_TILE" , |
148 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, |
149 | .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
150 | .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, |
151 | DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0 }, |
152 | .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, |
153 | } |
154 | }, |
155 | { .buffer_created = 0, .name = "NV12 Valid modifiers without DRM_MODE_FB_MODIFIERS" , |
156 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, |
157 | .handles = { 1, 1, 0 }, .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, |
158 | DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0 }, |
159 | .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, |
160 | } |
161 | }, |
162 | { .buffer_created = 0, .name = "NV12 Modifier for inexistent plane" , |
163 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, |
164 | .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
165 | .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, |
166 | DRM_FORMAT_MOD_SAMSUNG_64_32_TILE }, |
167 | .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, |
168 | } |
169 | }, |
170 | { .buffer_created = 0, .name = "NV12 Handle for inexistent plane" , |
171 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, |
172 | .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, |
173 | .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, |
174 | } |
175 | }, |
176 | { .buffer_created = 1, .name = "NV12 Handle for inexistent plane without DRM_MODE_FB_MODIFIERS" , |
177 | .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_NV12, |
178 | .handles = { 1, 1, 1 }, .pitches = { 600, 600, 600 }, |
179 | } |
180 | }, |
181 | { .buffer_created = 1, .name = "YVU420 DRM_MODE_FB_MODIFIERS set without modifier" , |
182 | .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_YVU420, |
183 | .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, |
184 | .pitches = { 600, 300, 300 }, |
185 | } |
186 | }, |
187 | { .buffer_created = 1, .name = "YVU420 Normal sizes" , |
188 | .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_YVU420, |
189 | .handles = { 1, 1, 1 }, .pitches = { 600, 300, 300 }, |
190 | } |
191 | }, |
192 | { .buffer_created = 1, .name = "YVU420 Max sizes" , |
193 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
194 | .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), |
195 | DIV_ROUND_UP(MAX_WIDTH, 2) }, |
196 | } |
197 | }, |
198 | { .buffer_created = 0, .name = "YVU420 Invalid pitch" , |
199 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
200 | .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) - 1, |
201 | DIV_ROUND_UP(MAX_WIDTH, 2) }, |
202 | } |
203 | }, |
204 | { .buffer_created = 1, .name = "YVU420 Different pitches" , |
205 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
206 | .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) + 1, |
207 | DIV_ROUND_UP(MAX_WIDTH, 2) + 7 }, |
208 | } |
209 | }, |
210 | { .buffer_created = 1, .name = "YVU420 Different buffer offsets/pitches" , |
211 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
212 | .handles = { 1, 1, 1 }, .offsets = { MAX_WIDTH, MAX_WIDTH + |
213 | MAX_WIDTH * MAX_HEIGHT, MAX_WIDTH + 2 * MAX_WIDTH * MAX_HEIGHT }, |
214 | .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) + 1, |
215 | DIV_ROUND_UP(MAX_WIDTH, 2) + 7 }, |
216 | } |
217 | }, |
218 | { .buffer_created = 0, |
219 | .name = "YVU420 Modifier set just for plane 0, without DRM_MODE_FB_MODIFIERS" , |
220 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
221 | .handles = { 1, 1, 1 }, .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 }, |
222 | .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, |
223 | } |
224 | }, |
225 | { .buffer_created = 0, |
226 | .name = "YVU420 Modifier set just for planes 0, 1, without DRM_MODE_FB_MODIFIERS" , |
227 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
228 | .handles = { 1, 1, 1 }, |
229 | .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 }, |
230 | .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, |
231 | } |
232 | }, |
233 | { .buffer_created = 0, |
234 | .name = "YVU420 Modifier set just for plane 0, 1, with DRM_MODE_FB_MODIFIERS" , |
235 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
236 | .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, |
237 | .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 }, |
238 | .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, |
239 | } |
240 | }, |
241 | { .buffer_created = 1, .name = "YVU420 Valid modifier" , |
242 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
243 | .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, |
244 | .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, |
245 | AFBC_FORMAT_MOD_SPARSE }, |
246 | .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, |
247 | } |
248 | }, |
249 | { .buffer_created = 0, .name = "YVU420 Different modifiers per plane" , |
250 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
251 | .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, |
252 | .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE | AFBC_FORMAT_MOD_YTR, |
253 | AFBC_FORMAT_MOD_SPARSE }, |
254 | .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, |
255 | } |
256 | }, |
257 | { .buffer_created = 0, .name = "YVU420 Modifier for inexistent plane" , |
258 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, |
259 | .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, |
260 | .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, |
261 | AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE }, |
262 | .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, |
263 | } |
264 | }, |
265 | { .buffer_created = 1, .name = "X0L2 Normal sizes" , |
266 | .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_X0L2, |
267 | .handles = { 1, 0, 0 }, .pitches = { 1200, 0, 0 } |
268 | } |
269 | }, |
270 | { .buffer_created = 1, .name = "X0L2 Max sizes" , |
271 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, |
272 | .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH, 0, 0 } |
273 | } |
274 | }, |
275 | { .buffer_created = 0, .name = "X0L2 Invalid pitch" , |
276 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, |
277 | .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH - 1, 0, 0 } |
278 | } |
279 | }, |
280 | { .buffer_created = 1, .name = "X0L2 Pitch greater than minimum required" , |
281 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, |
282 | .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 } |
283 | } |
284 | }, |
285 | { .buffer_created = 0, .name = "X0L2 Handle for inexistent plane" , |
286 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, |
287 | .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
288 | .pitches = { 2 * MAX_WIDTH + 1, 0, 0 } |
289 | } |
290 | }, |
291 | { .buffer_created = 1, |
292 | .name = "X0L2 Offset for inexistent plane, without DRM_MODE_FB_MODIFIERS set" , |
293 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, |
294 | .handles = { 1, 0, 0 }, .offsets = { 0, 0, 3 }, |
295 | .pitches = { 2 * MAX_WIDTH + 1, 0, 0 } |
296 | } |
297 | }, |
298 | { .buffer_created = 0, .name = "X0L2 Modifier without DRM_MODE_FB_MODIFIERS set" , |
299 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, |
300 | .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }, |
301 | .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 }, |
302 | } |
303 | }, |
304 | { .buffer_created = 1, .name = "X0L2 Valid modifier" , |
305 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, |
306 | .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }, |
307 | .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, |
308 | } |
309 | }, |
310 | { .buffer_created = 0, .name = "X0L2 Modifier for inexistent plane" , |
311 | .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, |
312 | .pixel_format = DRM_FORMAT_X0L2, .handles = { 1, 0, 0 }, |
313 | .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }, |
314 | .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 }, |
315 | .flags = DRM_MODE_FB_MODIFIERS, |
316 | } |
317 | }, |
318 | }; |
319 | |
320 | static struct drm_framebuffer *fb_create_mock(struct drm_device *dev, |
321 | struct drm_file *file_priv, |
322 | const struct drm_mode_fb_cmd2 *mode_cmd) |
323 | { |
324 | int *buffer_created = dev->dev_private; |
325 | *buffer_created = 1; |
326 | return ERR_PTR(error: -EINVAL); |
327 | } |
328 | |
329 | static struct drm_mode_config_funcs mock_config_funcs = { |
330 | .fb_create = fb_create_mock, |
331 | }; |
332 | |
333 | static int drm_framebuffer_test_init(struct kunit *test) |
334 | { |
335 | struct drm_device *mock; |
336 | |
337 | mock = kunit_kzalloc(test, size: sizeof(*mock), GFP_KERNEL); |
338 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock); |
339 | |
340 | mock->mode_config.min_width = MIN_WIDTH; |
341 | mock->mode_config.max_width = MAX_WIDTH; |
342 | mock->mode_config.min_height = MIN_HEIGHT; |
343 | mock->mode_config.max_height = MAX_HEIGHT; |
344 | mock->mode_config.funcs = &mock_config_funcs; |
345 | |
346 | test->priv = mock; |
347 | return 0; |
348 | } |
349 | |
350 | static void drm_test_framebuffer_create(struct kunit *test) |
351 | { |
352 | const struct drm_framebuffer_test *params = test->param_value; |
353 | struct drm_device *mock = test->priv; |
354 | int buffer_created = 0; |
355 | |
356 | mock->dev_private = &buffer_created; |
357 | drm_internal_framebuffer_create(dev: mock, r: ¶ms->cmd, NULL); |
358 | KUNIT_EXPECT_EQ(test, params->buffer_created, buffer_created); |
359 | } |
360 | |
361 | static void drm_framebuffer_test_to_desc(const struct drm_framebuffer_test *t, char *desc) |
362 | { |
363 | strcpy(p: desc, q: t->name); |
364 | } |
365 | |
366 | KUNIT_ARRAY_PARAM(drm_framebuffer_create, drm_framebuffer_create_cases, |
367 | drm_framebuffer_test_to_desc); |
368 | |
369 | static struct kunit_case drm_framebuffer_tests[] = { |
370 | KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), |
371 | { } |
372 | }; |
373 | |
374 | static struct kunit_suite drm_framebuffer_test_suite = { |
375 | .name = "drm_framebuffer" , |
376 | .init = drm_framebuffer_test_init, |
377 | .test_cases = drm_framebuffer_tests, |
378 | }; |
379 | |
380 | kunit_test_suite(drm_framebuffer_test_suite); |
381 | |
382 | MODULE_LICENSE("GPL" ); |
383 | |