blob: 373c4d0bffda0d1bd354c7b5974647ed30430edd [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
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020072 gem_set_tiling(fd, handle, tiling, 1024);
Chris Wilson8f3f8622009-09-01 10:09:55 +010073
Daniel Vetterff93f352012-03-24 19:22:21 +010074 ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
Chris Wilson8f3f8622009-09-01 10:09:55 +010075
76 /* XXX: mmap_gtt pulls the bo into the GTT read domain. */
Daniel Vetter673e6b22012-01-10 16:05:34 +010077 gem_sync(fd, handle);
Chris Wilson8f3f8622009-09-01 10:09:55 +010078
79 return ptr;
80}
81
82static void *
83bo_copy (void *_arg)
84{
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020085 struct test *t = (struct test *)_arg;
86 int fd = t->fd;
Daniel Vetter2e9e27c2011-10-15 13:46:19 +020087 int n;
Chris Wilson8f3f8622009-09-01 10:09:55 +010088 char *a, *b;
89
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +020090 a = bo_create (fd, t->tiling);
91 b = bo_create (fd, t->tiling);
Chris Wilson8f3f8622009-09-01 10:09:55 +010092
Daniel Vetter2e9e27c2011-10-15 13:46:19 +020093 for (n = 0; n < 1000; n++) {
94 memcpy (a, b, OBJECT_SIZE);
Alan Coopersmith00751592012-01-06 15:45:28 -080095 sched_yield ();
Chris Wilson8f3f8622009-09-01 10:09:55 +010096 }
97
98 return NULL;
99}
100
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200101static void
102_bo_write_verify(struct test *t)
Chris Wilson8f3f8622009-09-01 10:09:55 +0100103{
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200104 int fd = t->fd;
105 int i, k;
106 volatile uint32_t **s;
107 uint32_t v;
108 unsigned int dwords = OBJECT_SIZE >> 2;
109 const char *tile_str[] = { "none", "x", "y" };
Chris Wilson8f3f8622009-09-01 10:09:55 +0100110
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200111 assert (t->tiling >= 0 && t->tiling <= I915_TILING_Y);
112 assert (t->num_surfaces > 0);
113
114 s = calloc(sizeof(**s), t->num_surfaces);
115
116 for (k = 0; k < t->num_surfaces; k++) {
117 s[k] = bo_create(fd, t->tiling);
118 }
119
120 for (k = 0; k < t->num_surfaces; k++) {
121 volatile uint32_t *a = s[k];
122
123 for (i = 0; i < dwords; i++) {
124 a[i] = i;
125 v = a[i];
126 if (v != i) {
127 printf("tiling %s: write failed at %d (%x)\n",
128 tile_str[t->tiling], i, v);
129 _exit(-1);
130 }
131 }
132
133 for (i = 0; i < dwords; i++) {
134 v = a[i];
135 if (v != i) {
136 printf("tiling %s: verify failed at %d (%x)\n",
137 tile_str[t->tiling], i, v);
138 exit(-2);
139 }
140 }
141 }
142
143 free(s);
144}
145
146static void *
147bo_write_verify(void *_arg)
148{
149 struct test *t = (struct test *)_arg;
150 int i;
151
152 for (i = 0; i < 10; i++)
153 _bo_write_verify(t);
154
155 return 0;
156}
157
158static int run_test(int threads_per_fence, void *f, int tiling,
159 int surfaces_per_thread)
160{
161 struct test t;
162 drm_i915_getparam_t gp;
163 pthread_t *threads;
164 int n, num_fences, num_threads;
165 int ret;
166
167 t.fd = drm_open_any();
168 t.tiling = tiling;
169 t.num_surfaces = surfaces_per_thread;
Chris Wilson8f3f8622009-09-01 10:09:55 +0100170
171 gp.param = I915_PARAM_NUM_FENCES_AVAIL;
172 gp.value = &num_fences;
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200173 ret = ioctl(t.fd, DRM_IOCTL_I915_GETPARAM, &gp);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100174 assert (ret == 0);
175
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200176 num_threads = threads_per_fence * num_fences;
Chris Wilson8f3f8622009-09-01 10:09:55 +0100177
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200178 printf("%s: threads %d, fences %d, tiling %d, surfaces per thread %d\n",
179 f == bo_copy ? "copy" : "write-verify", num_threads,
180 num_fences, tiling, surfaces_per_thread);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100181
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200182 if (threads_per_fence) {
183 threads = calloc(sizeof(*threads), num_threads);
184 assert (threads != NULL);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100185
Mika Kuoppalaee79b8f2013-03-27 12:48:07 +0200186 for (n = 0; n < num_threads; n++)
187 pthread_create (&threads[n], NULL, f, &t);
188
189 for (n = 0; n < num_threads; n++)
190 pthread_join (threads[n], NULL);
191 } else {
192 void *(*func)(void *) = f;
193 assert(func(&t) == (void *)0);
194 }
195
196 close(t.fd);
197
198 return 0;
199}
200
201int
202main(int argc, char **argv)
203{
204 drmtest_subtest_init(argc, argv);
205
206 if (drmtest_run_subtest("bo-write-verify-none"))
207 assert (run_test(0, bo_write_verify, I915_TILING_NONE, 80) == 0);
208
209 if (drmtest_run_subtest("bo-write-verify-x"))
210 assert (run_test(0, bo_write_verify, I915_TILING_X, 80) == 0);
211
212 if (drmtest_run_subtest("bo-write-verify-y"))
213 assert (run_test(0, bo_write_verify, I915_TILING_Y, 80) == 0);
214
215 if (drmtest_run_subtest("bo-write-verify-threaded-none"))
216 assert (run_test(5, bo_write_verify, I915_TILING_NONE, 2) == 0);
217
218 if (drmtest_run_subtest("bo-write-verify-threaded-x"))
219 assert (run_test(5, bo_write_verify, I915_TILING_X, 2) == 0);
220
221 if (drmtest_run_subtest("bo-write-verify-threaded-y"))
222 assert (run_test(5, bo_write_verify, I915_TILING_Y, 2) == 0);
223
224 if (drmtest_run_subtest("bo-copy"))
225 assert(run_test(1, bo_copy, I915_TILING_X, 1) == 0);
Chris Wilson8f3f8622009-09-01 10:09:55 +0100226
227 return 0;
228}