tests/gem_dummy_reloc_loop: some updates
[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 <assert.h>
32 #include <fcntl.h>
33 #include <inttypes.h>
34 #include <errno.h>
35 #include <sys/stat.h>
36 #include <sys/time.h>
37 #include "drm.h"
38 #include "i915_drm.h"
39 #include "drmtest.h"
40 #include "intel_bufmgr.h"
41 #include "intel_batchbuffer.h"
42 #include "intel_gpu_tools.h"
43 #include "i830_reg.h"
44
45 static drm_intel_bufmgr *bufmgr;
46 struct intel_batchbuffer *batch;
47 static drm_intel_bo *target_buffer;
48
49 /*
50  * Testcase: Basic check of ring<->cpu sync using a dummy reloc
51  *
52  * The last test (that randomly switches the ring) seems to be pretty effective
53  * at hitting the missed irq bug that's worked around with the HWSTAM irq write.
54  */
55
56
57 #define MI_COND_BATCH_BUFFER_END        (0x36<<23 | 1)
58 #define MI_DO_COMPARE                   (1<<21)
59 static void
60 dummy_reloc_loop(int ring)
61 {
62         int i;
63
64         for (i = 0; i < 0x100000; i++) {
65                 if (ring == I915_EXEC_RENDER) {
66                         BEGIN_BATCH(4);
67                         OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE);
68                         OUT_BATCH(0xffffffff); /* compare dword */
69                         OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
70                                         I915_GEM_DOMAIN_RENDER, 0);
71                         OUT_BATCH(MI_NOOP);
72                         ADVANCE_BATCH();
73                 } else {
74                         BEGIN_BATCH(4);
75                         OUT_BATCH(MI_FLUSH_DW | 1);
76                         OUT_BATCH(0); /* reserved */
77                         OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
78                                         I915_GEM_DOMAIN_RENDER, 0);
79                         OUT_BATCH(MI_NOOP | (1<<22) | (0xf));
80                         ADVANCE_BATCH();
81                 }
82                 intel_batchbuffer_flush_on_ring(batch, ring);
83
84                 drm_intel_bo_map(target_buffer, 0);
85                 // map to force completion
86                 drm_intel_bo_unmap(target_buffer);
87         }
88 }
89
90 static void
91 dummy_reloc_loop_random_ring(void)
92 {
93         int i;
94
95         srandom(0xdeadbeef);
96
97         for (i = 0; i < 0x100000; i++) {
98                 int ring = random() % 3 + 1;
99
100                 if (ring == I915_EXEC_RENDER) {
101                         BEGIN_BATCH(4);
102                         OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE);
103                         OUT_BATCH(0xffffffff); /* compare dword */
104                         OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
105                                         I915_GEM_DOMAIN_RENDER, 0);
106                         OUT_BATCH(MI_NOOP);
107                         ADVANCE_BATCH();
108                 } else {
109                         BEGIN_BATCH(4);
110                         OUT_BATCH(MI_FLUSH_DW | 1);
111                         OUT_BATCH(0); /* reserved */
112                         OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
113                                         I915_GEM_DOMAIN_RENDER, 0);
114                         OUT_BATCH(MI_NOOP | (1<<22) | (0xf));
115                         ADVANCE_BATCH();
116                 }
117                 intel_batchbuffer_flush_on_ring(batch, ring);
118
119                 drm_intel_bo_map(target_buffer, 0);
120                 // map to force waiting on rendering
121                 drm_intel_bo_unmap(target_buffer);
122         }
123 }
124
125 int main(int argc, char **argv)
126 {
127         int fd;
128         int devid;
129
130         drmtest_subtest_init(argc, argv);
131
132         fd = drm_open_any();
133         devid = intel_get_drm_devid(fd);
134         if (!HAS_BLT_RING(devid)) {
135                 fprintf(stderr, "not (yet) implemented for pre-snb\n");
136                 return 77;
137         }
138
139         bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
140         if (!bufmgr) {
141                 fprintf(stderr, "failed to init libdrm\n");
142                 exit(-1);
143         }
144         drm_intel_bufmgr_gem_enable_reuse(bufmgr);
145
146         batch = intel_batchbuffer_alloc(bufmgr, devid);
147         if (!batch) {
148                 fprintf(stderr, "failed to create batch buffer\n");
149                 exit(-1);
150         }
151
152         target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
153         if (!target_buffer) {
154                 fprintf(stderr, "failed to alloc target buffer\n");
155                 exit(-1);
156         }
157
158         if (drmtest_run_subtest("render")) {
159                 printf("running dummy loop on render\n");
160                 dummy_reloc_loop(I915_EXEC_RENDER);
161                 printf("dummy loop run on render completed\n");
162         }
163
164         if (drmtest_run_subtest("bsd")) {
165                 if (HAS_BSD_RING(devid)) {
166                         sleep(2);
167                         printf("running dummy loop on bsd\n");
168                         dummy_reloc_loop(I915_EXEC_BSD);
169                         printf("dummy loop run on bsd completed\n");
170                 }
171         }
172
173         if (drmtest_run_subtest("blt")) {
174                 if (HAS_BLT_RING(devid)) {
175                         sleep(2);
176                         printf("running dummy loop on blt\n");
177                         dummy_reloc_loop(I915_EXEC_BLT);
178                         printf("dummy loop run on blt completed\n");
179                 }
180         }
181
182         if (drmtest_run_subtest("mixed")) {
183                 if (HAS_BLT_RING(devid) && HAS_BSD_RING(devid)) {
184                         sleep(2);
185                         printf("running dummy loop on random rings\n");
186                         dummy_reloc_loop_random_ring();
187                         printf("dummy loop run on random rings completed\n");
188                 }
189         }
190
191         drm_intel_bo_unreference(target_buffer);
192         intel_batchbuffer_free(batch);
193         drm_intel_bufmgr_destroy(bufmgr);
194
195         close(fd);
196
197         return 0;
198 }