blob: 4d0de5c4eee4942de79397fd2a30627f080d913f [file] [log] [blame]
Daniel Vetter08cf5372011-03-19 21:34:55 +01001/*
2 * Copyright © 2011 Daniel Vetter
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 * Daniel Vetter <daniel.vetter@ffwll.ch>
25 *
26 * Partially based upon gem_tiled_fence_blits.c
27 */
28
29/** @file gem_stress.c
30 *
31 * This is a general gem coherency test. It's designed to eventually replicate
32 * any possible sequence of access patterns. It works by copying a set of tiles
33 * between two sets of backing buffer objects, randomly permutating the assinged
34 * position on each copy operations.
35 *
36 * The copy operation are done in tiny portions (to reduce any race windows
37 * for corruptions, hence increasing the chances for observing one) and are
38 * constantly switched between all means to copy stuff (fenced blitter, unfenced
39 * render, mmap, pwrite/read).
40 *
41 * After every complete move of a set tiling parameters of a buffer are randomly
42 * changed to simulate the effects of libdrm caching.
43 *
44 * Buffers are 1mb big to nicely fit into fences on gen2/3. A few are further
45 * split up to test relaxed fencing. Using this to push the average working set
46 * size over the available gtt space forces objects to be mapped as unfenceable
47 * (and as a side-effect tests gtt map/unmap coherency).
48 *
49 * In short: designed for maximum evilness.
50 */
51
Thomas Wood804e11f2015-08-17 17:57:43 +010052#include "igt.h"
Daniel Vetter7dc00012014-03-22 15:31:15 +010053#include <stdlib.h>
54#include <sys/ioctl.h>
55#include <stdio.h>
56#include <string.h>
Daniel Vetter7dc00012014-03-22 15:31:15 +010057#include <fcntl.h>
58#include <inttypes.h>
59#include <errno.h>
60#include <sys/stat.h>
61#include <sys/time.h>
Daniel Vetterf5daeec2014-03-23 13:35:09 +010062
63#include <drm.h>
64
Daniel Vetter7dc00012014-03-22 15:31:15 +010065#include "intel_bufmgr.h"
Daniel Vetter08cf5372011-03-19 21:34:55 +010066
Thomas Woodb2ac2642014-11-28 11:02:44 +000067IGT_TEST_DESCRIPTION("General gem coherency test.");
68
Daniel Vetter2aac2232011-03-25 21:53:07 +010069#define CMD_POLY_STIPPLE_OFFSET 0x7906
70
Thomas Wood80d2c9b2014-07-21 15:57:16 +010071#define DUCTAPE 0xdead0001
72#define TILESZ 0xdead0002
73#define CHCK_RENDER 0xdead0003
74
Daniel Vetter08cf5372011-03-19 21:34:55 +010075/** TODO:
76 * - beat on relaxed fencing (i.e. mappable/fenceable tracking in the kernel)
77 * - render copy (to check fence tracking and cache coherency management by the
78 * kernel)
79 * - multi-threading: probably just a wrapper script to launch multiple
80 * instances + an option to accordingly reduce the working set
81 * - gen6 inter-ring coherency (needs render copy, first)
Daniel Vetter80aae9b2011-03-20 21:12:20 +010082 * - variable buffer size
83 * - add an option to fork a second process that randomly sends signals to the
84 * first one (to check consistency of the kernel recovery paths)
Daniel Vetter08cf5372011-03-19 21:34:55 +010085 */
86
Daniel Vettera6751ba2011-03-31 23:29:25 +020087drm_intel_bufmgr *bufmgr;
Daniel Vetter08cf5372011-03-19 21:34:55 +010088struct intel_batchbuffer *batch;
Daniel Vettera6751ba2011-03-31 23:29:25 +020089int drm_fd;
90int devid;
91int num_fences;
Daniel Vetter08cf5372011-03-19 21:34:55 +010092
93drm_intel_bo *busy_bo;
94
Daniel Vetterb9fe6732012-01-18 17:47:33 +010095struct option_struct {
96 unsigned scratch_buf_size;
97 unsigned max_dimension;
98 unsigned num_buffers;
99 int trace_tile;
100 int no_hw;
101 int gpu_busy_load;
102 int use_render;
103 int use_blt;
104 int forced_tiling;
105 int use_cpu_maps;
106 int total_rounds;
107 int fail;
108 int tiles_per_buf;
109 int ducttape;
110 int tile_size;
111 int check_render_cpyfn;
112 int use_signal_helper;
113};
114
Daniel Vettera6751ba2011-03-31 23:29:25 +0200115struct option_struct options;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100116
Daniel Vetter699d3092012-01-18 01:03:20 +0100117#define MAX_BUFS 4096
118#define SCRATCH_BUF_SIZE 1024*1024
119#define BUSY_BUF_SIZE (256*4096)
120#define TILE_BYTES(size) ((size)*(size)*sizeof(uint32_t))
121
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100122static struct igt_buf buffers[2][MAX_BUFS];
Daniel Vetter08cf5372011-03-19 21:34:55 +0100123/* tile i is at logical position tile_permutation[i] */
Daniel Vetter22fe0982011-03-27 14:26:43 +0200124static unsigned *tile_permutation;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100125static unsigned num_buffers = 0;
126static unsigned current_set = 0;
127static unsigned target_set = 0;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200128static unsigned num_total_tiles = 0;
129
Daniel Vettera6751ba2011-03-31 23:29:25 +0200130int fence_storm = 0;
Daniel Vetter294c78f2011-03-27 15:25:12 +0200131static int gpu_busy_load = 10;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100132
Daniel Vetter336f85d2011-06-13 22:02:52 +0200133struct {
134 unsigned num_failed;
135 unsigned max_failed_reads;
136} stats;
137
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100138static void tile2xy(struct igt_buf *buf, unsigned tile, unsigned *x, unsigned *y)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100139{
Daniel Vetter83440952013-08-13 12:35:58 +0200140 igt_assert(tile < buf->num_tiles);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200141 *x = (tile*options.tile_size) % (buf->stride/sizeof(uint32_t));
142 *y = ((tile*options.tile_size) / (buf->stride/sizeof(uint32_t))) * options.tile_size;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100143}
144
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200145static void emit_blt(drm_intel_bo *src_bo, uint32_t src_tiling, unsigned src_pitch,
146 unsigned src_x, unsigned src_y, unsigned w, unsigned h,
147 drm_intel_bo *dst_bo, uint32_t dst_tiling, unsigned dst_pitch,
148 unsigned dst_x, unsigned dst_y)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100149{
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200150 uint32_t cmd_bits = 0;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100151
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200152 if (IS_965(devid) && src_tiling) {
Daniel Vetter08cf5372011-03-19 21:34:55 +0100153 src_pitch /= 4;
154 cmd_bits |= XY_SRC_COPY_BLT_SRC_TILED;
155 }
156
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200157 if (IS_965(devid) && dst_tiling) {
Daniel Vetter08cf5372011-03-19 21:34:55 +0100158 dst_pitch /= 4;
159 cmd_bits |= XY_SRC_COPY_BLT_DST_TILED;
160 }
161
162 /* copy lower half to upper half */
Chris Wilson10552b52014-08-30 11:44:51 +0100163 BLIT_COPY_BATCH_START(cmd_bits);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100164 OUT_BATCH((3 << 24) | /* 32 bits */
165 (0xcc << 16) | /* copy ROP */
166 dst_pitch);
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200167 OUT_BATCH(dst_y << 16 | dst_x);
168 OUT_BATCH((dst_y+h) << 16 | (dst_x+w));
169 OUT_RELOC_FENCED(dst_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
170 OUT_BATCH(src_y << 16 | src_x);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100171 OUT_BATCH(src_pitch);
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200172 OUT_RELOC_FENCED(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100173 ADVANCE_BATCH();
Daniel Vetter7af82bb2011-11-27 02:39:14 +0100174
Chris Wilson10552b52014-08-30 11:44:51 +0100175 if (batch->gen >= 6) {
176 BEGIN_BATCH(3, 0);
Daniel Vetter7af82bb2011-11-27 02:39:14 +0100177 OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
178 OUT_BATCH(0);
179 OUT_BATCH(0);
180 ADVANCE_BATCH();
181 }
Daniel Vetter08cf5372011-03-19 21:34:55 +0100182}
183
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200184/* All this gem trashing wastes too much cpu time, so give the gpu something to
185 * do to increase changes for races. */
Daniel Vetterf7c2dab2012-01-18 17:51:48 +0100186static void keep_gpu_busy(void)
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200187{
188 int tmp;
189
190 tmp = 1 << gpu_busy_load;
Matt Roper07be8fe2015-03-05 15:01:00 -0800191 igt_assert_lte(tmp, 1024);
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200192
193 emit_blt(busy_bo, 0, 4096, 0, 0, tmp, 128,
194 busy_bo, 0, 4096, 0, 128);
195}
196
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100197static void set_to_cpu_domain(struct igt_buf *buf, int writing)
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200198{
Daniel Vetter673e6b22012-01-10 16:05:34 +0100199 gem_set_domain(drm_fd, buf->bo->handle, I915_GEM_DOMAIN_CPU,
200 writing ? I915_GEM_DOMAIN_CPU : 0);
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200201}
202
Daniel Vetter08cf5372011-03-19 21:34:55 +0100203static unsigned int copyfunc_seq = 0;
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100204static void (*copyfunc)(struct igt_buf *src, unsigned src_x, unsigned src_y,
205 struct igt_buf *dst, unsigned dst_x, unsigned dst_y,
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100206 unsigned logical_tile_no);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100207
208/* stride, x, y in units of uint32_t! */
209static void cpucpy2d(uint32_t *src, unsigned src_stride, unsigned src_x, unsigned src_y,
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100210 uint32_t *dst, unsigned dst_stride, unsigned dst_x, unsigned dst_y,
211 unsigned logical_tile_no)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100212{
213 int i, j;
Daniel Vetter874163d2011-03-27 14:02:49 +0200214 int failed = 0;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100215
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200216 for (i = 0; i < options.tile_size; i++) {
217 for (j = 0; j < options.tile_size; j++) {
Daniel Vetter08cf5372011-03-19 21:34:55 +0100218 unsigned dst_ofs = dst_x + j + dst_stride * (dst_y + i);
219 unsigned src_ofs = src_x + j + src_stride * (src_y + i);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200220 unsigned expect = logical_tile_no*options.tile_size*options.tile_size
221 + i*options.tile_size + j;
Daniel Vettercd640cc2011-03-27 21:33:29 +0200222 uint32_t tmp = src[src_ofs];
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100223 if (tmp != expect) {
Daniel Vetterc9c55452014-06-13 18:27:59 +0200224 igt_info("mismatch at tile %i pos %i, read %i, expected %i, diff %i\n", logical_tile_no, i * options.tile_size + j, tmp, expect, (int)tmp - expect);
225 igt_fail_on(options.trace_tile >= 0 && options.fail);
Daniel Vetter336f85d2011-06-13 22:02:52 +0200226 failed++;
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100227 }
Daniel Vetter6daa8832011-06-13 00:22:01 +0200228 /* when not aborting, correct any errors */
229 dst[dst_ofs] = expect;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100230 }
231 }
Daniel Vetterc9c55452014-06-13 18:27:59 +0200232 igt_fail_on(failed && options.fail);
Daniel Vetter336f85d2011-06-13 22:02:52 +0200233
234 if (failed > stats.max_failed_reads)
235 stats.max_failed_reads = failed;
236 if (failed)
237 stats.num_failed++;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100238}
239
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100240static void cpu_copyfunc(struct igt_buf *src, unsigned src_x, unsigned src_y,
241 struct igt_buf *dst, unsigned dst_x, unsigned dst_y,
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100242 unsigned logical_tile_no)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100243{
Daniel Vetter83440952013-08-13 12:35:58 +0200244 igt_assert(batch->ptr == batch->buffer);
Chris Wilson75f7e812011-05-25 14:49:40 +0100245
Daniel Vetterc0f34332011-06-13 13:18:35 +0200246 if (options.ducttape)
247 drm_intel_bo_wait_rendering(dst->bo);
248
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200249 if (options.use_cpu_maps) {
250 set_to_cpu_domain(src, 0);
251 set_to_cpu_domain(dst, 1);
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200252 }
253
Daniel Vetter08cf5372011-03-19 21:34:55 +0100254 cpucpy2d(src->data, src->stride/sizeof(uint32_t), src_x, src_y,
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100255 dst->data, dst->stride/sizeof(uint32_t), dst_x, dst_y,
256 logical_tile_no);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100257}
258
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100259static void prw_copyfunc(struct igt_buf *src, unsigned src_x, unsigned src_y,
260 struct igt_buf *dst, unsigned dst_x, unsigned dst_y,
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100261 unsigned logical_tile_no)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100262{
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200263 uint32_t tmp_tile[options.tile_size*options.tile_size];
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100264 int i;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100265
Daniel Vetter83440952013-08-13 12:35:58 +0200266 igt_assert(batch->ptr == batch->buffer);
Chris Wilson75f7e812011-05-25 14:49:40 +0100267
Daniel Vetterc0f34332011-06-13 13:18:35 +0200268 if (options.ducttape)
269 drm_intel_bo_wait_rendering(dst->bo);
270
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100271 if (src->tiling == I915_TILING_NONE) {
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200272 for (i = 0; i < options.tile_size; i++) {
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100273 unsigned ofs = src_x*sizeof(uint32_t) + src->stride*(src_y + i);
274 drm_intel_bo_get_subdata(src->bo, ofs,
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200275 options.tile_size*sizeof(uint32_t),
276 tmp_tile + options.tile_size*i);
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100277 }
278 } else {
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200279 if (options.use_cpu_maps)
280 set_to_cpu_domain(src, 0);
281
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100282 cpucpy2d(src->data, src->stride/sizeof(uint32_t), src_x, src_y,
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200283 tmp_tile, options.tile_size, 0, 0, logical_tile_no);
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100284 }
285
286 if (dst->tiling == I915_TILING_NONE) {
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200287 for (i = 0; i < options.tile_size; i++) {
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100288 unsigned ofs = dst_x*sizeof(uint32_t) + dst->stride*(dst_y + i);
289 drm_intel_bo_subdata(dst->bo, ofs,
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200290 options.tile_size*sizeof(uint32_t),
291 tmp_tile + options.tile_size*i);
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100292 }
293 } else {
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200294 if (options.use_cpu_maps)
295 set_to_cpu_domain(dst, 1);
296
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200297 cpucpy2d(tmp_tile, options.tile_size, 0, 0,
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100298 dst->data, dst->stride/sizeof(uint32_t), dst_x, dst_y,
299 logical_tile_no);
300 }
Daniel Vetter08cf5372011-03-19 21:34:55 +0100301}
302
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100303static void blitter_copyfunc(struct igt_buf *src, unsigned src_x, unsigned src_y,
304 struct igt_buf *dst, unsigned dst_x, unsigned dst_y,
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100305 unsigned logical_tile_no)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100306{
Daniel Vetter08cf5372011-03-19 21:34:55 +0100307 static unsigned keep_gpu_busy_counter = 0;
308
309 /* check both edges of the fence usage */
310 if (keep_gpu_busy_counter & 1 && !fence_storm)
311 keep_gpu_busy();
312
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200313 emit_blt(src->bo, src->tiling, src->stride, src_x, src_y,
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200314 options.tile_size, options.tile_size,
Daniel Vetteraeb0b6f2011-04-03 13:10:07 +0200315 dst->bo, dst->tiling, dst->stride, dst_x, dst_y);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100316
317 if (!(keep_gpu_busy_counter & 1) && !fence_storm)
318 keep_gpu_busy();
319
320 keep_gpu_busy_counter++;
321
322 if (src->tiling)
323 fence_storm--;
324 if (dst->tiling)
325 fence_storm--;
326
Daniel Vetter3f10ff82011-03-21 22:13:18 +0100327 if (fence_storm <= 1) {
Daniel Vetter08cf5372011-03-19 21:34:55 +0100328 fence_storm = 0;
329 intel_batchbuffer_flush(batch);
330 }
331}
332
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100333static void render_copyfunc(struct igt_buf *src, unsigned src_x, unsigned src_y,
334 struct igt_buf *dst, unsigned dst_x, unsigned dst_y,
Daniel Vettercd640cc2011-03-27 21:33:29 +0200335 unsigned logical_tile_no)
336{
Daniel Vetterf7c2dab2012-01-18 17:51:48 +0100337 static unsigned keep_gpu_busy_counter = 0;
Daniel Vetter53a4d9e2014-03-22 15:49:02 +0100338 igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(devid);
Daniel Vetterf7c2dab2012-01-18 17:51:48 +0100339
340 /* check both edges of the fence usage */
341 if (keep_gpu_busy_counter & 1)
342 keep_gpu_busy();
343
Ville Syrjäläfa86e332014-04-28 17:58:45 +0300344 if (rendercopy) {
345 /*
346 * Flush outstanding blts so that they don't end up on
347 * the render ring when that's not allowed (gen6+).
348 */
349 intel_batchbuffer_flush(batch);
Ville Syrjälä725da6e2013-11-21 19:05:17 +0200350 rendercopy(batch, NULL, src, src_x, src_y,
Daniel Vetter64f669f2012-11-29 14:59:57 +0100351 options.tile_size, options.tile_size,
352 dst, dst_x, dst_y);
Ville Syrjäläfa86e332014-04-28 17:58:45 +0300353 } else
Daniel Vettercd640cc2011-03-27 21:33:29 +0200354 blitter_copyfunc(src, src_x, src_y,
355 dst, dst_x, dst_y,
356 logical_tile_no);
Daniel Vetterf7c2dab2012-01-18 17:51:48 +0100357 if (!(keep_gpu_busy_counter & 1))
358 keep_gpu_busy();
359
360 keep_gpu_busy_counter++;
361 intel_batchbuffer_flush(batch);
Daniel Vettercd640cc2011-03-27 21:33:29 +0200362}
363
Daniel Vetter6a860b72011-03-29 19:23:35 +0200364static void next_copyfunc(int tile)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100365{
Daniel Vetter6a860b72011-03-29 19:23:35 +0200366 if (fence_storm) {
367 if (tile == options.trace_tile)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200368 igt_info(" using fence storm\n");
Daniel Vetter08cf5372011-03-19 21:34:55 +0100369 return;
Daniel Vetter6a860b72011-03-29 19:23:35 +0200370 }
Daniel Vetter08cf5372011-03-19 21:34:55 +0100371
Daniel Vetterfde66f92011-06-06 20:15:44 +0200372 if (copyfunc_seq % 61 == 0
373 && options.forced_tiling != I915_TILING_NONE) {
Daniel Vetter6a860b72011-03-29 19:23:35 +0200374 if (tile == options.trace_tile)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200375 igt_info(" using fence storm\n");
Daniel Vetter08cf5372011-03-19 21:34:55 +0100376 fence_storm = num_fences;
377 copyfunc = blitter_copyfunc;
Daniel Vetter6a860b72011-03-29 19:23:35 +0200378 } else if (copyfunc_seq % 17 == 0) {
379 if (tile == options.trace_tile)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200380 igt_info(" using cpu\n");
Daniel Vetter08cf5372011-03-19 21:34:55 +0100381 copyfunc = cpu_copyfunc;
Daniel Vetter6a860b72011-03-29 19:23:35 +0200382 } else if (copyfunc_seq % 19 == 0) {
383 if (tile == options.trace_tile)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200384 igt_info(" using prw\n");
Daniel Vetter08cf5372011-03-19 21:34:55 +0100385 copyfunc = prw_copyfunc;
Daniel Vetter1baab2e2011-03-30 21:46:04 +0200386 } else if (copyfunc_seq % 3 == 0 && options.use_render) {
Daniel Vettercd640cc2011-03-27 21:33:29 +0200387 if (tile == options.trace_tile)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200388 igt_info(" using render\n");
Daniel Vettercd640cc2011-03-27 21:33:29 +0200389 copyfunc = render_copyfunc;
Chris Wilson4e1f2f52011-05-25 13:41:28 +0100390 } else if (options.use_blt){
Daniel Vetter6a860b72011-03-29 19:23:35 +0200391 if (tile == options.trace_tile)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200392 igt_info(" using blitter\n");
Daniel Vetter08cf5372011-03-19 21:34:55 +0100393 copyfunc = blitter_copyfunc;
Chris Wilson4e1f2f52011-05-25 13:41:28 +0100394 } else if (options.use_render){
395 if (tile == options.trace_tile)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200396 igt_info(" using render\n");
Chris Wilson4e1f2f52011-05-25 13:41:28 +0100397 copyfunc = render_copyfunc;
398 } else {
399 copyfunc = cpu_copyfunc;
Daniel Vetter6a860b72011-03-29 19:23:35 +0200400 }
Daniel Vetter08cf5372011-03-19 21:34:55 +0100401
402 copyfunc_seq++;
403}
404
405static void fan_out(void)
406{
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200407 uint32_t tmp_tile[options.tile_size*options.tile_size];
Daniel Vetter08cf5372011-03-19 21:34:55 +0100408 uint32_t seq = 0;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200409 int i, k;
410 unsigned tile, buf_idx, x, y;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100411
Daniel Vetter22fe0982011-03-27 14:26:43 +0200412 for (i = 0; i < num_total_tiles; i++) {
413 tile = i;
Daniel Vetterc0f34332011-06-13 13:18:35 +0200414 buf_idx = tile / options.tiles_per_buf;
415 tile %= options.tiles_per_buf;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100416
Daniel Vetter22fe0982011-03-27 14:26:43 +0200417 tile2xy(&buffers[current_set][buf_idx], tile, &x, &y);
418
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200419 for (k = 0; k < options.tile_size*options.tile_size; k++)
Daniel Vetter22fe0982011-03-27 14:26:43 +0200420 tmp_tile[k] = seq++;
421
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200422 if (options.use_cpu_maps)
423 set_to_cpu_domain(&buffers[current_set][buf_idx], 1);
424
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200425 cpucpy2d(tmp_tile, options.tile_size, 0, 0,
Daniel Vetter22fe0982011-03-27 14:26:43 +0200426 buffers[current_set][buf_idx].data,
427 buffers[current_set][buf_idx].stride / sizeof(uint32_t),
428 x, y, i);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100429 }
430
Daniel Vetter22fe0982011-03-27 14:26:43 +0200431 for (i = 0; i < num_total_tiles; i++)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100432 tile_permutation[i] = i;
433}
434
435static void fan_in_and_check(void)
436{
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200437 uint32_t tmp_tile[options.tile_size*options.tile_size];
Daniel Vetter08cf5372011-03-19 21:34:55 +0100438 unsigned tile, buf_idx, x, y;
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100439 int i;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200440 for (i = 0; i < num_total_tiles; i++) {
Daniel Vetter08cf5372011-03-19 21:34:55 +0100441 tile = tile_permutation[i];
Daniel Vetterc0f34332011-06-13 13:18:35 +0200442 buf_idx = tile / options.tiles_per_buf;
443 tile %= options.tiles_per_buf;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100444
445 tile2xy(&buffers[current_set][buf_idx], tile, &x, &y);
446
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200447 if (options.use_cpu_maps)
448 set_to_cpu_domain(&buffers[current_set][buf_idx], 0);
449
Daniel Vetter08cf5372011-03-19 21:34:55 +0100450 cpucpy2d(buffers[current_set][buf_idx].data,
451 buffers[current_set][buf_idx].stride / sizeof(uint32_t),
452 x, y,
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200453 tmp_tile, options.tile_size, 0, 0,
Daniel Vetter80aae9b2011-03-20 21:12:20 +0100454 i);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100455 }
456}
457
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100458static void sanitize_stride(struct igt_buf *buf)
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200459{
460
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100461 if (igt_buf_height(buf) > options.max_dimension)
Daniel Vetter205510b2012-01-18 00:34:15 +0100462 buf->stride = buf->size / options.max_dimension;
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200463
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100464 if (igt_buf_height(buf) < options.tile_size)
Daniel Vetter205510b2012-01-18 00:34:15 +0100465 buf->stride = buf->size / options.tile_size;
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200466
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100467 if (igt_buf_width(buf) < options.tile_size)
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200468 buf->stride = options.tile_size * sizeof(uint32_t);
469
Daniel Vetter83440952013-08-13 12:35:58 +0200470 igt_assert(buf->stride <= 8192);
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100471 igt_assert(igt_buf_width(buf) <= options.max_dimension);
472 igt_assert(igt_buf_height(buf) <= options.max_dimension);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200473
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100474 igt_assert(igt_buf_width(buf) >= options.tile_size);
475 igt_assert(igt_buf_height(buf) >= options.tile_size);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200476
477}
478
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100479static void init_buffer(struct igt_buf *buf, unsigned size)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100480{
Daniel Vetter22fe0982011-03-27 14:26:43 +0200481 buf->bo = drm_intel_bo_alloc(bufmgr, "tiled bo", size, 4096);
Daniel Vetter205510b2012-01-18 00:34:15 +0100482 buf->size = size;
Daniel Vetter83440952013-08-13 12:35:58 +0200483 igt_assert(buf->bo);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100484 buf->tiling = I915_TILING_NONE;
Daniel Vetter1095a822011-06-06 20:16:35 +0200485 buf->stride = 4096;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200486
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200487 sanitize_stride(buf);
488
Daniel Vetter22fe0982011-03-27 14:26:43 +0200489 if (options.no_hw)
490 buf->data = malloc(size);
491 else {
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200492 if (options.use_cpu_maps)
493 drm_intel_bo_map(buf->bo, 1);
494 else
495 drm_intel_gem_bo_map_gtt(buf->bo);
Daniel Vetter22fe0982011-03-27 14:26:43 +0200496 buf->data = buf->bo->virtual;
497 }
498
Daniel Vetterc0f34332011-06-13 13:18:35 +0200499 buf->num_tiles = options.tiles_per_buf;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100500}
501
Daniel Vetter08cf5372011-03-19 21:34:55 +0100502static void exchange_buf(void *array, unsigned i, unsigned j)
503{
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100504 struct igt_buf *buf_arr, tmp;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100505 buf_arr = array;
506
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100507 memcpy(&tmp, &buf_arr[i], sizeof(struct igt_buf));
508 memcpy(&buf_arr[i], &buf_arr[j], sizeof(struct igt_buf));
509 memcpy(&buf_arr[j], &tmp, sizeof(struct igt_buf));
Daniel Vetter08cf5372011-03-19 21:34:55 +0100510}
511
Daniel Vettercd640cc2011-03-27 21:33:29 +0200512
Daniel Vetter08cf5372011-03-19 21:34:55 +0100513static void init_set(unsigned set)
514{
515 long int r;
516 int i;
517
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200518 igt_permute_array(buffers[set], num_buffers, exchange_buf);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100519
Daniel Vetter294c78f2011-03-27 15:25:12 +0200520 if (current_set == 1 && options.gpu_busy_load == 0) {
521 gpu_busy_load++;
522 if (gpu_busy_load > 10)
523 gpu_busy_load = 6;
524 }
525
Daniel Vetter08cf5372011-03-19 21:34:55 +0100526 for (i = 0; i < num_buffers; i++) {
527 r = random();
528 if ((r & 3) != 0)
529 continue;
530 r >>= 2;
531
532 if ((r & 3) != 0)
533 buffers[set][i].tiling = I915_TILING_X;
534 else
535 buffers[set][i].tiling = I915_TILING_NONE;
536 r >>= 2;
Daniel Vettera67091b2011-04-12 22:26:42 +0200537 if (options.forced_tiling >= 0)
538 buffers[set][i].tiling = options.forced_tiling;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100539
540 if (buffers[set][i].tiling == I915_TILING_NONE) {
541 /* min 64 byte stride */
542 r %= 8;
543 buffers[set][i].stride = 64 * (1 << r);
544 } else if (IS_GEN2(devid)) {
545 /* min 128 byte stride */
546 r %= 7;
547 buffers[set][i].stride = 128 * (1 << r);
548 } else {
549 /* min 512 byte stride */
550 r %= 5;
551 buffers[set][i].stride = 512 * (1 << r);
552 }
Chris Wilson3d66d912011-06-05 21:53:49 +0100553
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200554 sanitize_stride(&buffers[set][i]);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100555
Daniel Vetteraa67b222012-01-10 14:59:58 +0100556 gem_set_tiling(drm_fd, buffers[set][i].bo->handle,
557 buffers[set][i].tiling,
558 buffers[set][i].stride);
Daniel Vetter6a860b72011-03-29 19:23:35 +0200559
Daniel Vetterc0f34332011-06-13 13:18:35 +0200560 if (options.trace_tile != -1 && i == options.trace_tile/options.tiles_per_buf)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200561 igt_info("changing buffer %i containing tile %i: tiling %i, stride %i\n", i, options.trace_tile, buffers[set][i].tiling, buffers[set][i].stride);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100562 }
563}
564
565static void exchange_uint(void *array, unsigned i, unsigned j)
566{
567 unsigned *i_arr = array;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100568
Daniel Vetter2eca38e2015-02-07 12:37:48 +0100569 igt_swap(i_arr[i], i_arr[j]);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100570}
571
572static void copy_tiles(unsigned *permutation)
573{
574 unsigned src_tile, src_buf_idx, src_x, src_y;
575 unsigned dst_tile, dst_buf_idx, dst_x, dst_y;
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100576 struct igt_buf *src_buf, *dst_buf;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100577 int i, idx;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200578 for (i = 0; i < num_total_tiles; i++) {
Chris Wilson719ffef2011-05-22 10:34:12 +0100579 /* tile_permutation is independent of current_permutation, so
Daniel Vetter08cf5372011-03-19 21:34:55 +0100580 * abuse it to randomize the order of the src bos */
581 idx = tile_permutation[i];
Daniel Vetterc0f34332011-06-13 13:18:35 +0200582 src_buf_idx = idx / options.tiles_per_buf;
583 src_tile = idx % options.tiles_per_buf;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100584 src_buf = &buffers[current_set][src_buf_idx];
585
586 tile2xy(src_buf, src_tile, &src_x, &src_y);
587
Daniel Vetterc0f34332011-06-13 13:18:35 +0200588 dst_buf_idx = permutation[idx] / options.tiles_per_buf;
589 dst_tile = permutation[idx] % options.tiles_per_buf;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100590 dst_buf = &buffers[target_set][dst_buf_idx];
591
592 tile2xy(dst_buf, dst_tile, &dst_x, &dst_y);
593
Daniel Vetter6a860b72011-03-29 19:23:35 +0200594 if (options.trace_tile == i)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200595 igt_info("copying tile %i from %i (%i, %i) to %i (%i, %i)", i, tile_permutation[i], src_buf_idx, src_tile, permutation[idx], dst_buf_idx, dst_tile);
Daniel Vetter6a860b72011-03-29 19:23:35 +0200596
Daniel Vetter22fe0982011-03-27 14:26:43 +0200597 if (options.no_hw) {
598 cpucpy2d(src_buf->data,
599 src_buf->stride / sizeof(uint32_t),
600 src_x, src_y,
601 dst_buf->data,
602 dst_buf->stride / sizeof(uint32_t),
603 dst_x, dst_y,
604 i);
605 } else {
Daniel Vetter6a860b72011-03-29 19:23:35 +0200606 next_copyfunc(i);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100607
Daniel Vetter22fe0982011-03-27 14:26:43 +0200608 copyfunc(src_buf, src_x, src_y, dst_buf, dst_x, dst_y,
609 i);
610 }
Daniel Vetter08cf5372011-03-19 21:34:55 +0100611 }
612
613 intel_batchbuffer_flush(batch);
614}
615
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200616static void sanitize_tiles_per_buf(void)
617{
618 if (options.tiles_per_buf > options.scratch_buf_size / TILE_BYTES(options.tile_size))
619 options.tiles_per_buf = options.scratch_buf_size / TILE_BYTES(options.tile_size);
620}
621
Damien Lespiaufd6846c2015-05-14 14:19:01 +0100622static int parse_options(int opt, int opt_index, void *data)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100623{
Thomas Wood80d2c9b2014-07-21 15:57:16 +0100624 int tmp;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200625
Thomas Wood80d2c9b2014-07-21 15:57:16 +0100626 switch(opt) {
Daniel Vetter22fe0982011-03-27 14:26:43 +0200627 case 'd':
628 options.no_hw = 1;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200629 igt_info("no-hw debug mode\n");
Daniel Vetter22fe0982011-03-27 14:26:43 +0200630 break;
Chris Wilson4227da82011-07-02 08:59:32 +0100631 case 'S':
632 options.use_signal_helper = 0;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200633 igt_info("disabling that pesky nuisance who keeps interrupting us\n");
Chris Wilson4227da82011-07-02 08:59:32 +0100634 break;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200635 case 's':
636 tmp = atoi(optarg);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200637 if (tmp < options.tile_size*8192)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200638 igt_info("scratch buffer size needs to be at least %i\n", options.tile_size * 8192);
Daniel Vetter22fe0982011-03-27 14:26:43 +0200639 else if (tmp & (tmp - 1)) {
Daniel Vetterc9c55452014-06-13 18:27:59 +0200640 igt_info("scratch buffer size needs to be a power-of-two\n");
Daniel Vetter22fe0982011-03-27 14:26:43 +0200641 } else {
Daniel Vetterc9c55452014-06-13 18:27:59 +0200642 igt_info("fixed scratch buffer size to %u\n", tmp);
Daniel Vetter22fe0982011-03-27 14:26:43 +0200643 options.scratch_buf_size = tmp;
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200644 sanitize_tiles_per_buf();
Daniel Vetter22fe0982011-03-27 14:26:43 +0200645 }
646 break;
Daniel Vetter294c78f2011-03-27 15:25:12 +0200647 case 'g':
648 tmp = atoi(optarg);
649 if (tmp < 0 || tmp > 10)
Daniel Vetterc9c55452014-06-13 18:27:59 +0200650 igt_info("gpu busy load needs to be bigger than 0 and smaller than 10\n");
Daniel Vetter294c78f2011-03-27 15:25:12 +0200651 else {
Daniel Vetterc9c55452014-06-13 18:27:59 +0200652 igt_info("gpu busy load factor set to %i\n", tmp);
Daniel Vetter294c78f2011-03-27 15:25:12 +0200653 gpu_busy_load = options.gpu_busy_load = tmp;
654 }
655 break;
Daniel Vetter130daf92011-03-27 15:37:26 +0200656 case 'c':
657 options.num_buffers = atoi(optarg);
Daniel Vetterc9c55452014-06-13 18:27:59 +0200658 igt_info("buffer count set to %i\n", options.num_buffers);
Daniel Vetter130daf92011-03-27 15:37:26 +0200659 break;
Daniel Vetter6a860b72011-03-29 19:23:35 +0200660 case 't':
661 options.trace_tile = atoi(optarg);
Daniel Vetterc9c55452014-06-13 18:27:59 +0200662 igt_info("tracing tile %i\n", options.trace_tile);
Daniel Vetter6a860b72011-03-29 19:23:35 +0200663 break;
Daniel Vetter1baab2e2011-03-30 21:46:04 +0200664 case 'r':
665 options.use_render = 0;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200666 igt_info("disabling render copy\n");
Daniel Vettere68652c2011-04-04 22:10:21 +0200667 break;
Chris Wilson4e1f2f52011-05-25 13:41:28 +0100668 case 'b':
669 options.use_blt = 0;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200670 igt_info("disabling blt copy\n");
Chris Wilson4e1f2f52011-05-25 13:41:28 +0100671 break;
Daniel Vettere68652c2011-04-04 22:10:21 +0200672 case 'u':
Daniel Vettera67091b2011-04-12 22:26:42 +0200673 options.forced_tiling = I915_TILING_NONE;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200674 igt_info("disabling tiling\n");
Daniel Vettere68652c2011-04-04 22:10:21 +0200675 break;
Daniel Vettera67091b2011-04-12 22:26:42 +0200676 case 'x':
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200677 if (options.use_cpu_maps) {
Daniel Vetterc9c55452014-06-13 18:27:59 +0200678 igt_info("tiling not possible with cpu maps\n");
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200679 } else {
680 options.forced_tiling = I915_TILING_X;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200681 igt_info("using only X-tiling\n");
Daniel Vetterb11d67a2011-04-27 22:13:29 +0200682 }
683 break;
684 case 'm':
685 options.use_cpu_maps = 1;
686 options.forced_tiling = I915_TILING_NONE;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200687 igt_info("disabling tiling\n");
Daniel Vettera67091b2011-04-12 22:26:42 +0200688 break;
Daniel Vetter9649dd72011-06-07 22:30:03 +0200689 case 'o':
690 options.total_rounds = atoi(optarg);
Daniel Vetterc9c55452014-06-13 18:27:59 +0200691 igt_info("total rounds %i\n", options.total_rounds);
Daniel Vetter9649dd72011-06-07 22:30:03 +0200692 break;
Daniel Vetter6daa8832011-06-13 00:22:01 +0200693 case 'f':
694 options.fail = 0;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200695 igt_info("not failing when detecting errors\n");
Daniel Vetter6daa8832011-06-13 00:22:01 +0200696 break;
Daniel Vetterc0f34332011-06-13 13:18:35 +0200697 case 'p':
698 options.tiles_per_buf = atoi(optarg);
Daniel Vetterc9c55452014-06-13 18:27:59 +0200699 igt_info("tiles per buffer %i\n", options.tiles_per_buf);
Daniel Vetterc0f34332011-06-13 13:18:35 +0200700 break;
701 case DUCTAPE:
Daniel Vetter74670c72011-07-17 23:33:27 +0200702 options.ducttape = 0;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200703 igt_info("applying duct-tape\n");
Daniel Vetterc0f34332011-06-13 13:18:35 +0200704 break;
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200705 case TILESZ:
706 options.tile_size = atoi(optarg);
707 sanitize_tiles_per_buf();
Daniel Vetterc9c55452014-06-13 18:27:59 +0200708 igt_info("til size %i\n", options.tile_size);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200709 break;
Daniel Vetter10079562011-06-13 20:14:53 +0200710 case CHCK_RENDER:
711 options.check_render_cpyfn = 1;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200712 igt_info("checking render copy function\n");
Daniel Vetter10079562011-06-13 20:14:53 +0200713 break;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200714 }
715
Daniel Vetter72503282011-06-06 18:59:54 +0200716 /* actually 32767, according to docs, but that kills our nice pot calculations. */
717 options.max_dimension = 16*1024;
Chris Wilson3d66d912011-06-05 21:53:49 +0100718 if (options.use_render) {
719 if (IS_GEN2(devid) || IS_GEN3(devid))
720 options.max_dimension = 2048;
721 else
722 options.max_dimension = 8192;
723 }
Daniel Vetterc9c55452014-06-13 18:27:59 +0200724 igt_info("Limiting buffer to %dx%d\n", options.max_dimension, options.max_dimension);
Thomas Wood80d2c9b2014-07-21 15:57:16 +0100725
726 return 0;
Daniel Vetter22fe0982011-03-27 14:26:43 +0200727}
728
729static void init(void)
730{
731 int i;
Daniel Vetterbfa6f5d2011-03-25 21:54:02 +0100732 unsigned tmp;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100733
Daniel Vetter130daf92011-03-27 15:37:26 +0200734 if (options.num_buffers == 0) {
735 tmp = gem_aperture_size(drm_fd);
Ville Syrjälä8032f522014-12-03 14:51:16 +0200736 tmp = min(256 * (1024 * 1024), tmp);
Daniel Vetter130daf92011-03-27 15:37:26 +0200737 num_buffers = 2 * tmp / options.scratch_buf_size / 3;
738 num_buffers /= 2;
Daniel Vetterc9c55452014-06-13 18:27:59 +0200739 igt_info("using %u buffers\n", num_buffers);
Daniel Vetter130daf92011-03-27 15:37:26 +0200740 } else
741 num_buffers = options.num_buffers;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100742
743 bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
744 drm_intel_bufmgr_gem_enable_reuse(bufmgr);
Daniel Vettercd640cc2011-03-27 21:33:29 +0200745 drm_intel_bufmgr_gem_enable_fenced_relocs(bufmgr);
Daniel Vetter14e12b82013-09-12 14:21:56 +0200746 num_fences = gem_available_fences(drm_fd);
Matt Roper07be8fe2015-03-05 15:01:00 -0800747 igt_assert_lt(4, num_fences);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100748 batch = intel_batchbuffer_alloc(bufmgr, devid);
Daniel Vettera67091b2011-04-12 22:26:42 +0200749
Chris Wilson652d9eb2011-03-21 07:58:51 +0000750 busy_bo = drm_intel_bo_alloc(bufmgr, "tiled bo", BUSY_BUF_SIZE, 4096);
Daniel Vetteraa67b222012-01-10 14:59:58 +0100751 if (options.forced_tiling >= 0)
752 gem_set_tiling(drm_fd, busy_bo->handle, options.forced_tiling, 4096);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100753
754 for (i = 0; i < num_buffers; i++) {
Daniel Vetter22fe0982011-03-27 14:26:43 +0200755 init_buffer(&buffers[0][i], options.scratch_buf_size);
756 init_buffer(&buffers[1][i], options.scratch_buf_size);
757
758 num_total_tiles += buffers[0][i].num_tiles;
Daniel Vetter08cf5372011-03-19 21:34:55 +0100759 }
760 current_set = 0;
761
Daniel Vetter08cf5372011-03-19 21:34:55 +0100762 /* just in case it helps reproducability */
763 srandom(0xdeadbeef);
Daniel Vetter22fe0982011-03-27 14:26:43 +0200764}
765
Chris Wilson719ffef2011-05-22 10:34:12 +0100766static void check_render_copyfunc(void)
767{
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100768 struct igt_buf src, dst;
Chris Wilson719ffef2011-05-22 10:34:12 +0100769 uint32_t *ptr;
Chris Wilsonbfa23b42011-06-05 21:34:07 +0100770 int i, j, pass;
Chris Wilson719ffef2011-05-22 10:34:12 +0100771
Daniel Vetter10079562011-06-13 20:14:53 +0200772 if (!options.check_render_cpyfn)
773 return;
774
Chris Wilson719ffef2011-05-22 10:34:12 +0100775 init_buffer(&src, options.scratch_buf_size);
776 init_buffer(&dst, options.scratch_buf_size);
777
Chris Wilsonbfa23b42011-06-05 21:34:07 +0100778 for (pass = 0; pass < 16; pass++) {
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100779 int sx = random() % (igt_buf_width(&src)-options.tile_size);
780 int sy = random() % (igt_buf_height(&src)-options.tile_size);
781 int dx = random() % (igt_buf_width(&dst)-options.tile_size);
782 int dy = random() % (igt_buf_height(&dst)-options.tile_size);
Chris Wilson719ffef2011-05-22 10:34:12 +0100783
Chris Wilsonbfa23b42011-06-05 21:34:07 +0100784 if (options.use_cpu_maps)
785 set_to_cpu_domain(&src, 1);
Chris Wilson719ffef2011-05-22 10:34:12 +0100786
Chris Wilsonbfa23b42011-06-05 21:34:07 +0100787 memset(src.data, 0xff, options.scratch_buf_size);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200788 for (j = 0; j < options.tile_size; j++) {
Chris Wilsonbfa23b42011-06-05 21:34:07 +0100789 ptr = (uint32_t*)((char *)src.data + sx*4 + (sy+j) * src.stride);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200790 for (i = 0; i < options.tile_size; i++)
791 ptr[i] = j * options.tile_size + i;
Chris Wilsonbfa23b42011-06-05 21:34:07 +0100792 }
793
794 render_copyfunc(&src, sx, sy, &dst, dx, dy, 0);
795
796 if (options.use_cpu_maps)
797 set_to_cpu_domain(&dst, 0);
798
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200799 for (j = 0; j < options.tile_size; j++) {
Chris Wilsonbfa23b42011-06-05 21:34:07 +0100800 ptr = (uint32_t*)((char *)dst.data + dx*4 + (dy+j) * dst.stride);
Daniel Vetter5b253ce2011-06-13 20:09:38 +0200801 for (i = 0; i < options.tile_size; i++)
802 if (ptr[i] != j * options.tile_size + i) {
Daniel Vetterc9c55452014-06-13 18:27:59 +0200803 igt_info("render copyfunc mismatch at (%d, %d): found %d, expected %d\n", i, j, ptr[i], j * options.tile_size + i);
Chris Wilsonbfa23b42011-06-05 21:34:07 +0100804 }
805 }
Chris Wilson719ffef2011-05-22 10:34:12 +0100806 }
807}
808
809
Daniel Vetter22fe0982011-03-27 14:26:43 +0200810int main(int argc, char **argv)
811{
812 int i, j;
813 unsigned *current_permutation, *tmp_permutation;
Thomas Wood80d2c9b2014-07-21 15:57:16 +0100814 static struct option long_options[] = {
815 {"no-hw", 0, 0, 'd'},
816 {"buf-size", 1, 0, 's'},
817 {"gpu-busy-load", 1, 0, 'g'},
818 {"no-signals", 0, 0, 'S'},
819 {"buffer-count", 1, 0, 'c'},
820 {"trace-tile", 1, 0, 't'},
821 {"disable-blt", 0, 0, 'b'},
822 {"disable-render", 0, 0, 'r'},
823 {"untiled", 0, 0, 'u'},
824 {"x-tiled", 0, 0, 'x'},
825 {"use-cpu-maps", 0, 0, 'm'},
826 {"rounds", 1, 0, 'o'},
827 {"no-fail", 0, 0, 'f'},
828 {"tiles-per-buf", 0, 0, 'p'},
829 {"remove-duct-tape", 0, 0, DUCTAPE},
830 {"tile-size", 1, 0, TILESZ},
831 {"check-render-cpyfn", 0, 0, CHCK_RENDER},
832 {NULL, 0, 0, 0},
833 };
Daniel Vetter22fe0982011-03-27 14:26:43 +0200834
Thomas Wood80d2c9b2014-07-21 15:57:16 +0100835 options.scratch_buf_size = 256*4096;
836 options.no_hw = 0;
837 options.use_signal_helper = 1;
838 options.gpu_busy_load = 0;
839 options.num_buffers = 0;
840 options.trace_tile = -1;
841 options.use_render = 1;
842 options.use_blt = 1;
843 options.forced_tiling = -1;
844 options.use_cpu_maps = 0;
845 options.total_rounds = 512;
846 options.fail = 1;
847 options.ducttape = 1;
848 options.tile_size = 16;
849 options.tiles_per_buf = options.scratch_buf_size / TILE_BYTES(options.tile_size);
850 options.check_render_cpyfn = 0;
851
Thomas Wood8fb19782015-02-18 16:19:59 +0000852 igt_simple_init_parse_opts(&argc, argv,"ds:g:c:t:rbuxmo:fp:",
Damien Lespiaufd6846c2015-05-14 14:19:01 +0100853 long_options, NULL, parse_options, NULL);
Tim Gore8abca6f2014-06-20 11:28:12 +0100854
Micah Fedkec81d2932015-07-22 21:54:02 +0000855 drm_fd = drm_open_driver(DRIVER_INTEL);
Chris Wilson3d66d912011-06-05 21:53:49 +0100856 devid = intel_get_drm_devid(drm_fd);
857
Chris Wilson4227da82011-07-02 08:59:32 +0100858 /* start our little helper early before too may allocations occur */
Chris Wilson4227da82011-07-02 08:59:32 +0100859 if (options.use_signal_helper)
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200860 igt_fork_signal_helper();
Chris Wilson4227da82011-07-02 08:59:32 +0100861
Daniel Vetter22fe0982011-03-27 14:26:43 +0200862 init();
863
Chris Wilson719ffef2011-05-22 10:34:12 +0100864 check_render_copyfunc();
865
Daniel Vetter22fe0982011-03-27 14:26:43 +0200866 tile_permutation = malloc(num_total_tiles*sizeof(uint32_t));
867 current_permutation = malloc(num_total_tiles*sizeof(uint32_t));
868 tmp_permutation = malloc(num_total_tiles*sizeof(uint32_t));
Daniel Vetter83440952013-08-13 12:35:58 +0200869 igt_assert(tile_permutation);
870 igt_assert(current_permutation);
871 igt_assert(tmp_permutation);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100872
873 fan_out();
874
Daniel Vetter9649dd72011-06-07 22:30:03 +0200875 for (i = 0; i < options.total_rounds; i++) {
Daniel Vetterc9c55452014-06-13 18:27:59 +0200876 igt_info("round %i\n", i);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100877 if (i % 64 == 63) {
878 fan_in_and_check();
Daniel Vetterc9c55452014-06-13 18:27:59 +0200879 igt_info("everything correct after %i rounds\n", i + 1);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100880 }
881
882 target_set = (current_set + 1) & 1;
883 init_set(target_set);
884
Daniel Vetter22fe0982011-03-27 14:26:43 +0200885 for (j = 0; j < num_total_tiles; j++)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100886 current_permutation[j] = j;
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200887 igt_permute_array(current_permutation, num_total_tiles, exchange_uint);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100888
889 copy_tiles(current_permutation);
890
Daniel Vetter22fe0982011-03-27 14:26:43 +0200891 memcpy(tmp_permutation, tile_permutation, sizeof(unsigned)*num_total_tiles);
Daniel Vetter08cf5372011-03-19 21:34:55 +0100892
893 /* accumulate the permutations */
Daniel Vetter22fe0982011-03-27 14:26:43 +0200894 for (j = 0; j < num_total_tiles; j++)
Daniel Vetter08cf5372011-03-19 21:34:55 +0100895 tile_permutation[j] = current_permutation[tmp_permutation[j]];
896
897 current_set = target_set;
898 }
899
900 fan_in_and_check();
901
Daniel Vetterc9c55452014-06-13 18:27:59 +0200902 igt_info("num failed tiles %u, max incoherent bytes %zd\n", stats.num_failed, stats.max_failed_reads * sizeof(uint32_t));
Daniel Vetter336f85d2011-06-13 22:02:52 +0200903
Daniel Vetter08cf5372011-03-19 21:34:55 +0100904 intel_batchbuffer_free(batch);
905 drm_intel_bufmgr_destroy(bufmgr);
906
907 close(drm_fd);
908
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200909 igt_stop_signal_helper();
Chris Wilson4227da82011-07-02 08:59:32 +0100910
Daniel Vetter43065382014-10-02 11:18:20 +0200911 igt_exit();
Daniel Vetter08cf5372011-03-19 21:34:55 +0100912}