tests/gem_exec_parse: Test for batches w/o MI_BATCH_BUFFER_END
[platform/upstream/intel-gpu-tools.git] / tests / gem_exec_parse.c
1 /*
2  * Copyright © 2013 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  */
24
25 #include <stdlib.h>
26 #include <stdint.h>
27 #include <stdio.h>
28 #include "drm.h"
29 #include "i915_drm.h"
30 #include "drmtest.h"
31
32 #ifndef I915_PARAM_CMD_PARSER_VERSION
33 #define I915_PARAM_CMD_PARSER_VERSION       28
34 #endif
35
36 static int exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds,
37                               int size, int patch_offset, uint64_t expected_value)
38 {
39         struct drm_i915_gem_execbuffer2 execbuf;
40         struct drm_i915_gem_exec_object2 objs[2];
41         struct drm_i915_gem_relocation_entry reloc[1];
42
43         uint32_t target_bo = gem_create(fd, 4096);
44         uint64_t actual_value = 0;
45
46         gem_write(fd, cmd_bo, 0, cmds, size);
47
48         reloc[0].offset = patch_offset;
49         reloc[0].delta = 0;
50         reloc[0].target_handle = target_bo;
51         reloc[0].read_domains = I915_GEM_DOMAIN_RENDER;
52         reloc[0].write_domain = I915_GEM_DOMAIN_RENDER;
53         reloc[0].presumed_offset = 0;
54
55         objs[0].handle = target_bo;
56         objs[0].relocation_count = 0;
57         objs[0].relocs_ptr = 0;
58         objs[0].alignment = 0;
59         objs[0].offset = 0;
60         objs[0].flags = 0;
61         objs[0].rsvd1 = 0;
62         objs[0].rsvd2 = 0;
63
64         objs[1].handle = cmd_bo;
65         objs[1].relocation_count = 1;
66         objs[1].relocs_ptr = (uintptr_t)reloc;
67         objs[1].alignment = 0;
68         objs[1].offset = 0;
69         objs[1].flags = 0;
70         objs[1].rsvd1 = 0;
71         objs[1].rsvd2 = 0;
72
73         execbuf.buffers_ptr = (uintptr_t)objs;
74         execbuf.buffer_count = 2;
75         execbuf.batch_start_offset = 0;
76         execbuf.batch_len = size;
77         execbuf.cliprects_ptr = 0;
78         execbuf.num_cliprects = 0;
79         execbuf.DR1 = 0;
80         execbuf.DR4 = 0;
81         execbuf.flags = I915_EXEC_RENDER;
82         i915_execbuffer2_set_context_id(execbuf, 0);
83         execbuf.rsvd2 = 0;
84
85         gem_execbuf(fd, &execbuf);
86         gem_sync(fd, cmd_bo);
87
88         gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value));
89         igt_assert(expected_value == actual_value);
90
91         gem_close(fd, target_bo);
92
93         return 1;
94 }
95
96 static int exec_batch(int fd, uint32_t cmd_bo, uint32_t *cmds,
97                       int size, int ring, int expected_ret)
98 {
99         struct drm_i915_gem_execbuffer2 execbuf;
100         struct drm_i915_gem_exec_object2 objs[1];
101         int ret;
102
103         gem_write(fd, cmd_bo, 0, cmds, size);
104
105         objs[0].handle = cmd_bo;
106         objs[0].relocation_count = 0;
107         objs[0].relocs_ptr = 0;
108         objs[0].alignment = 0;
109         objs[0].offset = 0;
110         objs[0].flags = 0;
111         objs[0].rsvd1 = 0;
112         objs[0].rsvd2 = 0;
113
114         execbuf.buffers_ptr = (uintptr_t)objs;
115         execbuf.buffer_count = 1;
116         execbuf.batch_start_offset = 0;
117         execbuf.batch_len = size;
118         execbuf.cliprects_ptr = 0;
119         execbuf.num_cliprects = 0;
120         execbuf.DR1 = 0;
121         execbuf.DR4 = 0;
122         execbuf.flags = ring;
123         i915_execbuffer2_set_context_id(execbuf, 0);
124         execbuf.rsvd2 = 0;
125
126         ret = drmIoctl(fd,
127                        DRM_IOCTL_I915_GEM_EXECBUFFER2,
128                        &execbuf);
129         if (ret == 0)
130                 igt_assert(expected_ret == 0);
131         else
132                 igt_assert(-errno == expected_ret);
133
134         gem_sync(fd, cmd_bo);
135
136         return 1;
137 }
138
139 uint32_t handle;
140 int fd;
141
142 #define MI_ARB_ON_OFF (0x8 << 23)
143 #define MI_DISPLAY_FLIP ((0x14 << 23) | 1)
144 #define MI_LOAD_REGISTER_IMM ((0x22 << 23) | 1)
145
146 #define GFX_OP_PIPE_CONTROL     ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
147 #define   PIPE_CONTROL_QW_WRITE (1<<14)
148 #define   PIPE_CONTROL_LRI_POST_OP (1<<23)
149
150 igt_main
151 {
152         igt_fixture {
153                 int parser_version = 0;
154                 drm_i915_getparam_t gp;
155                 int rc;
156
157                 fd = drm_open_any();
158
159                 gp.param = I915_PARAM_CMD_PARSER_VERSION;
160                 gp.value = &parser_version;
161                 rc = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
162                 igt_require(!rc && parser_version > 0);
163
164                 handle = gem_create(fd, 4096);
165         }
166
167         igt_subtest("basic-allowed") {
168                 uint32_t pc[] = {
169                         GFX_OP_PIPE_CONTROL,
170                         PIPE_CONTROL_QW_WRITE,
171                         0, // To be patched
172                         0x12000000,
173                         0,
174                         MI_BATCH_BUFFER_END,
175                 };
176                 igt_assert(
177                         exec_batch_patched(fd, handle,
178                                            pc, sizeof(pc),
179                                            8, // patch offset,
180                                            0x12000000));
181         }
182
183         igt_subtest("basic-rejected") {
184                 uint32_t arb_on_off[] = {
185                         MI_ARB_ON_OFF,
186                         MI_BATCH_BUFFER_END,
187                 };
188                 uint32_t display_flip[] = {
189                         MI_DISPLAY_FLIP,
190                         0, 0, 0,
191                         MI_BATCH_BUFFER_END,
192                         0
193                 };
194                 igt_assert(
195                            exec_batch(fd, handle,
196                                       arb_on_off, sizeof(arb_on_off),
197                                       I915_EXEC_RENDER,
198                                       -EINVAL));
199                 igt_assert(
200                            exec_batch(fd, handle,
201                                       arb_on_off, sizeof(arb_on_off),
202                                       I915_EXEC_BSD,
203                                       -EINVAL));
204                 if (gem_has_vebox(fd)) {
205                         igt_assert(
206                                    exec_batch(fd, handle,
207                                               arb_on_off, sizeof(arb_on_off),
208                                               I915_EXEC_VEBOX,
209                                               -EINVAL));
210                 }
211                 igt_assert(
212                            exec_batch(fd, handle,
213                                       display_flip, sizeof(display_flip),
214                                       I915_EXEC_BLT,
215                                       -EINVAL));
216         }
217
218         igt_subtest("registers") {
219                 uint32_t lri_bad[] = {
220                         MI_LOAD_REGISTER_IMM,
221                         0, // disallowed register address
222                         0x12000000,
223                         MI_BATCH_BUFFER_END,
224                 };
225                 uint32_t lri_ok[] = {
226                         MI_LOAD_REGISTER_IMM,
227                         0x5280, // allowed register address (SO_WRITE_OFFSET[0])
228                         0x1,
229                         MI_BATCH_BUFFER_END,
230                 };
231                 igt_assert(
232                            exec_batch(fd, handle,
233                                       lri_bad, sizeof(lri_bad),
234                                       I915_EXEC_RENDER,
235                                       -EINVAL));
236                 igt_assert(
237                            exec_batch(fd, handle,
238                                       lri_ok, sizeof(lri_ok),
239                                       I915_EXEC_RENDER,
240                                       0));
241         }
242
243         igt_subtest("bitmasks") {
244                 uint32_t pc[] = {
245                         GFX_OP_PIPE_CONTROL,
246                         (PIPE_CONTROL_QW_WRITE |
247                          PIPE_CONTROL_LRI_POST_OP),
248                         0, // To be patched
249                         0x12000000,
250                         0,
251                         MI_BATCH_BUFFER_END,
252                 };
253                 igt_assert(
254                            exec_batch(fd, handle,
255                                       pc, sizeof(pc),
256                                       I915_EXEC_RENDER,
257                                       -EINVAL));
258         }
259
260         igt_subtest("batch-without-end") {
261                 uint32_t noop[1024] = { 0 };
262                 igt_assert(
263                            exec_batch(fd, handle,
264                                       noop, sizeof(noop),
265                                       I915_EXEC_RENDER,
266                                       -EINVAL));
267         }
268
269         igt_fixture {
270                 gem_close(fd, handle);
271
272                 close(fd);
273         }
274 }