blob: d32f3441e8c9ab5f6dfab408167d93eba9c0bdef [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
Jyoti Yadavf4a1e0d2017-12-13 15:20:52 +053041 struct igt_fb fb[4];
42
chandra kondurua26f9f92015-03-30 13:52:04 -070043 igt_plane_t *plane1;
44 igt_plane_t *plane2;
45 igt_plane_t *plane3;
Jyoti Yadavf4a1e0d2017-12-13 15:20:52 +053046 igt_plane_t *plane4;
chandra kondurua26f9f92015-03-30 13:52:04 -070047} data_t;
48
Maarten Lankhorst1fb3faa2018-01-15 11:11:39 +010049static int get_num_scalers(uint32_t devid, enum pipe pipe)
50{
51 igt_require(intel_gen(devid) >= 9);
52
53 if (intel_gen(devid) >= 10)
54 return 2;
55 else if (pipe != PIPE_C)
56 return 2;
57 else
58 return 1;
59}
60
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010061static void cleanup_crtc(data_t *data)
chandra kondurua26f9f92015-03-30 13:52:04 -070062{
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010063 int i;
chandra kondurua26f9f92015-03-30 13:52:04 -070064
Jyoti Yadav27a4e792017-12-13 15:20:50 +053065 igt_display_reset(&data->display);
chandra kondurua26f9f92015-03-30 13:52:04 -070066 igt_pipe_crc_free(data->pipe_crc);
67 data->pipe_crc = NULL;
68
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010069 for (i = 0; i < ARRAY_SIZE(data->fb); i++) {
70 if (!data->fb[i].fb_id)
71 continue;
72
73 igt_remove_fb(data->drm_fd, &data->fb[i]);
74 data->fb[i].fb_id = 0;
chandra kondurua26f9f92015-03-30 13:52:04 -070075 }
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010076}
77
78static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
79 igt_plane_t *plane, drmModeModeInfo *mode)
80{
81 igt_display_t *display = &data->display;
82
83 cleanup_crtc(data);
84
Maarten Lankhorst1538eb62018-01-11 15:03:50 +010085 igt_output_set_pipe(output, pipe);
86
87 /* create the pipe_crc object for this pipe */
88 data->pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
89
90 /* allocate fb for plane 1 */
91 igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
92 DRM_FORMAT_XRGB8888,
93 LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
94 &data->fb[0]);
95
96 igt_plane_set_fb(plane, &data->fb[0]);
chandra kondurua26f9f92015-03-30 13:52:04 -070097
Robert Fossca201702017-01-10 20:14:07 -050098 if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
chandra kondurua26f9f92015-03-30 13:52:04 -070099 igt_plane_t *primary;
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100100 int ret;
chandra kondurua26f9f92015-03-30 13:52:04 -0700101
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100102 /* Do we succeed without enabling the primary plane? */
103 ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
104 if (!ret)
105 return;
106
107 /*
108 * Fallback: set the primary plane to actually enable the pipe.
109 * Some drivers always require the primary plane to be enabled.
110 */
Robert Fossca201702017-01-10 20:14:07 -0500111 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100112 igt_plane_set_fb(primary, &data->fb[0]);
chandra kondurua26f9f92015-03-30 13:52:04 -0700113 }
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100114 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700115}
116
Jyoti Yadav27a4e792017-12-13 15:20:50 +0530117static void paint_fb(data_t *d, struct igt_fb *fb)
118{
119 cairo_t *cr;
120
121 cr = igt_get_cairo_ctx(d->drm_fd, fb);
122 igt_paint_color(cr, 0, 0, fb->width, fb->height, 0.0, 1.0, 0.0);
Maarten Lankhorstbe2f6fc2018-02-01 12:48:45 +0100123 igt_put_cairo_ctx(d->drm_fd, fb, cr);
Jyoti Yadav27a4e792017-12-13 15:20:50 +0530124}
125
126static void check_scaling_pipe_plane_rot(data_t *d, igt_plane_t *plane,
127 uint32_t pixel_format,
128 uint64_t tiling, enum pipe pipe,
129 igt_output_t *output,
130 igt_rotation_t rot)
131{
132 igt_display_t *display = &d->display;
133 int width, height;
134 drmModeModeInfo *mode;
135
136 cleanup_crtc(d);
137
138 igt_output_set_pipe(output, pipe);
139 mode = igt_output_get_mode(output);
140
141 /* create buffer in the range of min and max source side limit.*/
142 width = height = 9;
143 igt_create_fb(display->drm_fd, width, height,
144 pixel_format, tiling, &d->fb[0]);
145 paint_fb(d, &d->fb[0]);
146 igt_plane_set_fb(plane, &d->fb[0]);
147
148 /* Check min to full resolution upscaling */
149 igt_fb_set_position(&d->fb[0], plane, 0, 0);
150 igt_fb_set_size(&d->fb[0], plane, width, height);
151 igt_plane_set_position(plane, 0, 0);
152 igt_plane_set_size(plane, mode->hdisplay, mode->vdisplay);
153 igt_plane_set_rotation(plane, rot);
154 igt_display_commit2(display, COMMIT_ATOMIC);
155
156 igt_plane_set_fb(plane, NULL);
157 igt_plane_set_position(plane, 0, 0);
158}
159
160static const igt_rotation_t rotations[] = {
161 IGT_ROTATION_0,
162 IGT_ROTATION_90,
163 IGT_ROTATION_180,
164 IGT_ROTATION_270,
165};
166
167static void test_scaler_with_rotation_pipe(data_t *d, enum pipe pipe,
168 igt_output_t *output)
169{
170 igt_display_t *display = &d->display;
171 igt_plane_t *plane;
172
173 igt_output_set_pipe(output, pipe);
174 for_each_plane_on_pipe(display, pipe, plane) {
175 if (plane->type == DRM_PLANE_TYPE_CURSOR)
176 continue;
177
178 for (int i = 0; i < ARRAY_SIZE(rotations); i++) {
179 igt_rotation_t rot = rotations[i];
180
181 check_scaling_pipe_plane_rot(d, plane, DRM_FORMAT_XRGB8888,
182 LOCAL_I915_FORMAT_MOD_Y_TILED,
183 pipe, output, rot);
184 }
185 }
186}
187
188static bool can_draw(uint32_t drm_format)
189{
190 const uint32_t *drm_formats;
191 int format_count, i;
192
193 igt_get_all_cairo_formats(&drm_formats, &format_count);
194
195 for (i = 0; i < format_count; i++)
196 if (drm_formats[i] == drm_format)
197 return true;
198
199 return false;
200}
201
202static const uint64_t tilings[] = {
203 LOCAL_DRM_FORMAT_MOD_NONE,
204 LOCAL_I915_FORMAT_MOD_X_TILED,
205 LOCAL_I915_FORMAT_MOD_Y_TILED,
206 LOCAL_I915_FORMAT_MOD_Yf_TILED
207};
208
209static void test_scaler_with_pixel_format_pipe(data_t *d, enum pipe pipe, igt_output_t *output)
210{
211 igt_display_t *display = &d->display;
212 igt_plane_t *plane;
213
214 igt_output_set_pipe(output, pipe);
215
216 for_each_plane_on_pipe(display, pipe, plane) {
217 if (plane->type == DRM_PLANE_TYPE_CURSOR)
218 continue;
219
220 for (int i = 0; i < ARRAY_SIZE(tilings); i++) {
221 uint64_t tiling = tilings[i];
222
223 for (int j = 0; j < plane->drm_plane->count_formats; j++) {
224 uint32_t format = plane->drm_plane->formats[j];
225
226 if (can_draw(format))
227 check_scaling_pipe_plane_rot(d, plane,
228 format, tiling,
229 pipe, output, IGT_ROTATION_0);
230 }
231 }
232 }
233}
234
chandra kondurua26f9f92015-03-30 13:52:04 -0700235/* does iterative scaling on plane2 */
236static void iterate_plane_scaling(data_t *d, drmModeModeInfo *mode)
237{
238 igt_display_t *display = &d->display;
239
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100240 if (mode->hdisplay >= d->fb[1].width) {
chandra kondurua26f9f92015-03-30 13:52:04 -0700241 int w, h;
242 /* fixed fb */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100243 igt_fb_set_position(&d->fb[1], d->plane2, 0, 0);
244 igt_fb_set_size(&d->fb[1], d->plane2, d->fb[1].width, d->fb[1].height);
chandra kondurua26f9f92015-03-30 13:52:04 -0700245 igt_plane_set_position(d->plane2, 0, 0);
246
247 /* adjust plane size */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100248 for (w = d->fb[1].width; w <= mode->hdisplay; w+=10) {
249 h = w * d->fb[1].height / d->fb[1].width;
chandra kondurua26f9f92015-03-30 13:52:04 -0700250 igt_plane_set_size(d->plane2, w, h);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100251 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700252 }
253 } else {
254 int w, h;
255 /* fixed plane */
256 igt_plane_set_position(d->plane2, 0, 0);
257 igt_plane_set_size(d->plane2, mode->hdisplay, mode->vdisplay);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100258 igt_fb_set_position(&d->fb[1], d->plane2, 0, 0);
chandra kondurua26f9f92015-03-30 13:52:04 -0700259
260 /* adjust fb size */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100261 for (w = mode->hdisplay; w <= d->fb[1].width; w+=10) {
Mahesh Kumar085d4142017-12-13 15:20:47 +0530262 /* Source coordinates must not be clipped. */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100263 h = min(w * mode->hdisplay / mode->vdisplay, d->fb[1].height);
264 igt_fb_set_size(&d->fb[1], d->plane2, w, h);
265 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700266 }
267 }
268}
269
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100270static void
271test_plane_scaling_on_pipe(data_t *d, enum pipe pipe, igt_output_t *output)
chandra kondurua26f9f92015-03-30 13:52:04 -0700272{
273 igt_display_t *display = &d->display;
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100274 drmModeModeInfo *mode;
chandra kondurua26f9f92015-03-30 13:52:04 -0700275 int primary_plane_scaling = 0; /* For now */
276
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100277 mode = igt_output_get_mode(output);
chandra kondurua26f9f92015-03-30 13:52:04 -0700278
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100279 /* Set up display with plane 1 */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100280 d->plane1 = &display->pipes[pipe].planes[0];
281 prepare_crtc(d, output, pipe, d->plane1, mode);
282
283 igt_create_color_pattern_fb(display->drm_fd, 600, 600,
284 DRM_FORMAT_XRGB8888,
285 LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
286 .5, .5, .5, &d->fb[1]);
287
288 igt_create_pattern_fb(d->drm_fd,
289 mode->hdisplay, mode->vdisplay,
290 DRM_FORMAT_XRGB8888,
291 LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
292 &d->fb[2]);
chandra kondurua26f9f92015-03-30 13:52:04 -0700293
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100294 if (primary_plane_scaling) {
295 /* Primary plane upscaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100296 igt_fb_set_position(&d->fb[0], d->plane1, 100, 100);
297 igt_fb_set_size(&d->fb[0], d->plane1, 500, 500);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100298 igt_plane_set_position(d->plane1, 0, 0);
299 igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100300 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700301
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100302 /* Primary plane 1:1 no scaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100303 igt_fb_set_position(&d->fb[0], d->plane1, 0, 0);
304 igt_fb_set_size(&d->fb[0], d->plane1, d->fb[0].width, d->fb[0].height);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100305 igt_plane_set_position(d->plane1, 0, 0);
306 igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100307 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100308 }
chandra kondurua26f9f92015-03-30 13:52:04 -0700309
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100310 /* Set up fb[1]->plane2 mapping. */
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100311 d->plane2 = igt_output_get_plane(output, 1);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100312 igt_plane_set_fb(d->plane2, &d->fb[1]);
chandra kondurua26f9f92015-03-30 13:52:04 -0700313
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100314 /* 2nd plane windowed */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100315 igt_fb_set_position(&d->fb[1], d->plane2, 100, 100);
316 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 +0100317 igt_plane_set_position(d->plane2, 100, 100);
318 igt_plane_set_size(d->plane2, mode->hdisplay-200, mode->vdisplay-200);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100319 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700320
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100321 iterate_plane_scaling(d, mode);
chandra kondurua26f9f92015-03-30 13:52:04 -0700322
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100323 /* 2nd plane up scaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100324 igt_fb_set_position(&d->fb[1], d->plane2, 100, 100);
325 igt_fb_set_size(&d->fb[1], d->plane2, 500, 500);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100326 igt_plane_set_position(d->plane2, 10, 10);
327 igt_plane_set_size(d->plane2, mode->hdisplay-20, mode->vdisplay-20);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100328 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700329
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100330 /* 2nd plane downscaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100331 igt_fb_set_position(&d->fb[1], d->plane2, 0, 0);
332 igt_fb_set_size(&d->fb[1], d->plane2, d->fb[1].width, d->fb[1].height);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100333 igt_plane_set_position(d->plane2, 10, 10);
Mahesh Kumar085d4142017-12-13 15:20:47 +0530334
335 /* Downscale (10/9)x of original image */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100336 igt_plane_set_size(d->plane2, (d->fb[1].width * 10)/9, (d->fb[1].height * 10)/9);
337 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100338
339 if (primary_plane_scaling) {
340 /* Primary plane up scaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100341 igt_fb_set_position(&d->fb[0], d->plane1, 100, 100);
342 igt_fb_set_size(&d->fb[0], d->plane1, 500, 500);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100343 igt_plane_set_position(d->plane1, 0, 0);
344 igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100345 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100346 }
347
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100348 /* Set up fb[2]->plane3 mapping. */
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100349 d->plane3 = igt_output_get_plane(output, 2);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100350 igt_plane_set_fb(d->plane3, &d->fb[2]);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100351
Mahesh Kumar085d4142017-12-13 15:20:47 +0530352 if(d->plane3->type == DRM_PLANE_TYPE_CURSOR) {
353 igt_debug("Plane-3 doesnt exist on pipe %s\n", kmstest_pipe_name(pipe));
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100354 return;
Mahesh Kumar085d4142017-12-13 15:20:47 +0530355 }
356
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100357 /* 3rd plane windowed - no scaling */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100358 igt_fb_set_position(&d->fb[2], d->plane3, 100, 100);
359 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 +0100360 igt_plane_set_position(d->plane3, 100, 100);
361 igt_plane_set_size(d->plane3, mode->hdisplay-300, mode->vdisplay-300);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100362 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100363
364 /* Switch scaler from plane 2 to plane 3 */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100365 igt_fb_set_position(&d->fb[1], d->plane2, 100, 100);
366 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 +0100367 igt_plane_set_position(d->plane2, 100, 100);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100368 igt_plane_set_size(d->plane2, d->fb[1].width-200, d->fb[1].height-200);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100369
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100370 igt_fb_set_position(&d->fb[2], d->plane3, 100, 100);
371 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 +0100372 igt_plane_set_position(d->plane3, 10, 10);
373 igt_plane_set_size(d->plane3, mode->hdisplay-300, mode->vdisplay-300);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100374 igt_display_commit2(display, COMMIT_ATOMIC);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100375
376 if (primary_plane_scaling) {
377 /* Switch scaler from plane 1 to plane 2 */
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100378 igt_fb_set_position(&d->fb[0], d->plane1, 0, 0);
379 igt_fb_set_size(&d->fb[0], d->plane1, d->fb[0].width, d->fb[0].height);
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100380 igt_plane_set_position(d->plane1, 0, 0);
381 igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
382
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100383 igt_fb_set_position(&d->fb[1], d->plane2, 100, 100);
384 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 -0700385 igt_plane_set_position(d->plane2, 100, 100);
386 igt_plane_set_size(d->plane2, mode->hdisplay-200, mode->vdisplay-200);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100387 igt_display_commit2(display, COMMIT_ATOMIC);
chandra kondurua26f9f92015-03-30 13:52:04 -0700388 }
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100389}
390
Jyoti Yadav47430122017-12-13 15:20:51 +0530391static void
392test_scaler_with_clipping_clamping_scenario(data_t *d, enum pipe pipe, igt_output_t *output)
393{
394 drmModeModeInfo *mode;
395
396 igt_require(get_num_scalers(d->devid, pipe) >= 2);
397
398 mode = igt_output_get_mode(output);
399 d->plane1 = &d->display.pipes[pipe].planes[0];
400 prepare_crtc(d, output, pipe, d->plane1, mode);
401
402 igt_create_pattern_fb(d->drm_fd,
403 mode->hdisplay, mode->vdisplay,
404 DRM_FORMAT_XRGB8888,
405 LOCAL_I915_FORMAT_MOD_X_TILED, &d->fb[1]);
406
407 igt_create_pattern_fb(d->drm_fd,
408 mode->hdisplay, mode->vdisplay,
409 DRM_FORMAT_XRGB8888,
410 LOCAL_I915_FORMAT_MOD_Y_TILED, &d->fb[2]);
411
412 igt_plane_set_fb(d->plane1, &d->fb[1]);
413 d->plane2 = igt_output_get_plane(output, 1);
414 igt_plane_set_fb(d->plane2, &d->fb[2]);
415
416 igt_fb_set_position(&d->fb[1], d->plane1, 0, 0);
417 igt_fb_set_size(&d->fb[1], d->plane1, 300, 300);
418 igt_plane_set_position(d->plane1, 100, 400);
419 igt_fb_set_position(&d->fb[2], d->plane2, 0, 0);
420 igt_fb_set_size(&d->fb[2], d->plane2, 400, 400);
421 igt_plane_set_position(d->plane2, 100, 100);
422
423 /* scaled window size is outside the modeset area.*/
424 igt_plane_set_size(d->plane1, mode->hdisplay + 200,
425 mode->vdisplay + 200);
426 igt_plane_set_size(d->plane2, mode->hdisplay + 100,
427 mode->vdisplay + 100);
428 igt_display_commit2(&d->display, COMMIT_ATOMIC);
429}
430
Jyoti Yadavf4a1e0d2017-12-13 15:20:52 +0530431static void find_connected_pipe(igt_display_t *display, bool second, enum pipe *pipe, igt_output_t **output)
432{
433 enum pipe first = PIPE_NONE;
434 igt_output_t *first_output = NULL;
435 bool found = false;
436
437 for_each_pipe_with_valid_output(display, *pipe, *output) {
438 if (first == *pipe || *output == first_output)
439 continue;
440
441 if (second) {
442 first = *pipe;
443 first_output = *output;
444 second = false;
445 continue;
446 }
447
448 return;
449 }
450
451 if (first_output)
452 igt_require_f(found, "No second valid output found\n");
453 else
454 igt_require_f(found, "No valid outputs found\n");
455}
456
457static void test_scaler_with_multi_pipe_plane(data_t *d)
458{
459 igt_display_t *display = &d->display;
460 igt_output_t *output1, *output2;
461 drmModeModeInfo *mode1, *mode2;
462 enum pipe pipe1, pipe2;
463
464 cleanup_crtc(d);
465
466 find_connected_pipe(display, false, &pipe1, &output1);
467 find_connected_pipe(display, true, &pipe2, &output2);
468
469 igt_skip_on(!output1 || !output2);
470
471 igt_output_set_pipe(output1, pipe1);
472 igt_output_set_pipe(output2, pipe2);
473
474 d->plane1 = igt_output_get_plane(output1, 0);
475 d->plane2 = get_num_scalers(d->devid, pipe1) >= 2 ? igt_output_get_plane(output1, 1) : NULL;
476 d->plane3 = igt_output_get_plane(output2, 0);
477 d->plane4 = get_num_scalers(d->devid, pipe2) >= 2 ? igt_output_get_plane(output2, 1) : NULL;
478
479 mode1 = igt_output_get_mode(output1);
480 mode2 = igt_output_get_mode(output2);
481
482 igt_create_pattern_fb(d->drm_fd, 600, 600,
483 DRM_FORMAT_XRGB8888,
484 LOCAL_I915_FORMAT_MOD_Y_TILED, &d->fb[0]);
485
486 igt_create_pattern_fb(d->drm_fd, 500, 500,
487 DRM_FORMAT_XRGB8888,
488 LOCAL_I915_FORMAT_MOD_Y_TILED, &d->fb[1]);
489
490 igt_create_pattern_fb(d->drm_fd, 700, 700,
491 DRM_FORMAT_XRGB8888,
492 LOCAL_I915_FORMAT_MOD_Y_TILED, &d->fb[2]);
493
494 igt_create_pattern_fb(d->drm_fd, 400, 400,
495 DRM_FORMAT_XRGB8888,
496 LOCAL_I915_FORMAT_MOD_Y_TILED, &d->fb[3]);
497
498 igt_plane_set_fb(d->plane1, &d->fb[0]);
499 if (d->plane2)
500 igt_plane_set_fb(d->plane2, &d->fb[1]);
501 igt_plane_set_fb(d->plane3, &d->fb[2]);
502 if (d->plane4)
503 igt_plane_set_fb(d->plane4, &d->fb[3]);
504 igt_display_commit2(display, COMMIT_ATOMIC);
505
506 /* Upscaling Primary */
507 igt_plane_set_size(d->plane1, mode1->hdisplay, mode1->vdisplay);
508 igt_plane_set_size(d->plane3, mode2->hdisplay, mode2->vdisplay);
509 igt_display_commit2(display, COMMIT_ATOMIC);
510
511 /* Upscaling Sprites */
512 igt_plane_set_size(d->plane2 ?: d->plane1, mode1->hdisplay, mode1->vdisplay);
513 igt_plane_set_size(d->plane4 ?: d->plane3, mode2->hdisplay, mode2->vdisplay);
514 igt_display_commit2(display, COMMIT_ATOMIC);
515}
516
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100517igt_main
chandra kondurua26f9f92015-03-30 13:52:04 -0700518{
519 data_t data = {};
Maarten Lankhorsteeefac92018-01-09 12:58:48 +0100520 enum pipe pipe;
chandra kondurua26f9f92015-03-30 13:52:04 -0700521
522 igt_skip_on_simulation();
523
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100524 igt_fixture {
525 data.drm_fd = drm_open_driver(DRIVER_INTEL);
526 igt_require_pipe_crc(data.drm_fd);
527 igt_display_init(&data.display, data.drm_fd);
528 data.devid = intel_get_drm_devid(data.drm_fd);
Maarten Lankhorst1538eb62018-01-11 15:03:50 +0100529 igt_require(data.display.is_atomic);
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100530 }
chandra kondurua26f9f92015-03-30 13:52:04 -0700531
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100532 for_each_pipe_static(pipe) igt_subtest_group {
533 igt_output_t *output;
chandra kondurua26f9f92015-03-30 13:52:04 -0700534
Maarten Lankhorst1fb3faa2018-01-15 11:11:39 +0100535 igt_fixture {
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100536 igt_display_require_output_on_pipe(&data.display, pipe);
chandra kondurua26f9f92015-03-30 13:52:04 -0700537
Maarten Lankhorst1fb3faa2018-01-15 11:11:39 +0100538 igt_require(get_num_scalers(data.devid, pipe) > 0);
539 }
540
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100541 igt_subtest_f("pipe-%s-plane-scaling", kmstest_pipe_name(pipe))
542 for_each_valid_output_on_pipe(&data.display, pipe, output)
543 test_plane_scaling_on_pipe(&data, pipe, output);
Jyoti Yadav27a4e792017-12-13 15:20:50 +0530544
545 igt_subtest_f("pipe-%s-scaler-with-pixel-format", kmstest_pipe_name(pipe))
546 for_each_valid_output_on_pipe(&data.display, pipe, output)
547 test_scaler_with_pixel_format_pipe(&data, pipe, output);
548
549 igt_subtest_f("pipe-%s-scaler-with-rotation", kmstest_pipe_name(pipe))
550 for_each_valid_output_on_pipe(&data.display, pipe, output)
551 test_scaler_with_rotation_pipe(&data, pipe, output);
552
Jyoti Yadav47430122017-12-13 15:20:51 +0530553 igt_subtest_f("pipe-%s-scaler-with-clipping-clamping", kmstest_pipe_name(pipe))
554 for_each_valid_output_on_pipe(&data.display, pipe, output)
555 test_scaler_with_clipping_clamping_scenario(&data, pipe, output);
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100556 }
chandra kondurua26f9f92015-03-30 13:52:04 -0700557
Jyoti Yadavf4a1e0d2017-12-13 15:20:52 +0530558 igt_subtest_f("2x-scaler-multi-pipe")
559 test_scaler_with_multi_pipe_plane(&data);
560
Maarten Lankhorstc54ed642018-01-11 12:33:39 +0100561 igt_fixture
562 igt_display_fini(&data.display);
chandra kondurua26f9f92015-03-30 13:52:04 -0700563}