kms_rotation_crc: Remove useless comments
[platform/upstream/intel-gpu-tools.git] / tests / gem_ctx_exec.c
1 /*
2  * Copyright © 2012 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  *    Ben Widawsky <ben@bwidawsk.net>
25  *
26  */
27
28 /*
29  * This test covers basic context switch functionality
30  */
31
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <fcntl.h>
38 #include <inttypes.h>
39 #include <errno.h>
40 #include <sys/stat.h>
41 #include <sys/ioctl.h>
42 #include <sys/time.h>
43
44 #include <drm.h>
45
46 #include "ioctl_wrappers.h"
47 #include "drmtest.h"
48 #include "igt_aux.h"
49 #include "igt_debugfs.h"
50
51 struct local_drm_i915_gem_context_destroy {
52         __u32 ctx_id;
53         __u32 pad;
54 };
55
56 #define CONTEXT_DESTROY_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2e, struct local_drm_i915_gem_context_destroy)
57
58 static void context_destroy(int fd, uint32_t ctx_id)
59 {
60         struct local_drm_i915_gem_context_destroy destroy;
61         destroy.ctx_id = ctx_id;
62         do_ioctl(fd, CONTEXT_DESTROY_IOCTL, &destroy);
63 #include "igt_aux.h"
64 }
65
66 /* Copied from gem_exec_nop.c */
67 static int exec(int fd, uint32_t handle, int ring, int ctx_id)
68 {
69         struct drm_i915_gem_execbuffer2 execbuf;
70         struct drm_i915_gem_exec_object2 gem_exec;
71         int ret = 0;
72
73         gem_exec.handle = handle;
74         gem_exec.relocation_count = 0;
75         gem_exec.relocs_ptr = 0;
76         gem_exec.alignment = 0;
77         gem_exec.offset = 0;
78         gem_exec.flags = 0;
79         gem_exec.rsvd1 = 0;
80         gem_exec.rsvd2 = 0;
81
82         execbuf.buffers_ptr = (uintptr_t)&gem_exec;
83         execbuf.buffer_count = 1;
84         execbuf.batch_start_offset = 0;
85         execbuf.batch_len = 8;
86         execbuf.cliprects_ptr = 0;
87         execbuf.num_cliprects = 0;
88         execbuf.DR1 = 0;
89         execbuf.DR4 = 0;
90         execbuf.flags = ring;
91         i915_execbuffer2_set_context_id(execbuf, ctx_id);
92         execbuf.rsvd2 = 0;
93
94         ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2,
95                         &execbuf);
96
97         return ret;
98 }
99
100 static void big_exec(int fd, uint32_t handle, int ring)
101 {
102         struct drm_i915_gem_execbuffer2 execbuf;
103         struct drm_i915_gem_exec_object2 *gem_exec;
104         uint32_t ctx_id1, ctx_id2;
105         int num_buffers = gem_available_aperture_size(fd) / 4096;
106         int i;
107
108         /* Make sure we only fill half of RAM with gem objects. */
109         igt_require(intel_get_total_ram_mb() * 1024 / 2 > num_buffers * 4);
110
111         gem_exec = calloc(num_buffers + 1, sizeof(*gem_exec));
112         igt_assert(gem_exec);
113         memset(gem_exec, 0, (num_buffers + 1) * sizeof(*gem_exec));
114
115
116         ctx_id1 = gem_context_create(fd);
117         ctx_id2 = gem_context_create(fd);
118
119         gem_exec[0].handle = handle;
120
121
122         execbuf.buffers_ptr = (uintptr_t)gem_exec;
123         execbuf.buffer_count = num_buffers + 1;
124         execbuf.batch_start_offset = 0;
125         execbuf.batch_len = 8;
126         execbuf.cliprects_ptr = 0;
127         execbuf.num_cliprects = 0;
128         execbuf.DR1 = 0;
129         execbuf.DR4 = 0;
130         execbuf.flags = ring;
131         execbuf.rsvd2 = 0;
132
133         execbuf.buffer_count = 1;
134         i915_execbuffer2_set_context_id(execbuf, ctx_id1);
135         igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2,
136                             &execbuf) == 0);
137
138         for (i = 0; i < num_buffers; i++) {
139                 uint32_t tmp_handle = gem_create(fd, 4096);
140
141                 gem_exec[i].handle = tmp_handle;
142         }
143         gem_exec[i].handle = handle;
144         execbuf.buffer_count = i + 1;
145
146         /* figure out how many buffers we can exactly fit */
147         while (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2,
148                         &execbuf) != 0) {
149                 i--;
150                 gem_close(fd, gem_exec[i].handle);
151                 gem_exec[i].handle = handle;
152                 execbuf.buffer_count--;
153                 igt_info("trying buffer count %i\n", i - 1);
154         }
155
156         igt_info("reduced buffer count to %i from %i\n",
157                i - 1, num_buffers);
158
159         /* double check that it works */
160         igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2,
161                             &execbuf) == 0);
162
163         i915_execbuffer2_set_context_id(execbuf, ctx_id2);
164         igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2,
165                             &execbuf) == 0);
166         gem_sync(fd, handle);
167 }
168
169 uint32_t handle;
170 uint32_t batch[2] = {0, MI_BATCH_BUFFER_END};
171 uint32_t ctx_id;
172 int fd;
173
174 igt_main
175 {
176         igt_skip_on_simulation();
177                 igt_fixture {
178                 fd = drm_open_any_render();
179
180                 handle = gem_create(fd, 4096);
181
182                 /* check that we can create contexts. */
183                 ctx_id = gem_context_create(fd);
184                 context_destroy(fd, ctx_id);
185                 gem_write(fd, handle, 0, batch, sizeof(batch));
186         }
187
188         igt_subtest("basic") {
189                 ctx_id = gem_context_create(fd);
190                 igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0);
191                 gem_sync(fd, handle);
192                 context_destroy(fd, ctx_id);
193
194                 ctx_id = gem_context_create(fd);
195                 igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0);
196                 gem_sync(fd, handle);
197                 context_destroy(fd, ctx_id);
198
199                 igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) < 0);
200                 gem_sync(fd, handle);
201         }
202
203         igt_subtest("eviction")
204                 big_exec(fd, handle, I915_EXEC_RENDER);
205
206         igt_subtest("reset-pin-leak") {
207                 int i;
208
209                 /*
210                  * Use an explicit context to isolate the test from
211                  * any major code changes related to the per-file
212                  * default context (eg. if they would be eliminated).
213                  */
214                 ctx_id = gem_context_create(fd);
215
216                 /*
217                  * Iterate enough times that the kernel will
218                  * become unhappy if the ggtt pin count for
219                  * the last context is leaked at every reset.
220                  */
221                 for (i = 0; i < 20; i++) {
222                         igt_set_stop_rings(STOP_RING_DEFAULTS);
223                         igt_assert(exec(fd, handle, I915_EXEC_RENDER, 0) == 0);
224                         igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0);
225                         gem_sync(fd, handle);
226                 }
227
228                 context_destroy(fd, ctx_id);
229         }
230 }