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