1 /*
2 * Copyright © 2011 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 /** @file gem_linear_render_blits.c
29 *
30 * This is a test of doing many blits, with a working set
31 * larger than the aperture size.
32 *
33 * The goal is to simply ensure the basics work.
34 */
35
36 #include "config.h"
37
38 #include "igt.h"
39 #include <stdlib.h>
40 #include <sys/ioctl.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <fcntl.h>
44 #include <inttypes.h>
45 #include <errno.h>
46 #include <sys/stat.h>
47 #include <sys/time.h>
48
49 #include <drm.h>
50
51 #include "intel_bufmgr.h"
52
53 #define WIDTH 512
54 #define STRIDE (WIDTH*4)
55 #define HEIGHT 512
56 #define SIZE (HEIGHT*STRIDE)
57
58 static uint32_t linear[WIDTH*HEIGHT];
59 static igt_render_copyfunc_t render_copy;
60
61 static void
check_bo(int fd,uint32_t handle,uint32_t val)62 check_bo(int fd, uint32_t handle, uint32_t val)
63 {
64 int i;
65
66 gem_read(fd, handle, 0, linear, sizeof(linear));
67 for (i = 0; i < WIDTH*HEIGHT; i++) {
68 igt_assert_f(linear[i] == val,
69 "Expected 0x%08x, found 0x%08x "
70 "at offset 0x%08x\n",
71 val, linear[i], i * 4);
72 val++;
73 }
74 }
75
run_test(int fd,int count)76 static void run_test (int fd, int count)
77 {
78 drm_intel_bufmgr *bufmgr;
79 struct intel_batchbuffer *batch;
80 uint32_t *start_val;
81 drm_intel_bo **bo;
82 uint32_t start = 0;
83 int i, j;
84
85 render_copy = igt_get_render_copyfunc(intel_get_drm_devid(fd));
86 igt_require(render_copy);
87
88 bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
89 batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd));
90
91 bo = malloc(sizeof(*bo)*count);
92 start_val = malloc(sizeof(*start_val)*count);
93
94 for (i = 0; i < count; i++) {
95 bo[i] = drm_intel_bo_alloc(bufmgr, "", SIZE, 4096);
96 start_val[i] = start;
97 for (j = 0; j < WIDTH*HEIGHT; j++)
98 linear[j] = start++;
99 gem_write(fd, bo[i]->handle, 0, linear, sizeof(linear));
100 }
101
102 igt_info("Verifying initialisation - %d buffers of %d bytes\n", count, SIZE);
103 for (i = 0; i < count; i++)
104 check_bo(fd, bo[i]->handle, start_val[i]);
105
106 igt_info("Cyclic blits, forward...\n");
107 for (i = 0; i < count * 4; i++) {
108 struct igt_buf src = {}, dst = {};
109
110 src.bo = bo[i % count];
111 src.stride = STRIDE;
112 src.tiling = I915_TILING_NONE;
113 src.size = SIZE;
114 src.bpp = 32;
115
116 dst.bo = bo[(i + 1) % count];
117 dst.stride = STRIDE;
118 dst.tiling = I915_TILING_NONE;
119 dst.size = SIZE;
120 dst.bpp = 32;
121
122 render_copy(batch, NULL, &src, 0, 0, WIDTH, HEIGHT, &dst, 0, 0);
123 start_val[(i + 1) % count] = start_val[i % count];
124 }
125 for (i = 0; i < count; i++)
126 check_bo(fd, bo[i]->handle, start_val[i]);
127
128 if (igt_run_in_simulation())
129 return;
130
131 igt_info("Cyclic blits, backward...\n");
132 for (i = 0; i < count * 4; i++) {
133 struct igt_buf src = {}, dst = {};
134
135 src.bo = bo[(i + 1) % count];
136 src.stride = STRIDE;
137 src.tiling = I915_TILING_NONE;
138 src.size = SIZE;
139 src.bpp = 32;
140
141 dst.bo = bo[i % count];
142 dst.stride = STRIDE;
143 dst.tiling = I915_TILING_NONE;
144 dst.size = SIZE;
145 dst.bpp = 32;
146
147 render_copy(batch, NULL, &src, 0, 0, WIDTH, HEIGHT, &dst, 0, 0);
148 start_val[i % count] = start_val[(i + 1) % count];
149 }
150 for (i = 0; i < count; i++)
151 check_bo(fd, bo[i]->handle, start_val[i]);
152
153 igt_info("Random blits...\n");
154 for (i = 0; i < count * 4; i++) {
155 struct igt_buf src = {}, dst = {};
156 int s = random() % count;
157 int d = random() % count;
158
159 if (s == d)
160 continue;
161
162 src.bo = bo[s];
163 src.stride = STRIDE;
164 src.tiling = I915_TILING_NONE;
165 src.size = SIZE;
166 src.bpp = 32;
167
168 dst.bo = bo[d];
169 dst.stride = STRIDE;
170 dst.tiling = I915_TILING_NONE;
171 dst.size = SIZE;
172 dst.bpp = 32;
173
174 render_copy(batch, NULL, &src, 0, 0, WIDTH, HEIGHT, &dst, 0, 0);
175 start_val[d] = start_val[s];
176 }
177 for (i = 0; i < count; i++)
178 check_bo(fd, bo[i]->handle, start_val[i]);
179
180 /* release resources */
181 for (i = 0; i < count; i++) {
182 drm_intel_bo_unreference(bo[i]);
183 }
184 intel_batchbuffer_free(batch);
185 drm_intel_bufmgr_destroy(bufmgr);
186 }
187
188 igt_main
189 {
190 static int fd = 0;
191 int count=0;
192
193 igt_fixture {
194 fd = drm_open_driver(DRIVER_INTEL);
195 igt_require_gem(fd);
196 }
197
198 igt_subtest("basic") {
199 run_test(fd, 2);
200 }
201
202 /* the rest of the tests are too long for simulation */
203 igt_skip_on_simulation();
204
205 igt_subtest("aperture-thrash") {
206 count = 3 * gem_aperture_size(fd) / SIZE / 2;
207 intel_require_memory(count, SIZE, CHECK_RAM);
208 run_test(fd, count);
209 }
210
211 igt_subtest("aperture-shrink") {
212 igt_fork_shrink_helper(fd);
213
214 count = 3 * gem_aperture_size(fd) / SIZE / 2;
215 intel_require_memory(count, SIZE, CHECK_RAM);
216 run_test(fd, count);
217
218 igt_stop_shrink_helper();
219 }
220
221 igt_subtest("swap-thrash") {
222 uint64_t swap_mb = intel_get_total_swap_mb();
223 igt_require(swap_mb > 0);
224 count = ((intel_get_avail_ram_mb() + (swap_mb / 2)) * 1024*1024) / SIZE;
225 intel_require_memory(count, SIZE, CHECK_RAM | CHECK_SWAP);
226 run_test(fd, count);
227 }
228 }
229