• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2012 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Chris Wilson <chris@chris-wilson.co.uk>
25  *
26  */
27 
28 /* Exercises the basic execbuffer using the handle LUT interface */
29 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <fcntl.h>
34 #include <inttypes.h>
35 #include <errno.h>
36 #include <sys/stat.h>
37 #include <sys/time.h>
38 #include "drm.h"
39 #include "intel_reg.h"
40 #include "ioctl_wrappers.h"
41 #include "igt_debugfs.h"
42 #include "drmtest.h"
43 #include "i915/gem_mman.h"
44 
45 #define LOCAL_I915_EXEC_NO_RELOC (1<<11)
46 #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
47 
48 #define SKIP_RELOC 0x1
49 #define NO_RELOC 0x2
50 #define CYCLE_BATCH 0x4
51 #define FAULT 0x8
52 #define LUT 0x10
53 #define SEQUENTIAL_OFFSET 0x20
54 #define REVERSE_OFFSET 0x40
55 #define RANDOM_OFFSET 0x80
56 
57 static uint32_t
hars_petruska_f54_1_random(void)58 hars_petruska_f54_1_random (void)
59 {
60 	static uint32_t state = 0x12345678;
61 
62 #define rol(x,k) ((x << k) | (x >> (32-k)))
63 	return state = (state ^ rol (state, 5) ^ rol (state, 24)) + 0x37798849;
64 #undef rol
65 }
66 
67 #define ELAPSED(a,b) (1e6*((b)->tv_sec - (a)->tv_sec) + ((b)->tv_usec - (a)->tv_usec))
run(unsigned batch_size,unsigned flags,int num_objects,int num_relocs,int reps)68 static int run(unsigned batch_size,
69 	       unsigned flags,
70 	       int num_objects,
71 	       int num_relocs, int reps)
72 {
73 	uint32_t batch[2] = {MI_BATCH_BUFFER_END};
74 	uint32_t cycle[16];
75 	int fd, n, count, c, size = 0;
76 	struct drm_i915_gem_relocation_entry *reloc = NULL;
77 	struct drm_i915_gem_execbuffer2 execbuf;
78 	struct drm_i915_gem_exec_object2 *objects;
79 	struct timeval start, end;
80 	uint32_t reloc_handle = 0;
81 	struct drm_i915_gem_exec_object2 *gem_exec;
82 	struct drm_i915_gem_relocation_entry *mem_reloc = NULL;
83 	int *target;
84 
85 	gem_exec = calloc(sizeof(*gem_exec), num_objects + 1);
86 	mem_reloc = calloc(sizeof(*mem_reloc), num_relocs);
87 	target = calloc(sizeof(*target), num_relocs);
88 
89 	fd = drm_open_driver(DRIVER_INTEL);
90 
91 	for (n = 0; n < num_objects; n++)
92 		gem_exec[n].handle = gem_create(fd, 4096);
93 
94 	for (n = 0; n < 16; n++) {
95 		cycle[n] = gem_create(fd, batch_size);
96 		gem_write(fd, cycle[n], 0, batch, sizeof(batch));
97 	}
98 	gem_exec[num_objects].handle = cycle[c = 0];
99 
100 	for (n = 0; n < num_relocs; n++) {
101 		mem_reloc[n].offset = 1024;
102 		mem_reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
103 	}
104 	for (n = 0; n < num_relocs; n++) {
105 		if (flags & SEQUENTIAL_OFFSET)
106 			mem_reloc[n].offset = 8 + (8*n % (batch_size - 16));
107 		else if (flags & REVERSE_OFFSET)
108 			mem_reloc[n].offset = batch_size - 8 - (8*n % (batch_size - 16));
109 		else if (flags & RANDOM_OFFSET)
110 			mem_reloc[n].offset = 8 +
111 				8*hars_petruska_f54_1_random() % (batch_size - 16);
112 		else
113 			mem_reloc[n].offset = 1024;
114 		mem_reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
115 	}
116 
117 	if (num_relocs) {
118 		size = ALIGN(sizeof(*mem_reloc)*num_relocs, 4096);
119 		reloc_handle = gem_create(fd, size);
120 		reloc = __gem_mmap__cpu(fd, reloc_handle, 0, size, PROT_READ | PROT_WRITE);
121 		memcpy(reloc, mem_reloc, sizeof(*mem_reloc)*num_relocs);
122 		munmap(reloc, size);
123 
124 		if (flags & FAULT) {
125 			igt_disable_prefault();
126 			reloc = __gem_mmap__cpu(fd, reloc_handle, 0, size, PROT_READ | PROT_WRITE);
127 		} else
128 			reloc = mem_reloc;
129 	}
130 
131 	gem_exec[num_objects].relocation_count = num_relocs;
132 	gem_exec[num_objects].relocs_ptr = (uintptr_t)reloc;
133 	objects = gem_exec;
134 
135 	memset(&execbuf, 0, sizeof(execbuf));
136 	execbuf.buffers_ptr = (uintptr_t)objects;
137 	execbuf.buffer_count = num_objects + 1;
138 	if (flags & LUT)
139 		execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
140 	if (flags & NO_RELOC)
141 		execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
142 
143 	for (n = 0; n < num_relocs; n++) {
144 		target[n] = hars_petruska_f54_1_random() % num_objects;
145 		if (flags & LUT)
146 			reloc[n].target_handle = target[n];
147 		else
148 			reloc[n].target_handle = objects[target[n]].handle;
149 		reloc[n].presumed_offset = -1;
150 	}
151 
152 	gem_execbuf(fd, &execbuf);
153 
154 	while (reps--) {
155 		gettimeofday(&start, NULL);
156 		for (count = 0; count < 1000; count++) {
157 			if ((flags & SKIP_RELOC) == 0) {
158 				for (n = 0; n < num_relocs; n++)
159 					reloc[n].presumed_offset = -1;
160 				if (flags & CYCLE_BATCH) {
161 					c = (c + 1) % 16;
162 					gem_exec[num_objects].handle = cycle[c];
163 				}
164 			}
165 			if (flags & FAULT && reloc) {
166 				munmap(reloc, size);
167 				reloc = __gem_mmap__cpu(fd, reloc_handle, 0, size, PROT_READ | PROT_WRITE);
168 				gem_exec[num_objects].relocs_ptr = (uintptr_t)reloc;
169 			}
170 			gem_execbuf(fd, &execbuf);
171 		}
172 		gettimeofday(&end, NULL);
173 		printf("%.3f\n", ELAPSED(&start, &end));
174 	}
175 
176 	if (flags & FAULT && reloc) {
177 		munmap(reloc, size);
178 		igt_enable_prefault();
179 	}
180 
181 	return 0;
182 }
183 
main(int argc,char ** argv)184 int main(int argc, char **argv)
185 {
186 	unsigned num_objects = 1, num_relocs = 0, flags = 0;
187 	unsigned size = 4096;
188 	int reps = 13;
189 	int c;
190 
191 	while ((c = getopt (argc, argv, "b:r:s:e:l:m:o:")) != -1) {
192 		switch (c) {
193 		case 'l':
194 			reps = atoi(optarg);
195 			if (reps < 1)
196 				reps = 1;
197 			break;
198 
199 		case 's':
200 			size = atoi(optarg);
201 			if (size < 4096)
202 				size = 4096;
203 			size = ALIGN(size, 4096);
204 			break;
205 
206 		case 'e':
207 			if (strcmp(optarg, "busy") == 0) {
208 				flags |= 0;
209 			} else if (strcmp(optarg, "cyclic") == 0) {
210 				flags |= CYCLE_BATCH;
211 			} else if (strcmp(optarg, "fault") == 0) {
212 				flags |= FAULT;
213 			} else if (strcmp(optarg, "skip") == 0) {
214 				flags |= SKIP_RELOC;
215 			} else if (strcmp(optarg, "none") == 0) {
216 				flags |= SKIP_RELOC | NO_RELOC;
217 			} else {
218 				abort();
219 			}
220 			break;
221 
222 		case 'm':
223 			if (strcmp(optarg, "old") == 0) {
224 				flags |= 0;
225 			} else if (strcmp(optarg, "lut") == 0) {
226 				flags |= LUT;
227 			} else {
228 				abort();
229 			}
230 			break;
231 
232 		case 'o':
233 			if (strcmp(optarg, "constant") == 0) {
234 				flags |= 0;
235 			} else if (strcmp(optarg, "sequential") == 0) {
236 				flags |= SEQUENTIAL_OFFSET;
237 			} else if (strcmp(optarg, "reverse") == 0) {
238 				flags |= REVERSE_OFFSET;
239 			} else if (strcmp(optarg, "random") == 0) {
240 				flags |= RANDOM_OFFSET;
241 			} else {
242 				abort();
243 			}
244 			break;
245 
246 		case 'b':
247 			num_objects = atoi(optarg);
248 			if (num_objects < 1)
249 				num_objects = 1;
250 			break;
251 
252 		case 'r':
253 			num_relocs = atoi(optarg);
254 			break;
255 		}
256 	}
257 
258 	return run(size, flags, num_objects, num_relocs, reps);
259 }
260