blob: a5e967958ef0ccbb10d0442d2c2ce28089bbc536 [file] [log] [blame]
Chris Wilson8f3f8622009-09-01 10:09:55 +01001/*
2 * Copyright © 2008-9 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 * Eric Anholt <eric@anholt.net>
25 * Chris Wilson <chris@chris-wilson.co.uk>
26 *
27 */
28
Damien Lespiau7ee278f2013-02-20 14:40:07 +000029#ifdef HAVE_CONFIG_H
Alan Coopersmith504c4fa2012-01-06 15:45:29 -080030#include "config.h"
Damien Lespiau7ee278f2013-02-20 14:40:07 +000031#endif
Chris Wilson8f3f8622009-09-01 10:09:55 +010032
33#include <unistd.h>
34#include <stdlib.h>
35#include <stdio.h>
36#include <string.h>
Chris Wilson8f3f8622009-09-01 10:09:55 +010037#include <fcntl.h>
38#include <inttypes.h>
39#include <errno.h>
40#include <sys/stat.h>
41#include <sys/ioctl.h>
42#include <sys/mman.h>
43#include <pthread.h>
44#include "drm.h"
45#include "i915_drm.h"
46#include "drmtest.h"
47
Daniel Vetter2e9e27c2011-10-15 13:46:19 +020048#define OBJECT_SIZE (128*1024) /* restricted to 1MiB alignment on i915 fences */
Chris Wilson8f3f8622009-09-01 10:09:55 +010049
50/* Before introduction of the LRU list for fences, allocation of a fence for a page
51 * fault would use the first inactive fence (i.e. in preference one with no outstanding
52 * GPU activity, or it would wait on the first to finish). Given the choice, it would simply
53 * reuse the fence that had just been allocated for the previous page-fault - the worst choice
54 * when copying between two buffers and thus constantly swapping fences.
55 */
56
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020057struct test {
58 int fd;
59 int tiling;
60 int num_surfaces;
61};
62
Chris Wilson8f3f8622009-09-01 10:09:55 +010063static void *
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020064bo_create (int fd, int tiling)
Chris Wilson8f3f8622009-09-01 10:09:55 +010065{
Chris Wilson8f3f8622009-09-01 10:09:55 +010066 void *ptr;
67 int handle;
Chris Wilson8f3f8622009-09-01 10:09:55 +010068
Daniel Vetterff93f352012-03-24 19:22:21 +010069 handle = gem_create(fd, OBJECT_SIZE);
Chris Wilson8f3f8622009-09-01 10:09:55 +010070
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +020071 /* dirty cpu caches a bit ... */
72 ptr = gem_mmap__cpu(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
Daniel Vetter83440952013-08-13 12:35:58 +020073 igt_assert(ptr);
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +020074 memset(ptr, 0, OBJECT_SIZE);
75 munmap(ptr, OBJECT_SIZE);
76
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020077 gem_set_tiling(fd, handle, tiling, 1024);
Chris Wilson8f3f8622009-09-01 10:09:55 +010078
Daniel Vetterff93f352012-03-24 19:22:21 +010079 ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
Daniel Vetter83440952013-08-13 12:35:58 +020080 igt_assert(ptr);
Chris Wilson8f3f8622009-09-01 10:09:55 +010081
82 /* XXX: mmap_gtt pulls the bo into the GTT read domain. */
Daniel Vetter673e6b22012-01-10 16:05:34 +010083 gem_sync(fd, handle);
Chris Wilson8f3f8622009-09-01 10:09:55 +010084
85 return ptr;
86}
87
88static void *
89bo_copy (void *_arg)
90{
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020091 struct test *t = (struct test *)_arg;
92 int fd = t->fd;
Daniel Vetter2e9e27c2011-10-15 13:46:19 +020093 int n;
Chris Wilson8f3f8622009-09-01 10:09:55 +010094 char *a, *b;
95
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020096 a = bo_create (fd, t->tiling);
97 b = bo_create (fd, t->tiling);
Chris Wilson8f3f8622009-09-01 10:09:55 +010098
Daniel Vetter2e9e27c2011-10-15 13:46:19 +020099 for (n = 0; n < 1000; n++) {
100 memcpy (a, b, OBJECT_SIZE);
Alan Coopersmith00751592012-01-06 15:45:28 -0800101 sched_yield ();
Chris Wilson8f3f8622009-09-01 10:09:55 +0100102 }
103
104 return NULL;
105}
106
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200107static void
108_bo_write_verify(struct test *t)
Chris Wilson8f3f8622009-09-01 10:09:55 +0100109{
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200110 int fd = t->fd;
111 int i, k;
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200112 uint32_t **s;
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200113 uint32_t v;
114 unsigned int dwords = OBJECT_SIZE >> 2;
115 const char *tile_str[] = { "none", "x", "y" };
Chris Wilson8f3f8622009-09-01 10:09:55 +0100116
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200117 assert (t->tiling >= 0 && t->tiling <= I915_TILING_Y);
118 assert (t->num_surfaces > 0);
119
Chris Wilson74f6e412013-03-27 11:32:47 +0000120 s = calloc(sizeof(*s), t->num_surfaces);
Daniel Vetter83440952013-08-13 12:35:58 +0200121 igt_assert(s);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200122
Chris Wilson74f6e412013-03-27 11:32:47 +0000123 for (k = 0; k < t->num_surfaces; k++)
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200124 s[k] = bo_create(fd, t->tiling);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200125
126 for (k = 0; k < t->num_surfaces; k++) {
127 volatile uint32_t *a = s[k];
128
129 for (i = 0; i < dwords; i++) {
130 a[i] = i;
131 v = a[i];
132 if (v != i) {
133 printf("tiling %s: write failed at %d (%x)\n",
134 tile_str[t->tiling], i, v);
Daniel Vetter5e25fcc2013-08-13 12:56:06 +0200135 igt_fail(-1);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200136 }
137 }
138
139 for (i = 0; i < dwords; i++) {
140 v = a[i];
141 if (v != i) {
142 printf("tiling %s: verify failed at %d (%x)\n",
143 tile_str[t->tiling], i, v);
Daniel Vetter5e25fcc2013-08-13 12:56:06 +0200144 igt_fail(-2);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200145 }
146 }
147 }
148
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200149 for (k = 0; k < t->num_surfaces; k++)
150 munmap(s[k], OBJECT_SIZE);
151
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200152 free(s);
153}
154
155static void *
156bo_write_verify(void *_arg)
157{
158 struct test *t = (struct test *)_arg;
159 int i;
160
161 for (i = 0; i < 10; i++)
162 _bo_write_verify(t);
163
164 return 0;
165}
166
167static int run_test(int threads_per_fence, void *f, int tiling,
168 int surfaces_per_thread)
169{
170 struct test t;
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200171 pthread_t *threads;
172 int n, num_fences, num_threads;
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200173
174 t.fd = drm_open_any();
175 t.tiling = tiling;
176 t.num_surfaces = surfaces_per_thread;
Chris Wilson8f3f8622009-09-01 10:09:55 +0100177
Ville Syrjälä1d1f6832013-04-09 15:25:38 +0300178 num_fences = gem_available_fences(t.fd);
179 assert (num_fences > 0);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100180
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200181 num_threads = threads_per_fence * num_fences;
Chris Wilson8f3f8622009-09-01 10:09:55 +0100182
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200183 printf("%s: threads %d, fences %d, tiling %d, surfaces per thread %d\n",
184 f == bo_copy ? "copy" : "write-verify", num_threads,
185 num_fences, tiling, surfaces_per_thread);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100186
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200187 if (threads_per_fence) {
188 threads = calloc(sizeof(*threads), num_threads);
189 assert (threads != NULL);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100190
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200191 for (n = 0; n < num_threads; n++)
192 pthread_create (&threads[n], NULL, f, &t);
193
194 for (n = 0; n < num_threads; n++)
195 pthread_join (threads[n], NULL);
196 } else {
197 void *(*func)(void *) = f;
Daniel Vetter83440952013-08-13 12:35:58 +0200198 igt_assert(func(&t) == (void *)0);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200199 }
200
201 close(t.fd);
202
203 return 0;
204}
205
206int
207main(int argc, char **argv)
208{
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200209 igt_subtest_init(argc, argv);
210 igt_skip_on_simulation();
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200211
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200212 igt_subtest("bo-write-verify-none")
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200213 assert (run_test(0, bo_write_verify, I915_TILING_NONE, 80) == 0);
214
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200215 igt_subtest("bo-write-verify-x")
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200216 assert (run_test(0, bo_write_verify, I915_TILING_X, 80) == 0);
217
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200218 igt_subtest("bo-write-verify-y")
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200219 assert (run_test(0, bo_write_verify, I915_TILING_Y, 80) == 0);
220
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200221 igt_subtest("bo-write-verify-threaded-none")
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200222 assert (run_test(5, bo_write_verify, I915_TILING_NONE, 2) == 0);
223
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200224 igt_subtest("bo-write-verify-threaded-x") {
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200225 assert (run_test(2, bo_write_verify, I915_TILING_X, 2) == 0);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200226 assert (run_test(5, bo_write_verify, I915_TILING_X, 2) == 0);
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200227 assert (run_test(10, bo_write_verify, I915_TILING_X, 2) == 0);
228 assert (run_test(20, bo_write_verify, I915_TILING_X, 2) == 0);
229 }
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200230
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200231 igt_subtest("bo-write-verify-threaded-y") {
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200232 assert (run_test(2, bo_write_verify, I915_TILING_Y, 2) == 0);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200233 assert (run_test(5, bo_write_verify, I915_TILING_Y, 2) == 0);
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200234 assert (run_test(10, bo_write_verify, I915_TILING_Y, 2) == 0);
235 assert (run_test(20, bo_write_verify, I915_TILING_Y, 2) == 0);
236 }
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200237
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200238 igt_subtest("bo-copy")
Daniel Vetter83440952013-08-13 12:35:58 +0200239 igt_assert(run_test(1, bo_copy, I915_TILING_X, 1) == 0);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100240
Daniel Vettera1ca8ef2013-08-14 16:02:24 +0200241 igt_exit();
Chris Wilson8f3f8622009-09-01 10:09:55 +0100242}