1 /**************************************************************************
2 *
3 * Copyright (C) 2014 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24
25 /*
26 * basic library initialisation, teardown, reset
27 * and context creation tests.
28 */
29
30 #include <check.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <virglrenderer.h>
34 #include <gbm.h>
35 #include <sys/uio.h>
36 #include "testvirgl.h"
37 #include "virgl_hw.h"
38 struct myinfo_struct {
39 uint32_t test;
40 };
41
42 struct myinfo_struct mystruct;
43
44 static struct virgl_renderer_callbacks test_cbs;
45
START_TEST(virgl_init_no_cbs)46 START_TEST(virgl_init_no_cbs)
47 {
48 int ret;
49 ret = virgl_renderer_init(&mystruct, 0, NULL);
50 ck_assert_int_eq(ret, -1);
51 }
52 END_TEST
53
START_TEST(virgl_init_no_cookie)54 START_TEST(virgl_init_no_cookie)
55 {
56 int ret;
57 ret = virgl_renderer_init(NULL, 0, &test_cbs);
58 ck_assert_int_eq(ret, -1);
59 }
60 END_TEST
61
START_TEST(virgl_init_cbs_wrong_ver)62 START_TEST(virgl_init_cbs_wrong_ver)
63 {
64 int ret;
65 struct virgl_renderer_callbacks testcbs;
66 memset(&testcbs, 0, sizeof(testcbs));
67 testcbs.version = VIRGL_RENDERER_CALLBACKS_VERSION + 1;
68 ret = virgl_renderer_init(&mystruct, 0, &testcbs);
69 ck_assert_int_eq(ret, -1);
70 }
71 END_TEST
72
START_TEST(virgl_init_cleanup_without_init)73 START_TEST(virgl_init_cleanup_without_init)
74 {
75 virgl_renderer_cleanup(&mystruct);
76 }
77 END_TEST
78
START_TEST(virgl_init_reset_without_init)79 START_TEST(virgl_init_reset_without_init)
80 {
81 virgl_renderer_reset();
82 }
83 END_TEST
84
START_TEST(virgl_init_egl)85 START_TEST(virgl_init_egl)
86 {
87 int ret;
88 test_cbs.version = 1;
89 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
90 ck_assert_int_eq(ret, 0);
91 virgl_renderer_cleanup(&mystruct);
92 }
93
94 END_TEST
95
START_TEST(virgl_init_egl_double_init)96 START_TEST(virgl_init_egl_double_init)
97 {
98 int ret;
99 test_cbs.version = 1;
100 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
101 ck_assert_int_eq(ret, 0);
102 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
103 ck_assert_int_eq(ret, 0);
104 virgl_renderer_cleanup(&mystruct);
105 }
106 END_TEST
107
START_TEST(virgl_init_egl_double_init_conflict_args)108 START_TEST(virgl_init_egl_double_init_conflict_args)
109 {
110 struct myinfo_struct local_struct;
111 struct virgl_renderer_callbacks local_cbs;
112 int ret;
113
114 test_cbs.version = 1;
115 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
116 ck_assert_int_eq(ret, 0);
117
118 ret = virgl_renderer_init(&local_struct, context_flags, &test_cbs);
119 ck_assert_int_eq(ret, -EBUSY);
120
121 ret = virgl_renderer_init(&mystruct, 0, &test_cbs);
122 ck_assert_int_eq(ret, -EBUSY);
123
124 memset(&local_cbs, 0, sizeof(local_cbs));
125 local_cbs.version = 1;
126 ret = virgl_renderer_init(&mystruct, context_flags, &local_cbs);
127 ck_assert_int_eq(ret, -EBUSY);
128
129 virgl_renderer_cleanup(&mystruct);
130 }
131 END_TEST
132
START_TEST(virgl_init_egl_create_ctx)133 START_TEST(virgl_init_egl_create_ctx)
134 {
135 int ret;
136 test_cbs.version = 1;
137 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
138 ck_assert_int_eq(ret, 0);
139 ret = virgl_renderer_context_create(1, strlen("test1"), "test1");
140 ck_assert_int_eq(ret, 0);
141
142 virgl_renderer_context_destroy(1);
143 virgl_renderer_cleanup(&mystruct);
144 }
145 END_TEST
146
START_TEST(virgl_init_egl_create_ctx_0)147 START_TEST(virgl_init_egl_create_ctx_0)
148 {
149 int ret;
150
151 test_cbs.version = 1;
152 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
153 ck_assert_int_eq(ret, 0);
154 ret = virgl_renderer_context_create(0, strlen("test1"), "test1");
155 ck_assert_int_eq(ret, EINVAL);
156
157 virgl_renderer_cleanup(&mystruct);
158 }
159 END_TEST
160
START_TEST(virgl_init_egl_destroy_ctx_illegal)161 START_TEST(virgl_init_egl_destroy_ctx_illegal)
162 {
163 int ret;
164 test_cbs.version = 1;
165 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
166 ck_assert_int_eq(ret, 0);
167
168 virgl_renderer_context_destroy(1);
169 virgl_renderer_cleanup(&mystruct);
170 }
171 END_TEST
172
START_TEST(virgl_init_egl_create_ctx_leak)173 START_TEST(virgl_init_egl_create_ctx_leak)
174 {
175 testvirgl_init_single_ctx();
176
177 /* don't destroy the context - leak it make sure cleanup catches it */
178 /*virgl_renderer_context_destroy(1);*/
179 virgl_renderer_cleanup(&mystruct);
180 }
181 END_TEST
182
START_TEST(virgl_init_egl_create_ctx_create_bind_res)183 START_TEST(virgl_init_egl_create_ctx_create_bind_res)
184 {
185 int ret;
186 struct virgl_renderer_resource_create_args res;
187
188 testvirgl_init_simple_1d_resource(&res, 1);
189
190 ret = virgl_renderer_resource_create(&res, NULL, 0);
191 ck_assert_int_eq(ret, 0);
192
193 virgl_renderer_ctx_attach_resource(1, res.handle);
194
195 virgl_renderer_ctx_detach_resource(1, res.handle);
196
197 virgl_renderer_resource_unref(1);
198 }
199 END_TEST
200
START_TEST(virgl_init_egl_create_ctx_create_bind_res_illegal_ctx)201 START_TEST(virgl_init_egl_create_ctx_create_bind_res_illegal_ctx)
202 {
203 int ret;
204 struct virgl_renderer_resource_create_args res;
205
206 testvirgl_init_simple_1d_resource(&res, 1);
207
208 ret = virgl_renderer_resource_create(&res, NULL, 0);
209 ck_assert_int_eq(ret, 0);
210
211 virgl_renderer_ctx_attach_resource(2, res.handle);
212
213 virgl_renderer_resource_unref(1);
214 }
215 END_TEST
216
217
START_TEST(virgl_init_egl_create_ctx_create_bind_res_illegal_res)218 START_TEST(virgl_init_egl_create_ctx_create_bind_res_illegal_res)
219 {
220 int ret;
221 struct virgl_renderer_resource_create_args res;
222
223 testvirgl_init_simple_1d_resource(&res, 1);
224
225 ret = virgl_renderer_resource_create(&res, NULL, 0);
226 ck_assert_int_eq(ret, 0);
227
228 virgl_renderer_ctx_attach_resource(1, 2);
229
230 virgl_renderer_resource_unref(1);
231 }
232 END_TEST
233
START_TEST(virgl_init_egl_create_ctx_create_unbind_no_bind)234 START_TEST(virgl_init_egl_create_ctx_create_unbind_no_bind)
235 {
236 int ret;
237 struct virgl_renderer_resource_create_args res;
238
239 testvirgl_init_simple_1d_resource(&res, 1);
240
241 ret = virgl_renderer_resource_create(&res, NULL, 0);
242 ck_assert_int_eq(ret, 0);
243
244 virgl_renderer_ctx_detach_resource(1, res.handle);
245
246 virgl_renderer_resource_unref(1);
247 }
248 END_TEST
249
START_TEST(virgl_init_egl_create_ctx_create_unbind_illegal_ctx)250 START_TEST(virgl_init_egl_create_ctx_create_unbind_illegal_ctx)
251 {
252 int ret;
253 struct virgl_renderer_resource_create_args res;
254
255 testvirgl_init_simple_1d_resource(&res, 1);
256
257 ret = virgl_renderer_resource_create(&res, NULL, 0);
258 ck_assert_int_eq(ret, 0);
259
260 virgl_renderer_ctx_detach_resource(2, res.handle);
261
262 virgl_renderer_resource_unref(1);
263 }
264 END_TEST
265
266
START_TEST(virgl_init_egl_create_ctx_create_bind_res_leak)267 START_TEST(virgl_init_egl_create_ctx_create_bind_res_leak)
268 {
269 int ret;
270 struct virgl_renderer_resource_create_args res;
271
272 testvirgl_init_single_ctx_nr();
273
274 testvirgl_init_simple_1d_resource(&res, 1);
275
276 ret = virgl_renderer_resource_create(&res, NULL, 0);
277 ck_assert_int_eq(ret, 0);
278
279 virgl_renderer_ctx_attach_resource(1, res.handle);
280
281 /*virgl_renderer_ctx_detach_resource(1, res.handle);*/
282
283 /*virgl_renderer_resource_unref(1);*/
284 /* don't detach or destroy resource - it should still get cleanedup */
285 testvirgl_fini_single_ctx();
286 }
287 END_TEST
288
START_TEST(virgl_init_egl_create_ctx_reset)289 START_TEST(virgl_init_egl_create_ctx_reset)
290 {
291 int ret;
292
293 ret = testvirgl_init_single_ctx();
294 ck_assert_int_eq(ret, 0);
295
296 virgl_renderer_reset();
297
298 /* reset should have destroyed the context */
299 ret = virgl_renderer_context_create(1, strlen("test1"), "test1");
300 ck_assert_int_eq(ret, 0);
301 virgl_renderer_cleanup(&mystruct);
302 }
303 END_TEST
304
START_TEST(virgl_init_get_caps_set0)305 START_TEST(virgl_init_get_caps_set0)
306 {
307 int ret;
308 uint32_t max_ver, max_size;
309
310 test_cbs.version = 1;
311 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
312 ck_assert_int_eq(ret, 0);
313
314 virgl_renderer_get_cap_set(0, &max_ver, &max_size);
315 ck_assert_int_eq(max_ver, 0);
316 ck_assert_int_eq(max_size, 0);
317
318 virgl_renderer_cleanup(&mystruct);
319 }
320 END_TEST
321
START_TEST(virgl_init_get_caps_set1)322 START_TEST(virgl_init_get_caps_set1)
323 {
324 int ret;
325 uint32_t max_ver, max_size;
326 void *caps;
327 test_cbs.version = 1;
328 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
329 ck_assert_int_eq(ret, 0);
330
331 virgl_renderer_get_cap_set(1, &max_ver, &max_size);
332 ck_assert_int_ge(max_ver, 1);
333 ck_assert_int_ne(max_size, 0);
334 ck_assert_int_ge(max_size, sizeof(struct virgl_caps_v1));
335
336 caps = malloc(max_size);
337
338 virgl_renderer_fill_caps(0, 0, caps);
339
340 free(caps);
341 virgl_renderer_cleanup(&mystruct);
342 }
343 END_TEST
344
START_TEST(virgl_init_get_caps_null)345 START_TEST(virgl_init_get_caps_null)
346 {
347 int ret;
348 uint32_t max_ver, max_size;
349
350 test_cbs.version = 1;
351 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
352 ck_assert_int_eq(ret, 0);
353
354 virgl_renderer_get_cap_set(1, &max_ver, &max_size);
355 ck_assert_int_ge(max_ver, 1);
356 ck_assert_int_ne(max_size, 0);
357 ck_assert_int_ge(max_size, sizeof(struct virgl_caps_v1));
358
359 virgl_renderer_fill_caps(0, 0, NULL);
360
361 virgl_renderer_cleanup(&mystruct);
362 }
363 END_TEST
364
START_TEST(virgl_test_get_resource_info)365 START_TEST(virgl_test_get_resource_info)
366 {
367 int ret;
368 struct virgl_renderer_resource_create_args res;
369 struct virgl_renderer_resource_info info;
370
371 testvirgl_init_simple_2d_resource(&res, 1);
372 res.format = VIRGL_FORMAT_B8G8R8X8_UNORM;
373 ret = virgl_renderer_resource_create(&res, NULL, 0);
374 ck_assert_int_eq(ret, 0);
375
376 virgl_renderer_ctx_attach_resource(1, res.handle);
377
378 ret = virgl_renderer_resource_get_info(res.handle, &info);
379 ck_assert_int_eq(ret, 0);
380
381 ck_assert(info.drm_fourcc == GBM_FORMAT_ABGR8888 ||
382 info.drm_fourcc == GBM_FORMAT_ARGB8888 ||
383 info.drm_fourcc == GBM_FORMAT_XRGB8888);
384 ck_assert_int_eq(info.virgl_format, res.format);
385 ck_assert_int_eq(res.width, info.width);
386 ck_assert_int_eq(res.height, info.height);
387 ck_assert_int_eq(res.depth, info.depth);
388 ck_assert_int_eq(res.flags, info.flags);
389 virgl_renderer_ctx_detach_resource(1, res.handle);
390
391 virgl_renderer_resource_unref(1);
392 }
393 END_TEST
394
START_TEST(virgl_test_get_resource_info_no_info)395 START_TEST(virgl_test_get_resource_info_no_info)
396 {
397 int ret;
398 struct virgl_renderer_resource_create_args res;
399
400 testvirgl_init_simple_1d_resource(&res, 1);
401
402 ret = virgl_renderer_resource_create(&res, NULL, 0);
403 ck_assert_int_eq(ret, 0);
404
405 virgl_renderer_ctx_attach_resource(1, res.handle);
406
407 ret = virgl_renderer_resource_get_info(1, NULL);
408 ck_assert_int_eq(ret, EINVAL);
409
410 virgl_renderer_ctx_detach_resource(1, res.handle);
411 virgl_renderer_resource_unref(1);
412 }
413 END_TEST
414
415
START_TEST(virgl_test_get_resource_info_no_res)416 START_TEST(virgl_test_get_resource_info_no_res)
417 {
418 int ret;
419 struct virgl_renderer_resource_info info;
420
421 ret = virgl_renderer_resource_get_info(1, &info);
422 ck_assert_int_eq(ret, EINVAL);
423
424 virgl_renderer_resource_unref(1);
425 }
426 END_TEST
427
START_TEST(virgl_init_egl_create_ctx_create_attach_res)428 START_TEST(virgl_init_egl_create_ctx_create_attach_res)
429 {
430 int ret;
431 struct virgl_renderer_resource_create_args res;
432 struct iovec iovs[1];
433 struct iovec *iovs_r;
434 int num_r;
435
436 testvirgl_init_simple_1d_resource(&res, 1);
437
438 ret = virgl_renderer_resource_create(&res, NULL, 0);
439 ck_assert_int_eq(ret, 0);
440
441 iovs[0].iov_base = malloc(4096);
442 iovs[0].iov_len = 4096;
443
444 ret = virgl_renderer_resource_attach_iov(1, iovs, 1);
445 ck_assert_int_eq(ret, 0);
446
447 virgl_renderer_resource_detach_iov(1, &iovs_r, &num_r);
448
449 free(iovs[0].iov_base);
450 virgl_renderer_resource_unref(1);
451 }
452 END_TEST
453
START_TEST(virgl_init_egl_create_ctx_create_attach_res_detach_no_iovs)454 START_TEST(virgl_init_egl_create_ctx_create_attach_res_detach_no_iovs)
455 {
456 int ret;
457 struct virgl_renderer_resource_create_args res;
458 struct iovec iovs[1];
459 int num_r;
460
461 testvirgl_init_simple_1d_resource(&res, 1);
462
463 ret = virgl_renderer_resource_create(&res, NULL, 0);
464 ck_assert_int_eq(ret, 0);
465
466 iovs[0].iov_base = malloc(4096);
467 iovs[0].iov_len = 4096;
468
469 ret = virgl_renderer_resource_attach_iov(1, iovs, 1);
470 ck_assert_int_eq(ret, 0);
471
472 virgl_renderer_resource_detach_iov(1, NULL, &num_r);
473
474 free(iovs[0].iov_base);
475 virgl_renderer_resource_unref(1);
476 }
477 END_TEST
478
START_TEST(virgl_init_egl_create_ctx_create_attach_res_illegal_res)479 START_TEST(virgl_init_egl_create_ctx_create_attach_res_illegal_res)
480 {
481 int ret;
482 struct iovec iovs[1];
483
484 test_cbs.version = 1;
485 ret = virgl_renderer_init(&mystruct, context_flags, &test_cbs);
486 ck_assert_int_eq(ret, 0);
487
488 ret = virgl_renderer_resource_attach_iov(1, iovs, 1);
489 ck_assert_int_eq(ret, EINVAL);
490
491 virgl_renderer_resource_unref(1);
492 virgl_renderer_context_destroy(1);
493 virgl_renderer_cleanup(&mystruct);
494 }
495 END_TEST
496
virgl_init_suite(void)497 static Suite *virgl_init_suite(void)
498 {
499 Suite *s;
500 TCase *tc_core;
501
502 s = suite_create("virgl_init");
503 tc_core = tcase_create("init");
504
505 tcase_add_test(tc_core, virgl_init_no_cbs);
506 tcase_add_test(tc_core, virgl_init_no_cookie);
507 tcase_add_test(tc_core, virgl_init_cbs_wrong_ver);
508 tcase_add_test(tc_core, virgl_init_cleanup_without_init);
509 tcase_add_test(tc_core, virgl_init_reset_without_init);
510 tcase_add_test(tc_core, virgl_init_egl);
511 tcase_add_test(tc_core, virgl_init_egl_double_init);
512 tcase_add_test(tc_core, virgl_init_egl_double_init_conflict_args);
513 tcase_add_test(tc_core, virgl_init_egl_create_ctx);
514 tcase_add_test(tc_core, virgl_init_egl_create_ctx_0);
515 tcase_add_test(tc_core, virgl_init_egl_destroy_ctx_illegal);
516 tcase_add_test(tc_core, virgl_init_egl_create_ctx_leak);
517 tcase_add_test(tc_core, virgl_init_egl_create_ctx_reset);
518 tcase_add_test(tc_core, virgl_init_get_caps_set0);
519 tcase_add_test(tc_core, virgl_init_get_caps_set1);
520 tcase_add_test(tc_core, virgl_init_get_caps_null);
521 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_attach_res_illegal_res);
522 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_bind_res_leak);
523
524 suite_add_tcase(s, tc_core);
525
526 tc_core = tcase_create("init_std");
527 tcase_add_checked_fixture(tc_core, testvirgl_init_single_ctx_nr, testvirgl_fini_single_ctx);
528 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_bind_res);
529 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_bind_res_illegal_ctx);
530 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_bind_res_illegal_res);
531 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_unbind_no_bind);
532 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_unbind_illegal_ctx);
533
534 tcase_add_test(tc_core, virgl_test_get_resource_info);
535 tcase_add_test(tc_core, virgl_test_get_resource_info_no_info);
536 tcase_add_test(tc_core, virgl_test_get_resource_info_no_res);
537 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_attach_res);
538 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_attach_res_detach_no_iovs);
539
540 suite_add_tcase(s, tc_core);
541 return s;
542
543 }
544
545
main(void)546 int main(void)
547 {
548 Suite *s;
549 SRunner *sr;
550 int number_failed;
551
552 if (getenv("VRENDTEST_USE_EGL_SURFACELESS"))
553 context_flags |= VIRGL_RENDERER_USE_SURFACELESS;
554 if (getenv("VRENDTEST_USE_EGL_GLES"))
555 context_flags |= VIRGL_RENDERER_USE_GLES;
556
557 s = virgl_init_suite();
558 sr = srunner_create(s);
559
560 srunner_run_all(sr, CK_NORMAL);
561 number_failed = srunner_ntests_failed(sr);
562 srunner_free(sr);
563
564 return number_failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
565 }
566