modetest: switch usage to proper options grammar
[drm/libdrm.git] / tests / exynos / exynos_fimg2d_test.c
blobd85e2f6b67f59b072fb92e91b043f7444da54fa1
1 /*
2 * Copyright (C) 2013 Samsung Electronics Co.Ltd
3 * Authors:
4 * Inki Dae <inki.dae@samsung.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <time.h>
31 #include <unistd.h>
33 #include <sys/mman.h>
34 #include <linux/stddef.h>
36 #include <xf86drm.h>
37 #include <xf86drmMode.h>
38 #include <drm_fourcc.h>
40 #include "exynos_drm.h"
41 #include "exynos_drmif.h"
42 #include "exynos_fimg2d.h"
44 #define DRM_MODULE_NAME "exynos"
46 static unsigned int screen_width, screen_height;
48 struct connector {
49 uint32_t id;
50 char mode_str[64];
51 drmModeModeInfo *mode;
52 drmModeEncoder *encoder;
53 int crtc;
56 static void connector_find_mode(int fd, struct connector *c,
57 drmModeRes *resources)
59 drmModeConnector *connector;
60 int i, j;
62 /* First, find the connector & mode */
63 c->mode = NULL;
64 for (i = 0; i < resources->count_connectors; i++) {
65 connector = drmModeGetConnector(fd, resources->connectors[i]);
67 if (!connector) {
68 fprintf(stderr, "could not get connector %i: %s\n",
69 resources->connectors[i], strerror(errno));
70 continue;
73 if (!connector->count_modes) {
74 drmModeFreeConnector(connector);
75 continue;
78 if (connector->connector_id != c->id) {
79 drmModeFreeConnector(connector);
80 continue;
83 for (j = 0; j < connector->count_modes; j++) {
84 c->mode = &connector->modes[j];
85 if (!strcmp(c->mode->name, c->mode_str))
86 break;
89 /* Found it, break out */
90 if (c->mode)
91 break;
93 drmModeFreeConnector(connector);
96 if (!c->mode) {
97 fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
98 return;
101 /* Now get the encoder */
102 for (i = 0; i < resources->count_encoders; i++) {
103 c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);
105 if (!c->encoder) {
106 fprintf(stderr, "could not get encoder %i: %s\n",
107 resources->encoders[i], strerror(errno));
108 continue;
111 if (c->encoder->encoder_id == connector->encoder_id)
112 break;
114 drmModeFreeEncoder(c->encoder);
117 if (c->crtc == -1)
118 c->crtc = c->encoder->crtc_id;
121 static int drm_set_crtc(struct exynos_device *dev, struct connector *c,
122 unsigned int fb_id)
124 int ret;
126 ret = drmModeSetCrtc(dev->fd, c->crtc,
127 fb_id, 0, 0, &c->id, 1, c->mode);
128 if (ret)
129 drmMsg("failed to set mode: %s\n", strerror(errno));
131 return ret;
134 static struct exynos_bo *exynos_create_buffer(struct exynos_device *dev,
135 unsigned long size,
136 unsigned int flags)
138 struct exynos_bo *bo;
140 bo = exynos_bo_create(dev, size, flags);
141 if (!bo)
142 return bo;
144 if (!exynos_bo_map(bo)) {
145 exynos_bo_destroy(bo);
146 return NULL;
149 return bo;
152 /* Allocate buffer and fill it with checkerboard pattern, where the tiles *
153 * have a random color. The caller has to free the buffer. */
154 static void *create_checkerboard_pattern(unsigned int num_tiles_x,
155 unsigned int num_tiles_y, unsigned int tile_size)
157 unsigned int *buf;
158 unsigned int x, y, i, j;
159 const unsigned int stride = num_tiles_x * tile_size;
161 if (posix_memalign((void*)&buf, 64, num_tiles_y * tile_size * stride * 4) != 0)
162 return NULL;
164 for (x = 0; x < num_tiles_x; ++x) {
165 for (y = 0; y < num_tiles_y; ++y) {
166 const unsigned int color = 0xff000000 + (random() & 0xffffff);
168 for (i = 0; i < tile_size; ++i) {
169 for (j = 0; j < tile_size; ++j) {
170 buf[x * tile_size + y * stride * tile_size + i + j * stride] = color;
176 return buf;
179 static void exynos_destroy_buffer(struct exynos_bo *bo)
181 exynos_bo_destroy(bo);
184 static void wait_for_user_input(int last)
186 printf("press <ENTER> to %s\n", last ? "exit test application" :
187 "skip to next test");
189 getchar();
192 static int g2d_solid_fill_test(struct exynos_device *dev, struct exynos_bo *dst)
194 struct g2d_context *ctx;
195 struct g2d_image img = {0};
196 unsigned int count, img_w, img_h;
197 int ret = 0;
199 ctx = g2d_init(dev->fd);
200 if (!ctx)
201 return -EFAULT;
203 img.bo[0] = dst->handle;
205 printf("solid fill test.\n");
207 srand(time(NULL));
208 img_w = screen_width;
209 img_h = screen_height;
211 for (count = 0; count < 2; count++) {
212 unsigned int x, y, w, h;
214 x = rand() % (img_w / 2);
215 y = rand() % (img_h / 2);
216 w = rand() % (img_w - x);
217 h = rand() % (img_h - y);
219 img.width = img_w;
220 img.height = img_h;
221 img.stride = img.width * 4;
222 img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
223 img.color = 0xff000000 + (random() & 0xffffff);
225 ret = g2d_solid_fill(ctx, &img, x, y, w, h);
226 if (ret < 0)
227 goto err_fini;
229 ret = g2d_exec(ctx);
230 if (ret < 0)
231 break;
234 err_fini:
235 g2d_fini(ctx);
237 return ret;
240 static int g2d_copy_test(struct exynos_device *dev, struct exynos_bo *src,
241 struct exynos_bo *dst,
242 enum e_g2d_buf_type type)
244 struct g2d_context *ctx;
245 struct g2d_image src_img = {0}, dst_img = {0};
246 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
247 unsigned long userptr, size;
248 int ret;
250 ctx = g2d_init(dev->fd);
251 if (!ctx)
252 return -EFAULT;
254 dst_img.bo[0] = dst->handle;
256 src_x = 0;
257 src_y = 0;
258 dst_x = 0;
259 dst_y = 0;
260 img_w = screen_width;
261 img_h = screen_height;
263 switch (type) {
264 case G2D_IMGBUF_GEM:
265 src_img.bo[0] = src->handle;
266 break;
267 case G2D_IMGBUF_USERPTR:
268 size = img_w * img_h * 4;
270 userptr = (unsigned long)malloc(size);
271 if (!userptr) {
272 fprintf(stderr, "failed to allocate userptr.\n");
273 ret = -EFAULT;
274 goto fail;
277 src_img.user_ptr[0].userptr = userptr;
278 src_img.user_ptr[0].size = size;
279 break;
280 case G2D_IMGBUF_COLOR:
281 default:
282 ret = -EFAULT;
283 goto fail;
286 printf("copy test with %s.\n",
287 type == G2D_IMGBUF_GEM ? "gem" : "userptr");
289 src_img.width = img_w;
290 src_img.height = img_h;
291 src_img.stride = src_img.width * 4;
292 src_img.buf_type = type;
293 src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
294 src_img.color = 0xffff0000;
295 ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w, img_h);
296 if (ret < 0)
297 goto err_free_userptr;
299 dst_img.width = img_w;
300 dst_img.height = img_h;
301 dst_img.stride = dst_img.width * 4;
302 dst_img.buf_type = G2D_IMGBUF_GEM;
303 dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
305 ret = g2d_copy(ctx, &src_img, &dst_img, src_x, src_y, dst_x, dst_y,
306 img_w - 4, img_h - 4);
307 if (ret < 0)
308 goto err_free_userptr;
310 g2d_exec(ctx);
312 err_free_userptr:
313 if (type == G2D_IMGBUF_USERPTR)
314 if (userptr)
315 free((void *)userptr);
317 fail:
318 g2d_fini(ctx);
320 return ret;
323 static int g2d_move_test(struct exynos_device *dev,
324 struct exynos_bo *tmp,
325 struct exynos_bo *buf,
326 enum e_g2d_buf_type type)
328 struct g2d_context *ctx;
329 struct g2d_image img = {0}, tmp_img = {0};
330 unsigned int img_w, img_h, count;
331 int cur_x, cur_y;
332 void *checkerboard;
333 int ret;
335 static const struct g2d_step {
336 int x, y;
337 } steps[] = {
338 { 1, 0}, { 0, 1},
339 {-1, 0}, { 0, -1},
340 { 1, 1}, {-1, -1},
341 { 1, -1}, {-1, 1},
342 { 2, 1}, { 1, 2},
343 {-2, -1}, {-1, -2},
344 { 2, -1}, { 1, -2},
345 {-2, 1}, {-1, 2}
347 static const unsigned int num_steps =
348 sizeof(steps) / sizeof(struct g2d_step);
350 ctx = g2d_init(dev->fd);
351 if (!ctx)
352 return -EFAULT;
354 img.bo[0] = buf->handle;
356 /* create pattern of half the screen size */
357 checkerboard = create_checkerboard_pattern(screen_width / 64, screen_height / 64, 32);
358 if (!checkerboard) {
359 ret = -EFAULT;
360 goto fail;
363 img_w = (screen_width / 64) * 32;
364 img_h = (screen_height / 64) * 32;
366 switch (type) {
367 case G2D_IMGBUF_GEM:
368 memcpy(tmp->vaddr, checkerboard, img_w * img_h * 4);
369 tmp_img.bo[0] = tmp->handle;
370 break;
371 case G2D_IMGBUF_USERPTR:
372 tmp_img.user_ptr[0].userptr = (unsigned long)checkerboard;
373 tmp_img.user_ptr[0].size = img_w * img_h * 4;
374 break;
375 case G2D_IMGBUF_COLOR:
376 default:
377 ret = -EFAULT;
378 goto fail;
381 /* solid fill framebuffer with white color */
382 img.width = screen_width;
383 img.height = screen_height;
384 img.stride = screen_width * 4;
385 img.buf_type = G2D_IMGBUF_GEM;
386 img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
387 img.color = 0xffffffff;
389 /* put checkerboard pattern in the center of the framebuffer */
390 cur_x = (screen_width - img_w) / 2;
391 cur_y = (screen_height - img_h) / 2;
392 tmp_img.width = img_w;
393 tmp_img.height = img_h;
394 tmp_img.stride = img_w * 4;
395 tmp_img.buf_type = type;
396 tmp_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
398 ret = g2d_solid_fill(ctx, &img, 0, 0, screen_width, screen_height) ||
399 g2d_copy(ctx, &tmp_img, &img, 0, 0, cur_x, cur_y, img_w, img_h);
401 if (!ret)
402 ret = g2d_exec(ctx);
403 if (ret < 0)
404 goto fail;
406 printf("move test with %s.\n",
407 type == G2D_IMGBUF_GEM ? "gem" : "userptr");
409 srand(time(NULL));
410 for (count = 0; count < 256; ++count) {
411 const struct g2d_step *s;
413 /* select step and validate it */
414 while (1) {
415 s = &steps[random() % num_steps];
417 if (cur_x + s->x < 0 || cur_y + s->y < 0 ||
418 cur_x + img_w + s->x >= screen_width ||
419 cur_y + img_h + s->y >= screen_height)
420 continue;
421 else
422 break;
425 ret = g2d_move(ctx, &img, cur_x, cur_y, cur_x + s->x, cur_y + s->y,
426 img_w, img_h);
427 if (!ret)
428 ret = g2d_exec(ctx);
430 if (ret < 0)
431 goto fail;
433 cur_x += s->x;
434 cur_y += s->y;
436 usleep(100000);
439 fail:
440 g2d_fini(ctx);
442 free(checkerboard);
444 return ret;
447 static int g2d_copy_with_scale_test(struct exynos_device *dev,
448 struct exynos_bo *src,
449 struct exynos_bo *dst,
450 enum e_g2d_buf_type type)
452 struct g2d_context *ctx;
453 struct g2d_image src_img = {0}, dst_img = {0};
454 unsigned int src_x, src_y, img_w, img_h;
455 unsigned long userptr, size;
456 int ret;
458 ctx = g2d_init(dev->fd);
459 if (!ctx)
460 return -EFAULT;
462 dst_img.bo[0] = dst->handle;
464 src_x = 0;
465 src_y = 0;
466 img_w = screen_width;
467 img_h = screen_height;
469 switch (type) {
470 case G2D_IMGBUF_GEM:
471 src_img.bo[0] = src->handle;
472 break;
473 case G2D_IMGBUF_USERPTR:
474 size = img_w * img_h * 4;
476 userptr = (unsigned long)malloc(size);
477 if (!userptr) {
478 fprintf(stderr, "failed to allocate userptr.\n");
479 ret = -EFAULT;
480 goto fail;
483 src_img.user_ptr[0].userptr = userptr;
484 src_img.user_ptr[0].size = size;
485 break;
486 case G2D_IMGBUF_COLOR:
487 default:
488 ret = -EFAULT;
489 goto fail;
492 printf("copy and scale test with %s.\n",
493 type == G2D_IMGBUF_GEM ? "gem" : "userptr");
495 src_img.width = img_w;
496 src_img.height = img_h;
497 src_img.stride = src_img.width * 4;
498 src_img.buf_type = type;
499 src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
500 src_img.color = 0xffffffff;
501 ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w , img_h);
502 if (ret < 0)
503 goto err_free_userptr;
505 src_img.color = 0xff00ff00;
506 ret = g2d_solid_fill(ctx, &src_img, 5, 5, 100, 100);
507 if (ret < 0)
508 goto err_free_userptr;
510 dst_img.width = img_w;
511 dst_img.height = img_h;
512 dst_img.buf_type = G2D_IMGBUF_GEM;
513 dst_img.stride = dst_img.width * 4;
514 dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
516 ret = g2d_copy_with_scale(ctx, &src_img, &dst_img, 5, 5, 100, 100,
517 100, 100, 200, 200, 0);
518 if (ret < 0)
519 goto err_free_userptr;
521 g2d_exec(ctx);
523 err_free_userptr:
524 if (type == G2D_IMGBUF_USERPTR)
525 if (userptr)
526 free((void *)userptr);
528 fail:
529 g2d_fini(ctx);
531 return ret;
534 #ifdef EXYNOS_G2D_USERPTR_TEST
535 static int g2d_blend_test(struct exynos_device *dev,
536 struct exynos_bo *src,
537 struct exynos_bo *dst,
538 enum e_g2d_buf_type type)
540 struct g2d_context *ctx;
541 struct g2d_image src_img = {0}, dst_img = {0};
542 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
543 unsigned long userptr, size;
544 int ret;
546 ctx = g2d_init(dev->fd);
547 if (!ctx)
548 return -EFAULT;
550 dst_img.bo[0] = dst->handle;
552 src_x = 0;
553 src_y = 0;
554 dst_x = 0;
555 dst_y = 0;
556 img_w = screen_width;
557 img_h = screen_height;
559 switch (type) {
560 case G2D_IMGBUF_GEM:
561 src_img.bo[0] = src->handle;
562 break;
563 case G2D_IMGBUF_USERPTR:
564 size = img_w * img_h * 4;
566 userptr = (unsigned long)malloc(size);
567 if (!userptr) {
568 fprintf(stderr, "failed to allocate userptr.\n");
569 ret = -EFAULT;
570 goto fail;
573 src_img.user_ptr[0].userptr = userptr;
574 src_img.user_ptr[0].size = size;
575 break;
576 case G2D_IMGBUF_COLOR:
577 default:
578 ret = -EFAULT;
579 goto fail;
582 printf("blend test with %s.\n",
583 type == G2D_IMGBUF_GEM ? "gem" : "userptr");
585 src_img.width = img_w;
586 src_img.height = img_h;
587 src_img.stride = src_img.width * 4;
588 src_img.buf_type = type;
589 src_img.select_mode = G2D_SELECT_MODE_NORMAL;
590 src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
591 src_img.color = 0xffffffff;
592 ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w, img_h);
593 if (ret < 0)
594 goto err_free_userptr;
596 src_img.color = 0x770000ff;
597 ret = g2d_solid_fill(ctx, &src_img, 5, 5, 200, 200);
598 if (ret < 0)
599 goto err_free_userptr;
601 dst_img.width = img_w;
602 dst_img.height = img_h;
603 dst_img.stride = dst_img.width * 4;
604 dst_img.buf_type = G2D_IMGBUF_GEM;
605 dst_img.select_mode = G2D_SELECT_MODE_NORMAL;
606 dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
607 dst_img.color = 0xffffffff;
608 ret = g2d_solid_fill(ctx, &dst_img, dst_x, dst_y, img_w, img_h);
609 if (ret < 0)
610 goto err_free_userptr;
612 dst_img.color = 0x77ff0000;
613 ret = g2d_solid_fill(ctx, &dst_img, 105, 105, 200, 200);
614 if (ret < 0)
615 goto err_free_userptr;
617 ret = g2d_blend(ctx, &src_img, &dst_img, 5, 5, 105, 105, 200, 200,
618 G2D_OP_OVER);
619 if (ret < 0)
620 goto err_free_userptr;
622 g2d_exec(ctx);
624 err_free_userptr:
625 if (type == G2D_IMGBUF_USERPTR)
626 if (userptr)
627 free((void *)userptr);
629 fail:
630 g2d_fini(ctx);
632 return ret;
634 #endif
636 static int g2d_checkerboard_test(struct exynos_device *dev,
637 struct exynos_bo *src,
638 struct exynos_bo *dst,
639 enum e_g2d_buf_type type)
641 struct g2d_context *ctx;
642 struct g2d_image src_img = {0}, dst_img = {0};
643 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
644 void *checkerboard = NULL;
645 int ret;
647 ctx = g2d_init(dev->fd);
648 if (!ctx)
649 return -EFAULT;
651 dst_img.bo[0] = dst->handle;
653 src_x = 0;
654 src_y = 0;
655 dst_x = 0;
656 dst_y = 0;
658 checkerboard = create_checkerboard_pattern(screen_width / 32, screen_height / 32, 32);
659 if (!checkerboard) {
660 ret = -EFAULT;
661 goto fail;
664 img_w = screen_width - (screen_width % 32);
665 img_h = screen_height - (screen_height % 32);
667 switch (type) {
668 case G2D_IMGBUF_GEM:
669 memcpy(src->vaddr, checkerboard, img_w * img_h * 4);
670 src_img.bo[0] = src->handle;
671 break;
672 case G2D_IMGBUF_USERPTR:
673 src_img.user_ptr[0].userptr = (unsigned long)checkerboard;
674 src_img.user_ptr[0].size = img_w * img_h * 4;
675 break;
676 case G2D_IMGBUF_COLOR:
677 default:
678 ret = -EFAULT;
679 goto fail;
682 printf("checkerboard test with %s.\n",
683 type == G2D_IMGBUF_GEM ? "gem" : "userptr");
685 src_img.width = img_w;
686 src_img.height = img_h;
687 src_img.stride = src_img.width * 4;
688 src_img.buf_type = type;
689 src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
691 dst_img.width = screen_width;
692 dst_img.height = screen_height;
693 dst_img.stride = dst_img.width * 4;
694 dst_img.buf_type = G2D_IMGBUF_GEM;
695 dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
696 src_img.color = 0xff000000;
697 ret = g2d_solid_fill(ctx, &dst_img, src_x, src_y, screen_width, screen_height);
698 if (ret < 0)
699 goto fail;
701 ret = g2d_copy(ctx, &src_img, &dst_img, src_x, src_y, dst_x, dst_y,
702 img_w, img_h);
703 if (ret < 0)
704 goto fail;
706 g2d_exec(ctx);
708 fail:
709 free(checkerboard);
710 g2d_fini(ctx);
712 return ret;
715 static void usage(char *name)
717 fprintf(stderr, "usage: %s [-s]\n", name);
718 fprintf(stderr, "-s <connector_id>@<crtc_id>:<mode>\n");
719 exit(0);
722 extern char *optarg;
723 static const char optstr[] = "s:";
725 int main(int argc, char **argv)
727 struct exynos_device *dev;
728 struct exynos_bo *bo, *src;
729 struct connector con;
730 unsigned int fb_id;
731 uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
732 drmModeRes *resources;
733 int ret, fd, c;
735 memset(&con, 0, sizeof(struct connector));
737 if (argc != 3) {
738 usage(argv[0]);
739 return -EINVAL;
742 while ((c = getopt(argc, argv, optstr)) != -1) {
743 switch (c) {
744 case 's':
745 con.crtc = -1;
746 if (sscanf(optarg, "%d:0x%64s",
747 &con.id,
748 con.mode_str) != 2 &&
749 sscanf(optarg, "%d@%d:%64s",
750 &con.id,
751 &con.crtc,
752 con.mode_str) != 3)
753 usage(argv[0]);
754 break;
755 default:
756 usage(argv[0]);
757 break;
761 fd = drmOpen(DRM_MODULE_NAME, NULL);
762 if (fd < 0) {
763 fprintf(stderr, "failed to open.\n");
764 return fd;
767 dev = exynos_device_create(fd);
768 if (!dev) {
769 ret = -EFAULT;
770 goto err_drm_close;
773 resources = drmModeGetResources(dev->fd);
774 if (!resources) {
775 fprintf(stderr, "drmModeGetResources failed: %s\n",
776 strerror(errno));
777 ret = -EFAULT;
778 goto err_dev_destory;
781 connector_find_mode(dev->fd, &con, resources);
782 drmModeFreeResources(resources);
784 if (!con.mode) {
785 fprintf(stderr, "failed to find usable connector\n");
786 ret = -EFAULT;
787 goto err_dev_destory;
790 screen_width = con.mode->hdisplay;
791 screen_height = con.mode->vdisplay;
793 if (screen_width == 0 || screen_height == 0) {
794 fprintf(stderr, "failed to find sane resolution on connector\n");
795 ret = -EFAULT;
796 goto err_dev_destory;
799 printf("screen width = %d, screen height = %d\n", screen_width,
800 screen_height);
802 bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
803 if (!bo) {
804 ret = -EFAULT;
805 goto err_dev_destory;
808 handles[0] = bo->handle;
809 pitches[0] = screen_width * 4;
810 offsets[0] = 0;
812 ret = drmModeAddFB2(dev->fd, screen_width, screen_height,
813 DRM_FORMAT_XRGB8888, handles,
814 pitches, offsets, &fb_id, 0);
815 if (ret < 0)
816 goto err_destroy_buffer;
818 memset(bo->vaddr, 0xff, screen_width * screen_height * 4);
820 ret = drm_set_crtc(dev, &con, fb_id);
821 if (ret < 0)
822 goto err_rm_fb;
824 ret = g2d_solid_fill_test(dev, bo);
825 if (ret < 0) {
826 fprintf(stderr, "failed to solid fill operation.\n");
827 goto err_rm_fb;
830 wait_for_user_input(0);
832 src = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
833 if (!src) {
834 ret = -EFAULT;
835 goto err_rm_fb;
838 ret = g2d_copy_test(dev, src, bo, G2D_IMGBUF_GEM);
839 if (ret < 0) {
840 fprintf(stderr, "failed to test copy operation.\n");
841 goto err_free_src;
844 wait_for_user_input(0);
846 ret = g2d_move_test(dev, src, bo, G2D_IMGBUF_GEM);
847 if (ret < 0) {
848 fprintf(stderr, "failed to test move operation.\n");
849 goto err_free_src;
852 wait_for_user_input(0);
854 ret = g2d_copy_with_scale_test(dev, src, bo, G2D_IMGBUF_GEM);
855 if (ret < 0) {
856 fprintf(stderr, "failed to test copy and scale operation.\n");
857 goto err_free_src;
860 wait_for_user_input(0);
862 ret = g2d_checkerboard_test(dev, src, bo, G2D_IMGBUF_GEM);
863 if (ret < 0) {
864 fprintf(stderr, "failed to issue checkerboard test.\n");
865 goto err_free_src;
868 wait_for_user_input(1);
871 * The blend test uses the userptr functionality of exynos-drm, which
872 * is currently not safe to use. If the kernel hasn't been build with
873 * exynos-iommu support, then the blend test is going to produce (kernel)
874 * memory corruption, eventually leading to a system crash.
876 * Disable the test for now, until the kernel code has been sanitized.
878 #ifdef EXYNOS_G2D_USERPTR_TEST
879 ret = g2d_blend_test(dev, src, bo, G2D_IMGBUF_USERPTR);
880 if (ret < 0)
881 fprintf(stderr, "failed to test blend operation.\n");
883 getchar();
884 #endif
886 err_free_src:
887 if (src)
888 exynos_destroy_buffer(src);
890 err_rm_fb:
891 drmModeRmFB(dev->fd, fb_id);
893 err_destroy_buffer:
894 exynos_destroy_buffer(bo);
896 err_dev_destory:
897 exynos_device_destroy(dev);
899 err_drm_close:
900 drmClose(fd);
902 return ret;