exynos_fimg2d_perf.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. * Copyright (C) 2015 - Tobias Jakobi
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <time.h>
  26. #include <getopt.h>
  27. #include <errno.h>
  28. #include <xf86drm.h>
  29. #include "exynos_drm.h"
  30. #include "exynos_drmif.h"
  31. #include "exynos_fimg2d.h"
  32. static int output_mathematica = 0;
  33. static int fimg2d_perf_simple(struct exynos_bo *bo, struct g2d_context *ctx,
  34. unsigned buf_width, unsigned buf_height, unsigned iterations)
  35. {
  36. struct timespec tspec = { 0 };
  37. struct g2d_image img = { 0 };
  38. unsigned long long g2d_time;
  39. unsigned i;
  40. int ret = 0;
  41. img.width = buf_width;
  42. img.height = buf_height;
  43. img.stride = buf_width * 4;
  44. img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
  45. img.buf_type = G2D_IMGBUF_GEM;
  46. img.bo[0] = bo->handle;
  47. srand(time(NULL));
  48. printf("starting simple G2D performance test\n");
  49. printf("buffer width = %u, buffer height = %u, iterations = %u\n",
  50. buf_width, buf_height, iterations);
  51. if (output_mathematica)
  52. putchar('{');
  53. for (i = 0; i < iterations; ++i) {
  54. unsigned x, y, w, h;
  55. x = rand() % buf_width;
  56. y = rand() % buf_height;
  57. if (x == (buf_width - 1))
  58. x -= 1;
  59. if (y == (buf_height - 1))
  60. y -= 1;
  61. w = rand() % (buf_width - x);
  62. h = rand() % (buf_height - y);
  63. if (w == 0) w = 1;
  64. if (h == 0) h = 1;
  65. img.color = rand();
  66. ret = g2d_solid_fill(ctx, &img, x, y, w, h);
  67. clock_gettime(CLOCK_MONOTONIC, &tspec);
  68. if (ret == 0)
  69. ret = g2d_exec(ctx);
  70. if (ret != 0) {
  71. fprintf(stderr, "error: iteration %u failed (x = %u, y = %u, w = %u, h = %u)\n",
  72. i, x, y, w, h);
  73. break;
  74. } else {
  75. struct timespec end = { 0 };
  76. clock_gettime(CLOCK_MONOTONIC, &end);
  77. g2d_time = (end.tv_sec - tspec.tv_sec) * 1000000000ULL;
  78. g2d_time += (end.tv_nsec - tspec.tv_nsec);
  79. if (output_mathematica) {
  80. if (i != 0) putchar(',');
  81. printf("{%u,%llu}", w * h, g2d_time);
  82. } else {
  83. printf("num_pixels = %u, usecs = %llu\n", w * h, g2d_time);
  84. }
  85. }
  86. }
  87. if (output_mathematica)
  88. printf("}\n");
  89. return ret;
  90. }
  91. static int fimg2d_perf_multi(struct exynos_bo *bo, struct g2d_context *ctx,
  92. unsigned buf_width, unsigned buf_height, unsigned iterations, unsigned batch)
  93. {
  94. struct timespec tspec = { 0 };
  95. struct g2d_image *images;
  96. unsigned long long g2d_time;
  97. unsigned i, j;
  98. int ret = 0;
  99. images = calloc(batch, sizeof(struct g2d_image));
  100. if (images == NULL) {
  101. fprintf(stderr, "error: failed to allocate G2D images.\n");
  102. return -ENOMEM;
  103. }
  104. for (i = 0; i < batch; ++i) {
  105. images[i].width = buf_width;
  106. images[i].height = buf_height;
  107. images[i].stride = buf_width * 4;
  108. images[i].color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
  109. images[i].buf_type = G2D_IMGBUF_GEM;
  110. images[i].bo[0] = bo->handle;
  111. }
  112. srand(time(NULL));
  113. printf("starting multi G2D performance test (batch size = %u)\n", batch);
  114. printf("buffer width = %u, buffer height = %u, iterations = %u\n",
  115. buf_width, buf_height, iterations);
  116. if (output_mathematica)
  117. putchar('{');
  118. for (i = 0; i < iterations; ++i) {
  119. unsigned num_pixels = 0;
  120. for (j = 0; j < batch; ++j) {
  121. unsigned x, y, w, h;
  122. x = rand() % buf_width;
  123. y = rand() % buf_height;
  124. if (x == (buf_width - 1))
  125. x -= 1;
  126. if (y == (buf_height - 1))
  127. y -= 1;
  128. w = rand() % (buf_width - x);
  129. h = rand() % (buf_height - y);
  130. if (w == 0) w = 1;
  131. if (h == 0) h = 1;
  132. images[j].color = rand();
  133. num_pixels += w * h;
  134. ret = g2d_solid_fill(ctx, &images[j], x, y, w, h);
  135. if (ret != 0)
  136. break;
  137. }
  138. clock_gettime(CLOCK_MONOTONIC, &tspec);
  139. if (ret == 0)
  140. ret = g2d_exec(ctx);
  141. if (ret != 0) {
  142. fprintf(stderr, "error: iteration %u failed (num_pixels = %u)\n", i, num_pixels);
  143. break;
  144. } else {
  145. struct timespec end = { 0 };
  146. clock_gettime(CLOCK_MONOTONIC, &end);
  147. g2d_time = (end.tv_sec - tspec.tv_sec) * 1000000000ULL;
  148. g2d_time += (end.tv_nsec - tspec.tv_nsec);
  149. if (output_mathematica) {
  150. if (i != 0) putchar(',');
  151. printf("{%u,%llu}", num_pixels, g2d_time);
  152. } else {
  153. printf("num_pixels = %u, usecs = %llu\n", num_pixels, g2d_time);
  154. }
  155. }
  156. }
  157. if (output_mathematica)
  158. printf("}\n");
  159. free(images);
  160. return ret;
  161. }
  162. static void usage(const char *name)
  163. {
  164. fprintf(stderr, "usage: %s [-ibwh]\n\n", name);
  165. fprintf(stderr, "\t-i <number of iterations>\n");
  166. fprintf(stderr, "\t-b <size of a batch> (default = 3)\n\n");
  167. fprintf(stderr, "\t-w <buffer width> (default = 4096)\n");
  168. fprintf(stderr, "\t-h <buffer height> (default = 4096)\n\n");
  169. fprintf(stderr, "\t-M <enable Mathematica styled output>\n");
  170. exit(0);
  171. }
  172. int main(int argc, char **argv)
  173. {
  174. int fd, ret, c, parsefail;
  175. struct exynos_device *dev;
  176. struct g2d_context *ctx;
  177. struct exynos_bo *bo;
  178. unsigned int iters = 0, batch = 3;
  179. unsigned int bufw = 4096, bufh = 4096;
  180. ret = 0;
  181. parsefail = 0;
  182. while ((c = getopt(argc, argv, "i:b:w:h:M")) != -1) {
  183. switch (c) {
  184. case 'i':
  185. if (sscanf(optarg, "%u", &iters) != 1)
  186. parsefail = 1;
  187. break;
  188. case 'b':
  189. if (sscanf(optarg, "%u", &batch) != 1)
  190. parsefail = 1;
  191. break;
  192. case 'w':
  193. if (sscanf(optarg, "%u", &bufw) != 1)
  194. parsefail = 1;
  195. break;
  196. case 'h':
  197. if (sscanf(optarg, "%u", &bufh) != 1)
  198. parsefail = 1;
  199. break;
  200. case 'M':
  201. output_mathematica = 1;
  202. break;
  203. default:
  204. parsefail = 1;
  205. break;
  206. }
  207. }
  208. if (parsefail || (argc == 1) || (iters == 0))
  209. usage(argv[0]);
  210. if (bufw < 2 || bufw > 4096 || bufh < 2 || bufh > 4096) {
  211. fprintf(stderr, "error: buffer width/height should be in the range 2 to 4096.\n");
  212. ret = -1;
  213. goto out;
  214. }
  215. fd = drmOpen("exynos", NULL);
  216. if (fd < 0) {
  217. fprintf(stderr, "error: failed to open drm\n");
  218. ret = -1;
  219. goto out;
  220. }
  221. dev = exynos_device_create(fd);
  222. if (dev == NULL) {
  223. fprintf(stderr, "error: failed to create device\n");
  224. ret = -2;
  225. goto fail;
  226. }
  227. ctx = g2d_init(fd);
  228. if (ctx == NULL) {
  229. fprintf(stderr, "error: failed to init G2D\n");
  230. ret = -3;
  231. goto g2d_fail;
  232. }
  233. bo = exynos_bo_create(dev, bufw * bufh * 4, 0);
  234. if (bo == NULL) {
  235. fprintf(stderr, "error: failed to create bo\n");
  236. ret = -4;
  237. goto bo_fail;
  238. }
  239. ret = fimg2d_perf_simple(bo, ctx, bufw, bufh, iters);
  240. if (ret == 0)
  241. ret = fimg2d_perf_multi(bo, ctx, bufw, bufh, iters, batch);
  242. exynos_bo_destroy(bo);
  243. bo_fail:
  244. g2d_fini(ctx);
  245. g2d_fail:
  246. exynos_device_destroy(dev);
  247. fail:
  248. drmClose(fd);
  249. out:
  250. return ret;
  251. }