blob: d0634bbef732a3efbb21177e61709e55c0d3e268 [file] [log] [blame]
Chris Wilsoncd306d42015-07-24 18:54:11 +01001/*
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
Chris Wilsoncd306d42015-07-24 18:54:11 +010052static double elapsed(const struct timespec *start,
53 const struct timespec *end)
54{
55 return (end->tv_sec - start->tv_sec) + 1e-9*(end->tv_nsec - start->tv_nsec);
56}
57
58static void make_busy(int fd, uint32_t handle)
59{
60 struct drm_i915_gem_execbuffer2 execbuf;
61 struct drm_i915_gem_exec_object2 gem_exec;
62
63 const uint32_t buf[] = {MI_BATCH_BUFFER_END};
64 gem_write(fd, handle, 0, buf, sizeof(buf));
65
66 memset(&gem_exec, 0, sizeof(gem_exec));
67 gem_exec.handle = handle;
68
69 memset(&execbuf, 0, sizeof(execbuf));
70 execbuf.buffers_ptr = (uintptr_t)&gem_exec;
71 execbuf.buffer_count = 1;
72 execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
73 execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
74 if (__gem_execbuf(fd, &execbuf)) {
75 execbuf.flags = 0;
76 gem_execbuf(fd, &execbuf);
77 }
78}
79
80int main(int argc, char **argv)
81{
Micah Fedkec81d2932015-07-22 21:54:02 +000082 int fd = drm_open_driver(DRIVER_INTEL);
Chris Wilsoncd306d42015-07-24 18:54:11 +010083 int size = 0;
84 int busy = 0;
85 int reps = 13;
86 int c, n, s;
87
88 while ((c = getopt (argc, argv, "bs:r:")) != -1) {
89 switch (c) {
90 case 's':
91 size = atoi(optarg);
92 break;
93
94 case 'r':
95 reps = atoi(optarg);
96 if (reps < 1)
97 reps = 1;
98 break;
99
100 case 'b':
101 busy = true;
102 break;
103
104 default:
105 break;
106 }
107 }
108
109 if (size == 0) {
110 for (s = 4096; s <= OBJECT_SIZE; s <<= 1) {
111 igt_stats_t stats;
112
113 igt_stats_init_with_size(&stats, reps);
114 for (n = 0; n < reps; n++) {
115 struct timespec start, end;
116 uint64_t count = 0;
117
118 clock_gettime(CLOCK_MONOTONIC, &start);
119 do {
120 for (c = 0; c < 1000; c++) {
121 uint32_t handle;
122
123 handle = gem_create(fd, s);
124 gem_set_domain(fd, handle,
125 I915_GEM_DOMAIN_GTT,
126 I915_GEM_DOMAIN_GTT);
127 if (busy)
128 make_busy(fd, handle);
129 gem_close(fd, handle);
130 }
131 count += c;
132 clock_gettime(CLOCK_MONOTONIC, &end);
133 } while (end.tv_sec - start.tv_sec < 2);
134
135 igt_stats_push_float(&stats, count / elapsed(&start, &end));
136 }
137 printf("%f\n", igt_stats_get_trimean(&stats));
138 igt_stats_fini(&stats);
139 }
140 } else {
141 for (n = 0; n < reps; n++) {
142 struct timespec start, end;
143 uint64_t count = 0;
144
145 clock_gettime(CLOCK_MONOTONIC, &start);
146 do {
147 for (c = 0; c < 1000; c++) {
148 uint32_t handle;
149
150 handle = gem_create(fd, size);
151 gem_set_domain(fd, handle,
152 I915_GEM_DOMAIN_GTT,
153 I915_GEM_DOMAIN_GTT);
154 if (busy)
155 make_busy(fd, handle);
156 gem_close(fd, handle);
157 }
158 count += c;
159 clock_gettime(CLOCK_MONOTONIC, &end);
160 } while (end.tv_sec - start.tv_sec < 2);
161
162 printf("%f\n", count / elapsed(&start, &end));
163 }
164 }
165
166 return 0;
167}