xref: /aosp_15_r20/external/igt-gpu-tools/benchmarks/gem_busy.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
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