packaging: only on x86* arch
[platform/upstream/intel-gpu-tools.git] / tests / gem_dummy_reloc_loop.c
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  *    Daniel Vetter <daniel.vetter@ffwll.ch> (based on gem_storedw_*.c)
25  *
26  */
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <fcntl.h>
32 #include <inttypes.h>
33 #include <errno.h>
34 #include <sys/stat.h>
35 #include <sys/time.h>
36 #include "drm.h"
37 #include "ioctl_wrappers.h"
38 #include "drmtest.h"
39 #include "intel_bufmgr.h"
40 #include "intel_batchbuffer.h"
41 #include "intel_io.h"
42 #include "i830_reg.h"
43 #include "intel_chipset.h"
44
45 #define LOCAL_I915_EXEC_VEBOX (4<<0)
46
47 static drm_intel_bufmgr *bufmgr;
48 struct intel_batchbuffer *batch;
49 static drm_intel_bo *target_buffer;
50
51 #define NUM_FD  50
52
53 static int mfd[NUM_FD];
54 static drm_intel_bufmgr *mbufmgr[NUM_FD];
55 static struct intel_batchbuffer *mbatch[NUM_FD];
56 static drm_intel_bo *mbuffer[NUM_FD];
57
58 /*
59  * Testcase: Basic check of ring<->cpu sync using a dummy reloc
60  *
61  * The last test (that randomly switches the ring) seems to be pretty effective
62  * at hitting the missed irq bug that's worked around with the HWSTAM irq write.
63  */
64
65
66 #define MI_COND_BATCH_BUFFER_END        (0x36<<23 | 1)
67 #define MI_DO_COMPARE                   (1<<21)
68 static void
69 dummy_reloc_loop(int ring)
70 {
71         int i;
72
73         for (i = 0; i < 0x100000; i++) {
74                 BEGIN_BATCH(4, 1);
75                 if (ring == I915_EXEC_RENDER) {
76                         OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE);
77                         OUT_BATCH(0xffffffff); /* compare dword */
78                         OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
79                                         I915_GEM_DOMAIN_RENDER, 0);
80                         OUT_BATCH(MI_NOOP);
81                 } else {
82                         OUT_BATCH(MI_FLUSH_DW | 1);
83                         OUT_BATCH(0); /* reserved */
84                         OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
85                                         I915_GEM_DOMAIN_RENDER, 0);
86                         OUT_BATCH(MI_NOOP | (1<<22) | (0xf));
87                 }
88                 ADVANCE_BATCH();
89                 intel_batchbuffer_flush_on_ring(batch, ring);
90
91                 drm_intel_bo_map(target_buffer, 0);
92                 // map to force completion
93                 drm_intel_bo_unmap(target_buffer);
94         }
95 }
96
97 static void
98 dummy_reloc_loop_random_ring(int num_rings)
99 {
100         int i;
101
102         srandom(0xdeadbeef);
103
104         for (i = 0; i < 0x100000; i++) {
105                 int ring = random() % num_rings + 1;
106
107                 BEGIN_BATCH(4, 1);
108                 if (ring == I915_EXEC_RENDER) {
109                         OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE);
110                         OUT_BATCH(0xffffffff); /* compare dword */
111                         OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
112                                         I915_GEM_DOMAIN_RENDER, 0);
113                         OUT_BATCH(MI_NOOP);
114                 } else {
115                         OUT_BATCH(MI_FLUSH_DW | 1);
116                         OUT_BATCH(0); /* reserved */
117                         OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
118                                         I915_GEM_DOMAIN_RENDER, 0);
119                         OUT_BATCH(MI_NOOP | (1<<22) | (0xf));
120                 }
121                 ADVANCE_BATCH();
122                 intel_batchbuffer_flush_on_ring(batch, ring);
123
124                 drm_intel_bo_map(target_buffer, 0);
125                 // map to force waiting on rendering
126                 drm_intel_bo_unmap(target_buffer);
127         }
128 }
129
130 static void
131 dummy_reloc_loop_random_ring_multi_fd(int num_rings)
132 {
133         int i;
134         struct intel_batchbuffer *saved_batch;
135
136         saved_batch = batch;
137
138         srandom(0xdeadbeef);
139
140         for (i = 0; i < 0x100000; i++) {
141                 int mindex;
142                 int ring = random() % num_rings + 1;
143
144                 mindex = random() % NUM_FD;
145                 batch = mbatch[mindex];
146
147                 BEGIN_BATCH(4, 1);
148                 if (ring == I915_EXEC_RENDER) {
149                         OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE);
150                         OUT_BATCH(0xffffffff); /* compare dword */
151                         OUT_RELOC(mbuffer[mindex], I915_GEM_DOMAIN_RENDER,
152                                         I915_GEM_DOMAIN_RENDER, 0);
153                         OUT_BATCH(MI_NOOP);
154                 } else {
155                         OUT_BATCH(MI_FLUSH_DW | 1);
156                         OUT_BATCH(0); /* reserved */
157                         OUT_RELOC(mbuffer[mindex], I915_GEM_DOMAIN_RENDER,
158                                         I915_GEM_DOMAIN_RENDER, 0);
159                         OUT_BATCH(MI_NOOP | (1<<22) | (0xf));
160                 }
161                 ADVANCE_BATCH();
162                 intel_batchbuffer_flush_on_ring(batch, ring);
163
164                 drm_intel_bo_map(target_buffer, 0);
165                 // map to force waiting on rendering
166                 drm_intel_bo_unmap(target_buffer);
167         }
168
169         batch = saved_batch;
170 }
171
172 int fd;
173 int devid;
174 int num_rings;
175
176 igt_main
177 {
178         igt_skip_on_simulation();
179
180         igt_fixture {
181                 int i;
182                 fd = drm_open_any();
183                 devid = intel_get_drm_devid(fd);
184                 num_rings = gem_get_num_rings(fd);
185                 /* Not yet implemented on pre-snb. */
186                 igt_require(HAS_BLT_RING(devid));
187
188                 bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
189                 igt_assert(bufmgr);
190                 drm_intel_bufmgr_gem_enable_reuse(bufmgr);
191
192                 batch = intel_batchbuffer_alloc(bufmgr, devid);
193                 igt_assert(batch);
194
195                 target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
196                 igt_assert(target_buffer);
197
198                 /* Create multi drm_fd and map one gem object to multi gem_contexts */
199                 {
200                         unsigned int target_flink;
201                         char buffer_name[32];
202                         igt_assert(dri_bo_flink(target_buffer, &target_flink) == 0);
203
204                         for (i = 0; i < NUM_FD; i++) {
205                                 sprintf(buffer_name, "Target buffer %d\n", i);
206                                 mfd[i] = drm_open_any();
207                                 mbufmgr[i] = drm_intel_bufmgr_gem_init(mfd[i], 4096);
208                                 igt_assert_f(mbufmgr[i],
209                                              "fail to initialize buf manager "
210                                              "for drm_fd %d\n",
211                                              mfd[i]);
212                                 drm_intel_bufmgr_gem_enable_reuse(mbufmgr[i]);
213                                 mbatch[i] = intel_batchbuffer_alloc(mbufmgr[i], devid);
214                                 igt_assert_f(mbatch[i],
215                                              "fail to create batchbuffer "
216                                              "for drm_fd %d\n",
217                                              mfd[i]);
218                                 mbuffer[i] = intel_bo_gem_create_from_name(
219                                                                 mbufmgr[i],
220                                                                 buffer_name,
221                                                                 target_flink);
222                                 igt_assert_f(mbuffer[i],
223                                              "fail to create gem bo from global "
224                                              "gem_handle %d for drm_fd %d\n",
225                                              target_flink, mfd[i]);
226                         }
227                 }
228         }
229
230         igt_subtest("render") {
231                 igt_info("running dummy loop on render\n");
232                 dummy_reloc_loop(I915_EXEC_RENDER);
233                 igt_info("dummy loop run on render completed\n");
234         }
235
236         igt_subtest("bsd") {
237                 gem_require_ring(fd, I915_EXEC_BSD);
238                 sleep(2);
239                 igt_info("running dummy loop on bsd\n");
240                 dummy_reloc_loop(I915_EXEC_BSD);
241                 igt_info("dummy loop run on bsd completed\n");
242         }
243
244         igt_subtest("blt") {
245                 gem_require_ring(fd, I915_EXEC_BLT);
246                 sleep(2);
247                 igt_info("running dummy loop on blt\n");
248                 dummy_reloc_loop(I915_EXEC_BLT);
249                 igt_info("dummy loop run on blt completed\n");
250         }
251
252 #ifdef I915_EXEC_VEBOX
253         igt_subtest("vebox") {
254                 gem_require_ring(fd, I915_EXEC_VEBOX);
255                 sleep(2);
256                 igt_info("running dummy loop on vebox\n");
257                 dummy_reloc_loop(LOCAL_I915_EXEC_VEBOX);
258                 igt_info("dummy loop run on vebox completed\n");
259         }
260 #endif
261
262         igt_subtest("mixed") {
263                 if (num_rings > 1) {
264                         sleep(2);
265                         igt_info("running dummy loop on random rings\n");
266                         dummy_reloc_loop_random_ring(num_rings);
267                         igt_info("dummy loop run on random rings completed\n");
268                 }
269         }
270         igt_subtest("mixed_multi_fd") {
271                 if (num_rings > 1) {
272                         sleep(2);
273                         igt_info("running dummy loop on random rings based on "
274                                         "multi drm_fd\n");
275                         dummy_reloc_loop_random_ring_multi_fd(num_rings);
276                         igt_info("dummy loop run on random rings based on "
277                                         "multi drm_fd completed\n");
278                 }
279         }
280         igt_fixture {
281                 int i;
282                 /* Free the buffer/batchbuffer/buffer mgr for multi-fd */
283                 {
284                         for (i = 0; i < NUM_FD; i++) {
285                                 dri_bo_unreference(mbuffer[i]);
286                                 intel_batchbuffer_free(mbatch[i]);
287                                 drm_intel_bufmgr_destroy(mbufmgr[i]);
288                                 close(mfd[i]);
289                         }
290                 }
291                 drm_intel_bo_unreference(target_buffer);
292                 intel_batchbuffer_free(batch);
293                 drm_intel_bufmgr_destroy(bufmgr);
294
295                 close(fd);
296         }
297 }