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 /* transfer and iov related tests */
26 #include <check.h>
27 #include <stdlib.h>
28 #include <sys/uio.h>
29 #include <errno.h>
30 #include <virglrenderer.h>
31 #include "pipe/p_defines.h"
32 #include "virgl_hw.h"
33 #include "testvirgl_encode.h"
34
35 /* pass an illegal context to transfer fn */
START_TEST(virgl_test_transfer_read_illegal_ctx)36 START_TEST(virgl_test_transfer_read_illegal_ctx)
37 {
38 int ret;
39 struct virgl_box box;
40
41 ret = virgl_renderer_transfer_read_iov(1, 2, 0, 1, 1, &box, 0, NULL, 0);
42 ck_assert_int_eq(ret, EINVAL);
43 }
44 END_TEST
45
START_TEST(virgl_test_transfer_write_illegal_ctx)46 START_TEST(virgl_test_transfer_write_illegal_ctx)
47 {
48 int ret;
49 struct virgl_box box;
50
51 ret = virgl_renderer_transfer_write_iov(1, 2, 0, 1, 1, &box, 0, NULL, 0);
52 ck_assert_int_eq(ret, EINVAL);
53 }
54 END_TEST
55
56 /* pass a resource not bound to the context to transfers */
START_TEST(virgl_test_transfer_read_unbound_res)57 START_TEST(virgl_test_transfer_read_unbound_res)
58 {
59 int ret;
60 struct virgl_box box;
61
62 ret = virgl_renderer_transfer_read_iov(1, 1, 0, 1, 1, &box, 0, NULL, 0);
63 ck_assert_int_eq(ret, EINVAL);
64 }
65 END_TEST
66
START_TEST(virgl_test_transfer_write_unbound_res)67 START_TEST(virgl_test_transfer_write_unbound_res)
68 {
69 int ret;
70 struct virgl_box box;
71
72 ret = virgl_renderer_transfer_write_iov(1, 1, 0, 1, 1, &box, 0, NULL, 0);
73 ck_assert_int_eq(ret, EINVAL);
74 }
75 END_TEST
76
77 /* don't pass an IOV to read into */
START_TEST(virgl_test_transfer_read_no_iov)78 START_TEST(virgl_test_transfer_read_no_iov)
79 {
80 struct virgl_box box;
81 struct virgl_renderer_resource_create_args res;
82 int ret;
83
84 testvirgl_init_simple_1d_resource(&res, 1);
85
86 ret = virgl_renderer_resource_create(&res, NULL, 0);
87 ck_assert_int_eq(ret, 0);
88
89 virgl_renderer_ctx_attach_resource(1, res.handle);
90
91 ret = virgl_renderer_transfer_read_iov(1, 1, 0, 1, 1, &box, 0, NULL, 0);
92 ck_assert_int_eq(ret, EINVAL);
93 virgl_renderer_ctx_detach_resource(1, res.handle);
94
95 virgl_renderer_resource_unref(1);
96 }
97 END_TEST
98
START_TEST(virgl_test_transfer_write_no_iov)99 START_TEST(virgl_test_transfer_write_no_iov)
100 {
101 struct virgl_box box;
102 struct virgl_renderer_resource_create_args res;
103 int ret;
104
105 testvirgl_init_simple_1d_resource(&res, 1);
106
107 ret = virgl_renderer_resource_create(&res, NULL, 0);
108 ck_assert_int_eq(ret, 0);
109
110 virgl_renderer_ctx_attach_resource(1, res.handle);
111
112 ret = virgl_renderer_transfer_write_iov(1, 1, 0, 1, 1, &box, 0, NULL, 0);
113 ck_assert_int_eq(ret, EINVAL);
114 virgl_renderer_ctx_detach_resource(1, res.handle);
115
116 virgl_renderer_resource_unref(1);
117 }
118 END_TEST
119
START_TEST(virgl_test_transfer_read_no_box)120 START_TEST(virgl_test_transfer_read_no_box)
121 {
122 struct virgl_renderer_resource_create_args res;
123 struct iovec iovs[1];
124 int niovs = 1;
125 int ret;
126
127 testvirgl_init_simple_1d_resource(&res, 1);
128
129 ret = virgl_renderer_resource_create(&res, NULL, 0);
130 ck_assert_int_eq(ret, 0);
131
132 virgl_renderer_ctx_attach_resource(1, res.handle);
133
134 ret = virgl_renderer_transfer_read_iov(1, 1, 0, 1, 1, NULL, 0, iovs, niovs);
135 ck_assert_int_eq(ret, EINVAL);
136 virgl_renderer_ctx_detach_resource(1, res.handle);
137
138 virgl_renderer_resource_unref(1);
139 }
140 END_TEST
141
START_TEST(virgl_test_transfer_write_no_box)142 START_TEST(virgl_test_transfer_write_no_box)
143 {
144 struct virgl_renderer_resource_create_args res;
145 struct iovec iovs[1];
146 int niovs = 1;
147 int ret;
148
149 testvirgl_init_simple_1d_resource(&res, 1);
150
151 ret = virgl_renderer_resource_create(&res, NULL, 0);
152 ck_assert_int_eq(ret, 0);
153
154 virgl_renderer_ctx_attach_resource(1, res.handle);
155
156 ret = virgl_renderer_transfer_write_iov(1, 1, 0, 1, 1, NULL, 0, iovs, niovs);
157 ck_assert_int_eq(ret, EINVAL);
158 virgl_renderer_ctx_detach_resource(1, res.handle);
159
160 virgl_renderer_resource_unref(1);
161 }
162 END_TEST
163
164
165 /* pass a bad box argument */
START_TEST(virgl_test_transfer_read_1d_bad_box)166 START_TEST(virgl_test_transfer_read_1d_bad_box)
167 {
168 struct virgl_renderer_resource_create_args res;
169 struct iovec iovs[1];
170 int niovs = 1;
171 int ret;
172 struct virgl_box box;
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, res.handle);
180
181 box.x = box.y = box.z = 0;
182 box.w = 10;
183 box.h = 2;
184 box.d = 1;
185
186 ret = virgl_renderer_transfer_read_iov(1, 1, 0, 1, 1, &box, 0, iovs, niovs);
187 ck_assert_int_eq(ret, EINVAL);
188 virgl_renderer_ctx_detach_resource(1, res.handle);
189
190 virgl_renderer_resource_unref(1);
191 }
192 END_TEST
193
START_TEST(virgl_test_transfer_write_1d_bad_box)194 START_TEST(virgl_test_transfer_write_1d_bad_box)
195 {
196 struct virgl_renderer_resource_create_args res;
197 struct iovec iovs[1];
198 int niovs = 1;
199 int ret;
200 struct virgl_box box;
201
202 testvirgl_init_simple_1d_resource(&res, 1);
203
204 ret = virgl_renderer_resource_create(&res, NULL, 0);
205 ck_assert_int_eq(ret, 0);
206
207 virgl_renderer_ctx_attach_resource(1, res.handle);
208
209 box.x = box.y = box.z = 0;
210 box.w = 10;
211 box.h = 2;
212 box.d = 1;
213
214 ret = virgl_renderer_transfer_write_iov(1, 1, 0, 1, 1, &box, 0, iovs, niovs);
215 ck_assert_int_eq(ret, EINVAL);
216 virgl_renderer_ctx_detach_resource(1, res.handle);
217
218 virgl_renderer_resource_unref(1);
219 }
220 END_TEST
221
START_TEST(virgl_test_transfer_read_1d_array_bad_box)222 START_TEST(virgl_test_transfer_read_1d_array_bad_box)
223 {
224 struct virgl_renderer_resource_create_args res;
225 struct iovec iovs[1];
226 int niovs = 1;
227 int ret;
228 struct virgl_box box;
229
230 testvirgl_init_simple_1d_resource(&res, 1);
231 res.target = PIPE_TEXTURE_1D_ARRAY;
232 res.array_size = 5;
233
234 ret = virgl_renderer_resource_create(&res, NULL, 0);
235 ck_assert_int_eq(ret, 0);
236
237 virgl_renderer_ctx_attach_resource(1, res.handle);
238
239 box.x = box.y = box.z = 0;
240 box.w = 10;
241 box.h = 2;
242 box.d = 6;
243
244 ret = virgl_renderer_transfer_read_iov(1, 1, 0, 1, 1, &box, 0, iovs, niovs);
245 ck_assert_int_eq(ret, EINVAL);
246 virgl_renderer_ctx_detach_resource(1, res.handle);
247
248 virgl_renderer_resource_unref(1);
249 }
250 END_TEST
251
START_TEST(virgl_test_transfer_read_3d_bad_box)252 START_TEST(virgl_test_transfer_read_3d_bad_box)
253 {
254 struct virgl_renderer_resource_create_args res;
255 struct iovec iovs[1];
256 int niovs = 1;
257 int ret;
258 struct virgl_box box;
259
260 testvirgl_init_simple_1d_resource(&res, 1);
261 res.target = PIPE_TEXTURE_3D;
262 res.depth = 5;
263
264 ret = virgl_renderer_resource_create(&res, NULL, 0);
265 ck_assert_int_eq(ret, 0);
266
267 virgl_renderer_ctx_attach_resource(1, res.handle);
268
269 box.x = box.y = box.z = 0;
270 box.w = 10;
271 box.h = 2;
272 box.d = 6;
273
274 ret = virgl_renderer_transfer_read_iov(1, 1, 0, 1, 1, &box, 0, iovs, niovs);
275 ck_assert_int_eq(ret, EINVAL);
276 virgl_renderer_ctx_detach_resource(1, res.handle);
277
278 virgl_renderer_resource_unref(1);
279 }
280 END_TEST
281
START_TEST(virgl_test_transfer_1d)282 START_TEST(virgl_test_transfer_1d)
283 {
284 struct virgl_resource res;
285 unsigned char data[50*4];
286 struct iovec iov = { .iov_base = data, .iov_len = sizeof(data) };
287 int niovs = 1;
288 int ret;
289 unsigned i;
290 struct virgl_box box;
291
292 /* init and create simple 2D resource */
293 ret = testvirgl_create_backed_simple_1d_res(&res, 1);
294 ck_assert_int_eq(ret, 0);
295
296 /* attach resource to context */
297 virgl_renderer_ctx_attach_resource(1, res.handle);
298
299 box.x = box.y = box.z = 0;
300 box.w = 50;
301 box.h = 1;
302 box.d = 1;
303 for (i = 0; i < sizeof(data); i++)
304 data[i] = i;
305
306 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 0, 0, &box, 0, &iov, niovs);
307 ck_assert_int_eq(ret, 0);
308
309 ret = virgl_renderer_transfer_read_iov(res.handle, 1, 0, 0, 0, &box, 0, NULL, 0);
310 ck_assert_int_eq(ret, 0);
311
312 /* check the returned values */
313 unsigned char *ptr = res.iovs[0].iov_base;
314 for (i = 0; i < sizeof(data); i++) {
315 ck_assert_int_eq(ptr[i], i);
316 }
317
318 virgl_renderer_ctx_detach_resource(1, res.handle);
319 testvirgl_destroy_backed_res(&res);
320 }
321 END_TEST
322
START_TEST(virgl_test_transfer_1d_bad_iov)323 START_TEST(virgl_test_transfer_1d_bad_iov)
324 {
325 struct virgl_renderer_resource_create_args res;
326 struct iovec iovs[1] = { { NULL, 23 } };
327 int niovs = 1;
328 int ret;
329 struct virgl_box box = { .w = 50, .h = 1, .d = 1 };
330
331 testvirgl_init_simple_1d_resource(&res, 1);
332 res.target = PIPE_TEXTURE_1D;
333 res.depth = 1;
334
335 ret = virgl_renderer_resource_create(&res, NULL, 0);
336 ck_assert_int_eq(ret, 0);
337
338 virgl_renderer_ctx_attach_resource(1, res.handle);
339
340 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 0, 0, &box, 0, iovs, niovs);
341 ck_assert_int_eq(ret, EINVAL);
342
343 virgl_renderer_ctx_detach_resource(1, res.handle);
344
345 virgl_renderer_resource_unref(1);
346 }
347 END_TEST
348
START_TEST(virgl_test_transfer_1d_bad_iov_offset)349 START_TEST(virgl_test_transfer_1d_bad_iov_offset)
350 {
351 struct virgl_renderer_resource_create_args res;
352 unsigned char data[50*4];
353 struct iovec iov = { .iov_base = data, .iov_len = sizeof(data) };
354 int niovs = 1;
355 int ret;
356 struct virgl_box box = { .w = 50, .h = 1, .d = 1 };
357
358 testvirgl_init_simple_1d_resource(&res, 1);
359 res.target = PIPE_TEXTURE_1D;
360 res.depth = 1;
361
362 ret = virgl_renderer_resource_create(&res, NULL, 0);
363 ck_assert_int_eq(ret, 0);
364
365 virgl_renderer_ctx_attach_resource(1, res.handle);
366
367 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 0, 0, &box, 20, &iov, niovs);
368 ck_assert_int_eq(ret, EINVAL);
369
370 virgl_renderer_ctx_detach_resource(1, res.handle);
371
372 virgl_renderer_resource_unref(1);
373 }
374 END_TEST
375
START_TEST(virgl_test_transfer_1d_bad_layer_stride)376 START_TEST(virgl_test_transfer_1d_bad_layer_stride)
377 {
378 struct virgl_renderer_resource_create_args res;
379 unsigned char data[50*4];
380 struct iovec iov = { .iov_base = data, .iov_len = sizeof(data) };
381 int niovs = 1;
382 int ret;
383 struct virgl_box box = { .w = 50, .h = 1, .d = 1 };
384
385 testvirgl_init_simple_1d_resource(&res, 1);
386 res.target = PIPE_TEXTURE_1D;
387 res.depth = 1;
388
389 ret = virgl_renderer_resource_create(&res, NULL, 0);
390 ck_assert_int_eq(ret, 0);
391
392 virgl_renderer_ctx_attach_resource(1, res.handle);
393
394 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 0, 50, &box, 0, &iov, niovs);
395 ck_assert_int_eq(ret, EINVAL);
396
397 virgl_renderer_ctx_detach_resource(1, res.handle);
398
399 virgl_renderer_resource_unref(1);
400 }
401 END_TEST
402
START_TEST(virgl_test_transfer_2d_bad_layer_stride)403 START_TEST(virgl_test_transfer_2d_bad_layer_stride)
404 {
405 struct virgl_renderer_resource_create_args res;
406 unsigned char data[50*4];
407 struct iovec iov = { .iov_base = data, .iov_len = sizeof(data) };
408 int niovs = 1;
409 int ret;
410 struct virgl_box box = { .w = 50, .h = 1, .d = 1 };
411
412 testvirgl_init_simple_2d_resource(&res, 1);
413
414 ret = virgl_renderer_resource_create(&res, NULL, 0);
415 ck_assert_int_eq(ret, 0);
416
417 virgl_renderer_ctx_attach_resource(1, res.handle);
418
419 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 0, 50, &box, 0, &iov, niovs);
420 ck_assert_int_eq(ret, EINVAL);
421
422 virgl_renderer_ctx_detach_resource(1, res.handle);
423
424 virgl_renderer_resource_unref(1);
425 }
426 END_TEST
427
START_TEST(virgl_test_transfer_buffer_bad_layer_stride)428 START_TEST(virgl_test_transfer_buffer_bad_layer_stride)
429 {
430 struct virgl_renderer_resource_create_args res;
431 unsigned char data[50*4];
432 struct iovec iov = { .iov_base = data, .iov_len = sizeof(data) };
433 int niovs = 1;
434 int ret;
435 struct virgl_box box = { .w = 50, .h = 1, .d = 1 };
436
437 testvirgl_init_simple_buffer(&res, 1);
438
439 ret = virgl_renderer_resource_create(&res, NULL, 0);
440 ck_assert_int_eq(ret, 0);
441
442 virgl_renderer_ctx_attach_resource(1, res.handle);
443
444 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 0, 50, &box, 0, &iov, niovs);
445 ck_assert_int_eq(ret, EINVAL);
446
447 virgl_renderer_ctx_detach_resource(1, res.handle);
448
449 virgl_renderer_resource_unref(1);
450 }
451 END_TEST
452
START_TEST(virgl_test_transfer_2d_array_bad_layer_stride)453 START_TEST(virgl_test_transfer_2d_array_bad_layer_stride)
454 {
455 struct virgl_renderer_resource_create_args res;
456 unsigned char *data;
457 struct iovec iov;
458 int niovs = 1;
459 int ret;
460 struct virgl_box box = { .w = 50, .h = 5, .d = 2 };
461 int size = 50*50*2*4;
462 data = calloc(1, size);
463 iov.iov_base = data;
464 iov.iov_len = size;
465 testvirgl_init_simple_2d_resource(&res, 1);
466 res.target = PIPE_TEXTURE_2D_ARRAY;
467 res.array_size = 5;
468
469 ret = virgl_renderer_resource_create(&res, NULL, 0);
470 ck_assert_int_eq(ret, 0);
471
472 virgl_renderer_ctx_attach_resource(1, res.handle);
473
474 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 0, 100, &box, 0, &iov, niovs);
475 ck_assert_int_eq(ret, EINVAL);
476
477 virgl_renderer_ctx_detach_resource(1, res.handle);
478
479 virgl_renderer_resource_unref(1);
480 free(data);
481 }
482 END_TEST
483
START_TEST(virgl_test_transfer_2d_bad_level)484 START_TEST(virgl_test_transfer_2d_bad_level)
485 {
486 struct virgl_renderer_resource_create_args res;
487 unsigned char data[50*4];
488 struct iovec iov = { .iov_base = data, .iov_len = sizeof(data) };
489 int niovs = 1;
490 int ret;
491 struct virgl_box box = { .w = 50, .h = 1, .d = 1 };
492
493 testvirgl_init_simple_2d_resource(&res, 1);
494 res.last_level = 1;
495 ret = virgl_renderer_resource_create(&res, NULL, 0);
496 ck_assert_int_eq(ret, 0);
497
498 virgl_renderer_ctx_attach_resource(1, res.handle);
499
500 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 2, 0, 0, &box, 0, &iov, niovs);
501 ck_assert_int_eq(ret, EINVAL);
502
503 virgl_renderer_ctx_detach_resource(1, res.handle);
504
505 virgl_renderer_resource_unref(1);
506 }
507 END_TEST
508
509 /* test stride less than box size */
START_TEST(virgl_test_transfer_2d_bad_stride)510 START_TEST(virgl_test_transfer_2d_bad_stride)
511 {
512 struct virgl_renderer_resource_create_args res;
513 unsigned char data[50*4*2];
514 struct iovec iov = { .iov_base = data, .iov_len = sizeof(data) };
515 int niovs = 1;
516 int ret;
517 struct virgl_box box = { .w = 50, .h = 2, .d = 1 };
518
519 testvirgl_init_simple_2d_resource(&res, 1);
520
521 ret = virgl_renderer_resource_create(&res, NULL, 0);
522 ck_assert_int_eq(ret, 0);
523
524 virgl_renderer_ctx_attach_resource(1, res.handle);
525
526 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 10, 0, &box, 0, &iov, niovs);
527 ck_assert_int_eq(ret, EINVAL);
528
529 virgl_renderer_ctx_detach_resource(1, res.handle);
530
531 virgl_renderer_resource_unref(1);
532 }
533 END_TEST
534
535 /* for each texture type construct a valid and invalid transfer,
536 invalid using a box outside the bounds of the transfer */
537 #define LARGE_FLAG_WIDTH (1 << 0)
538 #define LARGE_FLAG_HEIGHT (1 << 1)
539 #define LARGE_FLAG_DEPTH (1 << 2)
get_resource_args(enum pipe_texture_target target,bool invalid,struct virgl_renderer_resource_create_args * args,struct pipe_box * box,int nsamples,int large_flags)540 static void get_resource_args(enum pipe_texture_target target, bool invalid,
541 struct virgl_renderer_resource_create_args *args,
542 struct pipe_box *box, int nsamples, int large_flags)
543 {
544 memset(args, 0, sizeof(*args));
545 memset(box, 0, sizeof(*box));
546
547 args->handle = 1;
548 args->target = target;
549 if (args->target == PIPE_BUFFER) {
550 args->format = PIPE_FORMAT_R8_UNORM;
551 args->bind = PIPE_BIND_VERTEX_BUFFER;
552 } else {
553 args->bind = PIPE_BIND_SAMPLER_VIEW;
554 args->format = PIPE_FORMAT_B8G8R8X8_UNORM;
555 }
556 args->nr_samples = nsamples;
557 args->flags = 0;
558
559 if (large_flags & LARGE_FLAG_WIDTH)
560 args->width = 65536*2;
561 else
562 args->width = 50;
563 args->height = args->depth = args->array_size = 1;
564
565 switch (target) {
566 case PIPE_TEXTURE_CUBE_ARRAY:
567 args->array_size = 12;
568 break;
569 case PIPE_TEXTURE_1D_ARRAY:
570 case PIPE_TEXTURE_2D_ARRAY:
571 args->array_size = 10;
572 break;
573 case PIPE_TEXTURE_3D:
574 args->depth = 8;
575 break;
576 case PIPE_TEXTURE_CUBE:
577 args->array_size = 6;
578 break;
579 default:
580 break;
581 }
582
583 switch (target) {
584 case PIPE_BUFFER:
585 case PIPE_TEXTURE_1D:
586 case PIPE_TEXTURE_1D_ARRAY:
587 break;
588 default:
589 if (large_flags & LARGE_FLAG_HEIGHT)
590 args->height = 64000;
591 else
592 args->height = 50;
593 break;
594 }
595
596 if (invalid) {
597 box->width = args->width + 10;
598 box->height = args->height;
599 box->depth = 1;
600 } else {
601 box->width = args->width;
602 box->height = args->height;
603 box->depth = 1;
604 if (args->depth > 1)
605 box->depth = 6;
606 if (args->array_size > 1)
607 box->depth = 4;
608 }
609 }
610
get_box_size(struct pipe_box * box,int elsize)611 static unsigned get_box_size(struct pipe_box *box, int elsize)
612 {
613 return elsize * box->width * box->height * box->depth;
614 }
615
virgl_test_transfer_res(enum pipe_texture_target target,bool write,bool invalid)616 static void virgl_test_transfer_res(enum pipe_texture_target target,
617 bool write, bool invalid)
618 {
619 struct virgl_renderer_resource_create_args res;
620 struct pipe_box box;
621 void *data;
622 struct iovec iovs[1];
623 int niovs = 1;
624 int ret;
625 int size;
626
627 get_resource_args(target, invalid, &res, &box, 1, 0);
628
629 size = get_box_size(&box, target == PIPE_BUFFER ? 1 : 4);
630 data = calloc(1, size);
631 iovs[0].iov_base = data;
632 iovs[0].iov_len = size;
633
634 ret = virgl_renderer_resource_create(&res, NULL, 0);
635 ck_assert_int_eq(ret, 0);
636
637 virgl_renderer_ctx_attach_resource(1, res.handle);
638
639 if (write)
640 ret = virgl_renderer_transfer_write_iov(res.handle, 1, 0, 0, 0,
641 (struct virgl_box *)&box, 0, iovs, niovs);
642 else
643 ret = virgl_renderer_transfer_read_iov(res.handle, 1, 0, 0, 0,
644 (struct virgl_box *)&box, 0, iovs, niovs);
645 ck_assert_int_eq(ret, invalid ? EINVAL : 0);
646 virgl_renderer_ctx_detach_resource(1, res.handle);
647
648 virgl_renderer_resource_unref(res.handle);
649 free(data);
650 }
651
START_TEST(virgl_test_transfer_res_read_valid)652 START_TEST(virgl_test_transfer_res_read_valid)
653 {
654 virgl_test_transfer_res(_i, false, false);
655 }
656 END_TEST
657
START_TEST(virgl_test_transfer_res_write_valid)658 START_TEST(virgl_test_transfer_res_write_valid)
659 {
660 virgl_test_transfer_res(_i, true, false);
661 }
662 END_TEST
663
START_TEST(virgl_test_transfer_res_read_invalid)664 START_TEST(virgl_test_transfer_res_read_invalid)
665 {
666 virgl_test_transfer_res(_i, false, true);
667 }
668 END_TEST
669
START_TEST(virgl_test_transfer_res_write_invalid)670 START_TEST(virgl_test_transfer_res_write_invalid)
671 {
672 virgl_test_transfer_res(_i, true, true);
673 }
674 END_TEST
675
virgl_test_transfer_inline(enum pipe_texture_target target,bool invalid,int large_flags)676 static void virgl_test_transfer_inline(enum pipe_texture_target target,
677 bool invalid, int large_flags)
678 {
679 struct virgl_renderer_resource_create_args args;
680 struct pipe_box box;
681 struct virgl_context ctx;
682 struct virgl_resource res;
683 int ret;
684 int elsize = target == 0 ? 1 : 4;
685 void *data;
686 unsigned size;
687 ret = testvirgl_init_ctx_cmdbuf(&ctx);
688 ck_assert_int_eq(ret, 0);
689
690 get_resource_args(target, invalid, &args, &box, 1, large_flags);
691
692 size = get_box_size(&box, elsize);
693 data = calloc(1, size);
694 ret = virgl_renderer_resource_create(&args, NULL, 0);
695 ck_assert_int_eq(ret, 0);
696
697 res.handle = args.handle;
698 res.base.target = args.target;
699 res.base.format = args.format;
700
701 virgl_renderer_ctx_attach_resource(ctx.ctx_id, res.handle);
702 virgl_encoder_inline_write(&ctx, &res, 0, 0, (struct pipe_box *)&box, data, box.width * elsize, 0);
703 ret = virgl_renderer_submit_cmd(ctx.cbuf->buf, ctx.ctx_id, ctx.cbuf->cdw);
704 ck_assert_int_eq(ret, invalid ? EINVAL : 0);
705 virgl_renderer_ctx_detach_resource(ctx.ctx_id, res.handle);
706
707 virgl_renderer_resource_unref(res.handle);
708 testvirgl_fini_ctx_cmdbuf(&ctx);
709 free(data);
710 }
711
START_TEST(virgl_test_transfer_inline_valid)712 START_TEST(virgl_test_transfer_inline_valid)
713 {
714 virgl_test_transfer_inline(_i, false, 0);
715 }
716 END_TEST
717
START_TEST(virgl_test_transfer_inline_invalid)718 START_TEST(virgl_test_transfer_inline_invalid)
719 {
720 virgl_test_transfer_inline(_i, true, 0);
721 }
722 END_TEST
723
START_TEST(virgl_test_transfer_inline_valid_large)724 START_TEST(virgl_test_transfer_inline_valid_large)
725 {
726 virgl_test_transfer_inline(_i, false, LARGE_FLAG_WIDTH);
727 }
728 END_TEST
729
virgl_init_suite(void)730 static Suite *virgl_init_suite(void)
731 {
732 Suite *s;
733 TCase *tc_core;
734
735 s = suite_create("virgl_transfer");
736 tc_core = tcase_create("transfer_direct");
737
738 tcase_add_checked_fixture(tc_core, testvirgl_init_single_ctx_nr, testvirgl_fini_single_ctx);
739 tcase_add_test(tc_core, virgl_test_transfer_read_illegal_ctx);
740 tcase_add_test(tc_core, virgl_test_transfer_write_illegal_ctx);
741 tcase_add_test(tc_core, virgl_test_transfer_read_unbound_res);
742 tcase_add_test(tc_core, virgl_test_transfer_write_unbound_res);
743 tcase_add_test(tc_core, virgl_test_transfer_read_no_iov);
744 tcase_add_test(tc_core, virgl_test_transfer_write_no_iov);
745 tcase_add_test(tc_core, virgl_test_transfer_read_no_box);
746 tcase_add_test(tc_core, virgl_test_transfer_write_no_box);
747 tcase_add_test(tc_core, virgl_test_transfer_read_1d_bad_box);
748 tcase_add_test(tc_core, virgl_test_transfer_write_1d_bad_box);
749 tcase_add_test(tc_core, virgl_test_transfer_read_1d_array_bad_box);
750 tcase_add_test(tc_core, virgl_test_transfer_read_3d_bad_box);
751 tcase_add_test(tc_core, virgl_test_transfer_1d);
752 tcase_add_test(tc_core, virgl_test_transfer_1d_bad_iov);
753 tcase_add_test(tc_core, virgl_test_transfer_1d_bad_iov_offset);
754 tcase_add_test(tc_core, virgl_test_transfer_1d_bad_layer_stride);
755 tcase_add_test(tc_core, virgl_test_transfer_2d_bad_layer_stride);
756 tcase_add_test(tc_core, virgl_test_transfer_buffer_bad_layer_stride);
757 tcase_add_test(tc_core, virgl_test_transfer_2d_array_bad_layer_stride);
758 tcase_add_test(tc_core, virgl_test_transfer_2d_bad_level);
759 tcase_add_test(tc_core, virgl_test_transfer_2d_bad_stride);
760
761 tcase_add_loop_test(tc_core, virgl_test_transfer_res_read_valid, 0, PIPE_MAX_TEXTURE_TYPES);
762 tcase_add_loop_test(tc_core, virgl_test_transfer_res_write_valid, 0, PIPE_MAX_TEXTURE_TYPES);
763 tcase_add_loop_test(tc_core, virgl_test_transfer_res_read_invalid, 0, PIPE_MAX_TEXTURE_TYPES);
764 tcase_add_loop_test(tc_core, virgl_test_transfer_res_write_invalid, 0, PIPE_MAX_TEXTURE_TYPES);
765 suite_add_tcase(s, tc_core);
766
767 tc_core = tcase_create("transfer_inline_write");
768 tcase_add_loop_test(tc_core, virgl_test_transfer_inline_valid, 0, PIPE_MAX_TEXTURE_TYPES);
769 tcase_add_loop_test(tc_core, virgl_test_transfer_inline_invalid, 0, PIPE_MAX_TEXTURE_TYPES);
770 tcase_add_loop_test(tc_core, virgl_test_transfer_inline_valid_large, 0, PIPE_MAX_TEXTURE_TYPES);
771
772 suite_add_tcase(s, tc_core);
773 return s;
774
775 }
776
777
main(void)778 int main(void)
779 {
780 Suite *s;
781 SRunner *sr;
782 int number_failed;
783
784 s = virgl_init_suite();
785 sr = srunner_create(s);
786
787 srunner_run_all(sr, CK_NORMAL);
788 number_failed = srunner_ntests_failed(sr);
789 srunner_free(sr);
790
791 return number_failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
792 }
793