• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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