xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_read_read_speed.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1 /*
2  * Copyright © 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 
24 /** @file gem_read_read_speed.c
25  *
26  * This is a test of performance with multiple readers from the same source.
27  */
28 
29 #include "igt.h"
30 #include "igt_sysfs.h"
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <fcntl.h>
35 #include <inttypes.h>
36 #include <errno.h>
37 #include <time.h>
38 #include <sys/stat.h>
39 #include <sys/time.h>
40 #include <sys/wait.h>
41 
42 #include <drm.h>
43 
44 #include "intel_bufmgr.h"
45 
46 IGT_TEST_DESCRIPTION("Test speed of concurrent reads between engines.");
47 
48 igt_render_copyfunc_t rendercopy;
49 struct intel_batchbuffer *batch;
50 int width, height;
51 
rcs_copy_bo(drm_intel_bo * dst,drm_intel_bo * src)52 static drm_intel_bo *rcs_copy_bo(drm_intel_bo *dst, drm_intel_bo *src)
53 {
54 	struct igt_buf d = {
55 		.bo = dst,
56 		.size = width * height * 4,
57 		.num_tiles = width * height * 4,
58 		.stride = width * 4,
59 		.bpp = 32,
60 	}, s = {
61 		.bo = src,
62 		.size = width * height * 4,
63 		.num_tiles = width * height * 4,
64 		.stride = width * 4,
65 		.bpp = 32,
66 	};
67 	uint32_t swizzle;
68 	drm_intel_bo *bo = batch->bo;
69 	drm_intel_bo_reference(bo);
70 
71 	drm_intel_bo_get_tiling(dst, &d.tiling, &swizzle);
72 	drm_intel_bo_get_tiling(src, &s.tiling, &swizzle);
73 
74 	rendercopy(batch, NULL,
75 		   &s, 0, 0,
76 		   width, height,
77 		   &d, 0, 0);
78 
79 	return bo;
80 }
81 
bcs_copy_bo(drm_intel_bo * dst,drm_intel_bo * src)82 static drm_intel_bo *bcs_copy_bo(drm_intel_bo *dst, drm_intel_bo *src)
83 {
84 	drm_intel_bo *bo = batch->bo;
85 	drm_intel_bo_reference(bo);
86 
87 	intel_blt_copy(batch,
88 		       src, 0, 0, 4*width,
89 		       dst, 0, 0, 4*width,
90 		       width, height, 32);
91 
92 	return bo;
93 }
94 
95 static void
set_bo(drm_intel_bo * bo,uint32_t val)96 set_bo(drm_intel_bo *bo, uint32_t val)
97 {
98 	int size = width * height;
99 	uint32_t *vaddr;
100 
101 	do_or_die(drm_intel_bo_map(bo, 1));
102 	vaddr = bo->virtual;
103 	while (size--)
104 		*vaddr++ = val;
105 	drm_intel_bo_unmap(bo);
106 }
107 
elapsed(const struct timespec * start,const struct timespec * end,int loop)108 static double elapsed(const struct timespec *start,
109 		      const struct timespec *end,
110 		      int loop)
111 {
112 	return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec)/1000)/loop;
113 }
114 
create_bo(drm_intel_bufmgr * bufmgr,const char * name)115 static drm_intel_bo *create_bo(drm_intel_bufmgr *bufmgr,
116 			       const char *name)
117 {
118 	uint32_t tiling_mode = I915_TILING_X;
119 	unsigned long pitch;
120 	return drm_intel_bo_alloc_tiled(bufmgr, name,
121 					width, height, 4,
122 					&tiling_mode, &pitch, 0);
123 }
124 
run(drm_intel_bufmgr * bufmgr,int _width,int _height,bool write_bcs,bool write_rcs)125 static void run(drm_intel_bufmgr *bufmgr, int _width, int _height,
126 		bool write_bcs, bool write_rcs)
127 {
128 	drm_intel_bo *src = NULL, *bcs = NULL, *rcs = NULL;
129 	drm_intel_bo *bcs_batch, *rcs_batch;
130 	struct timespec start, end;
131 	int loops = 1000;
132 
133 	width = _width;
134 	height = _height;
135 
136 	src = create_bo(bufmgr, "src");
137 	bcs = create_bo(bufmgr, "bcs");
138 	rcs = create_bo(bufmgr, "rcs");
139 
140 	set_bo(src, 0xdeadbeef);
141 
142 	if (write_bcs) {
143 		bcs_batch = bcs_copy_bo(src, bcs);
144 	} else {
145 		bcs_batch = bcs_copy_bo(bcs, src);
146 	}
147 	if (write_rcs) {
148 		rcs_batch = rcs_copy_bo(src, rcs);
149 	} else {
150 		rcs_batch = rcs_copy_bo(rcs, src);
151 	}
152 
153 	drm_intel_bo_unreference(rcs);
154 	drm_intel_bo_unreference(bcs);
155 
156 	drm_intel_gem_bo_start_gtt_access(src, true);
157 	clock_gettime(CLOCK_MONOTONIC, &start);
158 	for (int i = 0; i < loops; i++) {
159 		drm_intel_gem_bo_context_exec(rcs_batch, NULL, 4096, I915_EXEC_RENDER);
160 		drm_intel_gem_bo_context_exec(bcs_batch, NULL, 4096, I915_EXEC_BLT);
161 	}
162 	drm_intel_gem_bo_start_gtt_access(src, true);
163 	clock_gettime(CLOCK_MONOTONIC, &end);
164 
165 	igt_info("Time to %s-%s %dx%d [%dk]:		%7.3fµs\n",
166 		 write_bcs ? "write" : "read",
167 		 write_rcs ? "write" : "read",
168 		 width, height, 4*width*height/1024,
169 		 elapsed(&start, &end, loops));
170 
171 	drm_intel_bo_unreference(rcs_batch);
172 	drm_intel_bo_unreference(bcs_batch);
173 
174 	drm_intel_bo_unreference(src);
175 }
176 
177 igt_main
178 {
179 	const int sizes[] = {1, 128, 256, 512, 1024, 2048, 4096, 8192, 0};
180 	drm_intel_bufmgr *bufmgr = NULL;
181 	int fd, i;
182 
183 	igt_skip_on_simulation();
184 
185 	igt_fixture {
186 		int devid;
187 
188 		fd = drm_open_driver(DRIVER_INTEL);
189 		igt_require_gem(fd);
190 
191 		devid = intel_get_drm_devid(fd);
192 		igt_require(intel_gen(devid) >= 6);
193 
194 		rendercopy = igt_get_render_copyfunc(devid);
195 		igt_require(rendercopy);
196 
197 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
198 		igt_assert(bufmgr);
199 
200 		batch =  intel_batchbuffer_alloc(bufmgr, devid);
201 
202 		gem_submission_print_method(fd);
203 	}
204 
205 	for (i = 0; sizes[i] != 0; i++) {
206 		igt_subtest_f("read-read-%dx%d", sizes[i], sizes[i])
207 			run(bufmgr, sizes[i], sizes[i], false, false);
208 		igt_subtest_f("read-write-%dx%d", sizes[i], sizes[i])
209 			run(bufmgr, sizes[i], sizes[i], false, true);
210 		igt_subtest_f("write-read-%dx%d", sizes[i], sizes[i])
211 			run(bufmgr, sizes[i], sizes[i], true, false);
212 		igt_subtest_f("write-write-%dx%d", sizes[i], sizes[i])
213 			run(bufmgr, sizes[i], sizes[i], true, true);
214 	}
215 }
216