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_egl)73 START_TEST(virgl_init_egl)
74 {
75 int ret;
76 test_cbs.version = 1;
77 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
78 ck_assert_int_eq(ret, 0);
79 virgl_renderer_cleanup(&mystruct);
80 }
81
82 END_TEST
83
START_TEST(virgl_init_egl_create_ctx)84 START_TEST(virgl_init_egl_create_ctx)
85 {
86 int ret;
87 test_cbs.version = 1;
88 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
89 ck_assert_int_eq(ret, 0);
90 ret = virgl_renderer_context_create(1, strlen("test1"), "test1");
91 ck_assert_int_eq(ret, 0);
92
93 virgl_renderer_context_destroy(1);
94 virgl_renderer_cleanup(&mystruct);
95 }
96 END_TEST
97
START_TEST(virgl_init_egl_create_ctx_0)98 START_TEST(virgl_init_egl_create_ctx_0)
99 {
100 int ret;
101
102 test_cbs.version = 1;
103 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
104 ck_assert_int_eq(ret, 0);
105 ret = virgl_renderer_context_create(0, strlen("test1"), "test1");
106 ck_assert_int_eq(ret, EINVAL);
107
108 virgl_renderer_cleanup(&mystruct);
109 }
110 END_TEST
111
START_TEST(virgl_init_egl_destroy_ctx_illegal)112 START_TEST(virgl_init_egl_destroy_ctx_illegal)
113 {
114 int ret;
115 test_cbs.version = 1;
116 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
117 ck_assert_int_eq(ret, 0);
118
119 virgl_renderer_context_destroy(1);
120 virgl_renderer_cleanup(&mystruct);
121 }
122 END_TEST
123
START_TEST(virgl_init_egl_create_ctx_leak)124 START_TEST(virgl_init_egl_create_ctx_leak)
125 {
126 testvirgl_init_single_ctx();
127
128 /* don't destroy the context - leak it make sure cleanup catches it */
129 /*virgl_renderer_context_destroy(1);*/
130 virgl_renderer_cleanup(&mystruct);
131 }
132 END_TEST
133
START_TEST(virgl_init_egl_create_ctx_create_bind_res)134 START_TEST(virgl_init_egl_create_ctx_create_bind_res)
135 {
136 int ret;
137 struct virgl_renderer_resource_create_args res;
138
139 testvirgl_init_simple_1d_resource(&res, 1);
140
141 ret = virgl_renderer_resource_create(&res, NULL, 0);
142 ck_assert_int_eq(ret, 0);
143
144 virgl_renderer_ctx_attach_resource(1, res.handle);
145
146 virgl_renderer_ctx_detach_resource(1, res.handle);
147
148 virgl_renderer_resource_unref(1);
149 }
150 END_TEST
151
START_TEST(virgl_init_egl_create_ctx_create_bind_res_illegal_ctx)152 START_TEST(virgl_init_egl_create_ctx_create_bind_res_illegal_ctx)
153 {
154 int ret;
155 struct virgl_renderer_resource_create_args res;
156
157 testvirgl_init_simple_1d_resource(&res, 1);
158
159 ret = virgl_renderer_resource_create(&res, NULL, 0);
160 ck_assert_int_eq(ret, 0);
161
162 virgl_renderer_ctx_attach_resource(2, res.handle);
163
164 virgl_renderer_resource_unref(1);
165 }
166 END_TEST
167
168
START_TEST(virgl_init_egl_create_ctx_create_bind_res_illegal_res)169 START_TEST(virgl_init_egl_create_ctx_create_bind_res_illegal_res)
170 {
171 int ret;
172 struct virgl_renderer_resource_create_args res;
173
174 testvirgl_init_simple_1d_resource(&res, 1);
175
176 ret = virgl_renderer_resource_create(&res, NULL, 0);
177 ck_assert_int_eq(ret, 0);
178
179 virgl_renderer_ctx_attach_resource(1, 2);
180
181 virgl_renderer_resource_unref(1);
182 }
183 END_TEST
184
START_TEST(virgl_init_egl_create_ctx_create_unbind_no_bind)185 START_TEST(virgl_init_egl_create_ctx_create_unbind_no_bind)
186 {
187 int ret;
188 struct virgl_renderer_resource_create_args res;
189
190 testvirgl_init_simple_1d_resource(&res, 1);
191
192 ret = virgl_renderer_resource_create(&res, NULL, 0);
193 ck_assert_int_eq(ret, 0);
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_unbind_illegal_ctx)201 START_TEST(virgl_init_egl_create_ctx_create_unbind_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_detach_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_leak)218 START_TEST(virgl_init_egl_create_ctx_create_bind_res_leak)
219 {
220 int ret;
221 struct virgl_renderer_resource_create_args res;
222
223 testvirgl_init_single_ctx_nr();
224
225 testvirgl_init_simple_1d_resource(&res, 1);
226
227 ret = virgl_renderer_resource_create(&res, NULL, 0);
228 ck_assert_int_eq(ret, 0);
229
230 virgl_renderer_ctx_attach_resource(1, res.handle);
231
232 /*virgl_renderer_ctx_detach_resource(1, res.handle);*/
233
234 /*virgl_renderer_resource_unref(1);*/
235 /* don't detach or destroy resource - it should still get cleanedup */
236 testvirgl_fini_single_ctx();
237 }
238 END_TEST
239
START_TEST(virgl_init_egl_create_ctx_reset)240 START_TEST(virgl_init_egl_create_ctx_reset)
241 {
242 int ret;
243
244 ret = testvirgl_init_single_ctx();
245 ck_assert_int_eq(ret, 0);
246
247 virgl_renderer_reset();
248
249 /* reset should have destroyed the context */
250 ret = virgl_renderer_context_create(1, strlen("test1"), "test1");
251 ck_assert_int_eq(ret, 0);
252 virgl_renderer_cleanup(&mystruct);
253 }
254 END_TEST
255
START_TEST(virgl_init_get_caps_set0)256 START_TEST(virgl_init_get_caps_set0)
257 {
258 int ret;
259 uint32_t max_ver, max_size;
260
261 test_cbs.version = 1;
262 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
263 ck_assert_int_eq(ret, 0);
264
265 virgl_renderer_get_cap_set(0, &max_ver, &max_size);
266 ck_assert_int_eq(max_ver, 0);
267 ck_assert_int_eq(max_size, 0);
268
269 virgl_renderer_cleanup(&mystruct);
270 }
271 END_TEST
272
START_TEST(virgl_init_get_caps_set1)273 START_TEST(virgl_init_get_caps_set1)
274 {
275 int ret;
276 uint32_t max_ver, max_size;
277 void *caps;
278 test_cbs.version = 1;
279 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
280 ck_assert_int_eq(ret, 0);
281
282 virgl_renderer_get_cap_set(1, &max_ver, &max_size);
283 ck_assert_int_ge(max_ver, 1);
284 ck_assert_int_ne(max_size, 0);
285 ck_assert_int_ge(max_size, sizeof(struct virgl_caps_v1));
286
287 caps = malloc(max_size);
288
289 virgl_renderer_fill_caps(0, 0, caps);
290
291 free(caps);
292 virgl_renderer_cleanup(&mystruct);
293 }
294 END_TEST
295
START_TEST(virgl_init_get_caps_null)296 START_TEST(virgl_init_get_caps_null)
297 {
298 int ret;
299 uint32_t max_ver, max_size;
300
301 test_cbs.version = 1;
302 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
303 ck_assert_int_eq(ret, 0);
304
305 virgl_renderer_get_cap_set(1, &max_ver, &max_size);
306 ck_assert_int_ge(max_ver, 1);
307 ck_assert_int_ne(max_size, 0);
308 ck_assert_int_ge(max_size, sizeof(struct virgl_caps_v1));
309
310 virgl_renderer_fill_caps(0, 0, NULL);
311
312 virgl_renderer_cleanup(&mystruct);
313 }
314 END_TEST
315
START_TEST(virgl_test_get_resource_info)316 START_TEST(virgl_test_get_resource_info)
317 {
318 int ret;
319 struct virgl_renderer_resource_create_args res;
320 struct virgl_renderer_resource_info info;
321
322 testvirgl_init_simple_2d_resource(&res, 1);
323 res.format = VIRGL_FORMAT_B8G8R8X8_UNORM;
324 ret = virgl_renderer_resource_create(&res, NULL, 0);
325 ck_assert_int_eq(ret, 0);
326
327 virgl_renderer_ctx_attach_resource(1, res.handle);
328
329 ret = virgl_renderer_resource_get_info(res.handle, &info);
330 ck_assert_int_eq(ret, 0);
331
332 ck_assert(info.drm_fourcc == GBM_FORMAT_ABGR8888 ||
333 info.drm_fourcc == GBM_FORMAT_ARGB8888);
334 ck_assert_int_eq(info.virgl_format, res.format);
335 ck_assert_int_eq(res.width, info.width);
336 ck_assert_int_eq(res.height, info.height);
337 ck_assert_int_eq(res.depth, info.depth);
338 ck_assert_int_eq(res.flags, info.flags);
339 virgl_renderer_ctx_detach_resource(1, res.handle);
340
341 virgl_renderer_resource_unref(1);
342 }
343 END_TEST
344
START_TEST(virgl_test_get_resource_info_no_info)345 START_TEST(virgl_test_get_resource_info_no_info)
346 {
347 int ret;
348 struct virgl_renderer_resource_create_args res;
349
350 testvirgl_init_simple_1d_resource(&res, 1);
351
352 ret = virgl_renderer_resource_create(&res, NULL, 0);
353 ck_assert_int_eq(ret, 0);
354
355 virgl_renderer_ctx_attach_resource(1, res.handle);
356
357 ret = virgl_renderer_resource_get_info(1, NULL);
358 ck_assert_int_eq(ret, EINVAL);
359
360 virgl_renderer_ctx_detach_resource(1, res.handle);
361 virgl_renderer_resource_unref(1);
362 }
363 END_TEST
364
365
START_TEST(virgl_test_get_resource_info_no_res)366 START_TEST(virgl_test_get_resource_info_no_res)
367 {
368 int ret;
369 struct virgl_renderer_resource_info info;
370
371 ret = virgl_renderer_resource_get_info(1, &info);
372 ck_assert_int_eq(ret, EINVAL);
373
374 virgl_renderer_resource_unref(1);
375 }
376 END_TEST
377
START_TEST(virgl_init_egl_create_ctx_create_attach_res)378 START_TEST(virgl_init_egl_create_ctx_create_attach_res)
379 {
380 int ret;
381 struct virgl_renderer_resource_create_args res;
382 struct iovec iovs[1];
383 struct iovec *iovs_r;
384 int num_r;
385
386 testvirgl_init_simple_1d_resource(&res, 1);
387
388 ret = virgl_renderer_resource_create(&res, NULL, 0);
389 ck_assert_int_eq(ret, 0);
390
391 iovs[0].iov_base = malloc(4096);
392 iovs[0].iov_len = 4096;
393
394 ret = virgl_renderer_resource_attach_iov(1, iovs, 1);
395 ck_assert_int_eq(ret, 0);
396
397 virgl_renderer_resource_detach_iov(1, &iovs_r, &num_r);
398
399 free(iovs[0].iov_base);
400 virgl_renderer_resource_unref(1);
401 }
402 END_TEST
403
START_TEST(virgl_init_egl_create_ctx_create_attach_res_detach_no_iovs)404 START_TEST(virgl_init_egl_create_ctx_create_attach_res_detach_no_iovs)
405 {
406 int ret;
407 struct virgl_renderer_resource_create_args res;
408 struct iovec iovs[1];
409 int num_r;
410
411 testvirgl_init_simple_1d_resource(&res, 1);
412
413 ret = virgl_renderer_resource_create(&res, NULL, 0);
414 ck_assert_int_eq(ret, 0);
415
416 iovs[0].iov_base = malloc(4096);
417 iovs[0].iov_len = 4096;
418
419 ret = virgl_renderer_resource_attach_iov(1, iovs, 1);
420 ck_assert_int_eq(ret, 0);
421
422 virgl_renderer_resource_detach_iov(1, NULL, &num_r);
423
424 free(iovs[0].iov_base);
425 virgl_renderer_resource_unref(1);
426 }
427 END_TEST
428
START_TEST(virgl_init_egl_create_ctx_create_attach_res_illegal_res)429 START_TEST(virgl_init_egl_create_ctx_create_attach_res_illegal_res)
430 {
431 int ret;
432 struct iovec iovs[1];
433
434 test_cbs.version = 1;
435 ret = virgl_renderer_init(&mystruct, VIRGL_RENDERER_USE_EGL, &test_cbs);
436 ck_assert_int_eq(ret, 0);
437
438 ret = virgl_renderer_resource_attach_iov(1, iovs, 1);
439 ck_assert_int_eq(ret, EINVAL);
440
441 virgl_renderer_resource_unref(1);
442 virgl_renderer_context_destroy(1);
443 virgl_renderer_cleanup(&mystruct);
444 }
445 END_TEST
446
virgl_init_suite(void)447 static Suite *virgl_init_suite(void)
448 {
449 Suite *s;
450 TCase *tc_core;
451
452 s = suite_create("virgl_init");
453 tc_core = tcase_create("init");
454
455 tcase_add_test(tc_core, virgl_init_no_cbs);
456 tcase_add_test(tc_core, virgl_init_no_cookie);
457 tcase_add_test(tc_core, virgl_init_cbs_wrong_ver);
458 tcase_add_test(tc_core, virgl_init_egl);
459 tcase_add_test(tc_core, virgl_init_egl_create_ctx);
460 tcase_add_test(tc_core, virgl_init_egl_create_ctx_0);
461 tcase_add_test(tc_core, virgl_init_egl_destroy_ctx_illegal);
462 tcase_add_test(tc_core, virgl_init_egl_create_ctx_leak);
463 tcase_add_test(tc_core, virgl_init_egl_create_ctx_reset);
464 tcase_add_test(tc_core, virgl_init_get_caps_set0);
465 tcase_add_test(tc_core, virgl_init_get_caps_set1);
466 tcase_add_test(tc_core, virgl_init_get_caps_null);
467 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_attach_res_illegal_res);
468 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_bind_res_leak);
469
470 suite_add_tcase(s, tc_core);
471
472 tc_core = tcase_create("init_std");
473 tcase_add_checked_fixture(tc_core, testvirgl_init_single_ctx_nr, testvirgl_fini_single_ctx);
474 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_bind_res);
475 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_bind_res_illegal_ctx);
476 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_bind_res_illegal_res);
477 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_unbind_no_bind);
478 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_unbind_illegal_ctx);
479
480 tcase_add_test(tc_core, virgl_test_get_resource_info);
481 tcase_add_test(tc_core, virgl_test_get_resource_info_no_info);
482 tcase_add_test(tc_core, virgl_test_get_resource_info_no_res);
483 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_attach_res);
484 tcase_add_test(tc_core, virgl_init_egl_create_ctx_create_attach_res_detach_no_iovs);
485
486 suite_add_tcase(s, tc_core);
487 return s;
488
489 }
490
491
main(void)492 int main(void)
493 {
494 Suite *s;
495 SRunner *sr;
496 int number_failed;
497
498 s = virgl_init_suite();
499 sr = srunner_create(s);
500
501 srunner_run_all(sr, CK_NORMAL);
502 number_failed = srunner_ntests_failed(sr);
503 srunner_free(sr);
504
505 return number_failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
506 }
507