Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 1 | /* |
| 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 Ursulin | b117783 | 2015-03-03 14:11:06 +0000 | [diff] [blame] | 36 | #include "intel_chipset.h" |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 37 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 38 | IGT_TEST_DESCRIPTION("Test page flips and tiling scenarios"); |
Thomas Wood | b2ac264 | 2014-11-28 11:02:44 +0000 | [diff] [blame] | 39 | |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 40 | typedef struct { |
| 41 | int drm_fd; |
| 42 | igt_display_t display; |
Tvrtko Ursulin | b117783 | 2015-03-03 14:11:06 +0000 | [diff] [blame] | 43 | int gen; |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 44 | } data_t; |
| 45 | |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 46 | static void |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 47 | fill_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode) |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 48 | { |
| 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 Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 56 | static igt_pipe_crc_t *_pipe_crc; |
| 57 | |
| 58 | static igt_pipe_crc_t *pipe_crc_new(int pipe) |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 59 | { |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 60 | 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 | |
| 71 | static void pipe_crc_free(void) |
| 72 | { |
| 73 | if (_pipe_crc) { |
| 74 | igt_pipe_crc_free(_pipe_crc); |
| 75 | _pipe_crc = NULL; |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | static 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 | |
| 96 | static void |
| 97 | test_flip_tiling(data_t *data, igt_output_t *output, uint64_t tiling[2]) |
| 98 | { |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 99 | drmModeModeInfo *mode; |
| 100 | igt_plane_t *primary; |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 101 | struct igt_fb fb[2]; |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 102 | igt_pipe_crc_t *pipe_crc; |
| 103 | igt_crc_t reference_crc, crc; |
| 104 | int fb_id, pipe, ret, width; |
| 105 | |
Chris Wilson | be6bb4c | 2014-09-07 15:52:10 +0100 | [diff] [blame] | 106 | pipe = output->config.pipe; |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 107 | pipe_crc = pipe_crc_new(pipe); |
Chris Wilson | be6bb4c | 2014-09-07 15:52:10 +0100 | [diff] [blame] | 108 | igt_output_set_pipe(output, pipe); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 109 | |
| 110 | mode = igt_output_get_mode(output); |
| 111 | primary = igt_output_get_plane(output, 0); |
| 112 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 113 | 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 Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 128 | fb_id = igt_create_fb(data->drm_fd, width, mode->vdisplay, |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 129 | DRM_FORMAT_XRGB8888, tiling[0], |
| 130 | &fb[0]); |
| 131 | igt_assert(fb_id); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 132 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 133 | /* 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 Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 138 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 139 | 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 Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 144 | igt_display_commit(&data->display); |
| 145 | igt_pipe_crc_collect_crc(pipe_crc, &reference_crc); |
| 146 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 147 | /* Commit the first fb. */ |
| 148 | igt_plane_set_fb(primary, &fb[0]); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 149 | igt_display_commit(&data->display); |
| 150 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 151 | /* Flip to the second fb. */ |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 152 | ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id, |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 153 | 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 Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 159 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 160 | wait_for_pageflip(data->drm_fd); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 161 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 162 | /* Get a crc and compare with the reference. */ |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 163 | igt_pipe_crc_collect_crc(pipe_crc, &crc); |
Daniel Vetter | e588f6d | 2015-02-27 20:37:29 +0100 | [diff] [blame] | 164 | igt_assert_crc_equal(&reference_crc, &crc); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 165 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 166 | /* Clean up. */ |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 167 | igt_plane_set_fb(primary, NULL); |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 168 | pipe_crc_free(); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 169 | igt_output_set_pipe(output, PIPE_ANY); |
| 170 | igt_display_commit(&data->display); |
| 171 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 172 | igt_remove_fb(data->drm_fd, &fb[0]); |
| 173 | igt_remove_fb(data->drm_fd, &fb[1]); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | static data_t data; |
Daniel Vetter | 4fbd49b | 2014-04-11 16:16:31 +0200 | [diff] [blame] | 177 | igt_output_t *output; |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 178 | |
| 179 | igt_main |
| 180 | { |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 181 | igt_skip_on_simulation(); |
| 182 | |
| 183 | igt_fixture { |
Imre Deak | c256af5 | 2014-09-18 18:31:29 +0300 | [diff] [blame] | 184 | data.drm_fd = drm_open_any_master(); |
Tvrtko Ursulin | b117783 | 2015-03-03 14:11:06 +0000 | [diff] [blame] | 185 | data.gen = intel_gen(intel_get_drm_devid(data.drm_fd)); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 186 | |
Daniel Vetter | 33f0884 | 2014-08-12 11:23:09 +0200 | [diff] [blame] | 187 | kmstest_set_vt_graphics_mode(); |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 188 | |
| 189 | igt_require_pipe_crc(); |
| 190 | igt_display_init(&data.display, data.drm_fd); |
| 191 | } |
| 192 | |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 193 | /* |
| 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 Vetter | 4fbd49b | 2014-04-11 16:16:31 +0200 | [diff] [blame] | 201 | igt_subtest_f("flip-changes-tiling") { |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 202 | uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_X_TILED, |
| 203 | LOCAL_DRM_FORMAT_MOD_NONE }; |
| 204 | |
Daniel Vetter | 4fbd49b | 2014-04-11 16:16:31 +0200 | [diff] [blame] | 205 | for_each_connected_output(&data.display, output) |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 206 | test_flip_tiling(&data, output, tiling); |
Tvrtko Ursulin | b117783 | 2015-03-03 14:11:06 +0000 | [diff] [blame] | 207 | } |
| 208 | |
| 209 | igt_subtest_f("flip-changes-tiling-Y") { |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 210 | uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Y_TILED, |
| 211 | LOCAL_DRM_FORMAT_MOD_NONE }; |
| 212 | |
Tvrtko Ursulin | b117783 | 2015-03-03 14:11:06 +0000 | [diff] [blame] | 213 | igt_require_fb_modifiers(data.drm_fd); |
| 214 | igt_require(data.gen >= 9); |
| 215 | |
| 216 | for_each_connected_output(&data.display, output) |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 217 | test_flip_tiling(&data, output, tiling); |
Tvrtko Ursulin | b117783 | 2015-03-03 14:11:06 +0000 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | igt_subtest_f("flip-changes-tiling-Yf") { |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 221 | uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Yf_TILED, |
| 222 | LOCAL_DRM_FORMAT_MOD_NONE }; |
| 223 | |
Tvrtko Ursulin | b117783 | 2015-03-03 14:11:06 +0000 | [diff] [blame] | 224 | igt_require_fb_modifiers(data.drm_fd); |
| 225 | igt_require(data.gen >= 9); |
| 226 | |
| 227 | for_each_connected_output(&data.display, output) |
Tvrtko Ursulin | 8a5736b | 2015-05-12 11:06:34 +0100 | [diff] [blame^] | 228 | 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 Vetter | 4fbd49b | 2014-04-11 16:16:31 +0200 | [diff] [blame] | 305 | } |
Ander Conselvan de Oliveira | ddf8cc1 | 2014-04-02 15:31:38 +0300 | [diff] [blame] | 306 | |
| 307 | igt_fixture { |
| 308 | igt_display_fini(&data.display); |
| 309 | } |
| 310 | } |