blob: a361a00face49035e145e5c0f5e606ee7722c0c0 [file] [log] [blame]
chandra kondurua26f9f92015-03-30 13:52:04 -07001/*
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 */
24
Thomas Wood804e11f2015-08-17 17:57:43 +010025#include "igt.h"
chandra kondurua26f9f92015-03-30 13:52:04 -070026#include <math.h>
27
chandra kondurua26f9f92015-03-30 13:52:04 -070028
29IGT_TEST_DESCRIPTION("Test display plane scaling");
30
31typedef struct {
32 uint32_t devid;
33 int drm_fd;
34 igt_display_t display;
35 igt_crc_t ref_crc;
36 igt_pipe_crc_t *pipe_crc;
37
38 int image_w;
39 int image_h;
40
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010041 struct igt_fb fb[3];
chandra kondurua26f9f92015-03-30 13:52:04 -070042 igt_plane_t *plane1;
43 igt_plane_t *plane2;
44 igt_plane_t *plane3;
chandra kondurua26f9f92015-03-30 13:52:04 -070045} data_t;
46
Maarten Lankhorst1fb3faa2018-01-15 11:11:39 +010047static int get_num_scalers(uint32_t devid, enum pipe pipe)
48{
49 igt_require(intel_gen(devid) >= 9);
50
51 if (intel_gen(devid) >= 10)
52 return 2;
53 else if (pipe != PIPE_C)
54 return 2;
55 else
56 return 1;
57}
58
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010059static void cleanup_crtc(data_t *data)
chandra kondurua26f9f92015-03-30 13:52:04 -070060{
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010061 int i;
chandra kondurua26f9f92015-03-30 13:52:04 -070062
63 igt_pipe_crc_free(data->pipe_crc);
64 data->pipe_crc = NULL;
65
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010066 for (i = 0; i < ARRAY_SIZE(data->fb); i++) {
67 if (!data->fb[i].fb_id)
68 continue;
69
70 igt_remove_fb(data->drm_fd, &data->fb[i]);
71 data->fb[i].fb_id = 0;
chandra kondurua26f9f92015-03-30 13:52:04 -070072 }
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010073}
74
75static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
76 igt_plane_t *plane, drmModeModeInfo *mode)
77{
78 igt_display_t *display = &data->display;
79
80 cleanup_crtc(data);
81
82 igt_display_reset(display);
83 igt_output_set_pipe(output, pipe);
84
85 /* create the pipe_crc object for this pipe */
86 data->pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
87
88 /* allocate fb for plane 1 */
89 igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
90 DRM_FORMAT_XRGB8888,
91 LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
92 &data->fb[0]);
93
94 igt_plane_set_fb(plane, &data->fb[0]);
chandra kondurua26f9f92015-03-30 13:52:04 -070095
Robert Fossca201702017-01-10 20:14:07 -050096 if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
chandra kondurua26f9f92015-03-30 13:52:04 -070097 igt_plane_t *primary;
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010098 int ret;
chandra kondurua26f9f92015-03-30 13:52:04 -070099
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100100 /* Do we succeed without enabling the primary plane? */
101 ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
102 if (!ret)
103 return;
104
105 /*
106 * Fallback: set the primary plane to actually enable the pipe.
107 * Some drivers always require the primary plane to be enabled.
108 */
Robert Fossca201702017-01-10 20:14:07 -0500109 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100110 igt_plane_set_fb(primary, &data->fb[0]);
chandra kondurua26f9f92015-03-30 13:52:04 -0700111 }
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100112 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700113}
114
115/* does iterative scaling on plane2 */
116static void iterate_plane_scaling(data_t *d, drmModeModeInfo *mode)
117{
118 igt_display_t *display = &d->display;
119
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100120 if (mode->hdisplay >= d->fb[1].width) {
chandra kondurua26f9f92015-03-30 13:52:04 -0700121 int w, h;
122 /* fixed fb */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100123 igt_fb_set_position(&d->fb[1], d->plane2, 0, 0);
124 igt_fb_set_size(&d->fb[1], d->plane2, d->fb[1].width, d->fb[1].height);
chandra kondurua26f9f92015-03-30 13:52:04 -0700125 igt_plane_set_position(d->plane2, 0, 0);
126
127 /* adjust plane size */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100128 for (w = d->fb[1].width; w <= mode->hdisplay; w+=10) {
129 h = w * d->fb[1].height / d->fb[1].width;
chandra kondurua26f9f92015-03-30 13:52:04 -0700130 igt_plane_set_size(d->plane2, w, h);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100131 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700132 }
133 } else {
134 int w, h;
135 /* fixed plane */
136 igt_plane_set_position(d->plane2, 0, 0);
137 igt_plane_set_size(d->plane2, mode->hdisplay, mode->vdisplay);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100138 igt_fb_set_position(&d->fb[1], d->plane2, 0, 0);
chandra kondurua26f9f92015-03-30 13:52:04 -0700139
140 /* adjust fb size */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100141 for (w = mode->hdisplay; w <= d->fb[1].width; w+=10) {
Mahesh Kumar085d4142017-12-13 15:20:47 +0530142 /* Source coordinates must not be clipped. */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100143 h = min(w * mode->hdisplay / mode->vdisplay, d->fb[1].height);
144 igt_fb_set_size(&d->fb[1], d->plane2, w, h);
145 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700146 }
147 }
148}
149
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100150static void
151test_plane_scaling_on_pipe(data_t *d, enum pipe pipe, igt_output_t *output)
chandra kondurua26f9f92015-03-30 13:52:04 -0700152{
153 igt_display_t *display = &d->display;
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100154 drmModeModeInfo *mode;
chandra kondurua26f9f92015-03-30 13:52:04 -0700155 int primary_plane_scaling = 0; /* For now */
156
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100157 mode = igt_output_get_mode(output);
chandra kondurua26f9f92015-03-30 13:52:04 -0700158
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100159 /* Set up display with plane 1 */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100160 d->plane1 = &display->pipes[pipe].planes[0];
161 prepare_crtc(d, output, pipe, d->plane1, mode);
162
163 igt_create_color_pattern_fb(display->drm_fd, 600, 600,
164 DRM_FORMAT_XRGB8888,
165 LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
166 .5, .5, .5, &d->fb[1]);
167
168 igt_create_pattern_fb(d->drm_fd,
169 mode->hdisplay, mode->vdisplay,
170 DRM_FORMAT_XRGB8888,
171 LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
172 &d->fb[2]);
chandra kondurua26f9f92015-03-30 13:52:04 -0700173
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100174 if (primary_plane_scaling) {
175 /* Primary plane upscaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100176 igt_fb_set_position(&d->fb[0], d->plane1, 100, 100);
177 igt_fb_set_size(&d->fb[0], d->plane1, 500, 500);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100178 igt_plane_set_position(d->plane1, 0, 0);
179 igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100180 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700181
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100182 /* Primary plane 1:1 no scaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100183 igt_fb_set_position(&d->fb[0], d->plane1, 0, 0);
184 igt_fb_set_size(&d->fb[0], d->plane1, d->fb[0].width, d->fb[0].height);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100185 igt_plane_set_position(d->plane1, 0, 0);
186 igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100187 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100188 }
chandra kondurua26f9f92015-03-30 13:52:04 -0700189
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100190 /* Set up fb[1]->plane2 mapping. */
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100191 d->plane2 = igt_output_get_plane(output, 1);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100192 igt_plane_set_fb(d->plane2, &d->fb[1]);
chandra kondurua26f9f92015-03-30 13:52:04 -0700193
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100194 /* 2nd plane windowed */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100195 igt_fb_set_position(&d->fb[1], d->plane2, 100, 100);
196 igt_fb_set_size(&d->fb[1], d->plane2, d->fb[1].width-200, d->fb[1].height-200);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100197 igt_plane_set_position(d->plane2, 100, 100);
198 igt_plane_set_size(d->plane2, mode->hdisplay-200, mode->vdisplay-200);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100199 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700200
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100201 iterate_plane_scaling(d, mode);
chandra kondurua26f9f92015-03-30 13:52:04 -0700202
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100203 /* 2nd plane up scaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100204 igt_fb_set_position(&d->fb[1], d->plane2, 100, 100);
205 igt_fb_set_size(&d->fb[1], d->plane2, 500, 500);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100206 igt_plane_set_position(d->plane2, 10, 10);
207 igt_plane_set_size(d->plane2, mode->hdisplay-20, mode->vdisplay-20);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100208 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700209
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100210 /* 2nd plane downscaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100211 igt_fb_set_position(&d->fb[1], d->plane2, 0, 0);
212 igt_fb_set_size(&d->fb[1], d->plane2, d->fb[1].width, d->fb[1].height);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100213 igt_plane_set_position(d->plane2, 10, 10);
Mahesh Kumar085d4142017-12-13 15:20:47 +0530214
215 /* Downscale (10/9)x of original image */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100216 igt_plane_set_size(d->plane2, (d->fb[1].width * 10)/9, (d->fb[1].height * 10)/9);
217 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100218
219 if (primary_plane_scaling) {
220 /* Primary plane up scaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100221 igt_fb_set_position(&d->fb[0], d->plane1, 100, 100);
222 igt_fb_set_size(&d->fb[0], d->plane1, 500, 500);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100223 igt_plane_set_position(d->plane1, 0, 0);
224 igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100225 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100226 }
227
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100228 /* Set up fb[2]->plane3 mapping. */
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100229 d->plane3 = igt_output_get_plane(output, 2);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100230 igt_plane_set_fb(d->plane3, &d->fb[2]);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100231
Mahesh Kumar085d4142017-12-13 15:20:47 +0530232 if(d->plane3->type == DRM_PLANE_TYPE_CURSOR) {
233 igt_debug("Plane-3 doesnt exist on pipe %s\n", kmstest_pipe_name(pipe));
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100234 return;
Mahesh Kumar085d4142017-12-13 15:20:47 +0530235 }
236
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100237 /* 3rd plane windowed - no scaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100238 igt_fb_set_position(&d->fb[2], d->plane3, 100, 100);
239 igt_fb_set_size(&d->fb[2], d->plane3, d->fb[2].width-300, d->fb[2].height-300);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100240 igt_plane_set_position(d->plane3, 100, 100);
241 igt_plane_set_size(d->plane3, mode->hdisplay-300, mode->vdisplay-300);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100242 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100243
244 /* Switch scaler from plane 2 to plane 3 */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100245 igt_fb_set_position(&d->fb[1], d->plane2, 100, 100);
246 igt_fb_set_size(&d->fb[1], d->plane2, d->fb[1].width-200, d->fb[1].height-200);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100247 igt_plane_set_position(d->plane2, 100, 100);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100248 igt_plane_set_size(d->plane2, d->fb[1].width-200, d->fb[1].height-200);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100249
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100250 igt_fb_set_position(&d->fb[2], d->plane3, 100, 100);
251 igt_fb_set_size(&d->fb[2], d->plane3, d->fb[2].width-400, d->fb[2].height-400);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100252 igt_plane_set_position(d->plane3, 10, 10);
253 igt_plane_set_size(d->plane3, mode->hdisplay-300, mode->vdisplay-300);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100254 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100255
256 if (primary_plane_scaling) {
257 /* Switch scaler from plane 1 to plane 2 */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100258 igt_fb_set_position(&d->fb[0], d->plane1, 0, 0);
259 igt_fb_set_size(&d->fb[0], d->plane1, d->fb[0].width, d->fb[0].height);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100260 igt_plane_set_position(d->plane1, 0, 0);
261 igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
262
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100263 igt_fb_set_position(&d->fb[1], d->plane2, 100, 100);
264 igt_fb_set_size(&d->fb[1], d->plane2, d->fb[1].width-500,d->fb[1].height-500);
chandra kondurua26f9f92015-03-30 13:52:04 -0700265 igt_plane_set_position(d->plane2, 100, 100);
266 igt_plane_set_size(d->plane2, mode->hdisplay-200, mode->vdisplay-200);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100267 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700268 }
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100269}
270
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100271igt_main
chandra kondurua26f9f92015-03-30 13:52:04 -0700272{
273 data_t data = {};
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100274 enum pipe pipe;
chandra kondurua26f9f92015-03-30 13:52:04 -0700275
276 igt_skip_on_simulation();
277
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100278 igt_fixture {
279 data.drm_fd = drm_open_driver(DRIVER_INTEL);
280 igt_require_pipe_crc(data.drm_fd);
281 igt_display_init(&data.display, data.drm_fd);
282 data.devid = intel_get_drm_devid(data.drm_fd);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100283 igt_require(data.display.is_atomic);
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100284 }
chandra kondurua26f9f92015-03-30 13:52:04 -0700285
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100286 for_each_pipe_static(pipe) igt_subtest_group {
287 igt_output_t *output;
chandra kondurua26f9f92015-03-30 13:52:04 -0700288
Maarten Lankhorst1fb3faa2018-01-15 11:11:39 +0100289 igt_fixture {
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100290 igt_display_require_output_on_pipe(&data.display, pipe);
chandra kondurua26f9f92015-03-30 13:52:04 -0700291
Maarten Lankhorst1fb3faa2018-01-15 11:11:39 +0100292 igt_require(get_num_scalers(data.devid, pipe) > 0);
293 }
294
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100295 igt_subtest_f("pipe-%s-plane-scaling", kmstest_pipe_name(pipe))
296 for_each_valid_output_on_pipe(&data.display, pipe, output)
297 test_plane_scaling_on_pipe(&data, pipe, output);
298 }
chandra kondurua26f9f92015-03-30 13:52:04 -0700299
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100300 igt_fixture
301 igt_display_fini(&data.display);
chandra kondurua26f9f92015-03-30 13:52:04 -0700302}