Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 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 | |
Thomas Wood | 804e11f | 2015-08-17 17:57:43 +0100 | [diff] [blame] | 25 | #include "igt.h" |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 26 | #include <errno.h> |
Ville Syrjälä | fee27cf | 2014-01-13 17:05:19 +0200 | [diff] [blame] | 27 | #include <limits.h> |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 28 | #include <stdbool.h> |
| 29 | #include <stdio.h> |
| 30 | #include <string.h> |
| 31 | |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 32 | |
Thomas Wood | 3d0dca4 | 2014-10-13 11:40:12 +0100 | [diff] [blame] | 33 | IGT_TEST_DESCRIPTION( |
| 34 | "Use the display CRC support to validate cursor plane functionality. " |
| 35 | "The test will position the cursor plane either fully onscreen, " |
| 36 | "partially onscreen, or fully offscreen, using either a fully opaque " |
| 37 | "or fully transparent surface. In each case it then reads the PF CRC " |
| 38 | "and compares it with the CRC value obtained when the cursor plane " |
| 39 | "was disabled."); |
| 40 | |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 41 | #ifndef DRM_CAP_CURSOR_WIDTH |
| 42 | #define DRM_CAP_CURSOR_WIDTH 0x8 |
| 43 | #endif |
| 44 | #ifndef DRM_CAP_CURSOR_HEIGHT |
| 45 | #define DRM_CAP_CURSOR_HEIGHT 0x9 |
| 46 | #endif |
| 47 | |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 48 | typedef struct { |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 49 | int drm_fd; |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 50 | igt_display_t display; |
Daniel Vetter | 9aea7ae | 2014-03-26 09:18:11 +0100 | [diff] [blame] | 51 | struct igt_fb primary_fb; |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 52 | struct igt_fb fb; |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 53 | igt_output_t *output; |
| 54 | enum pipe pipe; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 55 | igt_crc_t ref_crc; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 56 | int left, right, top, bottom; |
Antti Koskipaa | 795eddc | 2014-04-10 15:08:09 +0300 | [diff] [blame] | 57 | int screenw, screenh; |
Matt Roper | cd99dde | 2015-10-15 16:54:32 -0700 | [diff] [blame] | 58 | int refresh; |
Antti Koskipaa | fe8041b | 2014-04-10 15:08:07 +0300 | [diff] [blame] | 59 | int curw, curh; /* cursor size */ |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 60 | int cursor_max_w, cursor_max_h; |
Ville Syrjälä | f6e8697 | 2014-04-24 19:07:18 +0300 | [diff] [blame] | 61 | igt_pipe_crc_t *pipe_crc; |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 62 | uint32_t devid; |
Daniel Vetter | a5c6b8d | 2015-03-13 18:02:45 +0100 | [diff] [blame] | 63 | unsigned flags; |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 64 | } data_t; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 65 | |
Daniel Vetter | a5c6b8d | 2015-03-13 18:02:45 +0100 | [diff] [blame] | 66 | #define TEST_DPMS (1<<0) |
| 67 | #define TEST_SUSPEND (1<<1) |
| 68 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 69 | static void draw_cursor(cairo_t *cr, int x, int y, int cw, int ch) |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 70 | { |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 71 | int wl, wr, ht, hb; |
| 72 | |
| 73 | /* deal with odd cursor width/height */ |
| 74 | wl = cw / 2; |
| 75 | wr = (cw + 1) / 2; |
| 76 | ht = ch / 2; |
| 77 | hb = (ch + 1) / 2; |
| 78 | |
Antti Koskipaa | 795eddc | 2014-04-10 15:08:09 +0300 | [diff] [blame] | 79 | /* Cairo doesn't like to be fed numbers that are too wild */ |
| 80 | if ((x < SHRT_MIN) || (x > SHRT_MAX) || (y < SHRT_MIN) || (y > SHRT_MAX)) |
| 81 | return; |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 82 | cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); |
| 83 | /* 4 color rectangles in the corners, RGBY */ |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 84 | igt_paint_color_alpha(cr, x, y, wl, ht, 1.0, 0.0, 0.0, 1.0); |
| 85 | igt_paint_color_alpha(cr, x + wl, y, wr, ht, 0.0, 1.0, 0.0, 1.0); |
| 86 | igt_paint_color_alpha(cr, x, y + ht, wl, hb, 0.0, 0.0, 1.0, 1.0); |
| 87 | igt_paint_color_alpha(cr, x + wl, y + ht, wr, hb, 0.5, 0.5, 0.5, 1.0); |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 88 | } |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 89 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 90 | static void cursor_enable(data_t *data) |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 91 | { |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 92 | igt_output_t *output = data->output; |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 93 | igt_plane_t *cursor; |
| 94 | |
Robert Foss | da67e73 | 2017-01-10 18:44:19 -0500 | [diff] [blame] | 95 | cursor = igt_output_get_plane_type(output, DRM_PLANE_TYPE_CURSOR); |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 96 | igt_plane_set_fb(cursor, &data->fb); |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 97 | igt_plane_set_size(cursor, data->curw, data->curh); |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 98 | } |
| 99 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 100 | static void cursor_disable(data_t *data) |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 101 | { |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 102 | igt_output_t *output = data->output; |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 103 | igt_plane_t *cursor; |
| 104 | |
Robert Foss | da67e73 | 2017-01-10 18:44:19 -0500 | [diff] [blame] | 105 | cursor = igt_output_get_plane_type(output, DRM_PLANE_TYPE_CURSOR); |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 106 | igt_plane_set_fb(cursor, NULL); |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 107 | } |
| 108 | |
Maarten Lankhorst | 6fcc8e8 | 2017-06-14 10:17:31 +0200 | [diff] [blame] | 109 | static bool chv_cursor_broken(data_t *data, int x) |
| 110 | { |
| 111 | /* |
| 112 | * CHV gets a FIFO underrun on pipe C when cursor x coordinate |
| 113 | * is negative and the cursor visible. |
| 114 | * |
| 115 | * i915 is fixed to return -EINVAL on cursor updates with those |
| 116 | * negative coordinates, so require cursor update to fail with |
| 117 | * -EINVAL in that case. |
| 118 | * |
| 119 | * See also kms_chv_cursor_fail.c |
| 120 | */ |
| 121 | if (x >= 0) |
| 122 | return false; |
| 123 | |
| 124 | return IS_CHERRYVIEW(data->devid) && data->pipe == PIPE_C; |
| 125 | } |
| 126 | |
| 127 | static bool cursor_visible(data_t *data, int x, int y) |
| 128 | { |
| 129 | if (x + data->curw <= 0 || y + data->curh <= 0) |
| 130 | return false; |
| 131 | |
| 132 | if (x >= data->screenw || y >= data->screenh) |
| 133 | return false; |
| 134 | |
| 135 | return true; |
| 136 | } |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 137 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 138 | static void do_single_test(data_t *data, int x, int y) |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 139 | { |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 140 | igt_display_t *display = &data->display; |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 141 | igt_pipe_crc_t *pipe_crc = data->pipe_crc; |
Antti Koskipaa | 795eddc | 2014-04-10 15:08:09 +0300 | [diff] [blame] | 142 | igt_crc_t crc, ref_crc; |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 143 | igt_plane_t *cursor; |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 144 | cairo_t *cr; |
Maarten Lankhorst | 6fcc8e8 | 2017-06-14 10:17:31 +0200 | [diff] [blame] | 145 | int ret = 0; |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 146 | |
Thomas Wood | 6a8d33c | 2014-09-30 17:05:39 +0100 | [diff] [blame] | 147 | igt_print_activity(); |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 148 | |
Antti Koskipaa | 795eddc | 2014-04-10 15:08:09 +0300 | [diff] [blame] | 149 | /* Hardware test */ |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 150 | cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 151 | igt_paint_test_pattern(cr, data->screenw, data->screenh); |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 152 | igt_put_cairo_ctx(data->drm_fd, &data->primary_fb, cr); |
| 153 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 154 | cursor_enable(data); |
Robert Foss | da67e73 | 2017-01-10 18:44:19 -0500 | [diff] [blame] | 155 | cursor = igt_output_get_plane_type(data->output, DRM_PLANE_TYPE_CURSOR); |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 156 | igt_plane_set_position(cursor, x, y); |
Maarten Lankhorst | 6fcc8e8 | 2017-06-14 10:17:31 +0200 | [diff] [blame] | 157 | |
| 158 | if (chv_cursor_broken(data, x) && cursor_visible(data, x, y)) { |
| 159 | ret = igt_display_try_commit2(display, COMMIT_LEGACY); |
| 160 | igt_assert_eq(ret, -EINVAL); |
| 161 | igt_plane_set_position(cursor, 0, y); |
| 162 | |
| 163 | return; |
| 164 | } |
| 165 | |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 166 | igt_display_commit(display); |
Maarten Lankhorst | 6fcc8e8 | 2017-06-14 10:17:31 +0200 | [diff] [blame] | 167 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 168 | igt_wait_for_vblank(data->drm_fd, data->pipe); |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 169 | igt_pipe_crc_collect_crc(pipe_crc, &crc); |
Daniel Vetter | a5c6b8d | 2015-03-13 18:02:45 +0100 | [diff] [blame] | 170 | |
| 171 | if (data->flags & (TEST_DPMS | TEST_SUSPEND)) { |
| 172 | igt_crc_t crc_after; |
| 173 | |
| 174 | if (data->flags & TEST_DPMS) { |
| 175 | igt_debug("dpms off/on cycle\n"); |
| 176 | kmstest_set_connector_dpms(data->drm_fd, |
| 177 | data->output->config.connector, |
| 178 | DRM_MODE_DPMS_OFF); |
| 179 | kmstest_set_connector_dpms(data->drm_fd, |
| 180 | data->output->config.connector, |
| 181 | DRM_MODE_DPMS_ON); |
| 182 | } |
| 183 | |
| 184 | if (data->flags & TEST_SUSPEND) |
Imre Deak | 022e6f8 | 2016-09-30 17:28:53 +0300 | [diff] [blame] | 185 | igt_system_suspend_autoresume(SUSPEND_STATE_MEM, |
| 186 | SUSPEND_TEST_NONE); |
Daniel Vetter | a5c6b8d | 2015-03-13 18:02:45 +0100 | [diff] [blame] | 187 | |
| 188 | igt_pipe_crc_collect_crc(pipe_crc, &crc_after); |
| 189 | igt_assert_crc_equal(&crc, &crc_after); |
| 190 | } |
| 191 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 192 | cursor_disable(data); |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 193 | igt_display_commit(display); |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 194 | |
Antti Koskipaa | 795eddc | 2014-04-10 15:08:09 +0300 | [diff] [blame] | 195 | /* Now render the same in software and collect crc */ |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 196 | cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 197 | draw_cursor(cr, x, y, data->curw, data->curh); |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 198 | igt_put_cairo_ctx(data->drm_fd, &data->primary_fb, cr); |
Antti Koskipaa | 795eddc | 2014-04-10 15:08:09 +0300 | [diff] [blame] | 199 | igt_display_commit(display); |
Daniel Vetter | 4fec18e | 2015-02-27 20:24:15 +0100 | [diff] [blame] | 200 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 201 | igt_wait_for_vblank(data->drm_fd, data->pipe); |
Antti Koskipaa | 795eddc | 2014-04-10 15:08:09 +0300 | [diff] [blame] | 202 | igt_pipe_crc_collect_crc(pipe_crc, &ref_crc); |
Daniel Vetter | e588f6d | 2015-02-27 20:37:29 +0100 | [diff] [blame] | 203 | igt_assert_crc_equal(&crc, &ref_crc); |
Daniel Vetter | 4fec18e | 2015-02-27 20:24:15 +0100 | [diff] [blame] | 204 | |
Damien Lespiau | 09ea86e | 2015-05-11 16:36:51 +0100 | [diff] [blame] | 205 | /* Clear screen afterwards */ |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 206 | cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); |
Damien Lespiau | 09ea86e | 2015-05-11 16:36:51 +0100 | [diff] [blame] | 207 | igt_paint_color(cr, 0, 0, data->screenw, data->screenh, 0.0, 0.0, 0.0); |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 208 | igt_put_cairo_ctx(data->drm_fd, &data->primary_fb, cr); |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 209 | } |
| 210 | |
Matt Roper | 9ca2cc1 | 2015-02-02 11:07:55 -0800 | [diff] [blame] | 211 | static void do_fail_test(data_t *data, int x, int y, int expect) |
| 212 | { |
| 213 | igt_display_t *display = &data->display; |
| 214 | igt_plane_t *cursor; |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 215 | cairo_t *cr; |
Matt Roper | 9ca2cc1 | 2015-02-02 11:07:55 -0800 | [diff] [blame] | 216 | int ret; |
| 217 | |
| 218 | igt_print_activity(); |
| 219 | |
| 220 | /* Hardware test */ |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 221 | cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); |
Matt Roper | 9ca2cc1 | 2015-02-02 11:07:55 -0800 | [diff] [blame] | 222 | igt_paint_test_pattern(cr, data->screenw, data->screenh); |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 223 | igt_put_cairo_ctx(data->drm_fd, &data->primary_fb, cr); |
| 224 | |
Matt Roper | 9ca2cc1 | 2015-02-02 11:07:55 -0800 | [diff] [blame] | 225 | cursor_enable(data); |
Robert Foss | da67e73 | 2017-01-10 18:44:19 -0500 | [diff] [blame] | 226 | cursor = igt_output_get_plane_type(data->output, DRM_PLANE_TYPE_CURSOR); |
Matt Roper | 9ca2cc1 | 2015-02-02 11:07:55 -0800 | [diff] [blame] | 227 | igt_plane_set_position(cursor, x, y); |
| 228 | ret = igt_display_try_commit2(display, COMMIT_LEGACY); |
| 229 | |
| 230 | igt_plane_set_position(cursor, 0, 0); |
| 231 | cursor_disable(data); |
| 232 | igt_display_commit(display); |
| 233 | |
Matt Roper | 07be8fe | 2015-03-05 15:01:00 -0800 | [diff] [blame] | 234 | igt_assert_eq(ret, expect); |
Matt Roper | 9ca2cc1 | 2015-02-02 11:07:55 -0800 | [diff] [blame] | 235 | } |
| 236 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 237 | static void do_test(data_t *data, |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 238 | int left, int right, int top, int bottom) |
| 239 | { |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 240 | do_single_test(data, left, top); |
| 241 | do_single_test(data, right, top); |
| 242 | do_single_test(data, right, bottom); |
| 243 | do_single_test(data, left, bottom); |
Antti Koskipaa | 7ec631c | 2014-04-10 15:08:06 +0300 | [diff] [blame] | 244 | } |
| 245 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 246 | static void test_crc_onscreen(data_t *data) |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 247 | { |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 248 | int left = data->left; |
| 249 | int right = data->right; |
| 250 | int top = data->top; |
| 251 | int bottom = data->bottom; |
| 252 | int cursor_w = data->curw; |
| 253 | int cursor_h = data->curh; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 254 | |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 255 | /* fully inside */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 256 | do_test(data, left, right, top, bottom); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 257 | |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 258 | /* 2 pixels inside */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 259 | do_test(data, left - (cursor_w-2), right + (cursor_w-2), top , bottom ); |
| 260 | do_test(data, left , right , top - (cursor_h-2), bottom + (cursor_h-2)); |
| 261 | do_test(data, left - (cursor_w-2), right + (cursor_w-2), top - (cursor_h-2), bottom + (cursor_h-2)); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 262 | |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 263 | /* 1 pixel inside */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 264 | do_test(data, left - (cursor_w-1), right + (cursor_w-1), top , bottom ); |
| 265 | do_test(data, left , right , top - (cursor_h-1), bottom + (cursor_h-1)); |
| 266 | do_test(data, left - (cursor_w-1), right + (cursor_w-1), top - (cursor_h-1), bottom + (cursor_h-1)); |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 267 | } |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 268 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 269 | static void test_crc_offscreen(data_t *data) |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 270 | { |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 271 | int left = data->left; |
| 272 | int right = data->right; |
| 273 | int top = data->top; |
| 274 | int bottom = data->bottom; |
| 275 | int cursor_w = data->curw; |
| 276 | int cursor_h = data->curh; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 277 | |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 278 | /* fully outside */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 279 | do_test(data, left - (cursor_w), right + (cursor_w), top , bottom ); |
| 280 | do_test(data, left , right , top - (cursor_h), bottom + (cursor_h)); |
| 281 | do_test(data, left - (cursor_w), right + (cursor_w), top - (cursor_h), bottom + (cursor_h)); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 282 | |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 283 | /* fully outside by 1 extra pixels */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 284 | do_test(data, left - (cursor_w+1), right + (cursor_w+1), top , bottom ); |
| 285 | do_test(data, left , right , top - (cursor_h+1), bottom + (cursor_h+1)); |
| 286 | do_test(data, left - (cursor_w+1), right + (cursor_w+1), top - (cursor_h+1), bottom + (cursor_h+1)); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 287 | |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 288 | /* fully outside by 2 extra pixels */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 289 | do_test(data, left - (cursor_w+2), right + (cursor_w+2), top , bottom ); |
| 290 | do_test(data, left , right , top - (cursor_h+2), bottom + (cursor_h+2)); |
| 291 | do_test(data, left - (cursor_w+2), right + (cursor_w+2), top - (cursor_h+2), bottom + (cursor_h+2)); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 292 | |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 293 | /* fully outside by a lot of extra pixels */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 294 | do_test(data, left - (cursor_w+512), right + (cursor_w+512), top , bottom ); |
| 295 | do_test(data, left , right , top - (cursor_h+512), bottom + (cursor_h+512)); |
| 296 | do_test(data, left - (cursor_w+512), right + (cursor_w+512), top - (cursor_h+512), bottom + (cursor_h+512)); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 297 | |
Antti Koskipaa | ead0173 | 2014-04-10 15:08:08 +0300 | [diff] [blame] | 298 | /* go nuts */ |
Matt Roper | 9ca2cc1 | 2015-02-02 11:07:55 -0800 | [diff] [blame] | 299 | do_test(data, INT_MIN, INT_MAX - cursor_w, INT_MIN, INT_MAX - cursor_h); |
| 300 | do_test(data, SHRT_MIN, SHRT_MAX, SHRT_MIN, SHRT_MAX); |
| 301 | |
| 302 | /* Make sure we get -ERANGE on integer overflow */ |
| 303 | do_fail_test(data, INT_MAX - cursor_w + 1, INT_MAX - cursor_h + 1, -ERANGE); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 304 | } |
| 305 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 306 | static void test_crc_sliding(data_t *data) |
Antti Koskipaa | 470e5ce | 2014-04-10 15:08:10 +0300 | [diff] [blame] | 307 | { |
| 308 | int i; |
| 309 | |
| 310 | /* Make sure cursor moves smoothly and pixel-by-pixel, and that there are |
| 311 | * no alignment issues. Horizontal, vertical and diagonal test. |
| 312 | */ |
| 313 | for (i = 0; i < 16; i++) { |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 314 | do_single_test(data, i, 0); |
| 315 | do_single_test(data, 0, i); |
| 316 | do_single_test(data, i, i); |
Antti Koskipaa | 470e5ce | 2014-04-10 15:08:10 +0300 | [diff] [blame] | 317 | } |
| 318 | } |
| 319 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 320 | static void test_crc_random(data_t *data) |
Antti Koskipaa | fafcff9 | 2014-04-10 15:08:11 +0300 | [diff] [blame] | 321 | { |
Daniel Vetter | a5c6b8d | 2015-03-13 18:02:45 +0100 | [diff] [blame] | 322 | int i, max; |
| 323 | |
| 324 | max = data->flags & (TEST_DPMS | TEST_SUSPEND) ? 2 : 50; |
Antti Koskipaa | fafcff9 | 2014-04-10 15:08:11 +0300 | [diff] [blame] | 325 | |
| 326 | /* Random cursor placement */ |
Daniel Vetter | a5c6b8d | 2015-03-13 18:02:45 +0100 | [diff] [blame] | 327 | for (i = 0; i < max; i++) { |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 328 | int x = rand() % (data->screenw + data->curw * 2) - data->curw; |
| 329 | int y = rand() % (data->screenh + data->curh * 2) - data->curh; |
| 330 | do_single_test(data, x, y); |
Antti Koskipaa | fafcff9 | 2014-04-10 15:08:11 +0300 | [diff] [blame] | 331 | } |
| 332 | } |
| 333 | |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 334 | static void prepare_crtc(data_t *data, igt_output_t *output, |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 335 | int cursor_w, int cursor_h) |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 336 | { |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 337 | drmModeModeInfo *mode; |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 338 | igt_display_t *display = &data->display; |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 339 | igt_plane_t *primary; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 340 | |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 341 | /* select the pipe we want to use */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 342 | igt_output_set_pipe(output, data->pipe); |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 343 | cursor_disable(data); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 344 | |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 345 | /* create and set the primary plane fb */ |
| 346 | mode = igt_output_get_mode(output); |
Daniel Vetter | 9aea7ae | 2014-03-26 09:18:11 +0100 | [diff] [blame] | 347 | igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 348 | DRM_FORMAT_XRGB8888, |
Tvrtko Ursulin | e36091d | 2015-03-03 14:11:01 +0000 | [diff] [blame] | 349 | LOCAL_DRM_FORMAT_MOD_NONE, |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 350 | 0.0, 0.0, 0.0, |
| 351 | &data->primary_fb); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 352 | |
Robert Foss | da67e73 | 2017-01-10 18:44:19 -0500 | [diff] [blame] | 353 | primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 354 | igt_plane_set_fb(primary, &data->primary_fb); |
Ville Syrjälä | 3d371a7 | 2013-11-22 23:46:32 +0200 | [diff] [blame] | 355 | |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 356 | igt_display_commit(display); |
| 357 | |
| 358 | /* create the pipe_crc object for this pipe */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 359 | if (data->pipe_crc) |
| 360 | igt_pipe_crc_free(data->pipe_crc); |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 361 | |
Chris Wilson | 83884e9 | 2017-03-21 17:16:03 +0000 | [diff] [blame] | 362 | data->pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 363 | INTEL_PIPE_CRC_SOURCE_AUTO); |
Daniel Vetter | 43def94 | 2013-10-31 16:06:40 +0100 | [diff] [blame] | 364 | |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 365 | /* x/y position where the cursor is still fully visible */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 366 | data->left = 0; |
| 367 | data->right = mode->hdisplay - cursor_w; |
| 368 | data->top = 0; |
| 369 | data->bottom = mode->vdisplay - cursor_h; |
| 370 | data->screenw = mode->hdisplay; |
| 371 | data->screenh = mode->vdisplay; |
| 372 | data->curw = cursor_w; |
| 373 | data->curh = cursor_h; |
Matt Roper | cd99dde | 2015-10-15 16:54:32 -0700 | [diff] [blame] | 374 | data->refresh = mode->vrefresh; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 375 | |
| 376 | /* make sure cursor is disabled */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 377 | cursor_disable(data); |
| 378 | igt_wait_for_vblank(data->drm_fd, data->pipe); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 379 | |
| 380 | /* get reference crc w/o cursor */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 381 | igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 382 | } |
| 383 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 384 | static void cleanup_crtc(data_t *data, igt_output_t *output) |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 385 | { |
Ville Syrjälä | a461515 | 2014-04-25 15:27:57 +0300 | [diff] [blame] | 386 | igt_display_t *display = &data->display; |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 387 | igt_plane_t *primary; |
| 388 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 389 | igt_pipe_crc_free(data->pipe_crc); |
| 390 | data->pipe_crc = NULL; |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 391 | |
Daniel Vetter | 9aea7ae | 2014-03-26 09:18:11 +0100 | [diff] [blame] | 392 | igt_remove_fb(data->drm_fd, &data->primary_fb); |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 393 | |
Robert Foss | da67e73 | 2017-01-10 18:44:19 -0500 | [diff] [blame] | 394 | primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY); |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 395 | igt_plane_set_fb(primary, NULL); |
| 396 | |
| 397 | igt_output_set_pipe(output, PIPE_ANY); |
Ville Syrjälä | a461515 | 2014-04-25 15:27:57 +0300 | [diff] [blame] | 398 | igt_display_commit(display); |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 399 | } |
| 400 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 401 | static void run_test(data_t *data, void (*testfunc)(data_t *), int cursor_w, int cursor_h) |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 402 | { |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 403 | igt_display_t *display = &data->display; |
| 404 | igt_output_t *output; |
| 405 | enum pipe p; |
Daniel Vetter | 43def94 | 2013-10-31 16:06:40 +0100 | [diff] [blame] | 406 | int valid_tests = 0; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 407 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 408 | igt_require(cursor_w <= data->cursor_max_w && |
| 409 | cursor_h <= data->cursor_max_h); |
| 410 | |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 411 | for_each_pipe_with_valid_output(display, p, output) { |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 412 | data->output = output; |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 413 | data->pipe = p; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 414 | |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 415 | prepare_crtc(data, output, cursor_w, cursor_h); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 416 | |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 417 | valid_tests++; |
Daniel Vetter | 43def94 | 2013-10-31 16:06:40 +0100 | [diff] [blame] | 418 | |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 419 | igt_info("Beginning %s on pipe %s, connector %s\n", |
| 420 | igt_subtest_name(), |
| 421 | kmstest_pipe_name(data->pipe), |
| 422 | igt_output_name(output)); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 423 | |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 424 | testfunc(data); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 425 | |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 426 | igt_info("\n%s on pipe %s, connector %s: PASSED\n\n", |
| 427 | igt_subtest_name(), |
| 428 | kmstest_pipe_name(data->pipe), |
| 429 | igt_output_name(output)); |
Daniel Vetter | 43def94 | 2013-10-31 16:06:40 +0100 | [diff] [blame] | 430 | |
Maarten Lankhorst | a546b67 | 2017-01-05 14:13:34 +0100 | [diff] [blame] | 431 | /* cleanup what prepare_crtc() has done */ |
| 432 | cleanup_crtc(data, output); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 433 | } |
Daniel Vetter | 43def94 | 2013-10-31 16:06:40 +0100 | [diff] [blame] | 434 | |
| 435 | igt_require_f(valid_tests, "no valid crtc/connector combinations found\n"); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 436 | } |
| 437 | |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 438 | static void create_cursor_fb(data_t *data, int cur_w, int cur_h) |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 439 | { |
| 440 | cairo_t *cr; |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 441 | uint32_t fb_id; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 442 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 443 | /* |
| 444 | * Make the FB slightly taller and leave the extra |
| 445 | * line opaque white, so that we can see that the |
| 446 | * hardware won't scan beyond what it should (esp. |
| 447 | * with non-square cursors). |
| 448 | */ |
| 449 | fb_id = igt_create_color_fb(data->drm_fd, cur_w, cur_h + 1, |
Tvrtko Ursulin | e36091d | 2015-03-03 14:11:01 +0000 | [diff] [blame] | 450 | DRM_FORMAT_ARGB8888, |
| 451 | LOCAL_DRM_FORMAT_MOD_NONE, |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 452 | 1.0, 1.0, 1.0, |
| 453 | &data->fb); |
| 454 | |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 455 | igt_assert(fb_id); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 456 | |
Antti Koskipaa | a593d61 | 2014-04-10 15:08:05 +0300 | [diff] [blame] | 457 | cr = igt_get_cairo_ctx(data->drm_fd, &data->fb); |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 458 | draw_cursor(cr, 0, 0, cur_w, cur_h); |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 459 | igt_put_cairo_ctx(data->drm_fd, &data->fb, cr); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 460 | } |
| 461 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 462 | static bool has_nonsquare_cursors(uint32_t devid) |
| 463 | { |
| 464 | /* |
| 465 | * Test non-square cursors a bit on the platforms |
| 466 | * that support such things. |
| 467 | */ |
Ville Syrjälä | a0433ca | 2017-06-01 21:15:45 +0300 | [diff] [blame] | 468 | if (devid == PCI_CHIP_845_G || devid == PCI_CHIP_I865_G) |
| 469 | return true; |
| 470 | |
| 471 | if (IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid)) |
| 472 | return false; |
| 473 | |
| 474 | return intel_gen(devid) >= 7; |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 475 | } |
| 476 | |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 477 | static void test_cursor_size(data_t *data) |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 478 | { |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 479 | igt_display_t *display = &data->display; |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 480 | igt_pipe_crc_t *pipe_crc = data->pipe_crc; |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 481 | igt_crc_t crc[10], ref_crc; |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 482 | cairo_t *cr; |
| 483 | uint32_t fb_id; |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 484 | int i, size; |
| 485 | int cursor_max_size = data->cursor_max_w; |
Matt Roper | 3f46e81 | 2014-06-30 16:44:30 -0700 | [diff] [blame] | 486 | int ret; |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 487 | |
| 488 | /* Create a maximum size cursor, then change the size in flight to |
| 489 | * smaller ones to see that the size is applied correctly |
| 490 | */ |
| 491 | fb_id = igt_create_fb(data->drm_fd, cursor_max_size, cursor_max_size, |
Tvrtko Ursulin | e36091d | 2015-03-03 14:11:01 +0000 | [diff] [blame] | 492 | DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE, |
| 493 | &data->fb); |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 494 | igt_assert(fb_id); |
| 495 | |
| 496 | /* Use a solid white rectangle as the cursor */ |
| 497 | cr = igt_get_cairo_ctx(data->drm_fd, &data->fb); |
| 498 | igt_paint_color_alpha(cr, 0, 0, cursor_max_size, cursor_max_size, 1.0, 1.0, 1.0, 1.0); |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 499 | igt_put_cairo_ctx(data->drm_fd, &data->fb, cr); |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 500 | |
| 501 | /* Hardware test loop */ |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 502 | cursor_enable(data); |
Matt Roper | 3f46e81 | 2014-06-30 16:44:30 -0700 | [diff] [blame] | 503 | ret = drmModeMoveCursor(data->drm_fd, data->output->config.crtc->crtc_id, 0, 0); |
Matt Roper | 07be8fe | 2015-03-05 15:01:00 -0800 | [diff] [blame] | 504 | igt_assert_eq(ret, 0); |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 505 | for (i = 0, size = cursor_max_size; size >= 64; size /= 2, i++) { |
| 506 | /* Change size in flight: */ |
Matt Roper | 3f46e81 | 2014-06-30 16:44:30 -0700 | [diff] [blame] | 507 | ret = drmModeSetCursor(data->drm_fd, data->output->config.crtc->crtc_id, |
| 508 | data->fb.gem_handle, size, size); |
Matt Roper | 07be8fe | 2015-03-05 15:01:00 -0800 | [diff] [blame] | 509 | igt_assert_eq(ret, 0); |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 510 | igt_wait_for_vblank(data->drm_fd, data->pipe); |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 511 | igt_pipe_crc_collect_crc(pipe_crc, &crc[i]); |
| 512 | } |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 513 | cursor_disable(data); |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 514 | /* Software test loop */ |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 515 | for (i = 0, size = cursor_max_size; size >= 64; size /= 2, i++) { |
| 516 | /* Now render the same in software and collect crc */ |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 517 | cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 518 | igt_paint_color_alpha(cr, 0, 0, size, size, 1.0, 1.0, 1.0, 1.0); |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 519 | igt_put_cairo_ctx(data->drm_fd, &data->primary_fb, cr); |
| 520 | |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 521 | igt_display_commit(display); |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 522 | igt_wait_for_vblank(data->drm_fd, data->pipe); |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 523 | igt_pipe_crc_collect_crc(pipe_crc, &ref_crc); |
| 524 | /* Clear screen afterwards */ |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 525 | cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); |
Matt Roper | 07087ad | 2014-06-30 16:44:29 -0700 | [diff] [blame] | 526 | igt_paint_color(cr, 0, 0, data->screenw, data->screenh, |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 527 | 0.0, 0.0, 0.0); |
Maarten Lankhorst | be2f6fc | 2018-02-01 12:48:45 +0100 | [diff] [blame^] | 528 | igt_put_cairo_ctx(data->drm_fd, &data->primary_fb, cr); |
Daniel Vetter | e588f6d | 2015-02-27 20:37:29 +0100 | [diff] [blame] | 529 | igt_assert_crc_equal(&crc[i], &ref_crc); |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 530 | } |
| 531 | } |
| 532 | |
Matt Roper | cd99dde | 2015-10-15 16:54:32 -0700 | [diff] [blame] | 533 | static void test_rapid_movement(data_t *data) |
| 534 | { |
| 535 | struct timeval start, end, delta; |
| 536 | int x = 0, y = 0; |
| 537 | long usec; |
| 538 | int crtc_id = data->output->config.crtc->crtc_id; |
| 539 | |
| 540 | igt_assert_eq(drmModeSetCursor(data->drm_fd, crtc_id, |
| 541 | data->fb.gem_handle, data->curw, data->curh), 0); |
| 542 | |
| 543 | gettimeofday(&start, NULL); |
| 544 | for ( ; x < 100; x++) |
| 545 | igt_assert_eq(drmModeMoveCursor(data->drm_fd, crtc_id, x, y), 0); |
| 546 | for ( ; y < 100; y++) |
| 547 | igt_assert_eq(drmModeMoveCursor(data->drm_fd, crtc_id, x, y), 0); |
| 548 | for ( ; x > 0; x--) |
| 549 | igt_assert_eq(drmModeMoveCursor(data->drm_fd, crtc_id, x, y), 0); |
| 550 | for ( ; y > 0; y--) |
| 551 | igt_assert_eq(drmModeMoveCursor(data->drm_fd, crtc_id, x, y), 0); |
| 552 | gettimeofday(&end, NULL); |
| 553 | |
| 554 | /* |
| 555 | * We've done 400 cursor updates now. If we're being throttled to |
| 556 | * vblank, then that would take roughly 400/refresh seconds. If the |
| 557 | * elapsed time is greater than 90% of that value, we'll consider it |
| 558 | * a failure (since cursor updates shouldn't be throttled). |
| 559 | */ |
| 560 | timersub(&end, &start, &delta); |
| 561 | usec = delta.tv_usec + 1000000 * delta.tv_sec; |
| 562 | igt_assert_lt(usec, 0.9 * 400 * 1000000 / data->refresh); |
| 563 | |
| 564 | igt_assert_eq(drmModeSetCursor(data->drm_fd, crtc_id, |
| 565 | 0, data->curw, data->curh), 0); |
| 566 | |
| 567 | } |
| 568 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 569 | static void run_test_generic(data_t *data) |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 570 | { |
| 571 | int cursor_size; |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 572 | for (cursor_size = 64; cursor_size <= 512; cursor_size *= 2) { |
| 573 | int w = cursor_size; |
| 574 | int h = cursor_size; |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 575 | |
Ville Syrjälä | f8e5a3f | 2014-04-25 13:49:11 +0300 | [diff] [blame] | 576 | igt_fixture |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 577 | create_cursor_fb(data, w, h); |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 578 | |
| 579 | /* Using created cursor FBs to test cursor support */ |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 580 | igt_subtest_f("cursor-%dx%d-onscreen", w, h) |
| 581 | run_test(data, test_crc_onscreen, w, h); |
| 582 | igt_subtest_f("cursor-%dx%d-offscreen", w, h) |
| 583 | run_test(data, test_crc_offscreen, w, h); |
| 584 | igt_subtest_f("cursor-%dx%d-sliding", w, h) |
| 585 | run_test(data, test_crc_sliding, w, h); |
| 586 | igt_subtest_f("cursor-%dx%d-random", w, h) |
| 587 | run_test(data, test_crc_random, w, h); |
Daniel Vetter | a5c6b8d | 2015-03-13 18:02:45 +0100 | [diff] [blame] | 588 | igt_subtest_f("cursor-%dx%d-dpms", w, h) { |
| 589 | data->flags = TEST_DPMS; |
| 590 | run_test(data, test_crc_random, w, h); |
| 591 | data->flags = 0; |
| 592 | } |
| 593 | |
| 594 | igt_subtest_f("cursor-%dx%d-suspend", w, h) { |
| 595 | data->flags = TEST_SUSPEND; |
| 596 | run_test(data, test_crc_random, w, h); |
| 597 | data->flags = 0; |
| 598 | } |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 599 | |
Matt Roper | cd99dde | 2015-10-15 16:54:32 -0700 | [diff] [blame] | 600 | igt_subtest_f("cursor-%dx%d-rapid-movement", w, h) { |
| 601 | run_test(data, test_rapid_movement, w, h); |
| 602 | } |
| 603 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 604 | igt_fixture |
| 605 | igt_remove_fb(data->drm_fd, &data->fb); |
| 606 | |
| 607 | /* |
| 608 | * Test non-square cursors a bit on the platforms |
| 609 | * that support such things. And make it a bit more |
| 610 | * interesting by using a non-pot height. |
| 611 | */ |
| 612 | h /= 3; |
| 613 | |
| 614 | igt_fixture |
| 615 | create_cursor_fb(data, w, h); |
| 616 | |
| 617 | /* Using created cursor FBs to test cursor support */ |
| 618 | igt_subtest_f("cursor-%dx%d-onscreen", w, h) { |
| 619 | igt_require(has_nonsquare_cursors(data->devid)); |
| 620 | run_test(data, test_crc_onscreen, w, h); |
| 621 | } |
| 622 | igt_subtest_f("cursor-%dx%d-offscreen", w, h) { |
| 623 | igt_require(has_nonsquare_cursors(data->devid)); |
| 624 | run_test(data, test_crc_offscreen, w, h); |
| 625 | } |
| 626 | igt_subtest_f("cursor-%dx%d-sliding", w, h) { |
| 627 | igt_require(has_nonsquare_cursors(data->devid)); |
| 628 | run_test(data, test_crc_sliding, w, h); |
| 629 | } |
| 630 | igt_subtest_f("cursor-%dx%d-random", w, h) { |
| 631 | igt_require(has_nonsquare_cursors(data->devid)); |
| 632 | run_test(data, test_crc_random, w, h); |
| 633 | } |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 634 | |
Ville Syrjälä | f8e5a3f | 2014-04-25 13:49:11 +0300 | [diff] [blame] | 635 | igt_fixture |
| 636 | igt_remove_fb(data->drm_fd, &data->fb); |
| 637 | } |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 638 | } |
| 639 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 640 | static data_t data; |
| 641 | |
Daniel Vetter | 071e9ca | 2013-10-31 16:23:26 +0100 | [diff] [blame] | 642 | igt_main |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 643 | { |
Ville Syrjälä | fb2ccb1 | 2014-04-25 13:50:59 +0300 | [diff] [blame] | 644 | uint64_t cursor_width = 64, cursor_height = 64; |
Daniel Vetter | 52edf3a | 2014-03-22 14:45:54 +0100 | [diff] [blame] | 645 | int ret; |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 646 | |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 647 | igt_skip_on_simulation(); |
| 648 | |
| 649 | igt_fixture { |
Micah Fedke | c81d293 | 2015-07-22 21:54:02 +0000 | [diff] [blame] | 650 | data.drm_fd = drm_open_driver_master(DRIVER_INTEL); |
Daniel Vetter | 1f0cf2d | 2013-10-31 17:02:41 +0100 | [diff] [blame] | 651 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 652 | data.devid = intel_get_drm_devid(data.drm_fd); |
| 653 | |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 654 | ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_WIDTH, &cursor_width); |
Ville Syrjälä | fb2ccb1 | 2014-04-25 13:50:59 +0300 | [diff] [blame] | 655 | igt_assert(ret == 0 || errno == EINVAL); |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 656 | /* Not making use of cursor_height since it is same as width, still reading */ |
| 657 | ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height); |
Ville Syrjälä | fb2ccb1 | 2014-04-25 13:50:59 +0300 | [diff] [blame] | 658 | igt_assert(ret == 0 || errno == EINVAL); |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 659 | |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 660 | /* We assume width and height are same so max is assigned width */ |
Chris Wilson | 3b94d3f | 2014-08-29 13:11:40 +0100 | [diff] [blame] | 661 | igt_assert_eq(cursor_width, cursor_height); |
Sagar Kamble | ba3a1a8 | 2014-03-18 15:59:43 +0530 | [diff] [blame] | 662 | |
Daniel Vetter | 33f0884 | 2014-08-12 11:23:09 +0200 | [diff] [blame] | 663 | kmstest_set_vt_graphics_mode(); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 664 | |
Chris Wilson | 83884e9 | 2017-03-21 17:16:03 +0000 | [diff] [blame] | 665 | igt_require_pipe_crc(data.drm_fd); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 666 | |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 667 | igt_display_init(&data.display, data.drm_fd); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 668 | } |
| 669 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 670 | data.cursor_max_w = cursor_width; |
| 671 | data.cursor_max_h = cursor_height; |
| 672 | |
Antti Koskipaa | 21fb118 | 2014-06-02 13:43:18 +0300 | [diff] [blame] | 673 | igt_subtest_f("cursor-size-change") |
| 674 | run_test(&data, test_cursor_size, cursor_width, cursor_height); |
| 675 | |
Ville Syrjälä | 25c55d3 | 2014-09-12 18:03:25 +0300 | [diff] [blame] | 676 | run_test_generic(&data); |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 677 | |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 678 | igt_fixture { |
Damien Lespiau | d435829 | 2014-02-05 17:14:12 +0000 | [diff] [blame] | 679 | igt_display_fini(&data.display); |
| 680 | } |
Ville Syrjälä | 08c27e3 | 2013-10-18 17:44:42 +0300 | [diff] [blame] | 681 | } |