xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_concurrent_all.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2009,2012,2013 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  *    Eric Anholt <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker  *    Chris Wilson <[email protected]>
26*d83cc019SAndroid Build Coastguard Worker  *    Daniel Vetter <[email protected]>
27*d83cc019SAndroid Build Coastguard Worker  *
28*d83cc019SAndroid Build Coastguard Worker  */
29*d83cc019SAndroid Build Coastguard Worker 
30*d83cc019SAndroid Build Coastguard Worker /** @file gem_concurrent.c
31*d83cc019SAndroid Build Coastguard Worker  *
32*d83cc019SAndroid Build Coastguard Worker  * This is a test of pread/pwrite/mmap behavior when writing to active
33*d83cc019SAndroid Build Coastguard Worker  * buffers.
34*d83cc019SAndroid Build Coastguard Worker  *
35*d83cc019SAndroid Build Coastguard Worker  * Based on gem_gtt_concurrent_blt.
36*d83cc019SAndroid Build Coastguard Worker  */
37*d83cc019SAndroid Build Coastguard Worker 
38*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
39*d83cc019SAndroid Build Coastguard Worker #include "igt_vgem.h"
40*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
41*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
42*d83cc019SAndroid Build Coastguard Worker #include <string.h>
43*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
44*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
45*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
46*d83cc019SAndroid Build Coastguard Worker #include <sys/resource.h>
47*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
48*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
49*d83cc019SAndroid Build Coastguard Worker #include <sys/wait.h>
50*d83cc019SAndroid Build Coastguard Worker 
51*d83cc019SAndroid Build Coastguard Worker #include <drm.h>
52*d83cc019SAndroid Build Coastguard Worker 
53*d83cc019SAndroid Build Coastguard Worker #include "intel_bufmgr.h"
54*d83cc019SAndroid Build Coastguard Worker 
55*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Test of pread/pwrite/mmap behavior when writing to active"
56*d83cc019SAndroid Build Coastguard Worker 		     " buffers.");
57*d83cc019SAndroid Build Coastguard Worker 
58*d83cc019SAndroid Build Coastguard Worker int fd, devid, gen;
59*d83cc019SAndroid Build Coastguard Worker int vgem_drv = -1;
60*d83cc019SAndroid Build Coastguard Worker int all;
61*d83cc019SAndroid Build Coastguard Worker int pass;
62*d83cc019SAndroid Build Coastguard Worker 
63*d83cc019SAndroid Build Coastguard Worker struct create {
64*d83cc019SAndroid Build Coastguard Worker 	const char *name;
65*d83cc019SAndroid Build Coastguard Worker 	void (*require)(const struct create *, unsigned);
66*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *(*create)(drm_intel_bufmgr *, uint64_t size);
67*d83cc019SAndroid Build Coastguard Worker };
68*d83cc019SAndroid Build Coastguard Worker 
69*d83cc019SAndroid Build Coastguard Worker struct size {
70*d83cc019SAndroid Build Coastguard Worker 	const char *name;
71*d83cc019SAndroid Build Coastguard Worker 	int width, height;
72*d83cc019SAndroid Build Coastguard Worker };
73*d83cc019SAndroid Build Coastguard Worker 
74*d83cc019SAndroid Build Coastguard Worker struct buffers {
75*d83cc019SAndroid Build Coastguard Worker 	const char *name;
76*d83cc019SAndroid Build Coastguard Worker 	const struct create *create;
77*d83cc019SAndroid Build Coastguard Worker 	const struct access_mode *mode;
78*d83cc019SAndroid Build Coastguard Worker 	const struct size *size;
79*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr *bufmgr;
80*d83cc019SAndroid Build Coastguard Worker 	struct intel_batchbuffer *batch;
81*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo **src, **dst;
82*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *snoop, *spare;
83*d83cc019SAndroid Build Coastguard Worker 	uint32_t *tmp;
84*d83cc019SAndroid Build Coastguard Worker 	int width, height, npixels, page_size;
85*d83cc019SAndroid Build Coastguard Worker 	int count, num_buffers;
86*d83cc019SAndroid Build Coastguard Worker };
87*d83cc019SAndroid Build Coastguard Worker 
88*d83cc019SAndroid Build Coastguard Worker #define MIN_BUFFERS 3
89*d83cc019SAndroid Build Coastguard Worker 
90*d83cc019SAndroid Build Coastguard Worker static void blt_copy_bo(struct buffers *b, drm_intel_bo *dst, drm_intel_bo *src);
91*d83cc019SAndroid Build Coastguard Worker 
92*d83cc019SAndroid Build Coastguard Worker static void
nop_release_bo(drm_intel_bo * bo)93*d83cc019SAndroid Build Coastguard Worker nop_release_bo(drm_intel_bo *bo)
94*d83cc019SAndroid Build Coastguard Worker {
95*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unreference(bo);
96*d83cc019SAndroid Build Coastguard Worker }
97*d83cc019SAndroid Build Coastguard Worker 
98*d83cc019SAndroid Build Coastguard Worker static void
prw_set_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)99*d83cc019SAndroid Build Coastguard Worker prw_set_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
100*d83cc019SAndroid Build Coastguard Worker {
101*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < b->npixels; i++)
102*d83cc019SAndroid Build Coastguard Worker 		b->tmp[i] = val;
103*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_subdata(bo, 0, 4*b->npixels, b->tmp);
104*d83cc019SAndroid Build Coastguard Worker }
105*d83cc019SAndroid Build Coastguard Worker 
106*d83cc019SAndroid Build Coastguard Worker static void
prw_cmp_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)107*d83cc019SAndroid Build Coastguard Worker prw_cmp_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
108*d83cc019SAndroid Build Coastguard Worker {
109*d83cc019SAndroid Build Coastguard Worker 	uint32_t *vaddr;
110*d83cc019SAndroid Build Coastguard Worker 
111*d83cc019SAndroid Build Coastguard Worker 	vaddr = b->tmp;
112*d83cc019SAndroid Build Coastguard Worker 	do_or_die(drm_intel_bo_get_subdata(bo, 0, 4*b->npixels, vaddr));
113*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < b->npixels; i++)
114*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(vaddr[i], val);
115*d83cc019SAndroid Build Coastguard Worker }
116*d83cc019SAndroid Build Coastguard Worker 
117*d83cc019SAndroid Build Coastguard Worker #define pixel(y, width) ((y)*(width) + (((y) + pass)%(width)))
118*d83cc019SAndroid Build Coastguard Worker 
119*d83cc019SAndroid Build Coastguard Worker static void
partial_set_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)120*d83cc019SAndroid Build Coastguard Worker partial_set_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
121*d83cc019SAndroid Build Coastguard Worker {
122*d83cc019SAndroid Build Coastguard Worker 	for (int y = 0; y < b->height; y++)
123*d83cc019SAndroid Build Coastguard Worker 		do_or_die(drm_intel_bo_subdata(bo, 4*pixel(y, b->width), 4, &val));
124*d83cc019SAndroid Build Coastguard Worker }
125*d83cc019SAndroid Build Coastguard Worker 
126*d83cc019SAndroid Build Coastguard Worker static void
partial_cmp_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)127*d83cc019SAndroid Build Coastguard Worker partial_cmp_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
128*d83cc019SAndroid Build Coastguard Worker {
129*d83cc019SAndroid Build Coastguard Worker 	for (int y = 0; y < b->height; y++) {
130*d83cc019SAndroid Build Coastguard Worker 		uint32_t buf;
131*d83cc019SAndroid Build Coastguard Worker 		do_or_die(drm_intel_bo_get_subdata(bo, 4*pixel(y, b->width), 4, &buf));
132*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(buf, val);
133*d83cc019SAndroid Build Coastguard Worker 	}
134*d83cc019SAndroid Build Coastguard Worker }
135*d83cc019SAndroid Build Coastguard Worker 
136*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
create_normal_bo(drm_intel_bufmgr * bufmgr,uint64_t size)137*d83cc019SAndroid Build Coastguard Worker create_normal_bo(drm_intel_bufmgr *bufmgr, uint64_t size)
138*d83cc019SAndroid Build Coastguard Worker {
139*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker 	bo = drm_intel_bo_alloc(bufmgr, "bo", size, 0);
142*d83cc019SAndroid Build Coastguard Worker 	igt_assert(bo);
143*d83cc019SAndroid Build Coastguard Worker 
144*d83cc019SAndroid Build Coastguard Worker 	return bo;
145*d83cc019SAndroid Build Coastguard Worker }
146*d83cc019SAndroid Build Coastguard Worker 
can_create_normal(const struct create * create,unsigned count)147*d83cc019SAndroid Build Coastguard Worker static void can_create_normal(const struct create *create, unsigned count)
148*d83cc019SAndroid Build Coastguard Worker {
149*d83cc019SAndroid Build Coastguard Worker }
150*d83cc019SAndroid Build Coastguard Worker 
151*d83cc019SAndroid Build Coastguard Worker #if HAVE_CREATE_PRIVATE
152*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
create_private_bo(drm_intel_bufmgr * bufmgr,uint64_t size)153*d83cc019SAndroid Build Coastguard Worker create_private_bo(drm_intel_bufmgr *bufmgr, uint64_t size)
154*d83cc019SAndroid Build Coastguard Worker {
155*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
156*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
157*d83cc019SAndroid Build Coastguard Worker 
158*d83cc019SAndroid Build Coastguard Worker 	/* XXX gem_create_with_flags(fd, size, I915_CREATE_PRIVATE); */
159*d83cc019SAndroid Build Coastguard Worker 
160*d83cc019SAndroid Build Coastguard Worker 	handle = gem_create(fd, size);
161*d83cc019SAndroid Build Coastguard Worker 	bo = gem_handle_to_libdrm_bo(bufmgr, fd, "stolen", handle);
162*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, handle);
163*d83cc019SAndroid Build Coastguard Worker 
164*d83cc019SAndroid Build Coastguard Worker 	return bo;
165*d83cc019SAndroid Build Coastguard Worker }
166*d83cc019SAndroid Build Coastguard Worker 
can_create_private(const struct create * create,unsigned count)167*d83cc019SAndroid Build Coastguard Worker static void can_create_private(const struct create *create, unsigned count)
168*d83cc019SAndroid Build Coastguard Worker {
169*d83cc019SAndroid Build Coastguard Worker 	igt_require(0);
170*d83cc019SAndroid Build Coastguard Worker }
171*d83cc019SAndroid Build Coastguard Worker #endif
172*d83cc019SAndroid Build Coastguard Worker 
173*d83cc019SAndroid Build Coastguard Worker #if HAVE_CREATE_STOLEN
174*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
create_stolen_bo(drm_intel_bufmgr * bufmgr,uint64_t size)175*d83cc019SAndroid Build Coastguard Worker create_stolen_bo(drm_intel_bufmgr *bufmgr, uint64_t size)
176*d83cc019SAndroid Build Coastguard Worker {
177*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
178*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 	/* XXX gem_create_with_flags(fd, size, I915_CREATE_STOLEN); */
181*d83cc019SAndroid Build Coastguard Worker 
182*d83cc019SAndroid Build Coastguard Worker 	handle = gem_create(fd, size);
183*d83cc019SAndroid Build Coastguard Worker 	bo = gem_handle_to_libdrm_bo(bufmgr, fd, "stolen", handle);
184*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, handle);
185*d83cc019SAndroid Build Coastguard Worker 
186*d83cc019SAndroid Build Coastguard Worker 	return bo;
187*d83cc019SAndroid Build Coastguard Worker }
188*d83cc019SAndroid Build Coastguard Worker 
can_create_stolen(const struct create * create,unsigned count)189*d83cc019SAndroid Build Coastguard Worker static void can_create_stolen(const struct create *create, unsigned count)
190*d83cc019SAndroid Build Coastguard Worker {
191*d83cc019SAndroid Build Coastguard Worker 	/* XXX check num_buffers against available stolen */
192*d83cc019SAndroid Build Coastguard Worker 	igt_require(0);
193*d83cc019SAndroid Build Coastguard Worker }
194*d83cc019SAndroid Build Coastguard Worker #endif
195*d83cc019SAndroid Build Coastguard Worker 
create_cpu_require(const struct create * create,unsigned count)196*d83cc019SAndroid Build Coastguard Worker static void create_cpu_require(const struct create *create, unsigned count)
197*d83cc019SAndroid Build Coastguard Worker {
198*d83cc019SAndroid Build Coastguard Worker #if HAVE_CREATE_STOLEN
199*d83cc019SAndroid Build Coastguard Worker 	igt_require(create->create != create_stolen_bo);
200*d83cc019SAndroid Build Coastguard Worker #endif
201*d83cc019SAndroid Build Coastguard Worker }
202*d83cc019SAndroid Build Coastguard Worker 
203*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
unmapped_create_bo(const struct buffers * b)204*d83cc019SAndroid Build Coastguard Worker unmapped_create_bo(const struct buffers *b)
205*d83cc019SAndroid Build Coastguard Worker {
206*d83cc019SAndroid Build Coastguard Worker 	return b->create->create(b->bufmgr, 4*b->npixels);
207*d83cc019SAndroid Build Coastguard Worker }
208*d83cc019SAndroid Build Coastguard Worker 
create_snoop_require(const struct create * create,unsigned count)209*d83cc019SAndroid Build Coastguard Worker static void create_snoop_require(const struct create *create, unsigned count)
210*d83cc019SAndroid Build Coastguard Worker {
211*d83cc019SAndroid Build Coastguard Worker 	create_cpu_require(create, count);
212*d83cc019SAndroid Build Coastguard Worker 	igt_require(!gem_has_llc(fd));
213*d83cc019SAndroid Build Coastguard Worker }
214*d83cc019SAndroid Build Coastguard Worker 
215*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
snoop_create_bo(const struct buffers * b)216*d83cc019SAndroid Build Coastguard Worker snoop_create_bo(const struct buffers *b)
217*d83cc019SAndroid Build Coastguard Worker {
218*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
219*d83cc019SAndroid Build Coastguard Worker 
220*d83cc019SAndroid Build Coastguard Worker 	bo = unmapped_create_bo(b);
221*d83cc019SAndroid Build Coastguard Worker 	gem_set_caching(fd, bo->handle, I915_CACHING_CACHED);
222*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_disable_reuse(bo);
223*d83cc019SAndroid Build Coastguard Worker 
224*d83cc019SAndroid Build Coastguard Worker 	return bo;
225*d83cc019SAndroid Build Coastguard Worker }
226*d83cc019SAndroid Build Coastguard Worker 
create_userptr_require(const struct create * create,unsigned count)227*d83cc019SAndroid Build Coastguard Worker static void create_userptr_require(const struct create *create, unsigned count)
228*d83cc019SAndroid Build Coastguard Worker {
229*d83cc019SAndroid Build Coastguard Worker 	static int has_userptr = -1;
230*d83cc019SAndroid Build Coastguard Worker 	if (has_userptr < 0) {
231*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_gem_userptr arg;
232*d83cc019SAndroid Build Coastguard Worker 
233*d83cc019SAndroid Build Coastguard Worker 		has_userptr = 0;
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 		memset(&arg, 0, sizeof(arg));
236*d83cc019SAndroid Build Coastguard Worker 		arg.user_ptr = -4096ULL;
237*d83cc019SAndroid Build Coastguard Worker 		arg.user_size = 8192;
238*d83cc019SAndroid Build Coastguard Worker 		errno = 0;
239*d83cc019SAndroid Build Coastguard Worker 		drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &arg);
240*d83cc019SAndroid Build Coastguard Worker 		if (errno == EFAULT) {
241*d83cc019SAndroid Build Coastguard Worker 			igt_assert(posix_memalign((void **)&arg.user_ptr,
242*d83cc019SAndroid Build Coastguard Worker 						  4096, arg.user_size) == 0);
243*d83cc019SAndroid Build Coastguard Worker 			has_userptr = drmIoctl(fd,
244*d83cc019SAndroid Build Coastguard Worker 					 LOCAL_IOCTL_I915_GEM_USERPTR,
245*d83cc019SAndroid Build Coastguard Worker 					 &arg) == 0;
246*d83cc019SAndroid Build Coastguard Worker 			free(from_user_pointer(arg.user_ptr));
247*d83cc019SAndroid Build Coastguard Worker 		}
248*d83cc019SAndroid Build Coastguard Worker 
249*d83cc019SAndroid Build Coastguard Worker 	}
250*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_userptr);
251*d83cc019SAndroid Build Coastguard Worker }
252*d83cc019SAndroid Build Coastguard Worker 
253*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
userptr_create_bo(const struct buffers * b)254*d83cc019SAndroid Build Coastguard Worker userptr_create_bo(const struct buffers *b)
255*d83cc019SAndroid Build Coastguard Worker {
256*d83cc019SAndroid Build Coastguard Worker 	struct local_i915_gem_userptr userptr;
257*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
258*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
259*d83cc019SAndroid Build Coastguard Worker 
260*d83cc019SAndroid Build Coastguard Worker 	memset(&userptr, 0, sizeof(userptr));
261*d83cc019SAndroid Build Coastguard Worker 	userptr.user_size = b->page_size;
262*d83cc019SAndroid Build Coastguard Worker 
263*d83cc019SAndroid Build Coastguard Worker 	ptr = mmap(NULL, userptr.user_size,
264*d83cc019SAndroid Build Coastguard Worker 		   PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
265*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ptr != (void *)-1);
266*d83cc019SAndroid Build Coastguard Worker 	userptr.user_ptr = to_user_pointer(ptr);
267*d83cc019SAndroid Build Coastguard Worker 
268*d83cc019SAndroid Build Coastguard Worker #if 0
269*d83cc019SAndroid Build Coastguard Worker 	do_or_die(drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr));
270*d83cc019SAndroid Build Coastguard Worker 	bo = gem_handle_to_libdrm_bo(b->bufmgr, fd, "userptr", userptr.handle);
271*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, userptr.handle);
272*d83cc019SAndroid Build Coastguard Worker #else
273*d83cc019SAndroid Build Coastguard Worker 	bo = drm_intel_bo_alloc_userptr(b->bufmgr, "name",
274*d83cc019SAndroid Build Coastguard Worker 					ptr, I915_TILING_NONE, 0,
275*d83cc019SAndroid Build Coastguard Worker 					userptr.user_size, 0);
276*d83cc019SAndroid Build Coastguard Worker 	igt_assert(bo);
277*d83cc019SAndroid Build Coastguard Worker #endif
278*d83cc019SAndroid Build Coastguard Worker 	bo->virtual = from_user_pointer(userptr.user_ptr);
279*d83cc019SAndroid Build Coastguard Worker 
280*d83cc019SAndroid Build Coastguard Worker 	return bo;
281*d83cc019SAndroid Build Coastguard Worker }
282*d83cc019SAndroid Build Coastguard Worker 
283*d83cc019SAndroid Build Coastguard Worker static void
userptr_set_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)284*d83cc019SAndroid Build Coastguard Worker userptr_set_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
285*d83cc019SAndroid Build Coastguard Worker {
286*d83cc019SAndroid Build Coastguard Worker 	int size = b->npixels;
287*d83cc019SAndroid Build Coastguard Worker 	uint32_t *vaddr = bo->virtual;
288*d83cc019SAndroid Build Coastguard Worker 
289*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, bo->handle,
290*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
291*d83cc019SAndroid Build Coastguard Worker 	while (size--)
292*d83cc019SAndroid Build Coastguard Worker 		*vaddr++ = val;
293*d83cc019SAndroid Build Coastguard Worker }
294*d83cc019SAndroid Build Coastguard Worker 
295*d83cc019SAndroid Build Coastguard Worker static void
userptr_cmp_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)296*d83cc019SAndroid Build Coastguard Worker userptr_cmp_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
297*d83cc019SAndroid Build Coastguard Worker {
298*d83cc019SAndroid Build Coastguard Worker 	int size =  b->npixels;
299*d83cc019SAndroid Build Coastguard Worker 	uint32_t *vaddr = bo->virtual;
300*d83cc019SAndroid Build Coastguard Worker 
301*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, bo->handle,
302*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_CPU, 0);
303*d83cc019SAndroid Build Coastguard Worker 	while (size--)
304*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(*vaddr++, val);
305*d83cc019SAndroid Build Coastguard Worker }
306*d83cc019SAndroid Build Coastguard Worker 
307*d83cc019SAndroid Build Coastguard Worker static void
userptr_release_bo(drm_intel_bo * bo)308*d83cc019SAndroid Build Coastguard Worker userptr_release_bo(drm_intel_bo *bo)
309*d83cc019SAndroid Build Coastguard Worker {
310*d83cc019SAndroid Build Coastguard Worker 	igt_assert(bo->virtual);
311*d83cc019SAndroid Build Coastguard Worker 
312*d83cc019SAndroid Build Coastguard Worker 	munmap(bo->virtual, bo->size);
313*d83cc019SAndroid Build Coastguard Worker 	bo->virtual = NULL;
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unreference(bo);
316*d83cc019SAndroid Build Coastguard Worker }
317*d83cc019SAndroid Build Coastguard Worker 
create_dmabuf_require(const struct create * create,unsigned count)318*d83cc019SAndroid Build Coastguard Worker static void create_dmabuf_require(const struct create *create, unsigned count)
319*d83cc019SAndroid Build Coastguard Worker {
320*d83cc019SAndroid Build Coastguard Worker 	static int has_dmabuf = -1;
321*d83cc019SAndroid Build Coastguard Worker 	if (has_dmabuf < 0) {
322*d83cc019SAndroid Build Coastguard Worker 		struct drm_prime_handle args;
323*d83cc019SAndroid Build Coastguard Worker 		void *ptr;
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 		memset(&args, 0, sizeof(args));
326*d83cc019SAndroid Build Coastguard Worker 		args.handle = gem_create(fd, 4096);
327*d83cc019SAndroid Build Coastguard Worker 		args.flags = DRM_RDWR;
328*d83cc019SAndroid Build Coastguard Worker 		args.fd = -1;
329*d83cc019SAndroid Build Coastguard Worker 
330*d83cc019SAndroid Build Coastguard Worker 		drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
331*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, args.handle);
332*d83cc019SAndroid Build Coastguard Worker 
333*d83cc019SAndroid Build Coastguard Worker 		has_dmabuf = 0;
334*d83cc019SAndroid Build Coastguard Worker 		ptr = mmap(NULL, 4096, PROT_READ, MAP_SHARED, args.fd, 0);
335*d83cc019SAndroid Build Coastguard Worker 		if (ptr != MAP_FAILED) {
336*d83cc019SAndroid Build Coastguard Worker 			has_dmabuf = 1;
337*d83cc019SAndroid Build Coastguard Worker 			munmap(ptr, 4096);
338*d83cc019SAndroid Build Coastguard Worker 		}
339*d83cc019SAndroid Build Coastguard Worker 
340*d83cc019SAndroid Build Coastguard Worker 		close(args.fd);
341*d83cc019SAndroid Build Coastguard Worker 	}
342*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_dmabuf);
343*d83cc019SAndroid Build Coastguard Worker 	intel_require_files(2*count);
344*d83cc019SAndroid Build Coastguard Worker }
345*d83cc019SAndroid Build Coastguard Worker 
346*d83cc019SAndroid Build Coastguard Worker struct dmabuf {
347*d83cc019SAndroid Build Coastguard Worker 	int fd;
348*d83cc019SAndroid Build Coastguard Worker 	void *map;
349*d83cc019SAndroid Build Coastguard Worker };
350*d83cc019SAndroid Build Coastguard Worker 
351*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
dmabuf_create_bo(const struct buffers * b)352*d83cc019SAndroid Build Coastguard Worker dmabuf_create_bo(const struct buffers *b)
353*d83cc019SAndroid Build Coastguard Worker {
354*d83cc019SAndroid Build Coastguard Worker 	struct drm_prime_handle args;
355*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
356*d83cc019SAndroid Build Coastguard Worker 	struct dmabuf *dmabuf;
357*d83cc019SAndroid Build Coastguard Worker 	int size;
358*d83cc019SAndroid Build Coastguard Worker 
359*d83cc019SAndroid Build Coastguard Worker 	size = b->page_size;
360*d83cc019SAndroid Build Coastguard Worker 
361*d83cc019SAndroid Build Coastguard Worker 	memset(&args, 0, sizeof(args));
362*d83cc019SAndroid Build Coastguard Worker 	args.handle = gem_create(fd, size);
363*d83cc019SAndroid Build Coastguard Worker 	args.flags = DRM_RDWR;
364*d83cc019SAndroid Build Coastguard Worker 	args.fd = -1;
365*d83cc019SAndroid Build Coastguard Worker 
366*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
367*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, args.handle);
368*d83cc019SAndroid Build Coastguard Worker 
369*d83cc019SAndroid Build Coastguard Worker 	bo = drm_intel_bo_gem_create_from_prime(b->bufmgr, args.fd, size);
370*d83cc019SAndroid Build Coastguard Worker 	igt_assert(bo);
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker 	dmabuf = malloc(sizeof(*dmabuf));
373*d83cc019SAndroid Build Coastguard Worker 	igt_assert(dmabuf);
374*d83cc019SAndroid Build Coastguard Worker 
375*d83cc019SAndroid Build Coastguard Worker 	dmabuf->fd = args.fd;
376*d83cc019SAndroid Build Coastguard Worker 	dmabuf->map = mmap(NULL, size,
377*d83cc019SAndroid Build Coastguard Worker 			   PROT_READ | PROT_WRITE, MAP_SHARED,
378*d83cc019SAndroid Build Coastguard Worker 			   dmabuf->fd, 0);
379*d83cc019SAndroid Build Coastguard Worker 	igt_assert(dmabuf->map != (void *)-1);
380*d83cc019SAndroid Build Coastguard Worker 
381*d83cc019SAndroid Build Coastguard Worker 	bo->virtual = dmabuf;
382*d83cc019SAndroid Build Coastguard Worker 
383*d83cc019SAndroid Build Coastguard Worker 	return bo;
384*d83cc019SAndroid Build Coastguard Worker }
385*d83cc019SAndroid Build Coastguard Worker 
386*d83cc019SAndroid Build Coastguard Worker static void
dmabuf_set_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)387*d83cc019SAndroid Build Coastguard Worker dmabuf_set_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
388*d83cc019SAndroid Build Coastguard Worker {
389*d83cc019SAndroid Build Coastguard Worker 	struct dmabuf *dmabuf = bo->virtual;
390*d83cc019SAndroid Build Coastguard Worker 	uint32_t *v = dmabuf->map;
391*d83cc019SAndroid Build Coastguard Worker 	int y;
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker 	prime_sync_start(dmabuf->fd, true);
394*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < b->height; y++)
395*d83cc019SAndroid Build Coastguard Worker 		v[pixel(y, b->width)] = val;
396*d83cc019SAndroid Build Coastguard Worker 	prime_sync_end(dmabuf->fd, true);
397*d83cc019SAndroid Build Coastguard Worker }
398*d83cc019SAndroid Build Coastguard Worker 
399*d83cc019SAndroid Build Coastguard Worker static void
dmabuf_cmp_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)400*d83cc019SAndroid Build Coastguard Worker dmabuf_cmp_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
401*d83cc019SAndroid Build Coastguard Worker {
402*d83cc019SAndroid Build Coastguard Worker 	struct dmabuf *dmabuf = bo->virtual;
403*d83cc019SAndroid Build Coastguard Worker 	uint32_t *v = dmabuf->map;
404*d83cc019SAndroid Build Coastguard Worker 	int y;
405*d83cc019SAndroid Build Coastguard Worker 
406*d83cc019SAndroid Build Coastguard Worker 	prime_sync_start(dmabuf->fd, false);
407*d83cc019SAndroid Build Coastguard Worker 	for (y = 0; y < b->height; y++)
408*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(v[pixel(y, b->width)], val);
409*d83cc019SAndroid Build Coastguard Worker 	prime_sync_end(dmabuf->fd, false);
410*d83cc019SAndroid Build Coastguard Worker }
411*d83cc019SAndroid Build Coastguard Worker 
412*d83cc019SAndroid Build Coastguard Worker static void
dmabuf_release_bo(drm_intel_bo * bo)413*d83cc019SAndroid Build Coastguard Worker dmabuf_release_bo(drm_intel_bo *bo)
414*d83cc019SAndroid Build Coastguard Worker {
415*d83cc019SAndroid Build Coastguard Worker 	struct dmabuf *dmabuf = bo->virtual;
416*d83cc019SAndroid Build Coastguard Worker 	igt_assert(dmabuf);
417*d83cc019SAndroid Build Coastguard Worker 
418*d83cc019SAndroid Build Coastguard Worker 	munmap(dmabuf->map, bo->size);
419*d83cc019SAndroid Build Coastguard Worker 	close(dmabuf->fd);
420*d83cc019SAndroid Build Coastguard Worker 	free(dmabuf);
421*d83cc019SAndroid Build Coastguard Worker 
422*d83cc019SAndroid Build Coastguard Worker 	bo->virtual = NULL;
423*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unreference(bo);
424*d83cc019SAndroid Build Coastguard Worker }
425*d83cc019SAndroid Build Coastguard Worker 
has_prime_export(int _fd)426*d83cc019SAndroid Build Coastguard Worker static bool has_prime_export(int _fd)
427*d83cc019SAndroid Build Coastguard Worker {
428*d83cc019SAndroid Build Coastguard Worker 	uint64_t value;
429*d83cc019SAndroid Build Coastguard Worker 
430*d83cc019SAndroid Build Coastguard Worker 	if (drmGetCap(_fd, DRM_CAP_PRIME, &value))
431*d83cc019SAndroid Build Coastguard Worker 		return false;
432*d83cc019SAndroid Build Coastguard Worker 
433*d83cc019SAndroid Build Coastguard Worker 	return value & DRM_PRIME_CAP_EXPORT;
434*d83cc019SAndroid Build Coastguard Worker }
435*d83cc019SAndroid Build Coastguard Worker 
create_vgem_require(const struct create * create,unsigned count)436*d83cc019SAndroid Build Coastguard Worker static void create_vgem_require(const struct create *create, unsigned count)
437*d83cc019SAndroid Build Coastguard Worker {
438*d83cc019SAndroid Build Coastguard Worker 	igt_require(vgem_drv != -1);
439*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_prime_export(vgem_drv));
440*d83cc019SAndroid Build Coastguard Worker 	create_dmabuf_require(create, count);
441*d83cc019SAndroid Build Coastguard Worker }
442*d83cc019SAndroid Build Coastguard Worker 
443*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
vgem_create_bo(const struct buffers * b)444*d83cc019SAndroid Build Coastguard Worker vgem_create_bo(const struct buffers *b)
445*d83cc019SAndroid Build Coastguard Worker {
446*d83cc019SAndroid Build Coastguard Worker 	struct drm_prime_handle args;
447*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
448*d83cc019SAndroid Build Coastguard Worker 	struct vgem_bo vgem;
449*d83cc019SAndroid Build Coastguard Worker 	struct dmabuf *dmabuf;
450*d83cc019SAndroid Build Coastguard Worker 
451*d83cc019SAndroid Build Coastguard Worker 	igt_assert(vgem_drv != -1);
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker 	vgem.width = b->width;
454*d83cc019SAndroid Build Coastguard Worker 	vgem.height = b->height;
455*d83cc019SAndroid Build Coastguard Worker 	vgem.bpp = 32;
456*d83cc019SAndroid Build Coastguard Worker 	vgem_create(vgem_drv, &vgem);
457*d83cc019SAndroid Build Coastguard Worker 
458*d83cc019SAndroid Build Coastguard Worker 	memset(&args, 0, sizeof(args));
459*d83cc019SAndroid Build Coastguard Worker 	args.handle = vgem.handle;
460*d83cc019SAndroid Build Coastguard Worker 	args.flags = DRM_RDWR;
461*d83cc019SAndroid Build Coastguard Worker 	args.fd = -1;
462*d83cc019SAndroid Build Coastguard Worker 
463*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(vgem_drv, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
464*d83cc019SAndroid Build Coastguard Worker 	gem_close(vgem_drv, args.handle);
465*d83cc019SAndroid Build Coastguard Worker 	igt_assert(args.fd != -1);
466*d83cc019SAndroid Build Coastguard Worker 
467*d83cc019SAndroid Build Coastguard Worker 	bo = drm_intel_bo_gem_create_from_prime(b->bufmgr, args.fd, vgem.size);
468*d83cc019SAndroid Build Coastguard Worker 	igt_assert(bo);
469*d83cc019SAndroid Build Coastguard Worker 
470*d83cc019SAndroid Build Coastguard Worker 	dmabuf = malloc(sizeof(*dmabuf));
471*d83cc019SAndroid Build Coastguard Worker 	igt_assert(dmabuf);
472*d83cc019SAndroid Build Coastguard Worker 
473*d83cc019SAndroid Build Coastguard Worker 	dmabuf->fd = args.fd;
474*d83cc019SAndroid Build Coastguard Worker 	dmabuf->map = mmap(NULL, vgem.size,
475*d83cc019SAndroid Build Coastguard Worker 			   PROT_READ | PROT_WRITE, MAP_SHARED,
476*d83cc019SAndroid Build Coastguard Worker 			   dmabuf->fd, 0);
477*d83cc019SAndroid Build Coastguard Worker 	igt_assert(dmabuf->map != (void *)-1);
478*d83cc019SAndroid Build Coastguard Worker 
479*d83cc019SAndroid Build Coastguard Worker 	bo->virtual = dmabuf;
480*d83cc019SAndroid Build Coastguard Worker 
481*d83cc019SAndroid Build Coastguard Worker 	return bo;
482*d83cc019SAndroid Build Coastguard Worker }
483*d83cc019SAndroid Build Coastguard Worker 
484*d83cc019SAndroid Build Coastguard Worker static void
gtt_set_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)485*d83cc019SAndroid Build Coastguard Worker gtt_set_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
486*d83cc019SAndroid Build Coastguard Worker {
487*d83cc019SAndroid Build Coastguard Worker 	uint32_t *vaddr = bo->virtual;
488*d83cc019SAndroid Build Coastguard Worker 
489*d83cc019SAndroid Build Coastguard Worker 	drm_intel_gem_bo_start_gtt_access(bo, true);
490*d83cc019SAndroid Build Coastguard Worker 	for (int y = 0; y < b->height; y++)
491*d83cc019SAndroid Build Coastguard Worker 		vaddr[pixel(y, b->width)] = val;
492*d83cc019SAndroid Build Coastguard Worker }
493*d83cc019SAndroid Build Coastguard Worker 
494*d83cc019SAndroid Build Coastguard Worker static void
gtt_cmp_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)495*d83cc019SAndroid Build Coastguard Worker gtt_cmp_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
496*d83cc019SAndroid Build Coastguard Worker {
497*d83cc019SAndroid Build Coastguard Worker 	uint32_t *vaddr = bo->virtual;
498*d83cc019SAndroid Build Coastguard Worker 
499*d83cc019SAndroid Build Coastguard Worker 	/* GTT access is slow. So we just compare a few points */
500*d83cc019SAndroid Build Coastguard Worker 	drm_intel_gem_bo_start_gtt_access(bo, false);
501*d83cc019SAndroid Build Coastguard Worker 	for (int y = 0; y < b->height; y++)
502*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(vaddr[pixel(y, b->width)], val);
503*d83cc019SAndroid Build Coastguard Worker }
504*d83cc019SAndroid Build Coastguard Worker 
505*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
map_bo(drm_intel_bo * bo)506*d83cc019SAndroid Build Coastguard Worker map_bo(drm_intel_bo *bo)
507*d83cc019SAndroid Build Coastguard Worker {
508*d83cc019SAndroid Build Coastguard Worker 	/* gtt map doesn't have a write parameter, so just keep the mapping
509*d83cc019SAndroid Build Coastguard Worker 	 * around (to avoid the set_domain with the gtt write domain set) and
510*d83cc019SAndroid Build Coastguard Worker 	 * manually tell the kernel when we start access the gtt. */
511*d83cc019SAndroid Build Coastguard Worker 	do_or_die(drm_intel_gem_bo_map_gtt(bo));
512*d83cc019SAndroid Build Coastguard Worker 
513*d83cc019SAndroid Build Coastguard Worker 	return bo;
514*d83cc019SAndroid Build Coastguard Worker }
515*d83cc019SAndroid Build Coastguard Worker 
516*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
tile_bo(drm_intel_bo * bo,int width)517*d83cc019SAndroid Build Coastguard Worker tile_bo(drm_intel_bo *bo, int width)
518*d83cc019SAndroid Build Coastguard Worker {
519*d83cc019SAndroid Build Coastguard Worker 	uint32_t tiling = I915_TILING_X;
520*d83cc019SAndroid Build Coastguard Worker 	uint32_t stride = width * 4;
521*d83cc019SAndroid Build Coastguard Worker 
522*d83cc019SAndroid Build Coastguard Worker 	do_or_die(drm_intel_bo_set_tiling(bo, &tiling, stride));
523*d83cc019SAndroid Build Coastguard Worker 
524*d83cc019SAndroid Build Coastguard Worker 	return bo;
525*d83cc019SAndroid Build Coastguard Worker }
526*d83cc019SAndroid Build Coastguard Worker 
527*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
gtt_create_bo(const struct buffers * b)528*d83cc019SAndroid Build Coastguard Worker gtt_create_bo(const struct buffers *b)
529*d83cc019SAndroid Build Coastguard Worker {
530*d83cc019SAndroid Build Coastguard Worker 	return map_bo(unmapped_create_bo(b));
531*d83cc019SAndroid Build Coastguard Worker }
532*d83cc019SAndroid Build Coastguard Worker 
533*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
gttX_create_bo(const struct buffers * b)534*d83cc019SAndroid Build Coastguard Worker gttX_create_bo(const struct buffers *b)
535*d83cc019SAndroid Build Coastguard Worker {
536*d83cc019SAndroid Build Coastguard Worker 	return tile_bo(gtt_create_bo(b), b->width);
537*d83cc019SAndroid Build Coastguard Worker }
538*d83cc019SAndroid Build Coastguard Worker 
bit17_require(void)539*d83cc019SAndroid Build Coastguard Worker static void bit17_require(void)
540*d83cc019SAndroid Build Coastguard Worker {
541*d83cc019SAndroid Build Coastguard Worker 	static struct drm_i915_gem_get_tiling2 {
542*d83cc019SAndroid Build Coastguard Worker 		uint32_t handle;
543*d83cc019SAndroid Build Coastguard Worker 		uint32_t tiling_mode;
544*d83cc019SAndroid Build Coastguard Worker 		uint32_t swizzle_mode;
545*d83cc019SAndroid Build Coastguard Worker 		uint32_t phys_swizzle_mode;
546*d83cc019SAndroid Build Coastguard Worker 	} arg;
547*d83cc019SAndroid Build Coastguard Worker #define DRM_IOCTL_I915_GEM_GET_TILING2	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling2)
548*d83cc019SAndroid Build Coastguard Worker 
549*d83cc019SAndroid Build Coastguard Worker 	if (arg.handle == 0) {
550*d83cc019SAndroid Build Coastguard Worker 		arg.handle = gem_create(fd, 4096);
551*d83cc019SAndroid Build Coastguard Worker 		gem_set_tiling(fd, arg.handle, I915_TILING_X, 512);
552*d83cc019SAndroid Build Coastguard Worker 
553*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(fd, DRM_IOCTL_I915_GEM_GET_TILING2, &arg);
554*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, arg.handle);
555*d83cc019SAndroid Build Coastguard Worker 	}
556*d83cc019SAndroid Build Coastguard Worker 	igt_require(arg.phys_swizzle_mode == arg.swizzle_mode);
557*d83cc019SAndroid Build Coastguard Worker }
558*d83cc019SAndroid Build Coastguard Worker 
wc_require(void)559*d83cc019SAndroid Build Coastguard Worker static void wc_require(void)
560*d83cc019SAndroid Build Coastguard Worker {
561*d83cc019SAndroid Build Coastguard Worker 	bit17_require();
562*d83cc019SAndroid Build Coastguard Worker 	gem_require_mmap_wc(fd);
563*d83cc019SAndroid Build Coastguard Worker }
564*d83cc019SAndroid Build Coastguard Worker 
565*d83cc019SAndroid Build Coastguard Worker static void
wc_create_require(const struct create * create,unsigned count)566*d83cc019SAndroid Build Coastguard Worker wc_create_require(const struct create *create, unsigned count)
567*d83cc019SAndroid Build Coastguard Worker {
568*d83cc019SAndroid Build Coastguard Worker 	wc_require();
569*d83cc019SAndroid Build Coastguard Worker }
570*d83cc019SAndroid Build Coastguard Worker 
571*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
wc_create_bo(const struct buffers * b)572*d83cc019SAndroid Build Coastguard Worker wc_create_bo(const struct buffers *b)
573*d83cc019SAndroid Build Coastguard Worker {
574*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
575*d83cc019SAndroid Build Coastguard Worker 
576*d83cc019SAndroid Build Coastguard Worker 	bo = unmapped_create_bo(b);
577*d83cc019SAndroid Build Coastguard Worker 	bo->virtual = gem_mmap__wc(fd, bo->handle, 0, bo->size, PROT_READ | PROT_WRITE);
578*d83cc019SAndroid Build Coastguard Worker 	return bo;
579*d83cc019SAndroid Build Coastguard Worker }
580*d83cc019SAndroid Build Coastguard Worker 
581*d83cc019SAndroid Build Coastguard Worker static void
wc_release_bo(drm_intel_bo * bo)582*d83cc019SAndroid Build Coastguard Worker wc_release_bo(drm_intel_bo *bo)
583*d83cc019SAndroid Build Coastguard Worker {
584*d83cc019SAndroid Build Coastguard Worker 	igt_assert(bo->virtual);
585*d83cc019SAndroid Build Coastguard Worker 
586*d83cc019SAndroid Build Coastguard Worker 	munmap(bo->virtual, bo->size);
587*d83cc019SAndroid Build Coastguard Worker 	bo->virtual = NULL;
588*d83cc019SAndroid Build Coastguard Worker 
589*d83cc019SAndroid Build Coastguard Worker 	nop_release_bo(bo);
590*d83cc019SAndroid Build Coastguard Worker }
591*d83cc019SAndroid Build Coastguard Worker 
592*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
gpu_create_bo(const struct buffers * b)593*d83cc019SAndroid Build Coastguard Worker gpu_create_bo(const struct buffers *b)
594*d83cc019SAndroid Build Coastguard Worker {
595*d83cc019SAndroid Build Coastguard Worker 	return unmapped_create_bo(b);
596*d83cc019SAndroid Build Coastguard Worker }
597*d83cc019SAndroid Build Coastguard Worker 
598*d83cc019SAndroid Build Coastguard Worker static drm_intel_bo *
gpuX_create_bo(const struct buffers * b)599*d83cc019SAndroid Build Coastguard Worker gpuX_create_bo(const struct buffers *b)
600*d83cc019SAndroid Build Coastguard Worker {
601*d83cc019SAndroid Build Coastguard Worker 	return tile_bo(gpu_create_bo(b), b->width);
602*d83cc019SAndroid Build Coastguard Worker }
603*d83cc019SAndroid Build Coastguard Worker 
604*d83cc019SAndroid Build Coastguard Worker static void
cpu_set_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)605*d83cc019SAndroid Build Coastguard Worker cpu_set_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
606*d83cc019SAndroid Build Coastguard Worker {
607*d83cc019SAndroid Build Coastguard Worker 	int size = b->npixels;
608*d83cc019SAndroid Build Coastguard Worker 	uint32_t *vaddr;
609*d83cc019SAndroid Build Coastguard Worker 
610*d83cc019SAndroid Build Coastguard Worker 	do_or_die(drm_intel_bo_map(bo, true));
611*d83cc019SAndroid Build Coastguard Worker 	vaddr = bo->virtual;
612*d83cc019SAndroid Build Coastguard Worker 	while (size--)
613*d83cc019SAndroid Build Coastguard Worker 		*vaddr++ = val;
614*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unmap(bo);
615*d83cc019SAndroid Build Coastguard Worker }
616*d83cc019SAndroid Build Coastguard Worker 
617*d83cc019SAndroid Build Coastguard Worker static void
cpu_cmp_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)618*d83cc019SAndroid Build Coastguard Worker cpu_cmp_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
619*d83cc019SAndroid Build Coastguard Worker {
620*d83cc019SAndroid Build Coastguard Worker 	int size = b->npixels;
621*d83cc019SAndroid Build Coastguard Worker 	uint32_t *vaddr;
622*d83cc019SAndroid Build Coastguard Worker 
623*d83cc019SAndroid Build Coastguard Worker 	do_or_die(drm_intel_bo_map(bo, false));
624*d83cc019SAndroid Build Coastguard Worker 	vaddr = bo->virtual;
625*d83cc019SAndroid Build Coastguard Worker 	while (size--)
626*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(*vaddr++, val);
627*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unmap(bo);
628*d83cc019SAndroid Build Coastguard Worker }
629*d83cc019SAndroid Build Coastguard Worker 
630*d83cc019SAndroid Build Coastguard Worker static void
gpu_set_bo(struct buffers * buffers,drm_intel_bo * bo,uint32_t val)631*d83cc019SAndroid Build Coastguard Worker gpu_set_bo(struct buffers *buffers, drm_intel_bo *bo, uint32_t val)
632*d83cc019SAndroid Build Coastguard Worker {
633*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc[1];
634*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 gem_exec[2];
635*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
636*d83cc019SAndroid Build Coastguard Worker 	uint32_t buf[10], *b;
637*d83cc019SAndroid Build Coastguard Worker 	uint32_t tiling, swizzle;
638*d83cc019SAndroid Build Coastguard Worker 
639*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
640*d83cc019SAndroid Build Coastguard Worker 
641*d83cc019SAndroid Build Coastguard Worker 	memset(reloc, 0, sizeof(reloc));
642*d83cc019SAndroid Build Coastguard Worker 	memset(gem_exec, 0, sizeof(gem_exec));
643*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
644*d83cc019SAndroid Build Coastguard Worker 
645*d83cc019SAndroid Build Coastguard Worker 	b = buf;
646*d83cc019SAndroid Build Coastguard Worker 	*b++ = XY_COLOR_BLT_CMD_NOLEN |
647*d83cc019SAndroid Build Coastguard Worker 		((gen >= 8) ? 5 : 4) |
648*d83cc019SAndroid Build Coastguard Worker 		COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
649*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 4 && tiling) {
650*d83cc019SAndroid Build Coastguard Worker 		b[-1] |= XY_COLOR_BLT_TILED;
651*d83cc019SAndroid Build Coastguard Worker 		*b = buffers->width;
652*d83cc019SAndroid Build Coastguard Worker 	} else
653*d83cc019SAndroid Build Coastguard Worker 		*b = buffers->width << 2;
654*d83cc019SAndroid Build Coastguard Worker 	*b++ |= 0xf0 << 16 | 1 << 25 | 1 << 24;
655*d83cc019SAndroid Build Coastguard Worker 	*b++ = 0;
656*d83cc019SAndroid Build Coastguard Worker 	*b++ = buffers->height << 16 | buffers->width;
657*d83cc019SAndroid Build Coastguard Worker 	reloc[0].offset = (b - buf) * sizeof(uint32_t);
658*d83cc019SAndroid Build Coastguard Worker 	reloc[0].target_handle = bo->handle;
659*d83cc019SAndroid Build Coastguard Worker 	reloc[0].read_domains = I915_GEM_DOMAIN_RENDER;
660*d83cc019SAndroid Build Coastguard Worker 	reloc[0].write_domain = I915_GEM_DOMAIN_RENDER;
661*d83cc019SAndroid Build Coastguard Worker 	*b++ = 0;
662*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8)
663*d83cc019SAndroid Build Coastguard Worker 		*b++ = 0;
664*d83cc019SAndroid Build Coastguard Worker 	*b++ = val;
665*d83cc019SAndroid Build Coastguard Worker 	*b++ = MI_BATCH_BUFFER_END;
666*d83cc019SAndroid Build Coastguard Worker 	if ((b - buf) & 1)
667*d83cc019SAndroid Build Coastguard Worker 		*b++ = 0;
668*d83cc019SAndroid Build Coastguard Worker 
669*d83cc019SAndroid Build Coastguard Worker 	gem_exec[0].handle = bo->handle;
670*d83cc019SAndroid Build Coastguard Worker 	gem_exec[0].flags = EXEC_OBJECT_NEEDS_FENCE;
671*d83cc019SAndroid Build Coastguard Worker 
672*d83cc019SAndroid Build Coastguard Worker 	gem_exec[1].handle = gem_create(fd, 4096);
673*d83cc019SAndroid Build Coastguard Worker 	gem_exec[1].relocation_count = 1;
674*d83cc019SAndroid Build Coastguard Worker 	gem_exec[1].relocs_ptr = to_user_pointer(reloc);
675*d83cc019SAndroid Build Coastguard Worker 
676*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(gem_exec);
677*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 2;
678*d83cc019SAndroid Build Coastguard Worker 	execbuf.batch_len = (b - buf) * sizeof(buf[0]);
679*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 6)
680*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags = I915_EXEC_BLT;
681*d83cc019SAndroid Build Coastguard Worker 
682*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, gem_exec[1].handle, 0, buf, execbuf.batch_len);
683*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
684*d83cc019SAndroid Build Coastguard Worker 
685*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, gem_exec[1].handle);
686*d83cc019SAndroid Build Coastguard Worker }
687*d83cc019SAndroid Build Coastguard Worker 
688*d83cc019SAndroid Build Coastguard Worker static void
gpu_cmp_bo(struct buffers * b,drm_intel_bo * bo,uint32_t val)689*d83cc019SAndroid Build Coastguard Worker gpu_cmp_bo(struct buffers *b, drm_intel_bo *bo, uint32_t val)
690*d83cc019SAndroid Build Coastguard Worker {
691*d83cc019SAndroid Build Coastguard Worker 	blt_copy_bo(b, b->snoop, bo);
692*d83cc019SAndroid Build Coastguard Worker 	cpu_cmp_bo(b, b->snoop, val);
693*d83cc019SAndroid Build Coastguard Worker }
694*d83cc019SAndroid Build Coastguard Worker 
695*d83cc019SAndroid Build Coastguard Worker struct access_mode {
696*d83cc019SAndroid Build Coastguard Worker 	const char *name;
697*d83cc019SAndroid Build Coastguard Worker 	void (*require)(const struct create *, unsigned);
698*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *(*create_bo)(const struct buffers *b);
699*d83cc019SAndroid Build Coastguard Worker 	void (*set_bo)(struct buffers *b, drm_intel_bo *bo, uint32_t val);
700*d83cc019SAndroid Build Coastguard Worker 	void (*cmp_bo)(struct buffers *b, drm_intel_bo *bo, uint32_t val);
701*d83cc019SAndroid Build Coastguard Worker 	void (*release_bo)(drm_intel_bo *bo);
702*d83cc019SAndroid Build Coastguard Worker };
703*d83cc019SAndroid Build Coastguard Worker igt_render_copyfunc_t rendercopy;
704*d83cc019SAndroid Build Coastguard Worker 
read_sysctl(const char * path)705*d83cc019SAndroid Build Coastguard Worker static int read_sysctl(const char *path)
706*d83cc019SAndroid Build Coastguard Worker {
707*d83cc019SAndroid Build Coastguard Worker 	FILE *file = fopen(path, "r");
708*d83cc019SAndroid Build Coastguard Worker 	int max = 0;
709*d83cc019SAndroid Build Coastguard Worker 	if (file) {
710*d83cc019SAndroid Build Coastguard Worker 		if (fscanf(file, "%d", &max) != 1)
711*d83cc019SAndroid Build Coastguard Worker 			max = 0; /* silence! */
712*d83cc019SAndroid Build Coastguard Worker 		fclose(file);
713*d83cc019SAndroid Build Coastguard Worker 	}
714*d83cc019SAndroid Build Coastguard Worker 	return max;
715*d83cc019SAndroid Build Coastguard Worker }
716*d83cc019SAndroid Build Coastguard Worker 
write_sysctl(const char * path,int value)717*d83cc019SAndroid Build Coastguard Worker static int write_sysctl(const char *path, int value)
718*d83cc019SAndroid Build Coastguard Worker {
719*d83cc019SAndroid Build Coastguard Worker 	FILE *file = fopen(path, "w");
720*d83cc019SAndroid Build Coastguard Worker 	if (file) {
721*d83cc019SAndroid Build Coastguard Worker 		fprintf(file, "%d", value);
722*d83cc019SAndroid Build Coastguard Worker 		fclose(file);
723*d83cc019SAndroid Build Coastguard Worker 	}
724*d83cc019SAndroid Build Coastguard Worker 	return read_sysctl(path);
725*d83cc019SAndroid Build Coastguard Worker }
726*d83cc019SAndroid Build Coastguard Worker 
set_max_map_count(int num_buffers)727*d83cc019SAndroid Build Coastguard Worker static bool set_max_map_count(int num_buffers)
728*d83cc019SAndroid Build Coastguard Worker {
729*d83cc019SAndroid Build Coastguard Worker 	int max = read_sysctl("/proc/sys/vm/max_map_count");
730*d83cc019SAndroid Build Coastguard Worker 	if (max < num_buffers + 1024)
731*d83cc019SAndroid Build Coastguard Worker 		max = write_sysctl("/proc/sys/vm/max_map_count",
732*d83cc019SAndroid Build Coastguard Worker 				   num_buffers + 1024);
733*d83cc019SAndroid Build Coastguard Worker 	return max > num_buffers;
734*d83cc019SAndroid Build Coastguard Worker }
735*d83cc019SAndroid Build Coastguard Worker 
buffers_init(struct buffers * b,const char * name,const struct create * create,const struct access_mode * mode,const struct size * size,int num_buffers,int _fd,int enable_reuse)736*d83cc019SAndroid Build Coastguard Worker static void buffers_init(struct buffers *b,
737*d83cc019SAndroid Build Coastguard Worker 			 const char *name,
738*d83cc019SAndroid Build Coastguard Worker 			 const struct create *create,
739*d83cc019SAndroid Build Coastguard Worker 			 const struct access_mode *mode,
740*d83cc019SAndroid Build Coastguard Worker 			 const struct size *size,
741*d83cc019SAndroid Build Coastguard Worker 			 int num_buffers,
742*d83cc019SAndroid Build Coastguard Worker 			 int _fd, int enable_reuse)
743*d83cc019SAndroid Build Coastguard Worker {
744*d83cc019SAndroid Build Coastguard Worker 	memset(b, 0, sizeof(*b));
745*d83cc019SAndroid Build Coastguard Worker 	b->name = name;
746*d83cc019SAndroid Build Coastguard Worker 	b->create = create;
747*d83cc019SAndroid Build Coastguard Worker 	b->mode = mode;
748*d83cc019SAndroid Build Coastguard Worker 	b->size = size;
749*d83cc019SAndroid Build Coastguard Worker 	b->num_buffers = num_buffers;
750*d83cc019SAndroid Build Coastguard Worker 	b->count = 0;
751*d83cc019SAndroid Build Coastguard Worker 
752*d83cc019SAndroid Build Coastguard Worker 	b->width = size->width;
753*d83cc019SAndroid Build Coastguard Worker 	b->height = size->height;
754*d83cc019SAndroid Build Coastguard Worker 	b->npixels = size->width * size->height;
755*d83cc019SAndroid Build Coastguard Worker 	b->page_size = 4*b->npixels;
756*d83cc019SAndroid Build Coastguard Worker 	b->page_size = (b->page_size + 4095) & -4096;
757*d83cc019SAndroid Build Coastguard Worker 	b->tmp = malloc(b->page_size);
758*d83cc019SAndroid Build Coastguard Worker 	igt_assert(b->tmp);
759*d83cc019SAndroid Build Coastguard Worker 
760*d83cc019SAndroid Build Coastguard Worker 	b->bufmgr = drm_intel_bufmgr_gem_init(_fd, 4096);
761*d83cc019SAndroid Build Coastguard Worker 	igt_assert(b->bufmgr);
762*d83cc019SAndroid Build Coastguard Worker 
763*d83cc019SAndroid Build Coastguard Worker 	b->src = malloc(2*sizeof(drm_intel_bo *)*num_buffers);
764*d83cc019SAndroid Build Coastguard Worker 	igt_assert(b->src);
765*d83cc019SAndroid Build Coastguard Worker 	b->dst = b->src + num_buffers;
766*d83cc019SAndroid Build Coastguard Worker 
767*d83cc019SAndroid Build Coastguard Worker 	if (enable_reuse)
768*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_gem_enable_reuse(b->bufmgr);
769*d83cc019SAndroid Build Coastguard Worker 	b->batch = intel_batchbuffer_alloc(b->bufmgr, devid);
770*d83cc019SAndroid Build Coastguard Worker 	igt_assert(b->batch);
771*d83cc019SAndroid Build Coastguard Worker }
772*d83cc019SAndroid Build Coastguard Worker 
buffers_destroy(struct buffers * b)773*d83cc019SAndroid Build Coastguard Worker static void buffers_destroy(struct buffers *b)
774*d83cc019SAndroid Build Coastguard Worker {
775*d83cc019SAndroid Build Coastguard Worker 	int count = b->count;
776*d83cc019SAndroid Build Coastguard Worker 	if (count == 0)
777*d83cc019SAndroid Build Coastguard Worker 		return;
778*d83cc019SAndroid Build Coastguard Worker 
779*d83cc019SAndroid Build Coastguard Worker 	/* Be safe so that we can clean up a partial creation */
780*d83cc019SAndroid Build Coastguard Worker 	b->count = 0;
781*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < count; i++) {
782*d83cc019SAndroid Build Coastguard Worker 		if (b->src[i]) {
783*d83cc019SAndroid Build Coastguard Worker 			b->mode->release_bo(b->src[i]);
784*d83cc019SAndroid Build Coastguard Worker 			b->src[i] = NULL;
785*d83cc019SAndroid Build Coastguard Worker 		} else
786*d83cc019SAndroid Build Coastguard Worker 			break;
787*d83cc019SAndroid Build Coastguard Worker 
788*d83cc019SAndroid Build Coastguard Worker 		if (b->dst[i]) {
789*d83cc019SAndroid Build Coastguard Worker 			b->mode->release_bo(b->dst[i]);
790*d83cc019SAndroid Build Coastguard Worker 			b->dst[i] = NULL;
791*d83cc019SAndroid Build Coastguard Worker 		}
792*d83cc019SAndroid Build Coastguard Worker 	}
793*d83cc019SAndroid Build Coastguard Worker 	if (b->snoop) {
794*d83cc019SAndroid Build Coastguard Worker 		nop_release_bo(b->snoop);
795*d83cc019SAndroid Build Coastguard Worker 		b->snoop = NULL;
796*d83cc019SAndroid Build Coastguard Worker 	}
797*d83cc019SAndroid Build Coastguard Worker 	if (b->spare) {
798*d83cc019SAndroid Build Coastguard Worker 		b->mode->release_bo(b->spare);
799*d83cc019SAndroid Build Coastguard Worker 		b->spare = NULL;
800*d83cc019SAndroid Build Coastguard Worker 	}
801*d83cc019SAndroid Build Coastguard Worker }
802*d83cc019SAndroid Build Coastguard Worker 
buffers_create(struct buffers * b)803*d83cc019SAndroid Build Coastguard Worker static void buffers_create(struct buffers *b)
804*d83cc019SAndroid Build Coastguard Worker {
805*d83cc019SAndroid Build Coastguard Worker 	int count = b->num_buffers;
806*d83cc019SAndroid Build Coastguard Worker 	igt_assert(b->bufmgr);
807*d83cc019SAndroid Build Coastguard Worker 
808*d83cc019SAndroid Build Coastguard Worker 	buffers_destroy(b);
809*d83cc019SAndroid Build Coastguard Worker 	igt_assert(b->count == 0);
810*d83cc019SAndroid Build Coastguard Worker 	b->count = count;
811*d83cc019SAndroid Build Coastguard Worker 
812*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < count; i++) {
813*d83cc019SAndroid Build Coastguard Worker 		b->src[i] = b->mode->create_bo(b);
814*d83cc019SAndroid Build Coastguard Worker 		b->dst[i] = b->mode->create_bo(b);
815*d83cc019SAndroid Build Coastguard Worker 	}
816*d83cc019SAndroid Build Coastguard Worker 	b->spare = b->mode->create_bo(b);
817*d83cc019SAndroid Build Coastguard Worker 	b->snoop = snoop_create_bo(b);
818*d83cc019SAndroid Build Coastguard Worker }
819*d83cc019SAndroid Build Coastguard Worker 
buffers_reset(struct buffers * b,bool enable_reuse)820*d83cc019SAndroid Build Coastguard Worker static void buffers_reset(struct buffers *b, bool enable_reuse)
821*d83cc019SAndroid Build Coastguard Worker {
822*d83cc019SAndroid Build Coastguard Worker 	b->bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
823*d83cc019SAndroid Build Coastguard Worker 	igt_assert(b->bufmgr);
824*d83cc019SAndroid Build Coastguard Worker 
825*d83cc019SAndroid Build Coastguard Worker 	if (enable_reuse)
826*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_gem_enable_reuse(b->bufmgr);
827*d83cc019SAndroid Build Coastguard Worker 	b->batch = intel_batchbuffer_alloc(b->bufmgr, devid);
828*d83cc019SAndroid Build Coastguard Worker 	igt_assert(b->batch);
829*d83cc019SAndroid Build Coastguard Worker }
830*d83cc019SAndroid Build Coastguard Worker 
buffers_fini(struct buffers * b)831*d83cc019SAndroid Build Coastguard Worker static void buffers_fini(struct buffers *b)
832*d83cc019SAndroid Build Coastguard Worker {
833*d83cc019SAndroid Build Coastguard Worker 	if (b->bufmgr == NULL)
834*d83cc019SAndroid Build Coastguard Worker 		return;
835*d83cc019SAndroid Build Coastguard Worker 
836*d83cc019SAndroid Build Coastguard Worker 	buffers_destroy(b);
837*d83cc019SAndroid Build Coastguard Worker 
838*d83cc019SAndroid Build Coastguard Worker 	free(b->tmp);
839*d83cc019SAndroid Build Coastguard Worker 	free(b->src);
840*d83cc019SAndroid Build Coastguard Worker 
841*d83cc019SAndroid Build Coastguard Worker 	intel_batchbuffer_free(b->batch);
842*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr_destroy(b->bufmgr);
843*d83cc019SAndroid Build Coastguard Worker 
844*d83cc019SAndroid Build Coastguard Worker 	memset(b, 0, sizeof(*b));
845*d83cc019SAndroid Build Coastguard Worker }
846*d83cc019SAndroid Build Coastguard Worker 
847*d83cc019SAndroid Build Coastguard Worker typedef void (*do_copy)(struct buffers *b, drm_intel_bo *dst, drm_intel_bo *src);
848*d83cc019SAndroid Build Coastguard Worker typedef igt_hang_t (*do_hang)(void);
849*d83cc019SAndroid Build Coastguard Worker 
render_copy_bo(struct buffers * b,drm_intel_bo * dst,drm_intel_bo * src)850*d83cc019SAndroid Build Coastguard Worker static void render_copy_bo(struct buffers *b, drm_intel_bo *dst, drm_intel_bo *src)
851*d83cc019SAndroid Build Coastguard Worker {
852*d83cc019SAndroid Build Coastguard Worker 	struct igt_buf d = {
853*d83cc019SAndroid Build Coastguard Worker 		.bo = dst,
854*d83cc019SAndroid Build Coastguard Worker 		.size = b->npixels * 4,
855*d83cc019SAndroid Build Coastguard Worker 		.num_tiles = b->npixels * 4,
856*d83cc019SAndroid Build Coastguard Worker 		.stride = b->width * 4,
857*d83cc019SAndroid Build Coastguard Worker 		.bpp = 32,
858*d83cc019SAndroid Build Coastguard Worker 	}, s = {
859*d83cc019SAndroid Build Coastguard Worker 		.bo = src,
860*d83cc019SAndroid Build Coastguard Worker 		.size = b->npixels * 4,
861*d83cc019SAndroid Build Coastguard Worker 		.num_tiles = b->npixels * 4,
862*d83cc019SAndroid Build Coastguard Worker 		.stride = b->width * 4,
863*d83cc019SAndroid Build Coastguard Worker 		.bpp = 32,
864*d83cc019SAndroid Build Coastguard Worker 	};
865*d83cc019SAndroid Build Coastguard Worker 	uint32_t swizzle;
866*d83cc019SAndroid Build Coastguard Worker 
867*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_get_tiling(dst, &d.tiling, &swizzle);
868*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_get_tiling(src, &s.tiling, &swizzle);
869*d83cc019SAndroid Build Coastguard Worker 
870*d83cc019SAndroid Build Coastguard Worker 	rendercopy(b->batch, NULL,
871*d83cc019SAndroid Build Coastguard Worker 		   &s, 0, 0,
872*d83cc019SAndroid Build Coastguard Worker 		   b->width, b->height,
873*d83cc019SAndroid Build Coastguard Worker 		   &d, 0, 0);
874*d83cc019SAndroid Build Coastguard Worker }
875*d83cc019SAndroid Build Coastguard Worker 
blt_copy_bo(struct buffers * b,drm_intel_bo * dst,drm_intel_bo * src)876*d83cc019SAndroid Build Coastguard Worker static void blt_copy_bo(struct buffers *b, drm_intel_bo *dst, drm_intel_bo *src)
877*d83cc019SAndroid Build Coastguard Worker {
878*d83cc019SAndroid Build Coastguard Worker 	intel_blt_copy(b->batch,
879*d83cc019SAndroid Build Coastguard Worker 		       src, 0, 0, 4*b->width,
880*d83cc019SAndroid Build Coastguard Worker 		       dst, 0, 0, 4*b->width,
881*d83cc019SAndroid Build Coastguard Worker 		       b->width, b->height, 32);
882*d83cc019SAndroid Build Coastguard Worker }
883*d83cc019SAndroid Build Coastguard Worker 
cpu_copy_bo(struct buffers * b,drm_intel_bo * dst,drm_intel_bo * src)884*d83cc019SAndroid Build Coastguard Worker static void cpu_copy_bo(struct buffers *b, drm_intel_bo *dst, drm_intel_bo *src)
885*d83cc019SAndroid Build Coastguard Worker {
886*d83cc019SAndroid Build Coastguard Worker 	const int size = b->page_size;
887*d83cc019SAndroid Build Coastguard Worker 	void *d, *s;
888*d83cc019SAndroid Build Coastguard Worker 
889*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_CPU, 0);
890*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
891*d83cc019SAndroid Build Coastguard Worker 	s = gem_mmap__cpu(fd, src->handle, 0, size, PROT_READ);
892*d83cc019SAndroid Build Coastguard Worker 	d = gem_mmap__cpu(fd, dst->handle, 0, size, PROT_WRITE);
893*d83cc019SAndroid Build Coastguard Worker 
894*d83cc019SAndroid Build Coastguard Worker 	memcpy(d, s, size);
895*d83cc019SAndroid Build Coastguard Worker 
896*d83cc019SAndroid Build Coastguard Worker 	munmap(d, size);
897*d83cc019SAndroid Build Coastguard Worker 	munmap(s, size);
898*d83cc019SAndroid Build Coastguard Worker }
899*d83cc019SAndroid Build Coastguard Worker 
gtt_copy_bo(struct buffers * b,drm_intel_bo * dst,drm_intel_bo * src)900*d83cc019SAndroid Build Coastguard Worker static void gtt_copy_bo(struct buffers *b, drm_intel_bo *dst, drm_intel_bo *src)
901*d83cc019SAndroid Build Coastguard Worker {
902*d83cc019SAndroid Build Coastguard Worker 	const int size = b->page_size;
903*d83cc019SAndroid Build Coastguard Worker 	void *d, *s;
904*d83cc019SAndroid Build Coastguard Worker 
905*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_GTT, 0);
906*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
907*d83cc019SAndroid Build Coastguard Worker 
908*d83cc019SAndroid Build Coastguard Worker 	s = gem_mmap__gtt(fd, src->handle, size, PROT_READ);
909*d83cc019SAndroid Build Coastguard Worker 	d = gem_mmap__gtt(fd, dst->handle, size, PROT_WRITE);
910*d83cc019SAndroid Build Coastguard Worker 
911*d83cc019SAndroid Build Coastguard Worker 	memcpy(d, s, size);
912*d83cc019SAndroid Build Coastguard Worker 
913*d83cc019SAndroid Build Coastguard Worker 	munmap(d, size);
914*d83cc019SAndroid Build Coastguard Worker 	munmap(s, size);
915*d83cc019SAndroid Build Coastguard Worker }
916*d83cc019SAndroid Build Coastguard Worker 
wc_copy_bo(struct buffers * b,drm_intel_bo * dst,drm_intel_bo * src)917*d83cc019SAndroid Build Coastguard Worker static void wc_copy_bo(struct buffers *b, drm_intel_bo *dst, drm_intel_bo *src)
918*d83cc019SAndroid Build Coastguard Worker {
919*d83cc019SAndroid Build Coastguard Worker 	const int size = b->page_size;
920*d83cc019SAndroid Build Coastguard Worker 	void *d, *s;
921*d83cc019SAndroid Build Coastguard Worker 
922*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_WC, 0);
923*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
924*d83cc019SAndroid Build Coastguard Worker 
925*d83cc019SAndroid Build Coastguard Worker 	s = gem_mmap__wc(fd, src->handle, 0, size, PROT_READ);
926*d83cc019SAndroid Build Coastguard Worker 	d = gem_mmap__wc(fd, dst->handle, 0, size, PROT_WRITE);
927*d83cc019SAndroid Build Coastguard Worker 
928*d83cc019SAndroid Build Coastguard Worker 	memcpy(d, s, size);
929*d83cc019SAndroid Build Coastguard Worker 
930*d83cc019SAndroid Build Coastguard Worker 	munmap(d, size);
931*d83cc019SAndroid Build Coastguard Worker 	munmap(s, size);
932*d83cc019SAndroid Build Coastguard Worker }
933*d83cc019SAndroid Build Coastguard Worker 
no_hang(void)934*d83cc019SAndroid Build Coastguard Worker static igt_hang_t no_hang(void)
935*d83cc019SAndroid Build Coastguard Worker {
936*d83cc019SAndroid Build Coastguard Worker 	return (igt_hang_t){0, 0};
937*d83cc019SAndroid Build Coastguard Worker }
938*d83cc019SAndroid Build Coastguard Worker 
bcs_hang(void)939*d83cc019SAndroid Build Coastguard Worker static igt_hang_t bcs_hang(void)
940*d83cc019SAndroid Build Coastguard Worker {
941*d83cc019SAndroid Build Coastguard Worker 	return igt_hang_ring(fd, I915_EXEC_BLT);
942*d83cc019SAndroid Build Coastguard Worker }
943*d83cc019SAndroid Build Coastguard Worker 
rcs_hang(void)944*d83cc019SAndroid Build Coastguard Worker static igt_hang_t rcs_hang(void)
945*d83cc019SAndroid Build Coastguard Worker {
946*d83cc019SAndroid Build Coastguard Worker 	return igt_hang_ring(fd, I915_EXEC_RENDER);
947*d83cc019SAndroid Build Coastguard Worker }
948*d83cc019SAndroid Build Coastguard Worker 
all_hang(void)949*d83cc019SAndroid Build Coastguard Worker static igt_hang_t all_hang(void)
950*d83cc019SAndroid Build Coastguard Worker {
951*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang = igt_hang_ring(fd, I915_EXEC_RENDER);
952*d83cc019SAndroid Build Coastguard Worker 	unsigned engine;
953*d83cc019SAndroid Build Coastguard Worker 
954*d83cc019SAndroid Build Coastguard Worker 	for_each_physical_engine(fd, engine) {
955*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_gem_execbuffer2 eb = hang.spin->execbuf;
956*d83cc019SAndroid Build Coastguard Worker 
957*d83cc019SAndroid Build Coastguard Worker 		if (engine == I915_EXEC_RENDER)
958*d83cc019SAndroid Build Coastguard Worker 			continue;
959*d83cc019SAndroid Build Coastguard Worker 
960*d83cc019SAndroid Build Coastguard Worker 		eb.flags = engine;
961*d83cc019SAndroid Build Coastguard Worker 		__gem_execbuf(fd, &eb);
962*d83cc019SAndroid Build Coastguard Worker 	}
963*d83cc019SAndroid Build Coastguard Worker 
964*d83cc019SAndroid Build Coastguard Worker 	return hang;
965*d83cc019SAndroid Build Coastguard Worker }
966*d83cc019SAndroid Build Coastguard Worker 
do_basic0(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)967*d83cc019SAndroid Build Coastguard Worker static void do_basic0(struct buffers *buffers,
968*d83cc019SAndroid Build Coastguard Worker 		      do_copy do_copy_func,
969*d83cc019SAndroid Build Coastguard Worker 		      do_hang do_hang_func)
970*d83cc019SAndroid Build Coastguard Worker {
971*d83cc019SAndroid Build Coastguard Worker 	buffers->mode->set_bo(buffers, buffers->src[0], 0xdeadbeef);
972*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < buffers->count; i++) {
973*d83cc019SAndroid Build Coastguard Worker 		igt_hang_t hang = do_hang_func();
974*d83cc019SAndroid Build Coastguard Worker 
975*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[0]);
976*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], 0xdeadbeef);
977*d83cc019SAndroid Build Coastguard Worker 
978*d83cc019SAndroid Build Coastguard Worker 		igt_post_hang_ring(fd, hang);
979*d83cc019SAndroid Build Coastguard Worker 	}
980*d83cc019SAndroid Build Coastguard Worker }
981*d83cc019SAndroid Build Coastguard Worker 
do_basic1(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)982*d83cc019SAndroid Build Coastguard Worker static void do_basic1(struct buffers *buffers,
983*d83cc019SAndroid Build Coastguard Worker 		      do_copy do_copy_func,
984*d83cc019SAndroid Build Coastguard Worker 		      do_hang do_hang_func)
985*d83cc019SAndroid Build Coastguard Worker {
986*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < buffers->count; i++) {
987*d83cc019SAndroid Build Coastguard Worker 		igt_hang_t hang = do_hang_func();
988*d83cc019SAndroid Build Coastguard Worker 
989*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], i);
990*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->dst[i], ~i);
991*d83cc019SAndroid Build Coastguard Worker 
992*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
993*d83cc019SAndroid Build Coastguard Worker 		usleep(0); /* let someone else claim the mutex */
994*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], i);
995*d83cc019SAndroid Build Coastguard Worker 
996*d83cc019SAndroid Build Coastguard Worker 		igt_post_hang_ring(fd, hang);
997*d83cc019SAndroid Build Coastguard Worker 	}
998*d83cc019SAndroid Build Coastguard Worker }
999*d83cc019SAndroid Build Coastguard Worker 
do_basicN(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1000*d83cc019SAndroid Build Coastguard Worker static void do_basicN(struct buffers *buffers,
1001*d83cc019SAndroid Build Coastguard Worker 		      do_copy do_copy_func,
1002*d83cc019SAndroid Build Coastguard Worker 		      do_hang do_hang_func)
1003*d83cc019SAndroid Build Coastguard Worker {
1004*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1005*d83cc019SAndroid Build Coastguard Worker 
1006*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < buffers->count; i++) {
1007*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], i);
1008*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->dst[i], ~i);
1009*d83cc019SAndroid Build Coastguard Worker 	}
1010*d83cc019SAndroid Build Coastguard Worker 
1011*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1012*d83cc019SAndroid Build Coastguard Worker 
1013*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < buffers->count; i++) {
1014*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
1015*d83cc019SAndroid Build Coastguard Worker 		usleep(0); /* let someone else claim the mutex */
1016*d83cc019SAndroid Build Coastguard Worker 	}
1017*d83cc019SAndroid Build Coastguard Worker 
1018*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < buffers->count; i++)
1019*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], i);
1020*d83cc019SAndroid Build Coastguard Worker 
1021*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1022*d83cc019SAndroid Build Coastguard Worker }
1023*d83cc019SAndroid Build Coastguard Worker 
do_overwrite_source(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1024*d83cc019SAndroid Build Coastguard Worker static void do_overwrite_source(struct buffers *buffers,
1025*d83cc019SAndroid Build Coastguard Worker 				do_copy do_copy_func,
1026*d83cc019SAndroid Build Coastguard Worker 				do_hang do_hang_func)
1027*d83cc019SAndroid Build Coastguard Worker {
1028*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1029*d83cc019SAndroid Build Coastguard Worker 	int i;
1030*d83cc019SAndroid Build Coastguard Worker 
1031*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++) {
1032*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], i);
1033*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->dst[i], ~i);
1034*d83cc019SAndroid Build Coastguard Worker 	}
1035*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++)
1036*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
1037*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1038*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1039*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef);
1040*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++)
1041*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], i);
1042*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1043*d83cc019SAndroid Build Coastguard Worker }
1044*d83cc019SAndroid Build Coastguard Worker 
do_overwrite_source_read(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func,int do_rcs)1045*d83cc019SAndroid Build Coastguard Worker static void do_overwrite_source_read(struct buffers *buffers,
1046*d83cc019SAndroid Build Coastguard Worker 				     do_copy do_copy_func,
1047*d83cc019SAndroid Build Coastguard Worker 				     do_hang do_hang_func,
1048*d83cc019SAndroid Build Coastguard Worker 				     int do_rcs)
1049*d83cc019SAndroid Build Coastguard Worker {
1050*d83cc019SAndroid Build Coastguard Worker 	const int half = buffers->count/2;
1051*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1052*d83cc019SAndroid Build Coastguard Worker 	int i;
1053*d83cc019SAndroid Build Coastguard Worker 
1054*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < half; i++) {
1055*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], i);
1056*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->dst[i], ~i);
1057*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->dst[i+half], ~i);
1058*d83cc019SAndroid Build Coastguard Worker 	}
1059*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < half; i++) {
1060*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
1061*d83cc019SAndroid Build Coastguard Worker 		if (do_rcs)
1062*d83cc019SAndroid Build Coastguard Worker 			render_copy_bo(buffers, buffers->dst[i+half], buffers->src[i]);
1063*d83cc019SAndroid Build Coastguard Worker 		else
1064*d83cc019SAndroid Build Coastguard Worker 			blt_copy_bo(buffers, buffers->dst[i+half], buffers->src[i]);
1065*d83cc019SAndroid Build Coastguard Worker 	}
1066*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1067*d83cc019SAndroid Build Coastguard Worker 	for (i = half; i--; )
1068*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef);
1069*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < half; i++) {
1070*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], i);
1071*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i+half], i);
1072*d83cc019SAndroid Build Coastguard Worker 	}
1073*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1074*d83cc019SAndroid Build Coastguard Worker }
1075*d83cc019SAndroid Build Coastguard Worker 
do_overwrite_source_read_bcs(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1076*d83cc019SAndroid Build Coastguard Worker static void do_overwrite_source_read_bcs(struct buffers *buffers,
1077*d83cc019SAndroid Build Coastguard Worker 					 do_copy do_copy_func,
1078*d83cc019SAndroid Build Coastguard Worker 					 do_hang do_hang_func)
1079*d83cc019SAndroid Build Coastguard Worker {
1080*d83cc019SAndroid Build Coastguard Worker 	do_overwrite_source_read(buffers, do_copy_func, do_hang_func, 0);
1081*d83cc019SAndroid Build Coastguard Worker }
1082*d83cc019SAndroid Build Coastguard Worker 
do_overwrite_source_read_rcs(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1083*d83cc019SAndroid Build Coastguard Worker static void do_overwrite_source_read_rcs(struct buffers *buffers,
1084*d83cc019SAndroid Build Coastguard Worker 					 do_copy do_copy_func,
1085*d83cc019SAndroid Build Coastguard Worker 					 do_hang do_hang_func)
1086*d83cc019SAndroid Build Coastguard Worker {
1087*d83cc019SAndroid Build Coastguard Worker 	do_overwrite_source_read(buffers, do_copy_func, do_hang_func, 1);
1088*d83cc019SAndroid Build Coastguard Worker }
1089*d83cc019SAndroid Build Coastguard Worker 
do_overwrite_source__rev(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1090*d83cc019SAndroid Build Coastguard Worker static void do_overwrite_source__rev(struct buffers *buffers,
1091*d83cc019SAndroid Build Coastguard Worker 				     do_copy do_copy_func,
1092*d83cc019SAndroid Build Coastguard Worker 				     do_hang do_hang_func)
1093*d83cc019SAndroid Build Coastguard Worker {
1094*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1095*d83cc019SAndroid Build Coastguard Worker 	int i;
1096*d83cc019SAndroid Build Coastguard Worker 
1097*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++) {
1098*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], i);
1099*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->dst[i], ~i);
1100*d83cc019SAndroid Build Coastguard Worker 	}
1101*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++)
1102*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
1103*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1104*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++)
1105*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef);
1106*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1107*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], i);
1108*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1109*d83cc019SAndroid Build Coastguard Worker }
1110*d83cc019SAndroid Build Coastguard Worker 
do_overwrite_source__one(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1111*d83cc019SAndroid Build Coastguard Worker static void do_overwrite_source__one(struct buffers *buffers,
1112*d83cc019SAndroid Build Coastguard Worker 				     do_copy do_copy_func,
1113*d83cc019SAndroid Build Coastguard Worker 				     do_hang do_hang_func)
1114*d83cc019SAndroid Build Coastguard Worker {
1115*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1116*d83cc019SAndroid Build Coastguard Worker 
1117*d83cc019SAndroid Build Coastguard Worker 	buffers->mode->set_bo(buffers, buffers->src[0], 0);
1118*d83cc019SAndroid Build Coastguard Worker 	buffers->mode->set_bo(buffers, buffers->dst[0], ~0);
1119*d83cc019SAndroid Build Coastguard Worker 	do_copy_func(buffers, buffers->dst[0], buffers->src[0]);
1120*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1121*d83cc019SAndroid Build Coastguard Worker 	buffers->mode->set_bo(buffers, buffers->src[0], 0xdeadbeef);
1122*d83cc019SAndroid Build Coastguard Worker 	buffers->mode->cmp_bo(buffers, buffers->dst[0], 0);
1123*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1124*d83cc019SAndroid Build Coastguard Worker }
1125*d83cc019SAndroid Build Coastguard Worker 
do_intermix(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func,int do_rcs)1126*d83cc019SAndroid Build Coastguard Worker static void do_intermix(struct buffers *buffers,
1127*d83cc019SAndroid Build Coastguard Worker 			do_copy do_copy_func,
1128*d83cc019SAndroid Build Coastguard Worker 			do_hang do_hang_func,
1129*d83cc019SAndroid Build Coastguard Worker 			int do_rcs)
1130*d83cc019SAndroid Build Coastguard Worker {
1131*d83cc019SAndroid Build Coastguard Worker 	const int half = buffers->count/2;
1132*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1133*d83cc019SAndroid Build Coastguard Worker 	int i;
1134*d83cc019SAndroid Build Coastguard Worker 
1135*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++) {
1136*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef^~i);
1137*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->dst[i], i);
1138*d83cc019SAndroid Build Coastguard Worker 	}
1139*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < half; i++) {
1140*d83cc019SAndroid Build Coastguard Worker 		if (do_rcs == 1 || (do_rcs == -1 && i & 1))
1141*d83cc019SAndroid Build Coastguard Worker 			render_copy_bo(buffers, buffers->dst[i], buffers->src[i]);
1142*d83cc019SAndroid Build Coastguard Worker 		else
1143*d83cc019SAndroid Build Coastguard Worker 			blt_copy_bo(buffers, buffers->dst[i], buffers->src[i]);
1144*d83cc019SAndroid Build Coastguard Worker 
1145*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i+half], buffers->src[i]);
1146*d83cc019SAndroid Build Coastguard Worker 
1147*d83cc019SAndroid Build Coastguard Worker 		if (do_rcs == 1 || (do_rcs == -1 && (i & 1) == 0))
1148*d83cc019SAndroid Build Coastguard Worker 			render_copy_bo(buffers, buffers->dst[i], buffers->dst[i+half]);
1149*d83cc019SAndroid Build Coastguard Worker 		else
1150*d83cc019SAndroid Build Coastguard Worker 			blt_copy_bo(buffers, buffers->dst[i], buffers->dst[i+half]);
1151*d83cc019SAndroid Build Coastguard Worker 
1152*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i+half], buffers->src[i+half]);
1153*d83cc019SAndroid Build Coastguard Worker 	}
1154*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1155*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 2*half; i++)
1156*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], 0xdeadbeef^~i);
1157*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1158*d83cc019SAndroid Build Coastguard Worker }
1159*d83cc019SAndroid Build Coastguard Worker 
do_intermix_rcs(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1160*d83cc019SAndroid Build Coastguard Worker static void do_intermix_rcs(struct buffers *buffers,
1161*d83cc019SAndroid Build Coastguard Worker 			    do_copy do_copy_func,
1162*d83cc019SAndroid Build Coastguard Worker 			    do_hang do_hang_func)
1163*d83cc019SAndroid Build Coastguard Worker {
1164*d83cc019SAndroid Build Coastguard Worker 	do_intermix(buffers, do_copy_func, do_hang_func, 1);
1165*d83cc019SAndroid Build Coastguard Worker }
1166*d83cc019SAndroid Build Coastguard Worker 
do_intermix_bcs(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1167*d83cc019SAndroid Build Coastguard Worker static void do_intermix_bcs(struct buffers *buffers,
1168*d83cc019SAndroid Build Coastguard Worker 			    do_copy do_copy_func,
1169*d83cc019SAndroid Build Coastguard Worker 			    do_hang do_hang_func)
1170*d83cc019SAndroid Build Coastguard Worker {
1171*d83cc019SAndroid Build Coastguard Worker 	do_intermix(buffers, do_copy_func, do_hang_func, 0);
1172*d83cc019SAndroid Build Coastguard Worker }
1173*d83cc019SAndroid Build Coastguard Worker 
do_intermix_both(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1174*d83cc019SAndroid Build Coastguard Worker static void do_intermix_both(struct buffers *buffers,
1175*d83cc019SAndroid Build Coastguard Worker 			     do_copy do_copy_func,
1176*d83cc019SAndroid Build Coastguard Worker 			     do_hang do_hang_func)
1177*d83cc019SAndroid Build Coastguard Worker {
1178*d83cc019SAndroid Build Coastguard Worker 	do_intermix(buffers, do_copy_func, do_hang_func, -1);
1179*d83cc019SAndroid Build Coastguard Worker }
1180*d83cc019SAndroid Build Coastguard Worker 
do_early_read(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1181*d83cc019SAndroid Build Coastguard Worker static void do_early_read(struct buffers *buffers,
1182*d83cc019SAndroid Build Coastguard Worker 			  do_copy do_copy_func,
1183*d83cc019SAndroid Build Coastguard Worker 			  do_hang do_hang_func)
1184*d83cc019SAndroid Build Coastguard Worker {
1185*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1186*d83cc019SAndroid Build Coastguard Worker 	int i;
1187*d83cc019SAndroid Build Coastguard Worker 
1188*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1189*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef);
1190*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++)
1191*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
1192*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1193*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1194*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], 0xdeadbeef);
1195*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1196*d83cc019SAndroid Build Coastguard Worker }
1197*d83cc019SAndroid Build Coastguard Worker 
do_read_read_bcs(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1198*d83cc019SAndroid Build Coastguard Worker static void do_read_read_bcs(struct buffers *buffers,
1199*d83cc019SAndroid Build Coastguard Worker 			     do_copy do_copy_func,
1200*d83cc019SAndroid Build Coastguard Worker 			     do_hang do_hang_func)
1201*d83cc019SAndroid Build Coastguard Worker {
1202*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1203*d83cc019SAndroid Build Coastguard Worker 	int i;
1204*d83cc019SAndroid Build Coastguard Worker 
1205*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1206*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef ^ i);
1207*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++) {
1208*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
1209*d83cc019SAndroid Build Coastguard Worker 		blt_copy_bo(buffers, buffers->spare, buffers->src[i]);
1210*d83cc019SAndroid Build Coastguard Worker 	}
1211*d83cc019SAndroid Build Coastguard Worker 	buffers->mode->cmp_bo(buffers, buffers->spare, 0xdeadbeef^(buffers->count-1));
1212*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1213*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1214*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], 0xdeadbeef ^ i);
1215*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1216*d83cc019SAndroid Build Coastguard Worker }
1217*d83cc019SAndroid Build Coastguard Worker 
do_write_read_bcs(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1218*d83cc019SAndroid Build Coastguard Worker static void do_write_read_bcs(struct buffers *buffers,
1219*d83cc019SAndroid Build Coastguard Worker 			      do_copy do_copy_func,
1220*d83cc019SAndroid Build Coastguard Worker 			      do_hang do_hang_func)
1221*d83cc019SAndroid Build Coastguard Worker {
1222*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1223*d83cc019SAndroid Build Coastguard Worker 	int i;
1224*d83cc019SAndroid Build Coastguard Worker 
1225*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1226*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef ^ i);
1227*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++) {
1228*d83cc019SAndroid Build Coastguard Worker 		blt_copy_bo(buffers, buffers->spare, buffers->src[i]);
1229*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->spare);
1230*d83cc019SAndroid Build Coastguard Worker 	}
1231*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1232*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1233*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], 0xdeadbeef ^ i);
1234*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1235*d83cc019SAndroid Build Coastguard Worker }
1236*d83cc019SAndroid Build Coastguard Worker 
do_read_read_rcs(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1237*d83cc019SAndroid Build Coastguard Worker static void do_read_read_rcs(struct buffers *buffers,
1238*d83cc019SAndroid Build Coastguard Worker 			     do_copy do_copy_func,
1239*d83cc019SAndroid Build Coastguard Worker 			     do_hang do_hang_func)
1240*d83cc019SAndroid Build Coastguard Worker {
1241*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1242*d83cc019SAndroid Build Coastguard Worker 	int i;
1243*d83cc019SAndroid Build Coastguard Worker 
1244*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1245*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef ^ i);
1246*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++) {
1247*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
1248*d83cc019SAndroid Build Coastguard Worker 		render_copy_bo(buffers, buffers->spare, buffers->src[i]);
1249*d83cc019SAndroid Build Coastguard Worker 	}
1250*d83cc019SAndroid Build Coastguard Worker 	buffers->mode->cmp_bo(buffers, buffers->spare, 0xdeadbeef^(buffers->count-1));
1251*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1252*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1253*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], 0xdeadbeef ^ i);
1254*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1255*d83cc019SAndroid Build Coastguard Worker }
1256*d83cc019SAndroid Build Coastguard Worker 
do_write_read_rcs(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1257*d83cc019SAndroid Build Coastguard Worker static void do_write_read_rcs(struct buffers *buffers,
1258*d83cc019SAndroid Build Coastguard Worker 			      do_copy do_copy_func,
1259*d83cc019SAndroid Build Coastguard Worker 			      do_hang do_hang_func)
1260*d83cc019SAndroid Build Coastguard Worker {
1261*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1262*d83cc019SAndroid Build Coastguard Worker 	int i;
1263*d83cc019SAndroid Build Coastguard Worker 
1264*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1265*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xdeadbeef ^ i);
1266*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++) {
1267*d83cc019SAndroid Build Coastguard Worker 		render_copy_bo(buffers, buffers->spare, buffers->src[i]);
1268*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->spare);
1269*d83cc019SAndroid Build Coastguard Worker 	}
1270*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1271*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1272*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], 0xdeadbeef ^ i);
1273*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1274*d83cc019SAndroid Build Coastguard Worker }
1275*d83cc019SAndroid Build Coastguard Worker 
do_gpu_read_after_write(struct buffers * buffers,do_copy do_copy_func,do_hang do_hang_func)1276*d83cc019SAndroid Build Coastguard Worker static void do_gpu_read_after_write(struct buffers *buffers,
1277*d83cc019SAndroid Build Coastguard Worker 				    do_copy do_copy_func,
1278*d83cc019SAndroid Build Coastguard Worker 				    do_hang do_hang_func)
1279*d83cc019SAndroid Build Coastguard Worker {
1280*d83cc019SAndroid Build Coastguard Worker 	igt_hang_t hang;
1281*d83cc019SAndroid Build Coastguard Worker 	int i;
1282*d83cc019SAndroid Build Coastguard Worker 
1283*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1284*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->set_bo(buffers, buffers->src[i], 0xabcdabcd);
1285*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < buffers->count; i++)
1286*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->dst[i], buffers->src[i]);
1287*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1288*d83cc019SAndroid Build Coastguard Worker 		do_copy_func(buffers, buffers->spare, buffers->dst[i]);
1289*d83cc019SAndroid Build Coastguard Worker 	hang = do_hang_func();
1290*d83cc019SAndroid Build Coastguard Worker 	for (i = buffers->count; i--; )
1291*d83cc019SAndroid Build Coastguard Worker 		buffers->mode->cmp_bo(buffers, buffers->dst[i], 0xabcdabcd);
1292*d83cc019SAndroid Build Coastguard Worker 	igt_post_hang_ring(fd, hang);
1293*d83cc019SAndroid Build Coastguard Worker }
1294*d83cc019SAndroid Build Coastguard Worker 
1295*d83cc019SAndroid Build Coastguard Worker typedef void (*do_test)(struct buffers *buffers,
1296*d83cc019SAndroid Build Coastguard Worker 			do_copy do_copy_func,
1297*d83cc019SAndroid Build Coastguard Worker 			do_hang do_hang_func);
1298*d83cc019SAndroid Build Coastguard Worker 
1299*d83cc019SAndroid Build Coastguard Worker typedef void (*run_wrap)(struct buffers *buffers,
1300*d83cc019SAndroid Build Coastguard Worker 			 do_test do_test_func,
1301*d83cc019SAndroid Build Coastguard Worker 			 do_copy do_copy_func,
1302*d83cc019SAndroid Build Coastguard Worker 			 do_hang do_hang_func);
1303*d83cc019SAndroid Build Coastguard Worker 
run_single(struct buffers * buffers,do_test do_test_func,do_copy do_copy_func,do_hang do_hang_func)1304*d83cc019SAndroid Build Coastguard Worker static void run_single(struct buffers *buffers,
1305*d83cc019SAndroid Build Coastguard Worker 		       do_test do_test_func,
1306*d83cc019SAndroid Build Coastguard Worker 		       do_copy do_copy_func,
1307*d83cc019SAndroid Build Coastguard Worker 		       do_hang do_hang_func)
1308*d83cc019SAndroid Build Coastguard Worker {
1309*d83cc019SAndroid Build Coastguard Worker 	pass = 0;
1310*d83cc019SAndroid Build Coastguard Worker 	do_test_func(buffers, do_copy_func, do_hang_func);
1311*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
1312*d83cc019SAndroid Build Coastguard Worker }
1313*d83cc019SAndroid Build Coastguard Worker 
run_interruptible(struct buffers * buffers,do_test do_test_func,do_copy do_copy_func,do_hang do_hang_func)1314*d83cc019SAndroid Build Coastguard Worker static void run_interruptible(struct buffers *buffers,
1315*d83cc019SAndroid Build Coastguard Worker 			      do_test do_test_func,
1316*d83cc019SAndroid Build Coastguard Worker 			      do_copy do_copy_func,
1317*d83cc019SAndroid Build Coastguard Worker 			      do_hang do_hang_func)
1318*d83cc019SAndroid Build Coastguard Worker {
1319*d83cc019SAndroid Build Coastguard Worker 	pass = 0;
1320*d83cc019SAndroid Build Coastguard Worker 	igt_while_interruptible(true)
1321*d83cc019SAndroid Build Coastguard Worker 		do_test_func(buffers, do_copy_func, do_hang_func);
1322*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
1323*d83cc019SAndroid Build Coastguard Worker }
1324*d83cc019SAndroid Build Coastguard Worker 
run_child(struct buffers * buffers,do_test do_test_func,do_copy do_copy_func,do_hang do_hang_func)1325*d83cc019SAndroid Build Coastguard Worker static void run_child(struct buffers *buffers,
1326*d83cc019SAndroid Build Coastguard Worker 		      do_test do_test_func,
1327*d83cc019SAndroid Build Coastguard Worker 		      do_copy do_copy_func,
1328*d83cc019SAndroid Build Coastguard Worker 		      do_hang do_hang_func)
1329*d83cc019SAndroid Build Coastguard Worker 
1330*d83cc019SAndroid Build Coastguard Worker {
1331*d83cc019SAndroid Build Coastguard Worker 	/* We inherit the buffers from the parent, but the bufmgr/batch
1332*d83cc019SAndroid Build Coastguard Worker 	 * needs to be local as the cache of reusable itself will be COWed,
1333*d83cc019SAndroid Build Coastguard Worker 	 * leading to the child closing an object without the parent knowing.
1334*d83cc019SAndroid Build Coastguard Worker 	 */
1335*d83cc019SAndroid Build Coastguard Worker 	pass = 0;
1336*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1)
1337*d83cc019SAndroid Build Coastguard Worker 		do_test_func(buffers, do_copy_func, do_hang_func);
1338*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1339*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
1340*d83cc019SAndroid Build Coastguard Worker }
1341*d83cc019SAndroid Build Coastguard Worker 
__run_forked(struct buffers * buffers,int num_children,int loops,bool interrupt,do_test do_test_func,do_copy do_copy_func,do_hang do_hang_func)1342*d83cc019SAndroid Build Coastguard Worker static void __run_forked(struct buffers *buffers,
1343*d83cc019SAndroid Build Coastguard Worker 			 int num_children, int loops, bool interrupt,
1344*d83cc019SAndroid Build Coastguard Worker 			 do_test do_test_func,
1345*d83cc019SAndroid Build Coastguard Worker 			 do_copy do_copy_func,
1346*d83cc019SAndroid Build Coastguard Worker 			 do_hang do_hang_func)
1347*d83cc019SAndroid Build Coastguard Worker 
1348*d83cc019SAndroid Build Coastguard Worker {
1349*d83cc019SAndroid Build Coastguard Worker 	/* purge the libdrm caches before cloing the process */
1350*d83cc019SAndroid Build Coastguard Worker 	buffers_destroy(buffers);
1351*d83cc019SAndroid Build Coastguard Worker 	intel_batchbuffer_free(buffers->batch);
1352*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr_destroy(buffers->bufmgr);
1353*d83cc019SAndroid Build Coastguard Worker 
1354*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, num_children) {
1355*d83cc019SAndroid Build Coastguard Worker 		int num_buffers;
1356*d83cc019SAndroid Build Coastguard Worker 
1357*d83cc019SAndroid Build Coastguard Worker 		/* recreate process local variables */
1358*d83cc019SAndroid Build Coastguard Worker 		fd = drm_open_driver(DRIVER_INTEL);
1359*d83cc019SAndroid Build Coastguard Worker 
1360*d83cc019SAndroid Build Coastguard Worker 		num_buffers = buffers->num_buffers / num_children;
1361*d83cc019SAndroid Build Coastguard Worker 		num_buffers += MIN_BUFFERS;
1362*d83cc019SAndroid Build Coastguard Worker 		if (num_buffers < buffers->num_buffers)
1363*d83cc019SAndroid Build Coastguard Worker 			buffers->num_buffers = num_buffers;
1364*d83cc019SAndroid Build Coastguard Worker 
1365*d83cc019SAndroid Build Coastguard Worker 		buffers_reset(buffers, true);
1366*d83cc019SAndroid Build Coastguard Worker 		buffers_create(buffers);
1367*d83cc019SAndroid Build Coastguard Worker 
1368*d83cc019SAndroid Build Coastguard Worker 		igt_while_interruptible(interrupt) {
1369*d83cc019SAndroid Build Coastguard Worker 			for (pass = 0; pass < loops; pass++)
1370*d83cc019SAndroid Build Coastguard Worker 				do_test_func(buffers,
1371*d83cc019SAndroid Build Coastguard Worker 					     do_copy_func,
1372*d83cc019SAndroid Build Coastguard Worker 					     do_hang_func);
1373*d83cc019SAndroid Build Coastguard Worker 		}
1374*d83cc019SAndroid Build Coastguard Worker 	}
1375*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1376*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
1377*d83cc019SAndroid Build Coastguard Worker 
1378*d83cc019SAndroid Build Coastguard Worker 	buffers_reset(buffers, true);
1379*d83cc019SAndroid Build Coastguard Worker }
1380*d83cc019SAndroid Build Coastguard Worker 
run_forked(struct buffers * buffers,do_test do_test_func,do_copy do_copy_func,do_hang do_hang_func)1381*d83cc019SAndroid Build Coastguard Worker static void run_forked(struct buffers *buffers,
1382*d83cc019SAndroid Build Coastguard Worker 		       do_test do_test_func,
1383*d83cc019SAndroid Build Coastguard Worker 		       do_copy do_copy_func,
1384*d83cc019SAndroid Build Coastguard Worker 		       do_hang do_hang_func)
1385*d83cc019SAndroid Build Coastguard Worker {
1386*d83cc019SAndroid Build Coastguard Worker 	const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
1387*d83cc019SAndroid Build Coastguard Worker 	__run_forked(buffers, ncpus, ncpus, false,
1388*d83cc019SAndroid Build Coastguard Worker 		     do_test_func, do_copy_func, do_hang_func);
1389*d83cc019SAndroid Build Coastguard Worker }
1390*d83cc019SAndroid Build Coastguard Worker 
run_bomb(struct buffers * buffers,do_test do_test_func,do_copy do_copy_func,do_hang do_hang_func)1391*d83cc019SAndroid Build Coastguard Worker static void run_bomb(struct buffers *buffers,
1392*d83cc019SAndroid Build Coastguard Worker 		     do_test do_test_func,
1393*d83cc019SAndroid Build Coastguard Worker 		     do_copy do_copy_func,
1394*d83cc019SAndroid Build Coastguard Worker 		     do_hang do_hang_func)
1395*d83cc019SAndroid Build Coastguard Worker {
1396*d83cc019SAndroid Build Coastguard Worker 	const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
1397*d83cc019SAndroid Build Coastguard Worker 	__run_forked(buffers, 8*ncpus, 2, true,
1398*d83cc019SAndroid Build Coastguard Worker 		     do_test_func, do_copy_func, do_hang_func);
1399*d83cc019SAndroid Build Coastguard Worker }
1400*d83cc019SAndroid Build Coastguard Worker 
cpu_require(void)1401*d83cc019SAndroid Build Coastguard Worker static void cpu_require(void)
1402*d83cc019SAndroid Build Coastguard Worker {
1403*d83cc019SAndroid Build Coastguard Worker 	bit17_require();
1404*d83cc019SAndroid Build Coastguard Worker }
1405*d83cc019SAndroid Build Coastguard Worker 
gtt_require(void)1406*d83cc019SAndroid Build Coastguard Worker static void gtt_require(void)
1407*d83cc019SAndroid Build Coastguard Worker {
1408*d83cc019SAndroid Build Coastguard Worker }
1409*d83cc019SAndroid Build Coastguard Worker 
bcs_require(void)1410*d83cc019SAndroid Build Coastguard Worker static void bcs_require(void)
1411*d83cc019SAndroid Build Coastguard Worker {
1412*d83cc019SAndroid Build Coastguard Worker }
1413*d83cc019SAndroid Build Coastguard Worker 
rcs_require(void)1414*d83cc019SAndroid Build Coastguard Worker static void rcs_require(void)
1415*d83cc019SAndroid Build Coastguard Worker {
1416*d83cc019SAndroid Build Coastguard Worker 	igt_require(rendercopy);
1417*d83cc019SAndroid Build Coastguard Worker }
1418*d83cc019SAndroid Build Coastguard Worker 
1419*d83cc019SAndroid Build Coastguard Worker static void
run_mode(const char * prefix,const struct create * create,const struct access_mode * mode,const struct size * size,const int num_buffers,const char * suffix,run_wrap run_wrap_func)1420*d83cc019SAndroid Build Coastguard Worker run_mode(const char *prefix,
1421*d83cc019SAndroid Build Coastguard Worker 	 const struct create *create,
1422*d83cc019SAndroid Build Coastguard Worker 	 const struct access_mode *mode,
1423*d83cc019SAndroid Build Coastguard Worker 	 const struct size *size,
1424*d83cc019SAndroid Build Coastguard Worker 	 const int num_buffers,
1425*d83cc019SAndroid Build Coastguard Worker 	 const char *suffix,
1426*d83cc019SAndroid Build Coastguard Worker 	 run_wrap run_wrap_func)
1427*d83cc019SAndroid Build Coastguard Worker {
1428*d83cc019SAndroid Build Coastguard Worker 	const struct {
1429*d83cc019SAndroid Build Coastguard Worker 		const char *prefix;
1430*d83cc019SAndroid Build Coastguard Worker 		do_copy copy;
1431*d83cc019SAndroid Build Coastguard Worker 		void (*require)(void);
1432*d83cc019SAndroid Build Coastguard Worker 	} pipelines[] = {
1433*d83cc019SAndroid Build Coastguard Worker 		{ "cpu", cpu_copy_bo, cpu_require },
1434*d83cc019SAndroid Build Coastguard Worker 		{ "gtt", gtt_copy_bo, gtt_require },
1435*d83cc019SAndroid Build Coastguard Worker 		{ "wc", wc_copy_bo, wc_require },
1436*d83cc019SAndroid Build Coastguard Worker 		{ "blt", blt_copy_bo, bcs_require },
1437*d83cc019SAndroid Build Coastguard Worker 		{ "render", render_copy_bo, rcs_require },
1438*d83cc019SAndroid Build Coastguard Worker 		{ NULL, NULL }
1439*d83cc019SAndroid Build Coastguard Worker 	}, *pskip = pipelines + 3, *p;
1440*d83cc019SAndroid Build Coastguard Worker 	const struct {
1441*d83cc019SAndroid Build Coastguard Worker 		const char *suffix;
1442*d83cc019SAndroid Build Coastguard Worker 		do_hang hang;
1443*d83cc019SAndroid Build Coastguard Worker 	} hangs[] = {
1444*d83cc019SAndroid Build Coastguard Worker 		{ "", no_hang },
1445*d83cc019SAndroid Build Coastguard Worker 		{ "-hang-blt", bcs_hang },
1446*d83cc019SAndroid Build Coastguard Worker 		{ "-hang-render", rcs_hang },
1447*d83cc019SAndroid Build Coastguard Worker 		{ "-hang-all", all_hang },
1448*d83cc019SAndroid Build Coastguard Worker 		{ NULL, NULL },
1449*d83cc019SAndroid Build Coastguard Worker 	}, *h;
1450*d83cc019SAndroid Build Coastguard Worker 	struct buffers buffers;
1451*d83cc019SAndroid Build Coastguard Worker 
1452*d83cc019SAndroid Build Coastguard Worker 	igt_fixture
1453*d83cc019SAndroid Build Coastguard Worker 		buffers_init(&buffers, prefix, create, mode,
1454*d83cc019SAndroid Build Coastguard Worker 			     size, num_buffers,
1455*d83cc019SAndroid Build Coastguard Worker 			     fd, run_wrap_func != run_child);
1456*d83cc019SAndroid Build Coastguard Worker 
1457*d83cc019SAndroid Build Coastguard Worker 	for (h = hangs; h->suffix; h++) {
1458*d83cc019SAndroid Build Coastguard Worker 		if (!all && *h->suffix)
1459*d83cc019SAndroid Build Coastguard Worker 			continue;
1460*d83cc019SAndroid Build Coastguard Worker 
1461*d83cc019SAndroid Build Coastguard Worker 		if (!*h->suffix)
1462*d83cc019SAndroid Build Coastguard Worker 			igt_fixture
1463*d83cc019SAndroid Build Coastguard Worker 				igt_fork_hang_detector(fd);
1464*d83cc019SAndroid Build Coastguard Worker 
1465*d83cc019SAndroid Build Coastguard Worker 		for (p = all ? pipelines : pskip; p->prefix; p++) {
1466*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group  {
1467*d83cc019SAndroid Build Coastguard Worker 				igt_fixture p->require();
1468*d83cc019SAndroid Build Coastguard Worker 
1469*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-sanitycheck0%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1470*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1471*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers, do_basic0,
1472*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1473*d83cc019SAndroid Build Coastguard Worker 				}
1474*d83cc019SAndroid Build Coastguard Worker 
1475*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-sanitycheck1%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1476*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1477*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers, do_basic1,
1478*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1479*d83cc019SAndroid Build Coastguard Worker 				}
1480*d83cc019SAndroid Build Coastguard Worker 
1481*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-sanitycheckN%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1482*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1483*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers, do_basicN,
1484*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1485*d83cc019SAndroid Build Coastguard Worker 				}
1486*d83cc019SAndroid Build Coastguard Worker 
1487*d83cc019SAndroid Build Coastguard Worker 				/* try to overwrite the source values */
1488*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-overwrite-source-one%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1489*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1490*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1491*d83cc019SAndroid Build Coastguard Worker 							do_overwrite_source__one,
1492*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1493*d83cc019SAndroid Build Coastguard Worker 				}
1494*d83cc019SAndroid Build Coastguard Worker 
1495*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-overwrite-source%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1496*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1497*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1498*d83cc019SAndroid Build Coastguard Worker 							do_overwrite_source,
1499*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1500*d83cc019SAndroid Build Coastguard Worker 				}
1501*d83cc019SAndroid Build Coastguard Worker 
1502*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-overwrite-source-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1503*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1504*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1505*d83cc019SAndroid Build Coastguard Worker 							do_overwrite_source_read_bcs,
1506*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1507*d83cc019SAndroid Build Coastguard Worker 				}
1508*d83cc019SAndroid Build Coastguard Worker 
1509*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-overwrite-source-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1510*d83cc019SAndroid Build Coastguard Worker 					igt_require(rendercopy);
1511*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1512*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1513*d83cc019SAndroid Build Coastguard Worker 							do_overwrite_source_read_rcs,
1514*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1515*d83cc019SAndroid Build Coastguard Worker 				}
1516*d83cc019SAndroid Build Coastguard Worker 
1517*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-overwrite-source-rev%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1518*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1519*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1520*d83cc019SAndroid Build Coastguard Worker 							do_overwrite_source__rev,
1521*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1522*d83cc019SAndroid Build Coastguard Worker 				}
1523*d83cc019SAndroid Build Coastguard Worker 
1524*d83cc019SAndroid Build Coastguard Worker 				/* try to intermix copies with GPU copies*/
1525*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-intermix-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1526*d83cc019SAndroid Build Coastguard Worker 					igt_require(rendercopy);
1527*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1528*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1529*d83cc019SAndroid Build Coastguard Worker 							do_intermix_rcs,
1530*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1531*d83cc019SAndroid Build Coastguard Worker 				}
1532*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-intermix-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1533*d83cc019SAndroid Build Coastguard Worker 					igt_require(rendercopy);
1534*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1535*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1536*d83cc019SAndroid Build Coastguard Worker 							do_intermix_bcs,
1537*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1538*d83cc019SAndroid Build Coastguard Worker 				}
1539*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-intermix-both%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1540*d83cc019SAndroid Build Coastguard Worker 					igt_require(rendercopy);
1541*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1542*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1543*d83cc019SAndroid Build Coastguard Worker 							do_intermix_both,
1544*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1545*d83cc019SAndroid Build Coastguard Worker 				}
1546*d83cc019SAndroid Build Coastguard Worker 
1547*d83cc019SAndroid Build Coastguard Worker 				/* try to read the results before the copy completes */
1548*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-early-read%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1549*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1550*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1551*d83cc019SAndroid Build Coastguard Worker 							do_early_read,
1552*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1553*d83cc019SAndroid Build Coastguard Worker 				}
1554*d83cc019SAndroid Build Coastguard Worker 
1555*d83cc019SAndroid Build Coastguard Worker 				/* concurrent reads */
1556*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-read-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1557*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1558*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1559*d83cc019SAndroid Build Coastguard Worker 							do_read_read_bcs,
1560*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1561*d83cc019SAndroid Build Coastguard Worker 				}
1562*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-read-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1563*d83cc019SAndroid Build Coastguard Worker 					igt_require(rendercopy);
1564*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1565*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1566*d83cc019SAndroid Build Coastguard Worker 							do_read_read_rcs,
1567*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1568*d83cc019SAndroid Build Coastguard Worker 				}
1569*d83cc019SAndroid Build Coastguard Worker 
1570*d83cc019SAndroid Build Coastguard Worker 				/* split copying between rings */
1571*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-write-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1572*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1573*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1574*d83cc019SAndroid Build Coastguard Worker 							do_write_read_bcs,
1575*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1576*d83cc019SAndroid Build Coastguard Worker 				}
1577*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-write-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1578*d83cc019SAndroid Build Coastguard Worker 					igt_require(rendercopy);
1579*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1580*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1581*d83cc019SAndroid Build Coastguard Worker 							do_write_read_rcs,
1582*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1583*d83cc019SAndroid Build Coastguard Worker 				}
1584*d83cc019SAndroid Build Coastguard Worker 
1585*d83cc019SAndroid Build Coastguard Worker 				/* and finally try to trick the kernel into loosing the pending write */
1586*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%s-%s-%s-gpu-read-after-write%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
1587*d83cc019SAndroid Build Coastguard Worker 					buffers_create(&buffers);
1588*d83cc019SAndroid Build Coastguard Worker 					run_wrap_func(&buffers,
1589*d83cc019SAndroid Build Coastguard Worker 							do_gpu_read_after_write,
1590*d83cc019SAndroid Build Coastguard Worker 							p->copy, h->hang);
1591*d83cc019SAndroid Build Coastguard Worker 				}
1592*d83cc019SAndroid Build Coastguard Worker 			}
1593*d83cc019SAndroid Build Coastguard Worker 		}
1594*d83cc019SAndroid Build Coastguard Worker 
1595*d83cc019SAndroid Build Coastguard Worker 		if (!*h->suffix)
1596*d83cc019SAndroid Build Coastguard Worker 			igt_fixture
1597*d83cc019SAndroid Build Coastguard Worker 				igt_stop_hang_detector();
1598*d83cc019SAndroid Build Coastguard Worker 	}
1599*d83cc019SAndroid Build Coastguard Worker 
1600*d83cc019SAndroid Build Coastguard Worker 	igt_fixture
1601*d83cc019SAndroid Build Coastguard Worker 		buffers_fini(&buffers);
1602*d83cc019SAndroid Build Coastguard Worker }
1603*d83cc019SAndroid Build Coastguard Worker 
1604*d83cc019SAndroid Build Coastguard Worker static void
run_modes(const char * style,const struct create * create,const struct access_mode * mode,const struct size * size,const int num)1605*d83cc019SAndroid Build Coastguard Worker run_modes(const char *style,
1606*d83cc019SAndroid Build Coastguard Worker 	  const struct create *create,
1607*d83cc019SAndroid Build Coastguard Worker 	  const struct access_mode *mode,
1608*d83cc019SAndroid Build Coastguard Worker 	  const struct size *size,
1609*d83cc019SAndroid Build Coastguard Worker 	  const int num)
1610*d83cc019SAndroid Build Coastguard Worker {
1611*d83cc019SAndroid Build Coastguard Worker 	const struct wrap {
1612*d83cc019SAndroid Build Coastguard Worker 		const char *suffix;
1613*d83cc019SAndroid Build Coastguard Worker 		run_wrap func;
1614*d83cc019SAndroid Build Coastguard Worker 	} wrappers[] = {
1615*d83cc019SAndroid Build Coastguard Worker 		{ "", run_single },
1616*d83cc019SAndroid Build Coastguard Worker 		{ "-child", run_child },
1617*d83cc019SAndroid Build Coastguard Worker 		{ "-forked", run_forked },
1618*d83cc019SAndroid Build Coastguard Worker 		{ "-interruptible", run_interruptible },
1619*d83cc019SAndroid Build Coastguard Worker 		{ "-bomb", run_bomb },
1620*d83cc019SAndroid Build Coastguard Worker 		{ NULL },
1621*d83cc019SAndroid Build Coastguard Worker 	};
1622*d83cc019SAndroid Build Coastguard Worker 
1623*d83cc019SAndroid Build Coastguard Worker 	while (mode->name) {
1624*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_group {
1625*d83cc019SAndroid Build Coastguard Worker 			igt_fixture {
1626*d83cc019SAndroid Build Coastguard Worker 				if (mode->require)
1627*d83cc019SAndroid Build Coastguard Worker 					mode->require(create, num);
1628*d83cc019SAndroid Build Coastguard Worker 			}
1629*d83cc019SAndroid Build Coastguard Worker 
1630*d83cc019SAndroid Build Coastguard Worker 			for (const struct wrap *w = wrappers; w->suffix; w++) {
1631*d83cc019SAndroid Build Coastguard Worker 				run_mode(style, create, mode, size, num,
1632*d83cc019SAndroid Build Coastguard Worker 					 w->suffix, w->func);
1633*d83cc019SAndroid Build Coastguard Worker 			}
1634*d83cc019SAndroid Build Coastguard Worker 		}
1635*d83cc019SAndroid Build Coastguard Worker 
1636*d83cc019SAndroid Build Coastguard Worker 		mode++;
1637*d83cc019SAndroid Build Coastguard Worker 	}
1638*d83cc019SAndroid Build Coastguard Worker }
1639*d83cc019SAndroid Build Coastguard Worker 
1640*d83cc019SAndroid Build Coastguard Worker static unsigned
num_buffers(uint64_t max,const struct size * s,const struct create * c,unsigned allow_mem)1641*d83cc019SAndroid Build Coastguard Worker num_buffers(uint64_t max,
1642*d83cc019SAndroid Build Coastguard Worker 	    const struct size *s,
1643*d83cc019SAndroid Build Coastguard Worker 	    const struct create *c,
1644*d83cc019SAndroid Build Coastguard Worker 	    unsigned allow_mem)
1645*d83cc019SAndroid Build Coastguard Worker {
1646*d83cc019SAndroid Build Coastguard Worker 	unsigned size = 4*s->width*s->height;
1647*d83cc019SAndroid Build Coastguard Worker 	uint64_t n;
1648*d83cc019SAndroid Build Coastguard Worker 
1649*d83cc019SAndroid Build Coastguard Worker 	igt_assert(size);
1650*d83cc019SAndroid Build Coastguard Worker 	n = max / (2*size);
1651*d83cc019SAndroid Build Coastguard Worker 	n += MIN_BUFFERS;
1652*d83cc019SAndroid Build Coastguard Worker 
1653*d83cc019SAndroid Build Coastguard Worker 	igt_require(n < INT32_MAX);
1654*d83cc019SAndroid Build Coastguard Worker 	igt_require(set_max_map_count(2*n));
1655*d83cc019SAndroid Build Coastguard Worker 
1656*d83cc019SAndroid Build Coastguard Worker 	if (c->require)
1657*d83cc019SAndroid Build Coastguard Worker 		c->require(c, n);
1658*d83cc019SAndroid Build Coastguard Worker 
1659*d83cc019SAndroid Build Coastguard Worker 	intel_require_memory(2*n, size, allow_mem);
1660*d83cc019SAndroid Build Coastguard Worker 
1661*d83cc019SAndroid Build Coastguard Worker 	return n;
1662*d83cc019SAndroid Build Coastguard Worker }
1663*d83cc019SAndroid Build Coastguard Worker 
1664*d83cc019SAndroid Build Coastguard Worker igt_main
1665*d83cc019SAndroid Build Coastguard Worker {
1666*d83cc019SAndroid Build Coastguard Worker 	const struct access_mode modes[] = {
1667*d83cc019SAndroid Build Coastguard Worker 		{
1668*d83cc019SAndroid Build Coastguard Worker 			.name = "prw",
1669*d83cc019SAndroid Build Coastguard Worker 			.create_bo = unmapped_create_bo,
1670*d83cc019SAndroid Build Coastguard Worker 			.set_bo = prw_set_bo,
1671*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = prw_cmp_bo,
1672*d83cc019SAndroid Build Coastguard Worker 			.release_bo = nop_release_bo,
1673*d83cc019SAndroid Build Coastguard Worker 		},
1674*d83cc019SAndroid Build Coastguard Worker 		{
1675*d83cc019SAndroid Build Coastguard Worker 			.name = "partial",
1676*d83cc019SAndroid Build Coastguard Worker 			.create_bo = unmapped_create_bo,
1677*d83cc019SAndroid Build Coastguard Worker 			.set_bo = partial_set_bo,
1678*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = partial_cmp_bo,
1679*d83cc019SAndroid Build Coastguard Worker 			.release_bo = nop_release_bo,
1680*d83cc019SAndroid Build Coastguard Worker 		},
1681*d83cc019SAndroid Build Coastguard Worker 		{
1682*d83cc019SAndroid Build Coastguard Worker 			.name = "cpu",
1683*d83cc019SAndroid Build Coastguard Worker 			.create_bo = unmapped_create_bo,
1684*d83cc019SAndroid Build Coastguard Worker 			.require = create_cpu_require,
1685*d83cc019SAndroid Build Coastguard Worker 			.set_bo = cpu_set_bo,
1686*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = cpu_cmp_bo,
1687*d83cc019SAndroid Build Coastguard Worker 			.release_bo = nop_release_bo,
1688*d83cc019SAndroid Build Coastguard Worker 		},
1689*d83cc019SAndroid Build Coastguard Worker 		{
1690*d83cc019SAndroid Build Coastguard Worker 			.name = "snoop",
1691*d83cc019SAndroid Build Coastguard Worker 			.create_bo = snoop_create_bo,
1692*d83cc019SAndroid Build Coastguard Worker 			.require = create_snoop_require,
1693*d83cc019SAndroid Build Coastguard Worker 			.set_bo = cpu_set_bo,
1694*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = cpu_cmp_bo,
1695*d83cc019SAndroid Build Coastguard Worker 			.release_bo = nop_release_bo,
1696*d83cc019SAndroid Build Coastguard Worker 		},
1697*d83cc019SAndroid Build Coastguard Worker 		{
1698*d83cc019SAndroid Build Coastguard Worker 			.name = "userptr",
1699*d83cc019SAndroid Build Coastguard Worker 			.create_bo = userptr_create_bo,
1700*d83cc019SAndroid Build Coastguard Worker 			.require = create_userptr_require,
1701*d83cc019SAndroid Build Coastguard Worker 			.set_bo = userptr_set_bo,
1702*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = userptr_cmp_bo,
1703*d83cc019SAndroid Build Coastguard Worker 			.release_bo = userptr_release_bo,
1704*d83cc019SAndroid Build Coastguard Worker 		},
1705*d83cc019SAndroid Build Coastguard Worker 		{
1706*d83cc019SAndroid Build Coastguard Worker 			.name = "dmabuf",
1707*d83cc019SAndroid Build Coastguard Worker 			.create_bo = dmabuf_create_bo,
1708*d83cc019SAndroid Build Coastguard Worker 			.require = create_dmabuf_require,
1709*d83cc019SAndroid Build Coastguard Worker 			.set_bo = dmabuf_set_bo,
1710*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = dmabuf_cmp_bo,
1711*d83cc019SAndroid Build Coastguard Worker 			.release_bo = dmabuf_release_bo,
1712*d83cc019SAndroid Build Coastguard Worker 		},
1713*d83cc019SAndroid Build Coastguard Worker 		{
1714*d83cc019SAndroid Build Coastguard Worker 			.name = "vgem",
1715*d83cc019SAndroid Build Coastguard Worker 			.create_bo = vgem_create_bo,
1716*d83cc019SAndroid Build Coastguard Worker 			.require = create_vgem_require,
1717*d83cc019SAndroid Build Coastguard Worker 			.set_bo = dmabuf_set_bo,
1718*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = dmabuf_cmp_bo,
1719*d83cc019SAndroid Build Coastguard Worker 			.release_bo = dmabuf_release_bo,
1720*d83cc019SAndroid Build Coastguard Worker 		},
1721*d83cc019SAndroid Build Coastguard Worker 		{
1722*d83cc019SAndroid Build Coastguard Worker 			.name = "gtt",
1723*d83cc019SAndroid Build Coastguard Worker 			.create_bo = gtt_create_bo,
1724*d83cc019SAndroid Build Coastguard Worker 			.set_bo = gtt_set_bo,
1725*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = gtt_cmp_bo,
1726*d83cc019SAndroid Build Coastguard Worker 			.release_bo = nop_release_bo,
1727*d83cc019SAndroid Build Coastguard Worker 		},
1728*d83cc019SAndroid Build Coastguard Worker 		{
1729*d83cc019SAndroid Build Coastguard Worker 			.name = "gttX",
1730*d83cc019SAndroid Build Coastguard Worker 			.create_bo = gttX_create_bo,
1731*d83cc019SAndroid Build Coastguard Worker 			.set_bo = gtt_set_bo,
1732*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = gtt_cmp_bo,
1733*d83cc019SAndroid Build Coastguard Worker 			.release_bo = nop_release_bo,
1734*d83cc019SAndroid Build Coastguard Worker 		},
1735*d83cc019SAndroid Build Coastguard Worker 		{
1736*d83cc019SAndroid Build Coastguard Worker 			.name = "wc",
1737*d83cc019SAndroid Build Coastguard Worker 			.require = wc_create_require,
1738*d83cc019SAndroid Build Coastguard Worker 			.create_bo = wc_create_bo,
1739*d83cc019SAndroid Build Coastguard Worker 			.set_bo = gtt_set_bo,
1740*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = gtt_cmp_bo,
1741*d83cc019SAndroid Build Coastguard Worker 			.release_bo = wc_release_bo,
1742*d83cc019SAndroid Build Coastguard Worker 		},
1743*d83cc019SAndroid Build Coastguard Worker 		{
1744*d83cc019SAndroid Build Coastguard Worker 			.name = "gpu",
1745*d83cc019SAndroid Build Coastguard Worker 			.create_bo = gpu_create_bo,
1746*d83cc019SAndroid Build Coastguard Worker 			.set_bo = gpu_set_bo,
1747*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = gpu_cmp_bo,
1748*d83cc019SAndroid Build Coastguard Worker 			.release_bo = nop_release_bo,
1749*d83cc019SAndroid Build Coastguard Worker 		},
1750*d83cc019SAndroid Build Coastguard Worker 		{
1751*d83cc019SAndroid Build Coastguard Worker 			.name = "gpuX",
1752*d83cc019SAndroid Build Coastguard Worker 			.create_bo = gpuX_create_bo,
1753*d83cc019SAndroid Build Coastguard Worker 			.set_bo = gpu_set_bo,
1754*d83cc019SAndroid Build Coastguard Worker 			.cmp_bo = gpu_cmp_bo,
1755*d83cc019SAndroid Build Coastguard Worker 			.release_bo = nop_release_bo,
1756*d83cc019SAndroid Build Coastguard Worker 		},
1757*d83cc019SAndroid Build Coastguard Worker 		{ NULL },
1758*d83cc019SAndroid Build Coastguard Worker 	};
1759*d83cc019SAndroid Build Coastguard Worker 	const struct create create[] = {
1760*d83cc019SAndroid Build Coastguard Worker 		{ "", can_create_normal, create_normal_bo},
1761*d83cc019SAndroid Build Coastguard Worker #if HAVE_CREATE_PRIVATE
1762*d83cc019SAndroid Build Coastguard Worker 		{ "private-", can_create_private, create_private_bo},
1763*d83cc019SAndroid Build Coastguard Worker #endif
1764*d83cc019SAndroid Build Coastguard Worker #if HAVE_CREATE_STOLEN
1765*d83cc019SAndroid Build Coastguard Worker 		{ "stolen-", can_create_stolen, create_stolen_bo},
1766*d83cc019SAndroid Build Coastguard Worker #endif
1767*d83cc019SAndroid Build Coastguard Worker 		{ NULL, NULL }
1768*d83cc019SAndroid Build Coastguard Worker 	};
1769*d83cc019SAndroid Build Coastguard Worker 	const struct size sizes[] = {
1770*d83cc019SAndroid Build Coastguard Worker 		{ "4KiB", 128, 8 },
1771*d83cc019SAndroid Build Coastguard Worker 		{ "256KiB", 128, 128 },
1772*d83cc019SAndroid Build Coastguard Worker 		{ "1MiB", 512, 512 },
1773*d83cc019SAndroid Build Coastguard Worker 		{ "16MiB", 2048, 2048 },
1774*d83cc019SAndroid Build Coastguard Worker 		{ NULL}
1775*d83cc019SAndroid Build Coastguard Worker 	};
1776*d83cc019SAndroid Build Coastguard Worker 	uint64_t pin_sz = 0;
1777*d83cc019SAndroid Build Coastguard Worker 	void *pinned = NULL;
1778*d83cc019SAndroid Build Coastguard Worker 	char name[80];
1779*d83cc019SAndroid Build Coastguard Worker 	int count = 0;
1780*d83cc019SAndroid Build Coastguard Worker 
1781*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
1782*d83cc019SAndroid Build Coastguard Worker 
1783*d83cc019SAndroid Build Coastguard Worker 	if (strstr(igt_test_name(), "all"))
1784*d83cc019SAndroid Build Coastguard Worker 		all = true;
1785*d83cc019SAndroid Build Coastguard Worker 
1786*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
1787*d83cc019SAndroid Build Coastguard Worker 		igt_allow_unlimited_files();
1788*d83cc019SAndroid Build Coastguard Worker 
1789*d83cc019SAndroid Build Coastguard Worker 		fd = drm_open_driver(DRIVER_INTEL);
1790*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(fd);
1791*d83cc019SAndroid Build Coastguard Worker 		intel_detect_and_clear_missed_interrupts(fd);
1792*d83cc019SAndroid Build Coastguard Worker 		devid = intel_get_drm_devid(fd);
1793*d83cc019SAndroid Build Coastguard Worker 		gen = intel_gen(devid);
1794*d83cc019SAndroid Build Coastguard Worker 		rendercopy = igt_get_render_copyfunc(devid);
1795*d83cc019SAndroid Build Coastguard Worker 
1796*d83cc019SAndroid Build Coastguard Worker 		vgem_drv = __drm_open_driver(DRIVER_VGEM);
1797*d83cc019SAndroid Build Coastguard Worker 	}
1798*d83cc019SAndroid Build Coastguard Worker 
1799*d83cc019SAndroid Build Coastguard Worker 	for (const struct create *c = create; c->name; c++) {
1800*d83cc019SAndroid Build Coastguard Worker 		for (const struct size *s = sizes; s->name; s++) {
1801*d83cc019SAndroid Build Coastguard Worker 			/* Minimum test set */
1802*d83cc019SAndroid Build Coastguard Worker 			snprintf(name, sizeof(name), "%s%s-%s",
1803*d83cc019SAndroid Build Coastguard Worker 				 c->name, s->name, "tiny");
1804*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1805*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1806*d83cc019SAndroid Build Coastguard Worker 					count = num_buffers(0, s, c, CHECK_RAM);
1807*d83cc019SAndroid Build Coastguard Worker 				}
1808*d83cc019SAndroid Build Coastguard Worker 				run_modes(name, c, modes, s, count);
1809*d83cc019SAndroid Build Coastguard Worker 			}
1810*d83cc019SAndroid Build Coastguard Worker 
1811*d83cc019SAndroid Build Coastguard Worker 			/* "Average" test set */
1812*d83cc019SAndroid Build Coastguard Worker 			snprintf(name, sizeof(name), "%s%s-%s",
1813*d83cc019SAndroid Build Coastguard Worker 				 c->name, s->name, "small");
1814*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1815*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1816*d83cc019SAndroid Build Coastguard Worker 					count = num_buffers(gem_mappable_aperture_size()/4,
1817*d83cc019SAndroid Build Coastguard Worker 							    s, c, CHECK_RAM);
1818*d83cc019SAndroid Build Coastguard Worker 				}
1819*d83cc019SAndroid Build Coastguard Worker 				run_modes(name, c, modes, s, count);
1820*d83cc019SAndroid Build Coastguard Worker 			}
1821*d83cc019SAndroid Build Coastguard Worker 
1822*d83cc019SAndroid Build Coastguard Worker 			/* Use the entire mappable aperture */
1823*d83cc019SAndroid Build Coastguard Worker 			snprintf(name, sizeof(name), "%s%s-%s",
1824*d83cc019SAndroid Build Coastguard Worker 				 c->name, s->name, "thrash");
1825*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1826*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1827*d83cc019SAndroid Build Coastguard Worker 					count = num_buffers(gem_mappable_aperture_size(),
1828*d83cc019SAndroid Build Coastguard Worker 							    s, c, CHECK_RAM);
1829*d83cc019SAndroid Build Coastguard Worker 				}
1830*d83cc019SAndroid Build Coastguard Worker 				run_modes(name, c, modes, s, count);
1831*d83cc019SAndroid Build Coastguard Worker 			}
1832*d83cc019SAndroid Build Coastguard Worker 
1833*d83cc019SAndroid Build Coastguard Worker 			/* Use the entire global GTT */
1834*d83cc019SAndroid Build Coastguard Worker 			snprintf(name, sizeof(name), "%s%s-%s",
1835*d83cc019SAndroid Build Coastguard Worker 				 c->name, s->name, "global");
1836*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1837*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1838*d83cc019SAndroid Build Coastguard Worker 					count = num_buffers(gem_global_aperture_size(fd),
1839*d83cc019SAndroid Build Coastguard Worker 							    s, c, CHECK_RAM);
1840*d83cc019SAndroid Build Coastguard Worker 				}
1841*d83cc019SAndroid Build Coastguard Worker 				run_modes(name, c, modes, s, count);
1842*d83cc019SAndroid Build Coastguard Worker 			}
1843*d83cc019SAndroid Build Coastguard Worker 
1844*d83cc019SAndroid Build Coastguard Worker 			/* Use the entire per-process GTT */
1845*d83cc019SAndroid Build Coastguard Worker 			snprintf(name, sizeof(name), "%s%s-%s",
1846*d83cc019SAndroid Build Coastguard Worker 				 c->name, s->name, "full");
1847*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1848*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1849*d83cc019SAndroid Build Coastguard Worker 					count = num_buffers(gem_aperture_size(fd),
1850*d83cc019SAndroid Build Coastguard Worker 							    s, c, CHECK_RAM);
1851*d83cc019SAndroid Build Coastguard Worker 				}
1852*d83cc019SAndroid Build Coastguard Worker 				run_modes(name, c, modes, s, count);
1853*d83cc019SAndroid Build Coastguard Worker 			}
1854*d83cc019SAndroid Build Coastguard Worker 
1855*d83cc019SAndroid Build Coastguard Worker 			snprintf(name, sizeof(name), "%s%s-%s",
1856*d83cc019SAndroid Build Coastguard Worker 				 c->name, s->name, "shrink");
1857*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1858*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1859*d83cc019SAndroid Build Coastguard Worker 					count = num_buffers(gem_mappable_aperture_size(),
1860*d83cc019SAndroid Build Coastguard Worker 							    s, c, CHECK_RAM);
1861*d83cc019SAndroid Build Coastguard Worker 
1862*d83cc019SAndroid Build Coastguard Worker 					igt_fork_shrink_helper(fd);
1863*d83cc019SAndroid Build Coastguard Worker 				}
1864*d83cc019SAndroid Build Coastguard Worker 				run_modes(name, c, modes, s, count);
1865*d83cc019SAndroid Build Coastguard Worker 
1866*d83cc019SAndroid Build Coastguard Worker 				igt_fixture
1867*d83cc019SAndroid Build Coastguard Worker 					igt_stop_shrink_helper();
1868*d83cc019SAndroid Build Coastguard Worker 			}
1869*d83cc019SAndroid Build Coastguard Worker 
1870*d83cc019SAndroid Build Coastguard Worker 			/* Use the entire mappable aperture, force swapping */
1871*d83cc019SAndroid Build Coastguard Worker 			snprintf(name, sizeof(name), "%s%s-%s",
1872*d83cc019SAndroid Build Coastguard Worker 				 c->name, s->name, "swap");
1873*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1874*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1875*d83cc019SAndroid Build Coastguard Worker 					if (intel_get_avail_ram_mb() > gem_mappable_aperture_size()/(1024*1024)) {
1876*d83cc019SAndroid Build Coastguard Worker 						pin_sz = intel_get_avail_ram_mb() - gem_mappable_aperture_size()/(1024*1024);
1877*d83cc019SAndroid Build Coastguard Worker 
1878*d83cc019SAndroid Build Coastguard Worker 						igt_debug("Pinning %lld MiB\n", (long long)pin_sz);
1879*d83cc019SAndroid Build Coastguard Worker 						pin_sz *= 1024 * 1024;
1880*d83cc019SAndroid Build Coastguard Worker 
1881*d83cc019SAndroid Build Coastguard Worker 						if (posix_memalign(&pinned, 4096, pin_sz) ||
1882*d83cc019SAndroid Build Coastguard Worker 						    mlock(pinned, pin_sz) ||
1883*d83cc019SAndroid Build Coastguard Worker 						    madvise(pinned, pin_sz, MADV_DONTFORK)) {
1884*d83cc019SAndroid Build Coastguard Worker 							free(pinned);
1885*d83cc019SAndroid Build Coastguard Worker 							pinned = NULL;
1886*d83cc019SAndroid Build Coastguard Worker 						}
1887*d83cc019SAndroid Build Coastguard Worker 						igt_require(pinned);
1888*d83cc019SAndroid Build Coastguard Worker 					}
1889*d83cc019SAndroid Build Coastguard Worker 
1890*d83cc019SAndroid Build Coastguard Worker 					count = num_buffers(gem_mappable_aperture_size(),
1891*d83cc019SAndroid Build Coastguard Worker 							    s, c, CHECK_RAM | CHECK_SWAP);
1892*d83cc019SAndroid Build Coastguard Worker 				}
1893*d83cc019SAndroid Build Coastguard Worker 				run_modes(name, c, modes, s, count);
1894*d83cc019SAndroid Build Coastguard Worker 
1895*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1896*d83cc019SAndroid Build Coastguard Worker 					if (pinned) {
1897*d83cc019SAndroid Build Coastguard Worker 						munlock(pinned, pin_sz);
1898*d83cc019SAndroid Build Coastguard Worker 						free(pinned);
1899*d83cc019SAndroid Build Coastguard Worker 						pinned = NULL;
1900*d83cc019SAndroid Build Coastguard Worker 					}
1901*d83cc019SAndroid Build Coastguard Worker 				}
1902*d83cc019SAndroid Build Coastguard Worker 			}
1903*d83cc019SAndroid Build Coastguard Worker 		}
1904*d83cc019SAndroid Build Coastguard Worker 	}
1905*d83cc019SAndroid Build Coastguard Worker }
1906