1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2011 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker *
4*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker *
11*d83cc019SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker * Software.
14*d83cc019SAndroid Build Coastguard Worker *
15*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker *
23*d83cc019SAndroid Build Coastguard Worker * Authors:
24*d83cc019SAndroid Build Coastguard Worker * Chris Wilson <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker *
26*d83cc019SAndroid Build Coastguard Worker */
27*d83cc019SAndroid Build Coastguard Worker
28*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
31*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
32*d83cc019SAndroid Build Coastguard Worker #include <string.h>
33*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
34*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
35*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
36*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
37*d83cc019SAndroid Build Coastguard Worker #include <sys/poll.h>
38*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
39*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
40*d83cc019SAndroid Build Coastguard Worker #include <time.h>
41*d83cc019SAndroid Build Coastguard Worker
42*d83cc019SAndroid Build Coastguard Worker #include "drm.h"
43*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
44*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
45*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
46*d83cc019SAndroid Build Coastguard Worker #include "intel_reg.h"
47*d83cc019SAndroid Build Coastguard Worker #include "igt_stats.h"
48*d83cc019SAndroid Build Coastguard Worker #include "i915/gem_mman.h"
49*d83cc019SAndroid Build Coastguard Worker
50*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_NO_RELOC (1<<11)
51*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
52*d83cc019SAndroid Build Coastguard Worker
53*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_SHIFT (13)
54*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
55*d83cc019SAndroid Build Coastguard Worker
56*d83cc019SAndroid Build Coastguard Worker #define ENGINE_FLAGS (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
57*d83cc019SAndroid Build Coastguard Worker
58*d83cc019SAndroid Build Coastguard Worker #define WRITE 0x1
59*d83cc019SAndroid Build Coastguard Worker #define IDLE 0x2
60*d83cc019SAndroid Build Coastguard Worker #define DMABUF 0x4
61*d83cc019SAndroid Build Coastguard Worker #define WAIT 0x8
62*d83cc019SAndroid Build Coastguard Worker #define SYNC 0x10
63*d83cc019SAndroid Build Coastguard Worker #define SYNCOBJ 0x20
64*d83cc019SAndroid Build Coastguard Worker
65*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_FENCE_ARRAY (1 << 19)
66*d83cc019SAndroid Build Coastguard Worker struct local_gem_exec_fence {
67*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
68*d83cc019SAndroid Build Coastguard Worker uint32_t flags;
69*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_FENCE_WAIT (1 << 0)
70*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_FENCE_SIGNAL (1 << 1)
71*d83cc019SAndroid Build Coastguard Worker };
72*d83cc019SAndroid Build Coastguard Worker
gem_busy(int fd,uint32_t handle)73*d83cc019SAndroid Build Coastguard Worker static void gem_busy(int fd, uint32_t handle)
74*d83cc019SAndroid Build Coastguard Worker {
75*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_busy busy = { .handle = handle };
76*d83cc019SAndroid Build Coastguard Worker ioctl(fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
77*d83cc019SAndroid Build Coastguard Worker }
78*d83cc019SAndroid Build Coastguard Worker
gem_wait__busy(int fd,uint32_t handle)79*d83cc019SAndroid Build Coastguard Worker static void gem_wait__busy(int fd, uint32_t handle)
80*d83cc019SAndroid Build Coastguard Worker {
81*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_wait wait = { .bo_handle = handle };
82*d83cc019SAndroid Build Coastguard Worker ioctl(fd, DRM_IOCTL_I915_GEM_WAIT, &wait);
83*d83cc019SAndroid Build Coastguard Worker }
84*d83cc019SAndroid Build Coastguard Worker
elapsed(const struct timespec * start,const struct timespec * end)85*d83cc019SAndroid Build Coastguard Worker static double elapsed(const struct timespec *start,
86*d83cc019SAndroid Build Coastguard Worker const struct timespec *end)
87*d83cc019SAndroid Build Coastguard Worker {
88*d83cc019SAndroid Build Coastguard Worker return 1e9*(end->tv_sec - start->tv_sec) +
89*d83cc019SAndroid Build Coastguard Worker (end->tv_nsec - start->tv_nsec);
90*d83cc019SAndroid Build Coastguard Worker }
91*d83cc019SAndroid Build Coastguard Worker
92*d83cc019SAndroid Build Coastguard Worker struct sync_merge_data {
93*d83cc019SAndroid Build Coastguard Worker char name[32];
94*d83cc019SAndroid Build Coastguard Worker __s32 fd2;
95*d83cc019SAndroid Build Coastguard Worker __s32 fence;
96*d83cc019SAndroid Build Coastguard Worker __u32 flags;
97*d83cc019SAndroid Build Coastguard Worker __u32 pad;
98*d83cc019SAndroid Build Coastguard Worker };
99*d83cc019SAndroid Build Coastguard Worker
100*d83cc019SAndroid Build Coastguard Worker #define SYNC_IOC_MAGIC '>'
101*d83cc019SAndroid Build Coastguard Worker #define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
102*d83cc019SAndroid Build Coastguard Worker
sync_merge(int fd1,int fd2)103*d83cc019SAndroid Build Coastguard Worker static int sync_merge(int fd1, int fd2)
104*d83cc019SAndroid Build Coastguard Worker {
105*d83cc019SAndroid Build Coastguard Worker struct sync_merge_data data;
106*d83cc019SAndroid Build Coastguard Worker
107*d83cc019SAndroid Build Coastguard Worker if (fd1 == -1)
108*d83cc019SAndroid Build Coastguard Worker return dup(fd2);
109*d83cc019SAndroid Build Coastguard Worker
110*d83cc019SAndroid Build Coastguard Worker if (fd2 == -1)
111*d83cc019SAndroid Build Coastguard Worker return dup(fd1);
112*d83cc019SAndroid Build Coastguard Worker
113*d83cc019SAndroid Build Coastguard Worker memset(&data, 0, sizeof(data));
114*d83cc019SAndroid Build Coastguard Worker data.fd2 = fd2;
115*d83cc019SAndroid Build Coastguard Worker strcpy(data.name, "i965");
116*d83cc019SAndroid Build Coastguard Worker
117*d83cc019SAndroid Build Coastguard Worker if (ioctl(fd1, SYNC_IOC_MERGE, &data))
118*d83cc019SAndroid Build Coastguard Worker return -errno;
119*d83cc019SAndroid Build Coastguard Worker
120*d83cc019SAndroid Build Coastguard Worker return data.fence;
121*d83cc019SAndroid Build Coastguard Worker }
122*d83cc019SAndroid Build Coastguard Worker
__syncobj_create(int fd)123*d83cc019SAndroid Build Coastguard Worker static uint32_t __syncobj_create(int fd)
124*d83cc019SAndroid Build Coastguard Worker {
125*d83cc019SAndroid Build Coastguard Worker struct local_syncobj_create {
126*d83cc019SAndroid Build Coastguard Worker uint32_t handle, flags;
127*d83cc019SAndroid Build Coastguard Worker } arg;
128*d83cc019SAndroid Build Coastguard Worker #define LOCAL_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct local_syncobj_create)
129*d83cc019SAndroid Build Coastguard Worker
130*d83cc019SAndroid Build Coastguard Worker memset(&arg, 0, sizeof(arg));
131*d83cc019SAndroid Build Coastguard Worker ioctl(fd, LOCAL_IOCTL_SYNCOBJ_CREATE, &arg);
132*d83cc019SAndroid Build Coastguard Worker
133*d83cc019SAndroid Build Coastguard Worker return arg.handle;
134*d83cc019SAndroid Build Coastguard Worker }
135*d83cc019SAndroid Build Coastguard Worker
syncobj_create(int fd)136*d83cc019SAndroid Build Coastguard Worker static uint32_t syncobj_create(int fd)
137*d83cc019SAndroid Build Coastguard Worker {
138*d83cc019SAndroid Build Coastguard Worker uint32_t ret;
139*d83cc019SAndroid Build Coastguard Worker
140*d83cc019SAndroid Build Coastguard Worker igt_assert_neq((ret = __syncobj_create(fd)), 0);
141*d83cc019SAndroid Build Coastguard Worker
142*d83cc019SAndroid Build Coastguard Worker return ret;
143*d83cc019SAndroid Build Coastguard Worker }
144*d83cc019SAndroid Build Coastguard Worker
145*d83cc019SAndroid Build Coastguard Worker #define LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
146*d83cc019SAndroid Build Coastguard Worker #define LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
147*d83cc019SAndroid Build Coastguard Worker struct local_syncobj_wait {
148*d83cc019SAndroid Build Coastguard Worker __u64 handles;
149*d83cc019SAndroid Build Coastguard Worker /* absolute timeout */
150*d83cc019SAndroid Build Coastguard Worker __s64 timeout_nsec;
151*d83cc019SAndroid Build Coastguard Worker __u32 count_handles;
152*d83cc019SAndroid Build Coastguard Worker __u32 flags;
153*d83cc019SAndroid Build Coastguard Worker __u32 first_signaled; /* only valid when not waiting all */
154*d83cc019SAndroid Build Coastguard Worker __u32 pad;
155*d83cc019SAndroid Build Coastguard Worker };
156*d83cc019SAndroid Build Coastguard Worker #define LOCAL_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct local_syncobj_wait)
__syncobj_wait(int fd,struct local_syncobj_wait * args)157*d83cc019SAndroid Build Coastguard Worker static int __syncobj_wait(int fd, struct local_syncobj_wait *args)
158*d83cc019SAndroid Build Coastguard Worker {
159*d83cc019SAndroid Build Coastguard Worker int err = 0;
160*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_WAIT, args))
161*d83cc019SAndroid Build Coastguard Worker err = -errno;
162*d83cc019SAndroid Build Coastguard Worker return err;
163*d83cc019SAndroid Build Coastguard Worker }
164*d83cc019SAndroid Build Coastguard Worker
loop(unsigned ring,int reps,int ncpus,unsigned flags)165*d83cc019SAndroid Build Coastguard Worker static int loop(unsigned ring, int reps, int ncpus, unsigned flags)
166*d83cc019SAndroid Build Coastguard Worker {
167*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
168*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj[2];
169*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc[2];
170*d83cc019SAndroid Build Coastguard Worker struct local_gem_exec_fence syncobj;
171*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
172*d83cc019SAndroid Build Coastguard Worker unsigned nengine;
173*d83cc019SAndroid Build Coastguard Worker uint32_t *batch;
174*d83cc019SAndroid Build Coastguard Worker double *shared;
175*d83cc019SAndroid Build Coastguard Worker int fd, i, gen;
176*d83cc019SAndroid Build Coastguard Worker int dmabuf;
177*d83cc019SAndroid Build Coastguard Worker
178*d83cc019SAndroid Build Coastguard Worker shared = mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
179*d83cc019SAndroid Build Coastguard Worker
180*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
181*d83cc019SAndroid Build Coastguard Worker gen = intel_gen(intel_get_drm_devid(fd));
182*d83cc019SAndroid Build Coastguard Worker
183*d83cc019SAndroid Build Coastguard Worker memset(obj, 0, sizeof(obj));
184*d83cc019SAndroid Build Coastguard Worker obj[0].handle = gem_create(fd, 4096);
185*d83cc019SAndroid Build Coastguard Worker if (flags & WRITE)
186*d83cc019SAndroid Build Coastguard Worker obj[0].flags = EXEC_OBJECT_WRITE;
187*d83cc019SAndroid Build Coastguard Worker obj[1].handle = gem_create(fd, 4096);
188*d83cc019SAndroid Build Coastguard Worker if (gem_mmap__has_wc(fd))
189*d83cc019SAndroid Build Coastguard Worker batch = gem_mmap__wc(fd, obj[1].handle, 0, 4096, PROT_WRITE);
190*d83cc019SAndroid Build Coastguard Worker else
191*d83cc019SAndroid Build Coastguard Worker batch = gem_mmap__gtt(fd, obj[1].handle, 4096, PROT_WRITE);
192*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[1].handle,
193*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
194*d83cc019SAndroid Build Coastguard Worker batch[0] = MI_BATCH_BUFFER_END;
195*d83cc019SAndroid Build Coastguard Worker
196*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
197*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(obj);
198*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
199*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
200*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
201*d83cc019SAndroid Build Coastguard Worker if (__gem_execbuf(fd, &execbuf)) {
202*d83cc019SAndroid Build Coastguard Worker execbuf.flags = 0;
203*d83cc019SAndroid Build Coastguard Worker if (__gem_execbuf(fd, &execbuf))
204*d83cc019SAndroid Build Coastguard Worker return 77;
205*d83cc019SAndroid Build Coastguard Worker }
206*d83cc019SAndroid Build Coastguard Worker
207*d83cc019SAndroid Build Coastguard Worker if (flags & SYNCOBJ) {
208*d83cc019SAndroid Build Coastguard Worker syncobj.handle = syncobj_create(fd);
209*d83cc019SAndroid Build Coastguard Worker syncobj.flags = LOCAL_EXEC_FENCE_SIGNAL;
210*d83cc019SAndroid Build Coastguard Worker
211*d83cc019SAndroid Build Coastguard Worker execbuf.cliprects_ptr = to_user_pointer(&syncobj);
212*d83cc019SAndroid Build Coastguard Worker execbuf.num_cliprects = 1;
213*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_FENCE_ARRAY;
214*d83cc019SAndroid Build Coastguard Worker }
215*d83cc019SAndroid Build Coastguard Worker
216*d83cc019SAndroid Build Coastguard Worker if (ring == -1) {
217*d83cc019SAndroid Build Coastguard Worker nengine = 0;
218*d83cc019SAndroid Build Coastguard Worker for (ring = 1; ring < 16; ring++) {
219*d83cc019SAndroid Build Coastguard Worker execbuf.flags &= ~ENGINE_FLAGS;
220*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= ring;
221*d83cc019SAndroid Build Coastguard Worker if (__gem_execbuf(fd, &execbuf) == 0)
222*d83cc019SAndroid Build Coastguard Worker engines[nengine++] = ring;
223*d83cc019SAndroid Build Coastguard Worker }
224*d83cc019SAndroid Build Coastguard Worker } else {
225*d83cc019SAndroid Build Coastguard Worker nengine = 1;
226*d83cc019SAndroid Build Coastguard Worker engines[0] = ring;
227*d83cc019SAndroid Build Coastguard Worker }
228*d83cc019SAndroid Build Coastguard Worker
229*d83cc019SAndroid Build Coastguard Worker obj[1].relocs_ptr = to_user_pointer(reloc);
230*d83cc019SAndroid Build Coastguard Worker obj[1].relocation_count = 2;
231*d83cc019SAndroid Build Coastguard Worker
232*d83cc019SAndroid Build Coastguard Worker if (flags & DMABUF)
233*d83cc019SAndroid Build Coastguard Worker dmabuf = prime_handle_to_fd(fd, obj[0].handle);
234*d83cc019SAndroid Build Coastguard Worker
235*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[1].handle,
236*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
237*d83cc019SAndroid Build Coastguard Worker
238*d83cc019SAndroid Build Coastguard Worker reloc[0].target_handle = obj[1].handle; /* recurse */
239*d83cc019SAndroid Build Coastguard Worker reloc[0].presumed_offset = obj[1].offset;
240*d83cc019SAndroid Build Coastguard Worker reloc[0].offset = sizeof(uint32_t);
241*d83cc019SAndroid Build Coastguard Worker reloc[0].delta = 0;
242*d83cc019SAndroid Build Coastguard Worker if (gen < 4)
243*d83cc019SAndroid Build Coastguard Worker reloc[0].delta = 1;
244*d83cc019SAndroid Build Coastguard Worker reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
245*d83cc019SAndroid Build Coastguard Worker reloc[0].write_domain = 0;
246*d83cc019SAndroid Build Coastguard Worker
247*d83cc019SAndroid Build Coastguard Worker reloc[1].target_handle = obj[0].handle;
248*d83cc019SAndroid Build Coastguard Worker reloc[1].presumed_offset = obj[0].offset;
249*d83cc019SAndroid Build Coastguard Worker reloc[1].offset = 1024;
250*d83cc019SAndroid Build Coastguard Worker reloc[1].delta = 0;
251*d83cc019SAndroid Build Coastguard Worker reloc[1].read_domains = I915_GEM_DOMAIN_RENDER;
252*d83cc019SAndroid Build Coastguard Worker reloc[1].write_domain = 0;
253*d83cc019SAndroid Build Coastguard Worker if (flags & WRITE)
254*d83cc019SAndroid Build Coastguard Worker reloc[1].write_domain = I915_GEM_DOMAIN_RENDER;
255*d83cc019SAndroid Build Coastguard Worker
256*d83cc019SAndroid Build Coastguard Worker while (reps--) {
257*d83cc019SAndroid Build Coastguard Worker int fence = -1;
258*d83cc019SAndroid Build Coastguard Worker memset(shared, 0, 4096);
259*d83cc019SAndroid Build Coastguard Worker
260*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[1].handle,
261*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
262*d83cc019SAndroid Build Coastguard Worker sleep(1); /* wait for the hw to go back to sleep */
263*d83cc019SAndroid Build Coastguard Worker batch[i = 0] = MI_BATCH_BUFFER_START;
264*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
265*d83cc019SAndroid Build Coastguard Worker batch[i] |= 1 << 8 | 1;
266*d83cc019SAndroid Build Coastguard Worker batch[++i] = obj[1].offset;
267*d83cc019SAndroid Build Coastguard Worker batch[++i] = obj[1].offset >> 32;
268*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 6) {
269*d83cc019SAndroid Build Coastguard Worker batch[i] |= 1 << 8;
270*d83cc019SAndroid Build Coastguard Worker batch[++i] = obj[1].offset;
271*d83cc019SAndroid Build Coastguard Worker } else {
272*d83cc019SAndroid Build Coastguard Worker batch[i] |= 2 << 6;
273*d83cc019SAndroid Build Coastguard Worker batch[++i] = obj[1].offset;
274*d83cc019SAndroid Build Coastguard Worker if (gen < 4)
275*d83cc019SAndroid Build Coastguard Worker batch[i] |= 1;
276*d83cc019SAndroid Build Coastguard Worker }
277*d83cc019SAndroid Build Coastguard Worker
278*d83cc019SAndroid Build Coastguard Worker if ((flags & IDLE) == 0) {
279*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < nengine; n++) {
280*d83cc019SAndroid Build Coastguard Worker execbuf.flags &= ~(3 << 16);
281*d83cc019SAndroid Build Coastguard Worker if (flags & SYNC)
282*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= 1 << 17;
283*d83cc019SAndroid Build Coastguard Worker execbuf.flags &= ~ENGINE_FLAGS;
284*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= engines[n];
285*d83cc019SAndroid Build Coastguard Worker gem_execbuf_wr(fd, &execbuf);
286*d83cc019SAndroid Build Coastguard Worker if (execbuf.flags & (1 << 17))
287*d83cc019SAndroid Build Coastguard Worker fence = sync_merge(fence, execbuf.rsvd2 >> 32);
288*d83cc019SAndroid Build Coastguard Worker }
289*d83cc019SAndroid Build Coastguard Worker }
290*d83cc019SAndroid Build Coastguard Worker
291*d83cc019SAndroid Build Coastguard Worker igt_fork(child, ncpus) {
292*d83cc019SAndroid Build Coastguard Worker struct timespec start, end;
293*d83cc019SAndroid Build Coastguard Worker unsigned count = 0;
294*d83cc019SAndroid Build Coastguard Worker
295*d83cc019SAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &start);
296*d83cc019SAndroid Build Coastguard Worker do {
297*d83cc019SAndroid Build Coastguard Worker if (flags & DMABUF) {
298*d83cc019SAndroid Build Coastguard Worker struct pollfd pfd = { .fd = dmabuf, .events = POLLOUT };
299*d83cc019SAndroid Build Coastguard Worker for (int inner = 0; inner < 1024; inner++)
300*d83cc019SAndroid Build Coastguard Worker poll(&pfd, 1, 0);
301*d83cc019SAndroid Build Coastguard Worker } else if (flags & SYNCOBJ) {
302*d83cc019SAndroid Build Coastguard Worker struct local_syncobj_wait arg = {
303*d83cc019SAndroid Build Coastguard Worker .handles = to_user_pointer(&syncobj.handle),
304*d83cc019SAndroid Build Coastguard Worker .count_handles = 1,
305*d83cc019SAndroid Build Coastguard Worker };
306*d83cc019SAndroid Build Coastguard Worker
307*d83cc019SAndroid Build Coastguard Worker for (int inner = 0; inner < 1024; inner++)
308*d83cc019SAndroid Build Coastguard Worker __syncobj_wait(fd, &arg);
309*d83cc019SAndroid Build Coastguard Worker } else if (flags & SYNC) {
310*d83cc019SAndroid Build Coastguard Worker struct pollfd pfd = { .fd = fence, .events = POLLOUT };
311*d83cc019SAndroid Build Coastguard Worker for (int inner = 0; inner < 1024; inner++)
312*d83cc019SAndroid Build Coastguard Worker poll(&pfd, 1, 0);
313*d83cc019SAndroid Build Coastguard Worker } else if (flags & WAIT) {
314*d83cc019SAndroid Build Coastguard Worker for (int inner = 0; inner < 1024; inner++)
315*d83cc019SAndroid Build Coastguard Worker gem_wait__busy(fd, obj[0].handle);
316*d83cc019SAndroid Build Coastguard Worker } else {
317*d83cc019SAndroid Build Coastguard Worker for (int inner = 0; inner < 1024; inner++)
318*d83cc019SAndroid Build Coastguard Worker gem_busy(fd, obj[0].handle);
319*d83cc019SAndroid Build Coastguard Worker }
320*d83cc019SAndroid Build Coastguard Worker
321*d83cc019SAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &end);
322*d83cc019SAndroid Build Coastguard Worker count += 1024;
323*d83cc019SAndroid Build Coastguard Worker } while (elapsed(&start, &end) < 2e9);
324*d83cc019SAndroid Build Coastguard Worker
325*d83cc019SAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &end);
326*d83cc019SAndroid Build Coastguard Worker shared[child] = elapsed(&start, &end) / count;
327*d83cc019SAndroid Build Coastguard Worker }
328*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
329*d83cc019SAndroid Build Coastguard Worker
330*d83cc019SAndroid Build Coastguard Worker batch[0] = MI_BATCH_BUFFER_END;
331*d83cc019SAndroid Build Coastguard Worker if (fence != -1)
332*d83cc019SAndroid Build Coastguard Worker close(fence);
333*d83cc019SAndroid Build Coastguard Worker
334*d83cc019SAndroid Build Coastguard Worker for (int child = 0; child < ncpus; child++)
335*d83cc019SAndroid Build Coastguard Worker shared[ncpus] += shared[child];
336*d83cc019SAndroid Build Coastguard Worker printf("%7.3f\n", shared[ncpus] / ncpus);
337*d83cc019SAndroid Build Coastguard Worker }
338*d83cc019SAndroid Build Coastguard Worker return 0;
339*d83cc019SAndroid Build Coastguard Worker }
340*d83cc019SAndroid Build Coastguard Worker
main(int argc,char ** argv)341*d83cc019SAndroid Build Coastguard Worker int main(int argc, char **argv)
342*d83cc019SAndroid Build Coastguard Worker {
343*d83cc019SAndroid Build Coastguard Worker unsigned ring = I915_EXEC_RENDER;
344*d83cc019SAndroid Build Coastguard Worker unsigned flags = 0;
345*d83cc019SAndroid Build Coastguard Worker int reps = 1;
346*d83cc019SAndroid Build Coastguard Worker int ncpus = 1;
347*d83cc019SAndroid Build Coastguard Worker int c;
348*d83cc019SAndroid Build Coastguard Worker
349*d83cc019SAndroid Build Coastguard Worker while ((c = getopt (argc, argv, "e:r:dfsSwWI")) != -1) {
350*d83cc019SAndroid Build Coastguard Worker switch (c) {
351*d83cc019SAndroid Build Coastguard Worker case 'e':
352*d83cc019SAndroid Build Coastguard Worker if (strcmp(optarg, "rcs") == 0)
353*d83cc019SAndroid Build Coastguard Worker ring = I915_EXEC_RENDER;
354*d83cc019SAndroid Build Coastguard Worker else if (strcmp(optarg, "vcs") == 0)
355*d83cc019SAndroid Build Coastguard Worker ring = I915_EXEC_BSD;
356*d83cc019SAndroid Build Coastguard Worker else if (strcmp(optarg, "bcs") == 0)
357*d83cc019SAndroid Build Coastguard Worker ring = I915_EXEC_BLT;
358*d83cc019SAndroid Build Coastguard Worker else if (strcmp(optarg, "vecs") == 0)
359*d83cc019SAndroid Build Coastguard Worker ring = I915_EXEC_VEBOX;
360*d83cc019SAndroid Build Coastguard Worker else if (strcmp(optarg, "all") == 0)
361*d83cc019SAndroid Build Coastguard Worker ring = -1;
362*d83cc019SAndroid Build Coastguard Worker else
363*d83cc019SAndroid Build Coastguard Worker ring = atoi(optarg);
364*d83cc019SAndroid Build Coastguard Worker break;
365*d83cc019SAndroid Build Coastguard Worker
366*d83cc019SAndroid Build Coastguard Worker case 'r':
367*d83cc019SAndroid Build Coastguard Worker reps = atoi(optarg);
368*d83cc019SAndroid Build Coastguard Worker if (reps < 1)
369*d83cc019SAndroid Build Coastguard Worker reps = 1;
370*d83cc019SAndroid Build Coastguard Worker break;
371*d83cc019SAndroid Build Coastguard Worker
372*d83cc019SAndroid Build Coastguard Worker case 'f':
373*d83cc019SAndroid Build Coastguard Worker ncpus = sysconf(_SC_NPROCESSORS_ONLN);
374*d83cc019SAndroid Build Coastguard Worker break;
375*d83cc019SAndroid Build Coastguard Worker
376*d83cc019SAndroid Build Coastguard Worker case 'd':
377*d83cc019SAndroid Build Coastguard Worker flags |= DMABUF;
378*d83cc019SAndroid Build Coastguard Worker break;
379*d83cc019SAndroid Build Coastguard Worker
380*d83cc019SAndroid Build Coastguard Worker case 'w':
381*d83cc019SAndroid Build Coastguard Worker flags |= WAIT;
382*d83cc019SAndroid Build Coastguard Worker break;
383*d83cc019SAndroid Build Coastguard Worker
384*d83cc019SAndroid Build Coastguard Worker case 's':
385*d83cc019SAndroid Build Coastguard Worker flags |= SYNC;
386*d83cc019SAndroid Build Coastguard Worker break;
387*d83cc019SAndroid Build Coastguard Worker
388*d83cc019SAndroid Build Coastguard Worker case 'S':
389*d83cc019SAndroid Build Coastguard Worker flags |= SYNCOBJ;
390*d83cc019SAndroid Build Coastguard Worker break;
391*d83cc019SAndroid Build Coastguard Worker
392*d83cc019SAndroid Build Coastguard Worker case 'W':
393*d83cc019SAndroid Build Coastguard Worker flags |= WRITE;
394*d83cc019SAndroid Build Coastguard Worker break;
395*d83cc019SAndroid Build Coastguard Worker
396*d83cc019SAndroid Build Coastguard Worker case 'I':
397*d83cc019SAndroid Build Coastguard Worker flags |= IDLE;
398*d83cc019SAndroid Build Coastguard Worker break;
399*d83cc019SAndroid Build Coastguard Worker default:
400*d83cc019SAndroid Build Coastguard Worker break;
401*d83cc019SAndroid Build Coastguard Worker }
402*d83cc019SAndroid Build Coastguard Worker }
403*d83cc019SAndroid Build Coastguard Worker
404*d83cc019SAndroid Build Coastguard Worker return loop(ring, reps, ncpus, flags);
405*d83cc019SAndroid Build Coastguard Worker }
406