| Chris Wilson | cd306d4 | 2015-07-24 18:54:11 +0100 | [diff] [blame^] | 1 | /* | 
|  | 2 | * Copyright © 2011-2015 Intel Corporation | 
|  | 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 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
|  | 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | 
|  | 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | 
|  | 21 | * IN THE SOFTWARE. | 
|  | 22 | * | 
|  | 23 | * Authors: | 
|  | 24 | *    Chris Wilson <chris@chris-wilson.co.uk> | 
|  | 25 | * | 
|  | 26 | */ | 
|  | 27 |  | 
|  | 28 | #include <unistd.h> | 
|  | 29 | #include <stdlib.h> | 
|  | 30 | #include <stdint.h> | 
|  | 31 | #include <stdio.h> | 
|  | 32 | #include <string.h> | 
|  | 33 | #include <fcntl.h> | 
|  | 34 | #include <inttypes.h> | 
|  | 35 | #include <errno.h> | 
|  | 36 | #include <sys/stat.h> | 
|  | 37 | #include <sys/ioctl.h> | 
|  | 38 | #include <sys/time.h> | 
|  | 39 | #include <time.h> | 
|  | 40 |  | 
|  | 41 | #include "drm.h" | 
|  | 42 | #include "ioctl_wrappers.h" | 
|  | 43 | #include "drmtest.h" | 
|  | 44 | #include "igt_aux.h" | 
|  | 45 | #include "igt_stats.h" | 
|  | 46 |  | 
|  | 47 | #define OBJECT_SIZE (1<<23) | 
|  | 48 |  | 
|  | 49 | #define LOCAL_I915_EXEC_NO_RELOC (1<<11) | 
|  | 50 | #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12) | 
|  | 51 |  | 
|  | 52 | static int __gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf) | 
|  | 53 | { | 
|  | 54 | int err = 0; | 
|  | 55 | if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf)) | 
|  | 56 | err = -errno; | 
|  | 57 | return err; | 
|  | 58 | } | 
|  | 59 |  | 
|  | 60 |  | 
|  | 61 | static double elapsed(const struct timespec *start, | 
|  | 62 | const struct timespec *end) | 
|  | 63 | { | 
|  | 64 | return (end->tv_sec - start->tv_sec) + 1e-9*(end->tv_nsec - start->tv_nsec); | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | static void make_busy(int fd, uint32_t handle) | 
|  | 68 | { | 
|  | 69 | struct drm_i915_gem_execbuffer2 execbuf; | 
|  | 70 | struct drm_i915_gem_exec_object2 gem_exec; | 
|  | 71 |  | 
|  | 72 | const uint32_t buf[] = {MI_BATCH_BUFFER_END}; | 
|  | 73 | gem_write(fd, handle, 0, buf, sizeof(buf)); | 
|  | 74 |  | 
|  | 75 | memset(&gem_exec, 0, sizeof(gem_exec)); | 
|  | 76 | gem_exec.handle = handle; | 
|  | 77 |  | 
|  | 78 | memset(&execbuf, 0, sizeof(execbuf)); | 
|  | 79 | execbuf.buffers_ptr = (uintptr_t)&gem_exec; | 
|  | 80 | execbuf.buffer_count = 1; | 
|  | 81 | execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT; | 
|  | 82 | execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC; | 
|  | 83 | if (__gem_execbuf(fd, &execbuf)) { | 
|  | 84 | execbuf.flags = 0; | 
|  | 85 | gem_execbuf(fd, &execbuf); | 
|  | 86 | } | 
|  | 87 | } | 
|  | 88 |  | 
|  | 89 | int main(int argc, char **argv) | 
|  | 90 | { | 
|  | 91 | int fd = drm_open_any(); | 
|  | 92 | int size = 0; | 
|  | 93 | int busy = 0; | 
|  | 94 | int reps = 13; | 
|  | 95 | int c, n, s; | 
|  | 96 |  | 
|  | 97 | while ((c = getopt (argc, argv, "bs:r:")) != -1) { | 
|  | 98 | switch (c) { | 
|  | 99 | case 's': | 
|  | 100 | size = atoi(optarg); | 
|  | 101 | break; | 
|  | 102 |  | 
|  | 103 | case 'r': | 
|  | 104 | reps = atoi(optarg); | 
|  | 105 | if (reps < 1) | 
|  | 106 | reps = 1; | 
|  | 107 | break; | 
|  | 108 |  | 
|  | 109 | case 'b': | 
|  | 110 | busy = true; | 
|  | 111 | break; | 
|  | 112 |  | 
|  | 113 | default: | 
|  | 114 | break; | 
|  | 115 | } | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | if (size == 0) { | 
|  | 119 | for (s = 4096; s <=  OBJECT_SIZE; s <<= 1) { | 
|  | 120 | igt_stats_t stats; | 
|  | 121 |  | 
|  | 122 | igt_stats_init_with_size(&stats, reps); | 
|  | 123 | for (n = 0; n < reps; n++) { | 
|  | 124 | struct timespec start, end; | 
|  | 125 | uint64_t count = 0; | 
|  | 126 |  | 
|  | 127 | clock_gettime(CLOCK_MONOTONIC, &start); | 
|  | 128 | do { | 
|  | 129 | for (c = 0; c < 1000; c++) { | 
|  | 130 | uint32_t handle; | 
|  | 131 |  | 
|  | 132 | handle = gem_create(fd, s); | 
|  | 133 | gem_set_domain(fd, handle, | 
|  | 134 | I915_GEM_DOMAIN_GTT, | 
|  | 135 | I915_GEM_DOMAIN_GTT); | 
|  | 136 | if (busy) | 
|  | 137 | make_busy(fd, handle); | 
|  | 138 | gem_close(fd, handle); | 
|  | 139 | } | 
|  | 140 | count += c; | 
|  | 141 | clock_gettime(CLOCK_MONOTONIC, &end); | 
|  | 142 | } while (end.tv_sec - start.tv_sec < 2); | 
|  | 143 |  | 
|  | 144 | igt_stats_push_float(&stats, count / elapsed(&start, &end)); | 
|  | 145 | } | 
|  | 146 | printf("%f\n", igt_stats_get_trimean(&stats)); | 
|  | 147 | igt_stats_fini(&stats); | 
|  | 148 | } | 
|  | 149 | } else { | 
|  | 150 | for (n = 0; n < reps; n++) { | 
|  | 151 | struct timespec start, end; | 
|  | 152 | uint64_t count = 0; | 
|  | 153 |  | 
|  | 154 | clock_gettime(CLOCK_MONOTONIC, &start); | 
|  | 155 | do { | 
|  | 156 | for (c = 0; c < 1000; c++) { | 
|  | 157 | uint32_t handle; | 
|  | 158 |  | 
|  | 159 | handle = gem_create(fd, size); | 
|  | 160 | gem_set_domain(fd, handle, | 
|  | 161 | I915_GEM_DOMAIN_GTT, | 
|  | 162 | I915_GEM_DOMAIN_GTT); | 
|  | 163 | if (busy) | 
|  | 164 | make_busy(fd, handle); | 
|  | 165 | gem_close(fd, handle); | 
|  | 166 | } | 
|  | 167 | count += c; | 
|  | 168 | clock_gettime(CLOCK_MONOTONIC, &end); | 
|  | 169 | } while (end.tv_sec - start.tv_sec < 2); | 
|  | 170 |  | 
|  | 171 | printf("%f\n", count / elapsed(&start, &end)); | 
|  | 172 | } | 
|  | 173 | } | 
|  | 174 |  | 
|  | 175 | return 0; | 
|  | 176 | } |