kms_rotation_crc: Allow the sprite test to run even without universal planes
[platform/upstream/intel-gpu-tools.git] / tests / kms_rotation_crc.c
1 /*
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
25 #include <errno.h>
26 #include <limits.h>
27 #include <stdbool.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/ioctl.h>
31 #include <stdint.h>
32 #include <stddef.h>
33 #include <fcntl.h>
34 #include <math.h>
35
36 #include "drmtest.h"
37 #include "igt_debugfs.h"
38 #include "igt_kms.h"
39 #include "igt_core.h"
40
41 #define DRM_ROTATE_0   0
42 #define DRM_ROTATE_90  1
43 #define DRM_ROTATE_180 2
44 #define DRM_ROTATE_270 3
45
46 typedef struct {
47         int gfx_fd;
48         igt_display_t display;
49         struct igt_fb fb;
50         igt_crc_t ref_crc;
51         igt_pipe_crc_t *pipe_crc;
52 } data_t;
53
54 static void
55 paint_squares(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode,
56               uint32_t rotation)
57 {
58         cairo_t *cr;
59         int w, h;
60
61         w = mode->hdisplay;
62         h = mode->vdisplay;
63
64         cr = igt_get_cairo_ctx(data->gfx_fd, &data->fb);
65
66         if (rotation == DRM_ROTATE_180) {
67                 cairo_translate(cr, w, h);
68                 cairo_rotate(cr, M_PI);
69         }
70
71         /* Paint with 4 squares of Red, Green, White, Blue Clockwise */
72         igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0);
73         igt_paint_color(cr, (w / 2) - 1, 0, w / 2, h / 2, 0.0, 1.0, 0.0);
74         igt_paint_color(cr, 0, (h / 2) - 1, w / 2, h / 2, 0.0, 0.0, 1.0);
75         igt_paint_color(cr, (w / 2) - 1, (h / 2) - 1, w / 2, h / 2, 1.0, 1.0, 1.0);
76
77         cairo_destroy(cr);
78 }
79
80 static bool prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
81                          igt_plane_t *plane)
82 {
83         drmModeModeInfo *mode;
84         igt_display_t *display = &data->display;
85         int fb_id;
86
87         igt_output_set_pipe(output, pipe);
88         igt_display_commit(display);
89
90         /* create the pipe_crc object for this pipe */
91         igt_pipe_crc_free(data->pipe_crc);
92         data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
93         if (!data->pipe_crc) {
94                 igt_info("auto crc not supported on this connector with pipe %i\n",
95                          pipe);
96                 return false;
97         }
98
99         mode = igt_output_get_mode(output);
100
101         fb_id = igt_create_fb(data->gfx_fd,
102                         mode->hdisplay, mode->vdisplay,
103                         DRM_FORMAT_XRGB8888,
104                         false, /* tiled */
105                         &data->fb);
106         igt_assert(fb_id);
107
108         paint_squares(data, &data->fb, mode, DRM_ROTATE_180);
109
110         igt_plane_set_fb(plane, &data->fb);
111         igt_display_commit(display);
112
113         /* Collect reference crc */
114         igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
115
116         paint_squares(data, &data->fb, mode, DRM_ROTATE_0);
117
118         igt_plane_set_fb(plane, &data->fb);
119         igt_display_commit(display);
120
121         return true;
122 }
123
124 static void cleanup_crtc(data_t *data, igt_output_t *output, igt_plane_t *plane)
125 {
126         igt_display_t *display = &data->display;
127
128         igt_pipe_crc_free(data->pipe_crc);
129         data->pipe_crc = NULL;
130
131         igt_remove_fb(data->gfx_fd, &data->fb);
132         igt_plane_set_fb(plane, NULL);
133         igt_output_set_pipe(output, PIPE_ANY);
134
135         igt_display_commit(display);
136 }
137
138 static void test_plane_rotation(data_t *data, enum igt_plane plane_type)
139 {
140         igt_display_t *display = &data->display;
141         igt_output_t *output;
142         enum pipe pipe;
143         int valid_tests = 0;
144         igt_crc_t crc_output;
145         enum igt_commit_style commit = COMMIT_LEGACY;
146
147         if (plane_type == IGT_PLANE_PRIMARY) {
148                 igt_require(data->display.has_universal_planes);
149                 commit = COMMIT_UNIVERSAL;
150         }
151
152         for_each_connected_output(display, output) {
153                 for_each_pipe(display, pipe) {
154                         igt_plane_t *plane;
155
156                         igt_output_set_pipe(output, pipe);
157
158                         plane = igt_output_get_plane(output, plane_type);
159                         igt_require(igt_plane_supports_rotation(plane));
160
161                         if (!prepare_crtc(data, output, pipe, plane))
162                                 continue;
163
164                         igt_plane_set_rotation(plane, IGT_ROTATION_180);
165                         igt_display_commit2(display, commit);
166
167                         igt_pipe_crc_collect_crc(data->pipe_crc, &crc_output);
168                         igt_assert(igt_crc_equal(&data->ref_crc, &crc_output));
169
170                         valid_tests++;
171                         cleanup_crtc(data, output, plane);
172                 }
173         }
174         igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
175 }
176
177 igt_main
178 {
179         data_t data = {};
180
181         igt_skip_on_simulation();
182
183         igt_fixture {
184                 data.gfx_fd = drm_open_any();
185
186                 igt_set_vt_graphics_mode();
187
188                 igt_require_pipe_crc();
189
190                 igt_display_init(&data.display, data.gfx_fd);
191         }
192
193         igt_subtest_f("primary-rotation")
194                 test_plane_rotation(&data, IGT_PLANE_PRIMARY);
195
196         igt_subtest_f("sprite-rotation")
197                 test_plane_rotation(&data, IGT_PLANE_2);
198
199         igt_fixture {
200                 igt_display_fini(&data.display);
201         }
202 }