xref: /aosp_15_r20/external/igt-gpu-tools/benchmarks/gem_mmap.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1 /*
2  * Copyright © 2011-2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Chris Wilson <[email protected]>
25  *
26  */
27 
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <fcntl.h>
34 #include <inttypes.h>
35 #include <errno.h>
36 #include <sys/stat.h>
37 #include <sys/ioctl.h>
38 #include <sys/time.h>
39 #include <time.h>
40 
41 #include "drm.h"
42 #include "ioctl_wrappers.h"
43 #include "drmtest.h"
44 #include "igt_aux.h"
45 #include "igt_stats.h"
46 #include "i915/gem_mman.h"
47 
48 #define OBJECT_SIZE (1<<23)
49 
elapsed(const struct timespec * start,const struct timespec * end)50 static double elapsed(const struct timespec *start,
51 		const struct timespec *end)
52 {
53 	return (end->tv_sec - start->tv_sec) + 1e-9*(end->tv_nsec - start->tv_nsec);
54 }
55 
main(int argc,char ** argv)56 int main(int argc, char **argv)
57 {
58 	int fd = drm_open_driver(DRIVER_INTEL);
59 	enum map {CPU, GTT, WC} map = CPU;
60 	enum dir {READ, WRITE, CLEAR, FAULT} dir = READ;
61 	int tiling = I915_TILING_NONE;
62 	struct timespec start, end;
63 	void *buf = malloc(OBJECT_SIZE);
64 	uint32_t handle;
65 	void *ptr, *src, *dst;
66 	int reps = 1;
67 	int loops;
68 	int c;
69 
70 	while ((c = getopt (argc, argv, "m:d:r:t:")) != -1) {
71 		switch (c) {
72 		case 'm':
73 			if (strcmp(optarg, "cpu") == 0)
74 				map = CPU;
75 			else if (strcmp(optarg, "gtt") == 0)
76 				map = GTT;
77 			else if (strcmp(optarg, "wc") == 0)
78 				map = WC;
79 			else
80 				abort();
81 			break;
82 
83 		case 'd':
84 			if (strcmp(optarg, "read") == 0)
85 				dir = READ;
86 			else if (strcmp(optarg, "write") == 0)
87 				dir = WRITE;
88 			else if (strcmp(optarg, "clear") == 0)
89 				dir = CLEAR;
90 			else if (strcmp(optarg, "fault") == 0)
91 				dir = FAULT;
92 			else
93 				abort();
94 			break;
95 
96 		case 't':
97 			if (strcmp(optarg, "x") == 0)
98 				tiling = I915_TILING_X;
99 			else if (strcmp(optarg, "y") == 0)
100 				tiling = I915_TILING_Y;
101 			else if (strcmp(optarg, "none") == 0)
102 				tiling = I915_TILING_NONE;
103 			else
104 				abort();
105 			break;
106 
107 		case 'r':
108 			reps = atoi(optarg);
109 			if (reps < 1)
110 				reps = 1;
111 			break;
112 
113 		default:
114 			break;
115 		}
116 	}
117 
118 	handle = gem_create(fd, OBJECT_SIZE);
119 	switch (map) {
120 	case CPU:
121 		ptr = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
122 		gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
123 		break;
124 	case GTT:
125 		ptr = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE);
126 		gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
127 		break;
128 	case WC:
129 		ptr = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
130 		gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
131 		break;
132 	default:
133 		abort();
134 	}
135 
136 	gem_set_tiling(fd, handle, tiling, 512);
137 
138 	if (dir == READ) {
139 		src = ptr;
140 		dst = buf;
141 	} else {
142 		src = buf;
143 		dst = ptr;
144 	}
145 
146 	clock_gettime(CLOCK_MONOTONIC, &start);
147 	switch (dir) {
148 	case CLEAR:
149 	case FAULT:
150 		memset(dst, 0, OBJECT_SIZE);
151 		break;
152 	default:
153 		memcpy(dst, src, OBJECT_SIZE);
154 		break;
155 	}
156 	clock_gettime(CLOCK_MONOTONIC, &end);
157 
158 	loops = 2 / elapsed(&start, &end);
159 	while (reps--) {
160 		clock_gettime(CLOCK_MONOTONIC, &start);
161 		for (c = 0; c < loops; c++) {
162 			int page;
163 
164 			switch (dir) {
165 			case CLEAR:
166 				memset(dst, 0, OBJECT_SIZE);
167 				break;
168 			case FAULT:
169 				munmap(ptr, OBJECT_SIZE);
170 				switch (map) {
171 				case CPU:
172 					ptr = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
173 					break;
174 				case GTT:
175 					ptr = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE);
176 					break;
177 				case WC:
178 					ptr = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
179 					break;
180 				default:
181 					abort();
182 				}
183 				for (page = 0; page < OBJECT_SIZE; page += 4096) {
184 					uint32_t *x = (uint32_t *)ptr + page/4;
185 					__asm__ __volatile__("": : :"memory");
186 					page += *x; /* should be zero! */
187 				}
188 				break;
189 			default:
190 				memcpy(dst, src, OBJECT_SIZE);
191 				break;
192 			}
193 		}
194 		clock_gettime(CLOCK_MONOTONIC, &end);
195 		printf("%7.3f\n", OBJECT_SIZE / elapsed(&start, &end) * loops / (1024*1024));
196 	}
197 
198 	return 0;
199 }
200