blob: c7fd4de2996f872df9c401b83a62a9b10b6841e8 [file] [log] [blame]
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +03001/*
2 * Copyright © 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 * Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
25 */
26
27#include <errno.h>
28#include <stdbool.h>
29#include <stdio.h>
30#include <string.h>
31
32#include "drmtest.h"
33#include "igt_debugfs.h"
34#include "igt_kms.h"
35#include "ioctl_wrappers.h"
Tvrtko Ursulinb1177832015-03-03 14:11:06 +000036#include "intel_chipset.h"
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +030037
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +010038IGT_TEST_DESCRIPTION("Test page flips and tiling scenarios");
Thomas Woodb2ac2642014-11-28 11:02:44 +000039
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +030040typedef struct {
41 int drm_fd;
42 igt_display_t display;
Tvrtko Ursulinb1177832015-03-03 14:11:06 +000043 int gen;
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +030044} data_t;
45
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +030046static void
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +010047fill_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode)
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +030048{
49 cairo_t *cr;
50
51 cr = igt_get_cairo_ctx(data->drm_fd, fb);
52 igt_paint_test_pattern(cr, mode->hdisplay, mode->vdisplay);
53 cairo_destroy(cr);
54}
55
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +010056static igt_pipe_crc_t *_pipe_crc;
57
58static igt_pipe_crc_t *pipe_crc_new(int pipe)
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +030059{
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +010060 if (_pipe_crc) {
61 igt_pipe_crc_free(_pipe_crc);
62 _pipe_crc = NULL;
63 }
64
65 _pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
66 igt_assert(_pipe_crc);
67
68 return _pipe_crc;
69}
70
71static void pipe_crc_free(void)
72{
73 if (_pipe_crc) {
74 igt_pipe_crc_free(_pipe_crc);
75 _pipe_crc = NULL;
76 }
77}
78
79static void wait_for_pageflip(int fd)
80{
81 drmEventContext evctx = { .version = DRM_EVENT_CONTEXT_VERSION };
82 struct timeval timeout = { .tv_sec = 0, .tv_usec = 32000 };
83 fd_set fds;
84 int ret;
85
86 /* Wait for pageflip completion, then consume event on fd */
87 FD_ZERO(&fds);
88 FD_SET(fd, &fds);
89 do {
90 ret = select(fd + 1, &fds, NULL, NULL, &timeout);
91 } while (ret < 0 && errno == EINTR);
92 igt_assert_eq(ret, 1);
93 igt_assert(drmHandleEvent(fd, &evctx) == 0);
94}
95
96static void
97test_flip_tiling(data_t *data, igt_output_t *output, uint64_t tiling[2])
98{
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +030099 drmModeModeInfo *mode;
100 igt_plane_t *primary;
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100101 struct igt_fb fb[2];
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300102 igt_pipe_crc_t *pipe_crc;
103 igt_crc_t reference_crc, crc;
104 int fb_id, pipe, ret, width;
105
Chris Wilsonbe6bb4c2014-09-07 15:52:10 +0100106 pipe = output->config.pipe;
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100107 pipe_crc = pipe_crc_new(pipe);
Chris Wilsonbe6bb4c2014-09-07 15:52:10 +0100108 igt_output_set_pipe(output, pipe);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300109
110 mode = igt_output_get_mode(output);
111 primary = igt_output_get_plane(output, 0);
112
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100113 width = mode->hdisplay;
114
115 if (tiling[0] != tiling[1] &&
116 (tiling[0] != LOCAL_DRM_FORMAT_MOD_NONE ||
117 tiling[1] != LOCAL_DRM_FORMAT_MOD_NONE)) {
118 /*
119 * Since a page flip to a buffer with different stride
120 * doesn't work, choose width so that the stride of both
121 * buffers is the same.
122 */
123 width = 512;
124 while (width < mode->hdisplay)
125 width *= 2;
126 }
127
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300128 fb_id = igt_create_fb(data->drm_fd, width, mode->vdisplay,
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100129 DRM_FORMAT_XRGB8888, tiling[0],
130 &fb[0]);
131 igt_assert(fb_id);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300132
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100133 /* Second fb has different background so CRC does not match. */
134 fb_id = igt_create_color_fb(data->drm_fd, width, mode->vdisplay,
135 DRM_FORMAT_XRGB8888, tiling[1],
136 0.5, 0.5, 0.5, &fb[1]);
137 igt_assert(fb_id);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300138
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100139 fill_fb(&fb[0], data, mode);
140 fill_fb(&fb[1], data, mode);
141
142 /* Set the crtc and generate a reference CRC. */
143 igt_plane_set_fb(primary, &fb[1]);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300144 igt_display_commit(&data->display);
145 igt_pipe_crc_collect_crc(pipe_crc, &reference_crc);
146
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100147 /* Commit the first fb. */
148 igt_plane_set_fb(primary, &fb[0]);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300149 igt_display_commit(&data->display);
150
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100151 /* Flip to the second fb. */
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300152 ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id,
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100153 fb[1].fb_id, DRM_MODE_PAGE_FLIP_EVENT, NULL);
154 /*
155 * Page flip should work but some transitions may be temporarily
156 * on some kernels.
157 */
158 igt_require(ret == 0);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300159
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100160 wait_for_pageflip(data->drm_fd);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300161
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100162 /* Get a crc and compare with the reference. */
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300163 igt_pipe_crc_collect_crc(pipe_crc, &crc);
Daniel Vettere588f6d2015-02-27 20:37:29 +0100164 igt_assert_crc_equal(&reference_crc, &crc);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300165
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100166 /* Clean up. */
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300167 igt_plane_set_fb(primary, NULL);
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100168 pipe_crc_free();
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300169 igt_output_set_pipe(output, PIPE_ANY);
170 igt_display_commit(&data->display);
171
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100172 igt_remove_fb(data->drm_fd, &fb[0]);
173 igt_remove_fb(data->drm_fd, &fb[1]);
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300174}
175
176static data_t data;
Daniel Vetter4fbd49b2014-04-11 16:16:31 +0200177igt_output_t *output;
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300178
179igt_main
180{
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300181 igt_skip_on_simulation();
182
183 igt_fixture {
Imre Deakc256af52014-09-18 18:31:29 +0300184 data.drm_fd = drm_open_any_master();
Tvrtko Ursulinb1177832015-03-03 14:11:06 +0000185 data.gen = intel_gen(intel_get_drm_devid(data.drm_fd));
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300186
Daniel Vetter33f08842014-08-12 11:23:09 +0200187 kmstest_set_vt_graphics_mode();
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300188
189 igt_require_pipe_crc();
190 igt_display_init(&data.display, data.drm_fd);
191 }
192
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100193 /*
194 * Test that a page flip from a tiled buffer to a linear one works
195 * correctly. First, it sets the crtc with the linear buffer and
196 * generates a reference crc for the pipe. Then, the crtc is set with
197 * the tiled one and page flip to the linear one issued. A new crc is
198 * generated and compared to the reference one.
199 */
200
Daniel Vetter4fbd49b2014-04-11 16:16:31 +0200201 igt_subtest_f("flip-changes-tiling") {
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100202 uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_X_TILED,
203 LOCAL_DRM_FORMAT_MOD_NONE };
204
Daniel Vetter4fbd49b2014-04-11 16:16:31 +0200205 for_each_connected_output(&data.display, output)
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100206 test_flip_tiling(&data, output, tiling);
Tvrtko Ursulinb1177832015-03-03 14:11:06 +0000207 }
208
209 igt_subtest_f("flip-changes-tiling-Y") {
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100210 uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Y_TILED,
211 LOCAL_DRM_FORMAT_MOD_NONE };
212
Tvrtko Ursulinb1177832015-03-03 14:11:06 +0000213 igt_require_fb_modifiers(data.drm_fd);
214 igt_require(data.gen >= 9);
215
216 for_each_connected_output(&data.display, output)
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100217 test_flip_tiling(&data, output, tiling);
Tvrtko Ursulinb1177832015-03-03 14:11:06 +0000218 }
219
220 igt_subtest_f("flip-changes-tiling-Yf") {
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100221 uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Yf_TILED,
222 LOCAL_DRM_FORMAT_MOD_NONE };
223
Tvrtko Ursulinb1177832015-03-03 14:11:06 +0000224 igt_require_fb_modifiers(data.drm_fd);
225 igt_require(data.gen >= 9);
226
227 for_each_connected_output(&data.display, output)
Tvrtko Ursulin8a5736b2015-05-12 11:06:34 +0100228 test_flip_tiling(&data, output, tiling);
229 }
230
231 /*
232 * Test that a page flip from a tiled buffer to another tiled one works
233 * correctly. First, it sets the crtc with the tiled buffer and
234 * generates a reference crc for the pipe. Then a page flip to second
235 * tiled buffer is issued. A new crc is generated and compared to the
236 * reference one.
237 */
238
239 igt_subtest_f("flip-X-tiled") {
240 uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_X_TILED,
241 LOCAL_I915_FORMAT_MOD_X_TILED };
242
243 for_each_connected_output(&data.display, output)
244 test_flip_tiling(&data, output, tiling);
245 }
246
247 igt_subtest_f("flip-Y-tiled") {
248 uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Y_TILED,
249 LOCAL_I915_FORMAT_MOD_Y_TILED };
250
251 igt_require_fb_modifiers(data.drm_fd);
252 igt_require(data.gen >= 9);
253
254 for_each_connected_output(&data.display, output)
255 test_flip_tiling(&data, output, tiling);
256 }
257
258 igt_subtest_f("flip-Yf-tiled") {
259 uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Yf_TILED,
260 LOCAL_I915_FORMAT_MOD_Yf_TILED };
261
262 igt_require_fb_modifiers(data.drm_fd);
263 igt_require(data.gen >= 9);
264
265 for_each_connected_output(&data.display, output)
266 test_flip_tiling(&data, output, tiling);
267 }
268
269 /*
270 * Test that a page flip from a linear buffer to a tiled one works
271 * correctly. First, it sets the crtc with the linear buffer and
272 * generates a reference crc for the pipe. Then a page flip to a tiled
273 * buffer is issued. A new crc is generated and compared to the
274 * reference one.
275 */
276
277 igt_subtest_f("flip-to-X-tiled") {
278 uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE,
279 LOCAL_I915_FORMAT_MOD_X_TILED };
280
281 for_each_connected_output(&data.display, output)
282 test_flip_tiling(&data, output, tiling);
283 }
284
285 igt_subtest_f("flip-to-Y-tiled") {
286 uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE,
287 LOCAL_I915_FORMAT_MOD_Y_TILED };
288
289 igt_require_fb_modifiers(data.drm_fd);
290 igt_require(data.gen >= 9);
291
292 for_each_connected_output(&data.display, output)
293 test_flip_tiling(&data, output, tiling);
294 }
295
296 igt_subtest_f("flip-to-Yf-tiled") {
297 uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE,
298 LOCAL_I915_FORMAT_MOD_Yf_TILED };
299
300 igt_require_fb_modifiers(data.drm_fd);
301 igt_require(data.gen >= 9);
302
303 for_each_connected_output(&data.display, output)
304 test_flip_tiling(&data, output, tiling);
Daniel Vetter4fbd49b2014-04-11 16:16:31 +0200305 }
Ander Conselvan de Oliveiraddf8cc12014-04-02 15:31:38 +0300306
307 igt_fixture {
308 igt_display_fini(&data.display);
309 }
310}