kms_rotation_crc: Remove useless comments
[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 <errno.h>
29
30 #include <drm.h>
31
32 #include "drmtest.h"
33 #include "ioctl_wrappers.h"
34 #include "intel_chipset.h"
35
36 #ifndef I915_PARAM_CMD_PARSER_VERSION
37 #define I915_PARAM_CMD_PARSER_VERSION       28
38 #endif
39
40 static int __gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf)
41 {
42         if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf))
43                 return -errno;
44
45         return 0;
46 }
47
48 static void exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds,
49                                int size, int patch_offset, uint64_t expected_value)
50 {
51         struct drm_i915_gem_execbuffer2 execbuf;
52         struct drm_i915_gem_exec_object2 objs[2];
53         struct drm_i915_gem_relocation_entry reloc[1];
54
55         uint32_t target_bo = gem_create(fd, 4096);
56         uint64_t actual_value = 0;
57
58         gem_write(fd, cmd_bo, 0, cmds, size);
59
60         reloc[0].offset = patch_offset;
61         reloc[0].delta = 0;
62         reloc[0].target_handle = target_bo;
63         reloc[0].read_domains = I915_GEM_DOMAIN_RENDER;
64         reloc[0].write_domain = I915_GEM_DOMAIN_RENDER;
65         reloc[0].presumed_offset = 0;
66
67         objs[0].handle = target_bo;
68         objs[0].relocation_count = 0;
69         objs[0].relocs_ptr = 0;
70         objs[0].alignment = 0;
71         objs[0].offset = 0;
72         objs[0].flags = 0;
73         objs[0].rsvd1 = 0;
74         objs[0].rsvd2 = 0;
75
76         objs[1].handle = cmd_bo;
77         objs[1].relocation_count = 1;
78         objs[1].relocs_ptr = (uintptr_t)reloc;
79         objs[1].alignment = 0;
80         objs[1].offset = 0;
81         objs[1].flags = 0;
82         objs[1].rsvd1 = 0;
83         objs[1].rsvd2 = 0;
84
85         execbuf.buffers_ptr = (uintptr_t)objs;
86         execbuf.buffer_count = 2;
87         execbuf.batch_start_offset = 0;
88         execbuf.batch_len = size;
89         execbuf.cliprects_ptr = 0;
90         execbuf.num_cliprects = 0;
91         execbuf.DR1 = 0;
92         execbuf.DR4 = 0;
93         execbuf.flags = I915_EXEC_RENDER;
94         i915_execbuffer2_set_context_id(execbuf, 0);
95         execbuf.rsvd2 = 0;
96
97         gem_execbuf(fd, &execbuf);
98         gem_sync(fd, cmd_bo);
99
100         gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value));
101         igt_assert_eq(expected_value, actual_value);
102
103         gem_close(fd, target_bo);
104 }
105
106 static void exec_batch(int fd, uint32_t cmd_bo, uint32_t *cmds,
107                        int size, int ring, int expected_ret)
108 {
109         struct drm_i915_gem_execbuffer2 execbuf;
110         struct drm_i915_gem_exec_object2 objs[1];
111
112         gem_write(fd, cmd_bo, 0, cmds, size);
113
114         objs[0].handle = cmd_bo;
115         objs[0].relocation_count = 0;
116         objs[0].relocs_ptr = 0;
117         objs[0].alignment = 0;
118         objs[0].offset = 0;
119         objs[0].flags = 0;
120         objs[0].rsvd1 = 0;
121         objs[0].rsvd2 = 0;
122
123         execbuf.buffers_ptr = (uintptr_t)objs;
124         execbuf.buffer_count = 1;
125         execbuf.batch_start_offset = 0;
126         execbuf.batch_len = size;
127         execbuf.cliprects_ptr = 0;
128         execbuf.num_cliprects = 0;
129         execbuf.DR1 = 0;
130         execbuf.DR4 = 0;
131         execbuf.flags = ring;
132         i915_execbuffer2_set_context_id(execbuf, 0);
133         execbuf.rsvd2 = 0;
134
135         igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret);
136
137         gem_sync(fd, cmd_bo);
138 }
139
140 static void exec_split_batch(int fd, uint32_t *cmds,
141                              int size, int ring, int expected_ret)
142 {
143         struct drm_i915_gem_execbuffer2 execbuf;
144         struct drm_i915_gem_exec_object2 objs[1];
145         uint32_t cmd_bo;
146         uint32_t noop[1024] = { 0 };
147
148         // Allocate and fill a 2-page batch with noops
149         cmd_bo = gem_create(fd, 4096 * 2);
150         gem_write(fd, cmd_bo, 0, noop, sizeof(noop));
151         gem_write(fd, cmd_bo, 4096, noop, sizeof(noop));
152
153         // Write the provided commands such that the first dword
154         // of the command buffer is the last dword of the first
155         // page (i.e. the command is split across the two pages).
156         gem_write(fd, cmd_bo, 4096-sizeof(uint32_t), cmds, size);
157
158         objs[0].handle = cmd_bo;
159         objs[0].relocation_count = 0;
160         objs[0].relocs_ptr = 0;
161         objs[0].alignment = 0;
162         objs[0].offset = 0;
163         objs[0].flags = 0;
164         objs[0].rsvd1 = 0;
165         objs[0].rsvd2 = 0;
166
167         execbuf.buffers_ptr = (uintptr_t)objs;
168         execbuf.buffer_count = 1;
169         execbuf.batch_start_offset = 0;
170         execbuf.batch_len = size;
171         execbuf.cliprects_ptr = 0;
172         execbuf.num_cliprects = 0;
173         execbuf.DR1 = 0;
174         execbuf.DR4 = 0;
175         execbuf.flags = ring;
176         i915_execbuffer2_set_context_id(execbuf, 0);
177         execbuf.rsvd2 = 0;
178
179         igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret);
180
181         gem_sync(fd, cmd_bo);
182         gem_close(fd, cmd_bo);
183 }
184
185 uint32_t handle;
186 int fd;
187
188 #define MI_ARB_ON_OFF (0x8 << 23)
189 #define MI_DISPLAY_FLIP ((0x14 << 23) | 1)
190 #define MI_LOAD_REGISTER_IMM ((0x22 << 23) | 1)
191
192 #define GFX_OP_PIPE_CONTROL     ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
193 #define   PIPE_CONTROL_QW_WRITE (1<<14)
194 #define   PIPE_CONTROL_LRI_POST_OP (1<<23)
195
196 #define OACONTROL 0x2360
197
198 igt_main
199 {
200         igt_fixture {
201                 int parser_version = 0;
202                 drm_i915_getparam_t gp;
203                 int rc;
204
205                 fd = drm_open_any();
206
207                 gp.param = I915_PARAM_CMD_PARSER_VERSION;
208                 gp.value = &parser_version;
209                 rc = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
210                 igt_require(!rc && parser_version > 0);
211
212                 igt_require(gem_uses_aliasing_ppgtt(fd));
213
214                 handle = gem_create(fd, 4096);
215
216                 /* ATM cmd parser only exists on gen7. */
217                 igt_require(intel_gen(intel_get_drm_devid(fd)) == 7);
218         }
219
220         igt_subtest("basic-allowed") {
221                 uint32_t pc[] = {
222                         GFX_OP_PIPE_CONTROL,
223                         PIPE_CONTROL_QW_WRITE,
224                         0, // To be patched
225                         0x12000000,
226                         0,
227                         MI_BATCH_BUFFER_END,
228                 };
229                 exec_batch_patched(fd, handle,
230                                    pc, sizeof(pc),
231                                    8, // patch offset,
232                                    0x12000000);
233         }
234
235         igt_subtest("basic-rejected") {
236                 uint32_t arb_on_off[] = {
237                         MI_ARB_ON_OFF,
238                         MI_BATCH_BUFFER_END,
239                 };
240                 uint32_t display_flip[] = {
241                         MI_DISPLAY_FLIP,
242                         0, 0, 0,
243                         MI_BATCH_BUFFER_END,
244                         0
245                 };
246                 exec_batch(fd, handle,
247                            arb_on_off, sizeof(arb_on_off),
248                            I915_EXEC_RENDER,
249                            -EINVAL);
250                 exec_batch(fd, handle,
251                            arb_on_off, sizeof(arb_on_off),
252                            I915_EXEC_BSD,
253                            -EINVAL);
254                 if (gem_has_vebox(fd)) {
255                         exec_batch(fd, handle,
256                                    arb_on_off, sizeof(arb_on_off),
257                                    I915_EXEC_VEBOX,
258                                    -EINVAL);
259                 }
260                 exec_batch(fd, handle,
261                            display_flip, sizeof(display_flip),
262                            I915_EXEC_BLT,
263                            -EINVAL);
264         }
265
266         igt_subtest("registers") {
267                 uint32_t lri_bad[] = {
268                         MI_LOAD_REGISTER_IMM,
269                         0, // disallowed register address
270                         0x12000000,
271                         MI_BATCH_BUFFER_END,
272                 };
273                 uint32_t lri_ok[] = {
274                         MI_LOAD_REGISTER_IMM,
275                         0x5280, // allowed register address (SO_WRITE_OFFSET[0])
276                         0x1,
277                         MI_BATCH_BUFFER_END,
278                 };
279                 exec_batch(fd, handle,
280                            lri_bad, sizeof(lri_bad),
281                            I915_EXEC_RENDER,
282                            -EINVAL);
283                 exec_batch(fd, handle,
284                            lri_ok, sizeof(lri_ok),
285                            I915_EXEC_RENDER,
286                            0);
287         }
288
289         igt_subtest("bitmasks") {
290                 uint32_t pc[] = {
291                         GFX_OP_PIPE_CONTROL,
292                         (PIPE_CONTROL_QW_WRITE |
293                          PIPE_CONTROL_LRI_POST_OP),
294                         0, // To be patched
295                         0x12000000,
296                         0,
297                         MI_BATCH_BUFFER_END,
298                 };
299                 exec_batch(fd, handle,
300                            pc, sizeof(pc),
301                            I915_EXEC_RENDER,
302                            -EINVAL);
303         }
304
305         igt_subtest("batch-without-end") {
306                 uint32_t noop[1024] = { 0 };
307                 exec_batch(fd, handle,
308                            noop, sizeof(noop),
309                            I915_EXEC_RENDER,
310                            -EINVAL);
311         }
312
313         igt_subtest("cmd-crossing-page") {
314                 uint32_t lri_ok[] = {
315                         MI_LOAD_REGISTER_IMM,
316                         0x5280, // allowed register address (SO_WRITE_OFFSET[0])
317                         0x1,
318                         MI_BATCH_BUFFER_END,
319                 };
320                 exec_split_batch(fd,
321                                  lri_ok, sizeof(lri_ok),
322                                  I915_EXEC_RENDER,
323                                  0);
324         }
325
326         igt_subtest("oacontrol-tracking") {
327                 uint32_t lri_ok[] = {
328                         MI_LOAD_REGISTER_IMM,
329                         OACONTROL,
330                         0x31337000,
331                         MI_LOAD_REGISTER_IMM,
332                         OACONTROL,
333                         0x0,
334                         MI_BATCH_BUFFER_END,
335                         0
336                 };
337                 uint32_t lri_bad[] = {
338                         MI_LOAD_REGISTER_IMM,
339                         OACONTROL,
340                         0x31337000,
341                         MI_BATCH_BUFFER_END,
342                 };
343                 uint32_t lri_extra_bad[] = {
344                         MI_LOAD_REGISTER_IMM,
345                         OACONTROL,
346                         0x31337000,
347                         MI_LOAD_REGISTER_IMM,
348                         OACONTROL,
349                         0x0,
350                         MI_LOAD_REGISTER_IMM,
351                         OACONTROL,
352                         0x31337000,
353                         MI_BATCH_BUFFER_END,
354                 };
355                 exec_batch(fd, handle,
356                            lri_ok, sizeof(lri_ok),
357                            I915_EXEC_RENDER,
358                            0);
359                 exec_batch(fd, handle,
360                            lri_bad, sizeof(lri_bad),
361                            I915_EXEC_RENDER,
362                            -EINVAL);
363                 exec_batch(fd, handle,
364                            lri_extra_bad, sizeof(lri_extra_bad),
365                            I915_EXEC_RENDER,
366                            -EINVAL);
367         }
368
369         igt_fixture {
370                 gem_close(fd, handle);
371
372                 close(fd);
373         }
374 }