lib/igt.cocci: Add stanza for for_each_pipe
[platform/upstream/intel-gpu-tools.git] / tests / gem_render_copy_redux.c
1 /*
2  * Copyright © 2013-2014 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  *    Damien Lespiau <damien.lespiau@intel.com>
25  */
26
27 /*
28  * This file is an "advanced" test for the render_copy() function, a very simple
29  * workload for the 3D engine. The basic test in gem_render_copy.c is intentionally
30  * kept extremely simple to allow for aub instrumentation and to ease debugging of
31  * the render copy functions themselves. This test on the overhand aims to stress
32  * the execbuffer interface with a simple render workload.
33  */
34
35 #include <stdbool.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <sys/ioctl.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <fcntl.h>
42 #include <inttypes.h>
43 #include <errno.h>
44 #include <sys/stat.h>
45 #include <sys/time.h>
46 #include <getopt.h>
47
48 #include <drm.h>
49
50 #include "ioctl_wrappers.h"
51 #include "drmtest.h"
52 #include "intel_bufmgr.h"
53 #include "intel_batchbuffer.h"
54 #include "intel_io.h"
55 #include "intel_chipset.h"
56 #include "igt_aux.h"
57
58 #define WIDTH 512
59 #define STRIDE (WIDTH*4)
60 #define HEIGHT 512
61 #define SIZE (HEIGHT*STRIDE)
62
63 #define SRC_COLOR       0xffff00ff
64 #define DST_COLOR       0xfff0ff00
65
66 typedef struct {
67         int fd;
68         uint32_t devid;
69         drm_intel_bufmgr *bufmgr;
70         struct intel_batchbuffer *batch;
71         igt_render_copyfunc_t render_copy;
72         uint32_t linear[WIDTH * HEIGHT];
73 } data_t;
74
75 static void data_init(data_t *data)
76 {
77         data->fd = drm_open_any();
78         data->devid = intel_get_drm_devid(data->fd);
79
80         data->bufmgr = drm_intel_bufmgr_gem_init(data->fd, 4096);
81         igt_assert(data->bufmgr);
82
83         data->render_copy = igt_get_render_copyfunc(data->devid);
84         igt_require_f(data->render_copy,
85                       "no render-copy function\n");
86
87         data->batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
88         igt_assert(data->batch);
89 }
90
91 static void data_fini(data_t *data)
92 {
93          intel_batchbuffer_free(data->batch);
94          drm_intel_bufmgr_destroy(data->bufmgr);
95          close(data->fd);
96 }
97
98 static void scratch_buf_init(data_t *data, struct igt_buf *buf,
99                              int width, int height, int stride, uint32_t color)
100 {
101         drm_intel_bo *bo;
102         int i;
103
104         bo = drm_intel_bo_alloc(data->bufmgr, "", SIZE, 4096);
105         for (i = 0; i < width * height; i++)
106                 data->linear[i] = color;
107         gem_write(data->fd, bo->handle, 0, data->linear,
108                   sizeof(data->linear));
109
110         buf->bo = bo;
111         buf->stride = stride;
112         buf->tiling = I915_TILING_NONE;
113         buf->size = SIZE;
114 }
115
116 static void scratch_buf_fini(data_t *data, struct igt_buf *buf)
117 {
118         dri_bo_unreference(buf->bo);
119         memset(buf, 0, sizeof(*buf));
120 }
121
122 static void
123 scratch_buf_check(data_t *data, struct igt_buf *buf, int x, int y,
124                   uint32_t color)
125 {
126         uint32_t val;
127
128         gem_read(data->fd, buf->bo->handle, 0,
129                  data->linear, sizeof(data->linear));
130         val = data->linear[y * WIDTH + x];
131         igt_assert_f(val == color,
132                      "Expected 0x%08x, found 0x%08x at (%d,%d)\n",
133                      color, val, x, y);
134 }
135
136 static void copy(data_t *data)
137 {
138         struct igt_buf src, dst;
139
140         scratch_buf_init(data, &src, WIDTH, HEIGHT, STRIDE, SRC_COLOR);
141         scratch_buf_init(data, &dst, WIDTH, HEIGHT, STRIDE, DST_COLOR);
142
143         scratch_buf_check(data, &src, WIDTH / 2, HEIGHT / 2, SRC_COLOR);
144         scratch_buf_check(data, &dst, WIDTH / 2, HEIGHT / 2, DST_COLOR);
145
146         data->render_copy(data->batch, NULL,
147                           &src, 0, 0, WIDTH, HEIGHT,
148                           &dst, WIDTH / 2, HEIGHT / 2);
149
150         scratch_buf_check(data, &dst, 10, 10, DST_COLOR);
151         scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR);
152
153         scratch_buf_fini(data, &src);
154         scratch_buf_fini(data, &dst);
155 }
156
157 static void copy_flink(data_t *data)
158 {
159         data_t local;
160         struct igt_buf src, dst;
161         struct igt_buf local_src, local_dst;
162         struct igt_buf flink;
163         uint32_t name;
164
165         data_init(&local);
166
167         scratch_buf_init(data, &src, WIDTH, HEIGHT, STRIDE, 0);
168         scratch_buf_init(data, &dst, WIDTH, HEIGHT, STRIDE, DST_COLOR);
169
170         data->render_copy(data->batch, NULL,
171                           &src, 0, 0, WIDTH, HEIGHT,
172                           &dst, WIDTH, HEIGHT);
173
174         scratch_buf_init(&local, &local_src, WIDTH, HEIGHT, STRIDE, 0);
175         scratch_buf_init(&local, &local_dst, WIDTH, HEIGHT, STRIDE, SRC_COLOR);
176
177         local.render_copy(local.batch, NULL,
178                           &local_src, 0, 0, WIDTH, HEIGHT,
179                           &local_dst, WIDTH, HEIGHT);
180
181
182         drm_intel_bo_flink(local_dst.bo, &name);
183         flink = local_dst;
184         flink.bo = drm_intel_bo_gem_create_from_name(data->bufmgr, "flink", name);
185
186         data->render_copy(data->batch, NULL,
187                           &flink, 0, 0, WIDTH, HEIGHT,
188                           &dst, WIDTH / 2, HEIGHT / 2);
189
190         scratch_buf_check(data, &dst, 10, 10, DST_COLOR);
191         scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR);
192
193         scratch_buf_check(data, &dst, 10, 10, DST_COLOR);
194         scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR);
195
196         scratch_buf_fini(data, &src);
197         scratch_buf_fini(data, &flink);
198         scratch_buf_fini(data, &dst);
199
200         scratch_buf_fini(&local, &local_src);
201         scratch_buf_fini(&local, &local_dst);
202
203         data_fini(&local);
204 }
205
206 int main(int argc, char **argv)
207 {
208         data_t data = {0, };
209
210         igt_subtest_init(argc, argv);
211
212         igt_fixture {
213                 data_init(&data);
214         }
215
216         igt_subtest("normal") {
217                 int loop = 100;
218                 while (loop--)
219                         copy(&data);
220         }
221
222         igt_subtest("interruptible") {
223                 int loop = 100;
224                 igt_fork_signal_helper();
225                 while (loop--)
226                         copy(&data);
227                 igt_stop_signal_helper();
228         }
229
230         igt_subtest("flink") {
231                 int loop = 100;
232                 while (loop--)
233                         copy_flink(&data);
234         }
235
236         igt_subtest("flink-interruptible") {
237                 int loop = 100;
238                 igt_fork_signal_helper();
239                 while (loop--)
240                         copy_flink(&data);
241                 igt_stop_signal_helper();
242         }
243
244         igt_exit();
245
246         return 0;
247 }