blob: 01fd0f6e91e0be4859c0379edd36e12565fe1a60 [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>
37#include <assert.h>
38#include <fcntl.h>
39#include <inttypes.h>
40#include <errno.h>
41#include <sys/stat.h>
42#include <sys/ioctl.h>
43#include <sys/mman.h>
44#include <pthread.h>
45#include "drm.h"
46#include "i915_drm.h"
47#include "drmtest.h"
48
Daniel Vetter2e9e27c2011-10-15 13:46:19 +020049#define OBJECT_SIZE (128*1024) /* restricted to 1MiB alignment on i915 fences */
Chris Wilson8f3f8622009-09-01 10:09:55 +010050
51/* Before introduction of the LRU list for fences, allocation of a fence for a page
52 * fault would use the first inactive fence (i.e. in preference one with no outstanding
53 * GPU activity, or it would wait on the first to finish). Given the choice, it would simply
54 * reuse the fence that had just been allocated for the previous page-fault - the worst choice
55 * when copying between two buffers and thus constantly swapping fences.
56 */
57
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020058struct test {
59 int fd;
60 int tiling;
61 int num_surfaces;
62};
63
Chris Wilson8f3f8622009-09-01 10:09:55 +010064static void *
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020065bo_create (int fd, int tiling)
Chris Wilson8f3f8622009-09-01 10:09:55 +010066{
Chris Wilson8f3f8622009-09-01 10:09:55 +010067 void *ptr;
68 int handle;
Chris Wilson8f3f8622009-09-01 10:09:55 +010069
Daniel Vetterff93f352012-03-24 19:22:21 +010070 handle = gem_create(fd, OBJECT_SIZE);
Chris Wilson8f3f8622009-09-01 10:09:55 +010071
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +020072 /* dirty cpu caches a bit ... */
73 ptr = gem_mmap__cpu(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
74 assert(ptr);
75 memset(ptr, 0, OBJECT_SIZE);
76 munmap(ptr, OBJECT_SIZE);
77
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020078 gem_set_tiling(fd, handle, tiling, 1024);
Chris Wilson8f3f8622009-09-01 10:09:55 +010079
Daniel Vetterff93f352012-03-24 19:22:21 +010080 ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
Chris Wilson74f6e412013-03-27 11:32:47 +000081 assert(ptr);
Chris Wilson8f3f8622009-09-01 10:09:55 +010082
83 /* XXX: mmap_gtt pulls the bo into the GTT read domain. */
Daniel Vetter673e6b22012-01-10 16:05:34 +010084 gem_sync(fd, handle);
Chris Wilson8f3f8622009-09-01 10:09:55 +010085
86 return ptr;
87}
88
89static void *
90bo_copy (void *_arg)
91{
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020092 struct test *t = (struct test *)_arg;
93 int fd = t->fd;
Daniel Vetter2e9e27c2011-10-15 13:46:19 +020094 int n;
Chris Wilson8f3f8622009-09-01 10:09:55 +010095 char *a, *b;
96
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020097 a = bo_create (fd, t->tiling);
98 b = bo_create (fd, t->tiling);
Chris Wilson8f3f8622009-09-01 10:09:55 +010099
Daniel Vetter2e9e27c2011-10-15 13:46:19 +0200100 for (n = 0; n < 1000; n++) {
101 memcpy (a, b, OBJECT_SIZE);
Alan Coopersmith00751592012-01-06 15:45:28 -0800102 sched_yield ();
Chris Wilson8f3f8622009-09-01 10:09:55 +0100103 }
104
105 return NULL;
106}
107
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200108static void
109_bo_write_verify(struct test *t)
Chris Wilson8f3f8622009-09-01 10:09:55 +0100110{
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200111 int fd = t->fd;
112 int i, k;
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200113 uint32_t **s;
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200114 uint32_t v;
115 unsigned int dwords = OBJECT_SIZE >> 2;
116 const char *tile_str[] = { "none", "x", "y" };
Chris Wilson8f3f8622009-09-01 10:09:55 +0100117
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200118 assert (t->tiling >= 0 && t->tiling <= I915_TILING_Y);
119 assert (t->num_surfaces > 0);
120
Chris Wilson74f6e412013-03-27 11:32:47 +0000121 s = calloc(sizeof(*s), t->num_surfaces);
122 assert(s);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200123
Chris Wilson74f6e412013-03-27 11:32:47 +0000124 for (k = 0; k < t->num_surfaces; k++)
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200125 s[k] = bo_create(fd, t->tiling);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200126
127 for (k = 0; k < t->num_surfaces; k++) {
128 volatile uint32_t *a = s[k];
129
130 for (i = 0; i < dwords; i++) {
131 a[i] = i;
132 v = a[i];
133 if (v != i) {
134 printf("tiling %s: write failed at %d (%x)\n",
135 tile_str[t->tiling], i, v);
136 _exit(-1);
137 }
138 }
139
140 for (i = 0; i < dwords; i++) {
141 v = a[i];
142 if (v != i) {
143 printf("tiling %s: verify failed at %d (%x)\n",
144 tile_str[t->tiling], i, v);
145 exit(-2);
146 }
147 }
148 }
149
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200150 for (k = 0; k < t->num_surfaces; k++)
151 munmap(s[k], OBJECT_SIZE);
152
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200153 free(s);
154}
155
156static void *
157bo_write_verify(void *_arg)
158{
159 struct test *t = (struct test *)_arg;
160 int i;
161
162 for (i = 0; i < 10; i++)
163 _bo_write_verify(t);
164
165 return 0;
166}
167
168static int run_test(int threads_per_fence, void *f, int tiling,
169 int surfaces_per_thread)
170{
171 struct test t;
172 drm_i915_getparam_t gp;
173 pthread_t *threads;
174 int n, num_fences, num_threads;
175 int ret;
176
177 t.fd = drm_open_any();
178 t.tiling = tiling;
179 t.num_surfaces = surfaces_per_thread;
Chris Wilson8f3f8622009-09-01 10:09:55 +0100180
181 gp.param = I915_PARAM_NUM_FENCES_AVAIL;
182 gp.value = &num_fences;
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200183 ret = ioctl(t.fd, DRM_IOCTL_I915_GETPARAM, &gp);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100184 assert (ret == 0);
185
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200186 num_threads = threads_per_fence * num_fences;
Chris Wilson8f3f8622009-09-01 10:09:55 +0100187
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200188 printf("%s: threads %d, fences %d, tiling %d, surfaces per thread %d\n",
189 f == bo_copy ? "copy" : "write-verify", num_threads,
190 num_fences, tiling, surfaces_per_thread);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100191
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200192 if (threads_per_fence) {
193 threads = calloc(sizeof(*threads), num_threads);
194 assert (threads != NULL);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100195
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200196 for (n = 0; n < num_threads; n++)
197 pthread_create (&threads[n], NULL, f, &t);
198
199 for (n = 0; n < num_threads; n++)
200 pthread_join (threads[n], NULL);
201 } else {
202 void *(*func)(void *) = f;
203 assert(func(&t) == (void *)0);
204 }
205
206 close(t.fd);
207
208 return 0;
209}
210
211int
212main(int argc, char **argv)
213{
214 drmtest_subtest_init(argc, argv);
215
216 if (drmtest_run_subtest("bo-write-verify-none"))
217 assert (run_test(0, bo_write_verify, I915_TILING_NONE, 80) == 0);
218
219 if (drmtest_run_subtest("bo-write-verify-x"))
220 assert (run_test(0, bo_write_verify, I915_TILING_X, 80) == 0);
221
222 if (drmtest_run_subtest("bo-write-verify-y"))
223 assert (run_test(0, bo_write_verify, I915_TILING_Y, 80) == 0);
224
225 if (drmtest_run_subtest("bo-write-verify-threaded-none"))
226 assert (run_test(5, bo_write_verify, I915_TILING_NONE, 2) == 0);
227
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200228 if (drmtest_run_subtest("bo-write-verify-threaded-x")) {
229 assert (run_test(2, bo_write_verify, I915_TILING_X, 2) == 0);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200230 assert (run_test(5, bo_write_verify, I915_TILING_X, 2) == 0);
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200231 assert (run_test(10, bo_write_verify, I915_TILING_X, 2) == 0);
232 assert (run_test(20, bo_write_verify, I915_TILING_X, 2) == 0);
233 }
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200234
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200235 if (drmtest_run_subtest("bo-write-verify-threaded-y")) {
236 assert (run_test(2, bo_write_verify, I915_TILING_Y, 2) == 0);
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200237 assert (run_test(5, bo_write_verify, I915_TILING_Y, 2) == 0);
Daniel Vetter0a8bfbf2013-04-08 09:19:05 +0200238 assert (run_test(10, bo_write_verify, I915_TILING_Y, 2) == 0);
239 assert (run_test(20, bo_write_verify, I915_TILING_Y, 2) == 0);
240 }
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200241
242 if (drmtest_run_subtest("bo-copy"))
243 assert(run_test(1, bo_copy, I915_TILING_X, 1) == 0);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100244
245 return 0;
246}