Skip to contentSkip to conversation

kms_rotation_crc:Add HW rotation test case for amdgpu

PATCH Superseded Sung Joon Kim 3 participants 5 messages Dec 16, 2020 – Dec 17, 2020 1 message not in the archive

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 kms_rotation_crc:Add HW rotation test case for amdgpu

Added Hw rotation case specifically for amdgpu. Currently, kms_rotation_crc tests intel gpus. Added conditions to bypass all the requirements needed for intel when testing amdgpu.

---
 tests/kms_rotation_crc.c | 1971 +++++++++++++++++++-------------------
 1 file changed, 1011 insertions(+), 960 deletions(-)
tests/kms_rotation_crc.c +1011 -960
index ffcc2cc2..f4f36144 100644
@@ -1,960 +1,1011 @@
-/*
- * Copyright © 2013,2014 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- */
-
-#include "igt.h"
-#include "igt_vec.h"
-#include <math.h>
-
-#define MAX_FENCES 32
-#define MAXMULTIPLANESAMOUNT 2
-#define TEST_MAX_WIDTH 640
-#define TEST_MAX_HEIGHT 480
-
-struct p_struct {
-	igt_plane_t *plane;
-	struct igt_fb fb;
-};
-
-enum p_pointorigo {
-	p_top = 1 << 0,
-	p_bottom = 1 << 1,
-	p_left = 1 << 2,
-	p_right = 1 << 3
-};
-
-struct p_point{
-	enum p_pointorigo origo;
-	float_t x;
-	float_t y;
-};
-
-typedef struct {
-	int gfx_fd;
-	igt_display_t display;
-	struct igt_fb fb;
-	struct igt_fb fb_reference;
-	struct igt_fb fb_flip;
-	igt_crc_t ref_crc;
-	igt_crc_t flip_crc;
-	igt_pipe_crc_t *pipe_crc;
-	igt_rotation_t rotation;
-	int pos_x;
-	int pos_y;
-	uint32_t override_fmt;
-	uint64_t override_tiling;
-	int devid;
-
-	struct p_struct *multiplaneoldview;
-	struct p_point planepos[MAXMULTIPLANESAMOUNT];
-
-	bool use_native_resolution;
-	bool extended;
-} data_t;
-
-typedef struct {
-	float r;
-	float g;
-	float b;
-} rgb_color_t;
-
-static void set_color(rgb_color_t *color, float r, float g, float b)
-{
-	color->r = r;
-	color->g = g;
-	color->b = b;
-}
-
-static void rotate_colors(rgb_color_t *tl, rgb_color_t *tr, rgb_color_t *br,
-			  rgb_color_t *bl, igt_rotation_t rotation)
-{
-	rgb_color_t bl_tmp, br_tmp, tl_tmp, tr_tmp;
-
-	if (rotation & IGT_REFLECT_X) {
-		igt_swap(*tl, *tr);
-		igt_swap(*bl, *br);
-	}
-
-	if (rotation & IGT_ROTATION_90) {
-		bl_tmp = *bl;
-		br_tmp = *br;
-		tl_tmp = *tl;
-		tr_tmp = *tr;
-		*tl = tr_tmp;
-		*bl = tl_tmp;
-		*tr = br_tmp;
-		*br = bl_tmp;
-	} else if (rotation & IGT_ROTATION_180) {
-		igt_swap(*tl, *br);
-		igt_swap(*tr, *bl);
-	} else if (rotation & IGT_ROTATION_270) {
-		bl_tmp = *bl;
-		br_tmp = *br;
-		tl_tmp = *tl;
-		tr_tmp = *tr;
-		*tl = bl_tmp;
-		*bl = br_tmp;
-		*tr = tl_tmp;
-		*br = tr_tmp;
-	}
-}
-
-#define RGB_COLOR(color) \
-	color.r, color.g, color.b
-
-static void
-paint_squares(data_t *data, igt_rotation_t rotation,
-	      struct igt_fb *fb, float o)
-{
-	cairo_t *cr;
-	unsigned int w = fb->width;
-	unsigned int h = fb->height;
-	rgb_color_t tl, tr, bl, br;
-
-	igt_assert_f(!(w&1), "rotation image must be even width, now attempted %d\n", w);
-	igt_assert_f(!(h&1), "rotation image must be even height, now attempted %d\n", h);
-
-	cr = igt_get_cairo_ctx(data->gfx_fd, fb);
-
-	set_color(&tl, o, 0.0f, 0.0f);
-	set_color(&tr, 0.0f, o, 0.0f);
-	set_color(&br, o, o, o);
-	set_color(&bl, 0.0f, 0.0f, o);
-
-	rotate_colors(&tl, &tr, &br, &bl, rotation);
-
-	igt_paint_color(cr, 0, 0, w / 2, h / 2, RGB_COLOR(tl));
-	igt_paint_color(cr, w / 2, 0, w / 2, h / 2, RGB_COLOR(tr));
-	igt_paint_color(cr, 0, h / 2, w / 2, h / 2, RGB_COLOR(bl));
-	igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, RGB_COLOR(br));
-
-	igt_put_cairo_ctx(cr);
-}
-
-static void remove_fbs(data_t *data)
-{
-	igt_remove_fb(data->gfx_fd, &data->fb);
-	igt_remove_fb(data->gfx_fd, &data->fb_reference);
-	igt_remove_fb(data->gfx_fd, &data->fb_flip);
-}
-
-static void cleanup_crtc(data_t *data)
-{
-	igt_display_t *display = &data->display;
-
-	igt_pipe_crc_free(data->pipe_crc);
-	data->pipe_crc = NULL;
-
-	remove_fbs(data);
-
-	igt_display_reset(display);
-}
-
-static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
-			 igt_plane_t *plane, bool start_crc)
-{
-	igt_display_t *display = &data->display;
-
-	cleanup_crtc(data);
-
-	igt_output_set_pipe(output, pipe);
-	igt_plane_set_rotation(plane, IGT_ROTATION_0);
-
-	/* create the pipe_crc object for this pipe */
-	igt_pipe_crc_free(data->pipe_crc);
-
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
-
-	if (start_crc)
-		igt_pipe_crc_start(data->pipe_crc);
-}
-
-enum rectangle_type {
-	rectangle,
-	square,
-	portrait,
-	landscape,
-	num_rectangle_types /* must be last */
-};
-
-static void prepare_fbs(data_t *data, igt_output_t *output,
-			igt_plane_t *plane, enum rectangle_type rect, uint32_t format)
-{
-	drmModeModeInfo *mode;
-	igt_display_t *display = &data->display;
-	unsigned int w, h, ref_w, ref_h, min_w, min_h;
-	uint64_t tiling = data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE;
-	uint32_t pixel_format = data->override_fmt ?: DRM_FORMAT_XRGB8888;
-	const float flip_opacity = 0.75;
-
-	remove_fbs(data);
-
-	igt_plane_set_rotation(plane, IGT_ROTATION_0);
-
-	mode = igt_output_get_mode(output);
-	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
-		if (data->use_native_resolution) {
-			w = mode->hdisplay;
-			h = mode->vdisplay;
-		} else {
-			w = min(TEST_MAX_WIDTH, mode->hdisplay);
-			h = min(TEST_MAX_HEIGHT, mode->vdisplay);
-		}
-
-		min_w = 256;
-		min_h = 256;
-	} else {
-		pixel_format = data->override_fmt ?: DRM_FORMAT_ARGB8888;
-
-		w = h = 256;
-		min_w = min_h = 64;
-	}
-
-	switch (rect) {
-	case rectangle:
-		break;
-	case square:
-		w = h = min(h, w);
-		break;
-	case portrait:
-		w = min_w;
-		break;
-	case landscape:
-		h = min_h;
-		break;
-	case num_rectangle_types:
-		igt_assert(0);
-	}
-
-	ref_w = w;
-	ref_h = h;
-
-	/*
-	 * For 90/270, we will use create smaller fb so that the rotated
-	 * frame can fit in
-	 */
-	if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270)) {
-		tiling = data->override_tiling ?: LOCAL_I915_FORMAT_MOD_Y_TILED;
-
-		igt_swap(w, h);
-	}
-
-	/*
-	 * Just try here if requested tiling format is generally available,
-	 * if one format fail it will skip entire subtest.
-	 */
-	igt_require(igt_display_has_format_mod(display, pixel_format, tiling));
-
-	/*
-	 * Create a reference software rotated flip framebuffer.
-	 */
-	igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format, tiling,
-		      &data->fb_flip);
-	paint_squares(data, data->rotation, &data->fb_flip,
-		      flip_opacity);
-	igt_plane_set_fb(plane, &data->fb_flip);
-	if (plane->type != DRM_PLANE_TYPE_CURSOR)
-		igt_plane_set_position(plane, data->pos_x, data->pos_y);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-
-	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->flip_crc);
-
-	/*
-	  * Prepare the non-rotated flip fb.
-	  */
-	igt_remove_fb(data->gfx_fd, &data->fb_flip);
-	igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling,
-		      &data->fb_flip);
-	paint_squares(data, IGT_ROTATION_0, &data->fb_flip,
-		      flip_opacity);
-
-	/*
-	 * Create a reference CRC for a software-rotated fb.
-	 */
-	igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format,
-		      data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE, &data->fb_reference);
-	paint_squares(data, data->rotation, &data->fb_reference, 1.0);
-
-	igt_plane_set_fb(plane, &data->fb_reference);
-	if (plane->type != DRM_PLANE_TYPE_CURSOR)
-		igt_plane_set_position(plane, data->pos_x, data->pos_y);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-
-	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->ref_crc);
-
-	/*
-	 * Prepare the plane with an non-rotated fb let the hw rotate it.
-	 */
-	igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);
-	paint_squares(data, IGT_ROTATION_0, &data->fb, 1.0);
-	igt_plane_set_fb(plane, &data->fb);
-
-	if (plane->type != DRM_PLANE_TYPE_CURSOR)
-		igt_plane_set_position(plane, data->pos_x, data->pos_y);
-}
-
-static void test_single_case(data_t *data, enum pipe pipe,
-			     igt_output_t *output, igt_plane_t *plane,
-			     enum rectangle_type rect,
-			     uint32_t format, bool test_bad_format)
-{
-	igt_display_t *display = &data->display;
-	igt_crc_t crc_output;
-	int ret;
-
-	igt_debug("Testing case %i on pipe %s, format %s\n", rect, kmstest_pipe_name(pipe), igt_format_str(format));
-	prepare_fbs(data, output, plane, rect, format);
-
-	igt_plane_set_rotation(plane, data->rotation);
-	if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
-		igt_plane_set_size(plane, data->fb.height, data->fb.width);
-
-	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
-	if (test_bad_format) {
-		igt_assert_eq(ret, -EINVAL);
-		return;
-	}
-
-	/* Verify commit was ok. */
-	igt_assert_eq(ret, 0);
-
-	/* Check CRC */
-	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);
-	igt_assert_crc_equal(&data->ref_crc, &crc_output);
-
-	/*
-	 * If flips are requested flip to a different fb and
-	 * check CRC against that one as well.
-	 */
-	if (data->fb_flip.fb_id) {
-		igt_plane_set_fb(plane, &data->fb_flip);
-		if (data->rotation == IGT_ROTATION_90 || data->rotation == IGT_ROTATION_270)
-			igt_plane_set_size(plane, data->fb.height, data->fb.width);
-
-		if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
-			igt_display_commit_atomic(display, DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, NULL);
-		} else {
-			ret = drmModePageFlip(data->gfx_fd,
-					output->config.crtc->crtc_id,
-					data->fb_flip.fb_id,
-					DRM_MODE_PAGE_FLIP_EVENT,
-					NULL);
-			igt_assert_eq(ret, 0);
-		}
-		kmstest_wait_for_pageflip(data->gfx_fd);
-		igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);
-		igt_assert_crc_equal(&data->flip_crc,
-				     &crc_output);
-	}
-}
-
-static bool test_format(data_t *data,
-			struct igt_vec *tested_formats,
-			uint32_t format)
-{
-	if (!igt_fb_supported_format(format))
-		return false;
-
-	if (!is_i915_device(data->gfx_fd) ||
-	    data->extended)
-		return true;
-
-	format = igt_reduce_format(format);
-
-	/* only test each format "class" once */
-	if (igt_vec_index(tested_formats, &format) >= 0)
-		return false;
-
-	igt_vec_push(tested_formats, &format);
-
-	return true;
-}
-
-static void test_plane_rotation(data_t *data, int plane_type, bool test_bad_format)
-{
-	igt_display_t *display = &data->display;
-	igt_output_t *output;
-	enum pipe pipe;
-
-	if (plane_type == DRM_PLANE_TYPE_CURSOR)
-		igt_require(display->has_cursor_plane);
-
-	igt_display_require_output(display);
-
-	for_each_pipe_with_valid_output(display, pipe, output) {
-		igt_plane_t *plane;
-		int i, j;
-
-		if (IS_CHERRYVIEW(data->devid) && pipe != PIPE_B)
-			continue;
-
-		igt_output_set_pipe(output, pipe);
-
-		plane = igt_output_get_plane_type(output, plane_type);
-		igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
-
-		prepare_crtc(data, output, pipe, plane, true);
-
-		for (i = 0; i < num_rectangle_types; i++) {
-			/* Unsupported on i915 */
-			if (plane_type == DRM_PLANE_TYPE_CURSOR &&
-			    i != square)
-				continue;
-
-			/* Only support partial covering primary plane on gen9+ */
-			if (plane_type == DRM_PLANE_TYPE_PRIMARY &&
-			    intel_gen(intel_get_drm_devid(data->gfx_fd)) < 9) {
-				if (i != rectangle)
-					continue;
-				else
-					data->use_native_resolution = true;
-			} else {
-				data->use_native_resolution = false;
-			}
-
-			if (!data->override_fmt) {
-				struct igt_vec tested_formats;
-
-				igt_vec_init(&tested_formats, sizeof(uint32_t));
-
-				for (j = 0; j < plane->drm_plane->count_formats; j++) {
-					uint32_t format = plane->drm_plane->formats[j];
-
-					if (!test_format(data, &tested_formats, format))
-						continue;
-
-					test_single_case(data, pipe, output, plane, i,
-							 format, test_bad_format);
-				}
-
-				igt_vec_fini(&tested_formats);
-			} else {
-				test_single_case(data, pipe, output, plane, i,
-						 data->override_fmt, test_bad_format);
-			}
-		}
-		igt_pipe_crc_stop(data->pipe_crc);
-	}
-}
-
-typedef struct {
-	int32_t x1, y1;
-	uint64_t width, height, tiling, planetype, format;
-	igt_rotation_t rotation_sw, rotation_hw;
-} planeinfos;
-
-static bool get_multiplane_crc(data_t *data, igt_output_t *output,
-			       igt_crc_t *crc_output, planeinfos *planeinfo,
-			       int numplanes)
-{
-	uint32_t w, h;
-	igt_display_t *display = &data->display;
-	struct p_struct *planes, *oldplanes;
-	int c, ret;
-
-	oldplanes = data->multiplaneoldview;
-	planes = calloc(sizeof(*planes), numplanes);
-
-	for (c = 0; c < numplanes; c++) {
-		planes[c].plane = igt_output_get_plane_type(output,
-							    planeinfo[c].planetype);
-
-		/*
-		 * make plane and fb width and height always divisible by 4
-		 * due to NV12 support and Intel hw workarounds.
-		 */
-		w = planeinfo[c].width & ~3;
-		h = planeinfo[c].height & ~3;
-
-		if (planeinfo[c].rotation_sw & (IGT_ROTATION_90 | IGT_ROTATION_270))
-			igt_swap(w, h);
-
-		if (!igt_plane_has_format_mod(planes[c].plane,
-					      planeinfo[c].format,
-					      planeinfo[c].tiling))
-			return false;
-
-		igt_create_fb(data->gfx_fd, w, h, planeinfo[c].format,
-			      planeinfo[c].tiling, &planes[c].fb);
-
-		paint_squares(data, planeinfo[c].rotation_sw, &planes[c].fb, 1.0f);
-		igt_plane_set_fb(planes[c].plane, &planes[c].fb);
-
-		if (planeinfo[c].rotation_hw & (IGT_ROTATION_90 | IGT_ROTATION_270))
-			igt_plane_set_size(planes[c].plane, h, w);
-
-		igt_plane_set_position(planes[c].plane, planeinfo[c].x1, planeinfo[c].y1);
-		igt_plane_set_rotation(planes[c].plane, planeinfo[c].rotation_hw);
-	}
-
-	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
-	igt_assert_eq(ret, 0);
-
-	igt_pipe_crc_get_current(data->gfx_fd, data->pipe_crc, crc_output);
-
-	for (c = 0; c < numplanes && oldplanes; c++)
-		igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);
-
-	free(oldplanes);
-	data->multiplaneoldview = (void*)planes;
-	return true;
-}
-
-static void pointlocation(data_t *data, planeinfos *p, drmModeModeInfo *mode,
-			  int c)
-{
-	if (data->planepos[c].origo & p_right) {
-		p[c].x1 = (int32_t)(data->planepos[c].x * min(TEST_MAX_WIDTH, mode->hdisplay)
-				+ mode->hdisplay);
-		p[c].x1 &= ~3;
-		/*
-		 * At this point is handled surface on right side. If display
-		 * mode is not divisible by 4 but with 2 point location is
-		 * fixed to match requirements. Because of YUV planes here is
-		 * intentionally ignored bit 1.
-		 */
-		p[c].x1 -= mode->hdisplay & 2;
-	} else {
-		p[c].x1 = (int32_t)(data->planepos[c].x * min(TEST_MAX_WIDTH, mode->hdisplay));
-		p[c].x1 &= ~3;
-	}
-
-	if (data->planepos[c].origo & p_bottom) {
-		p[c].y1 = (int32_t)(data->planepos[c].y * min(TEST_MAX_HEIGHT, mode->vdisplay)
-				+ mode->vdisplay);
-		p[c].y1 &= ~3;
-		p[c].y1 -= mode->vdisplay & 2;
-	} else {
-		p[c].y1 = (int32_t)(data->planepos[c].y * min(TEST_MAX_HEIGHT, mode->vdisplay));
-		p[c].y1 &= ~3;
-	}
-}
-
-/*
- * Here is pipe parameter which is now used only for first pipe.
- * It is left here if this test ever was wanted to be run on
- * different pipes.
- */
-static void test_multi_plane_rotation(data_t *data, enum pipe pipe)
-{
-	igt_display_t *display = &data->display;
-	igt_output_t *output;
-	igt_crc_t retcrc_sw, retcrc_hw;
-	planeinfos p[2];
-	int c, used_w, used_h;
-	struct p_struct *oldplanes;
-	drmModeModeInfo *mode;
-
-	static const struct {
-		igt_rotation_t rotation;
-		float_t width;
-		float_t height;
-		uint64_t tiling;
-	} planeconfigs[] = {
-	{IGT_ROTATION_0, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },
-	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },
-	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
-	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
-	{IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
-	{IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
-	{IGT_ROTATION_180, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },
-	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },
-	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
-	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
-	{IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
-	{IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
-	};
-
-	/*
-	* These are those modes which are tested. For testing feel interesting
-	* case with tiling are 2 bpp, 4 bpp and NV12.
-	*/
-	static const uint32_t formatlist[] = {DRM_FORMAT_RGB565,
-		DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12};
-
-	for_each_valid_output_on_pipe(display, pipe, output) {
-		int i, j, k, l;
-		igt_output_set_pipe(output, pipe);
-		mode = igt_output_get_mode(output);
-		igt_display_require_output(display);
-		igt_display_commit2(display, COMMIT_ATOMIC);
-
-		used_w = min(TEST_MAX_WIDTH, mode->hdisplay);
-		used_h = min(TEST_MAX_HEIGHT, mode->vdisplay);
-
-		data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe,
-						  INTEL_PIPE_CRC_SOURCE_AUTO);
-		igt_pipe_crc_start(data->pipe_crc);
-
-		for (i = 0; i < ARRAY_SIZE(planeconfigs); i++) {
-			p[0].planetype = DRM_PLANE_TYPE_PRIMARY;
-			p[0].width = (uint64_t)(planeconfigs[i].width * used_w);
-			p[0].height = (uint64_t)(planeconfigs[i].height * used_h);
-			p[0].tiling = planeconfigs[i].tiling;
-			pointlocation(data, (planeinfos *)&p, mode, 0);
-
-			for (k = 0; k < ARRAY_SIZE(formatlist); k++) {
-				p[0].format = formatlist[k];
-
-				for (j = 0; j < ARRAY_SIZE(planeconfigs); j++) {
-					p[1].planetype = DRM_PLANE_TYPE_OVERLAY;
-					p[1].width = (uint64_t)(planeconfigs[j].width * used_w);
-					p[1].height = (uint64_t)(planeconfigs[j].height * used_h);
-					p[1].tiling = planeconfigs[j].tiling;
-					pointlocation(data, (planeinfos *)&p,
-						      mode, 1);
-
-					for (l = 0; l < ARRAY_SIZE(formatlist); l++) {
-						p[1].format = formatlist[l];
-
-						/*
-						 * RGB565 90/270 degrees rotation is supported
-						 * from gen11 onwards.
-						 */
-						if (p[0].format == DRM_FORMAT_RGB565 &&
-						     (planeconfigs[i].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
-						     && intel_gen(data->devid) < 11)
-							continue;
-
-						if (p[1].format == DRM_FORMAT_RGB565 &&
-						     (planeconfigs[j].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
-						     && intel_gen(data->devid) < 11)
-							continue;
-
-						p[0].rotation_sw = planeconfigs[i].rotation;
-						p[0].rotation_hw = IGT_ROTATION_0;
-						p[1].rotation_sw = planeconfigs[j].rotation;
-						p[1].rotation_hw = IGT_ROTATION_0;
-						if (!get_multiplane_crc(data, output, &retcrc_sw,
-								   (planeinfos *)&p, MAXMULTIPLANESAMOUNT))
-							continue;
-
-						igt_swap(p[0].rotation_sw, p[0].rotation_hw);
-						igt_swap(p[1].rotation_sw, p[1].rotation_hw);
-						if (!get_multiplane_crc(data, output, &retcrc_hw,
-								   (planeinfos *)&p, MAXMULTIPLANESAMOUNT))
-							continue;
-
-						igt_assert_crc_equal(&retcrc_sw, &retcrc_hw);
-					}
-				}
-			}
-		}
-		igt_pipe_crc_stop(data->pipe_crc);
-		igt_pipe_crc_free(data->pipe_crc);
-		igt_output_set_pipe(output, PIPE_ANY);
-	}
-
-	/*
-	* Old fbs are deleted only after new ones are set on planes.
-	* This is done to speed up the test
-	*/
-	oldplanes = data->multiplaneoldview;
-	for (c = 0; c < MAXMULTIPLANESAMOUNT && oldplanes; c++)
-		igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);
-
-	free(oldplanes);
-	data->multiplaneoldview = NULL;
-	data->pipe_crc = NULL;
-}
-
-static void test_plane_rotation_exhaust_fences(data_t *data,
-					       enum pipe pipe,
-					       igt_output_t *output,
-					       igt_plane_t *plane)
-{
-	igt_display_t *display = &data->display;
-	uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
-	uint32_t format = DRM_FORMAT_XRGB8888;
-	int fd = data->gfx_fd;
-	drmModeModeInfo *mode;
-	struct igt_fb fb[MAX_FENCES+1] = {};
-	uint64_t size;
-	unsigned int stride, w, h;
-	uint64_t total_aperture_size, total_fbs_size;
-	int i;
-
-	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
-
-	prepare_crtc(data, output, pipe, plane, false);
-
-	mode = igt_output_get_mode(output);
-	w = mode->hdisplay;
-	h = mode->vdisplay;
-
-	igt_calc_fb_size(fd, w, h, format, tiling, &size, &stride);
-
-	/*
-	 * Make sure there is atleast 90% of the available GTT space left
-	 * for creating (MAX_FENCES+1) framebuffers.
-	 */
-	total_fbs_size = size * (MAX_FENCES + 1);
-	total_aperture_size = gem_available_aperture_size(fd);
-	igt_require(total_fbs_size < total_aperture_size * 0.9);
-
-	for (i = 0; i < MAX_FENCES + 1; i++) {
-		igt_create_fb(fd, w, h, format, tiling, &fb[i]);
-
-		igt_plane_set_fb(plane, &fb[i]);
-		igt_plane_set_rotation(plane, IGT_ROTATION_0);
-		igt_display_commit2(display, COMMIT_ATOMIC);
-
-		igt_plane_set_rotation(plane, IGT_ROTATION_90);
-		igt_plane_set_size(plane, h, w);
-		igt_display_commit2(display, COMMIT_ATOMIC);
-	}
-
-	for (i = 0; i < MAX_FENCES + 1; i++)
-		igt_remove_fb(fd, &fb[i]);
-}
-
-static const char *plane_test_str(unsigned plane)
-{
-	switch (plane) {
-	case DRM_PLANE_TYPE_PRIMARY:
-		return "primary";
-	case DRM_PLANE_TYPE_OVERLAY:
-		return "sprite";
-	case DRM_PLANE_TYPE_CURSOR:
-		return "cursor";
-	default:
-		igt_assert(0);
-	}
-}
-
-static const char *rot_test_str(igt_rotation_t rot)
-{
-	switch (rot) {
-	case IGT_ROTATION_0:
-		return "0";
-	case IGT_ROTATION_90:
-		return "90";
-	case IGT_ROTATION_180:
-		return "180";
-	case IGT_ROTATION_270:
-		return "270";
-	default:
-		igt_assert(0);
-	}
-}
-
-static const char *tiling_test_str(uint64_t tiling)
-{
-	switch (tiling) {
-	case LOCAL_I915_FORMAT_MOD_X_TILED:
-		return "x-tiled";
-	case LOCAL_I915_FORMAT_MOD_Y_TILED:
-		return "y-tiled";
-	case LOCAL_I915_FORMAT_MOD_Yf_TILED:
-		return "yf-tiled";
-	default:
-		igt_assert(0);
-	}
-}
-
-static int opt_handler(int opt, int opt_index, void *_data)
-{
-	data_t *data = _data;
-
-	switch (opt) {
-	case 'e':
-		data->extended = true;
-		break;
-	}
-
-	return IGT_OPT_HANDLER_SUCCESS;
-}
-
-static const struct option long_opts[] = {
-	{ .name = "extended", .has_arg = false, .val = 'e', },
-	{}
-};
-
-static const char help_str[] =
-	"  --extended\t\tRun the extended tests\n";
-
-static data_t data;
-
-igt_main_args("", long_opts, help_str, opt_handler, &data)
-{
-	struct rot_subtest {
-		unsigned plane;
-		igt_rotation_t rot;
-	} *subtest, subtests[] = {
-		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_90 },
-		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_180 },
-		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_270 },
-		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_90 },
-		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_180 },
-		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_270 },
-		{ DRM_PLANE_TYPE_CURSOR, IGT_ROTATION_180 },
-		{ 0, 0}
-	};
-
-	struct reflect_x {
-		uint64_t tiling;
-		igt_rotation_t rot;
-	} *reflect_x, reflect_x_subtests[] = {
-		{ LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0 },
-		{ LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180 },
-		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0 },
-		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90 },
-		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180 },
-		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270 },
-		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0 },
-		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90 },
-		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180 },
-		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270 },
-		{ 0, 0 }
-	};
-
-	int gen = 0;
-
-	igt_fixture {
-		data.gfx_fd = drm_open_driver_master(DRIVER_INTEL);
-		data.devid = intel_get_drm_devid(data.gfx_fd);
-		gen = intel_gen(data.devid);
-
-		kmstest_set_vt_graphics_mode();
-
-		igt_require_pipe_crc(data.gfx_fd);
-
-		igt_display_require(&data.display, data.gfx_fd);
-		igt_require(data.display.is_atomic);
-	}
-
-	for (subtest = subtests; subtest->rot; subtest++) {
-		igt_subtest_f("%s-rotation-%s",
-			      plane_test_str(subtest->plane),
-			      rot_test_str(subtest->rot)) {
-			igt_require(!(subtest->rot &
-				    (IGT_ROTATION_90 | IGT_ROTATION_270)) ||
-				    gen >= 9);
-			data.rotation = subtest->rot;
-			test_plane_rotation(&data, subtest->plane, false);
-		}
-	}
-
-	igt_subtest_f("sprite-rotation-90-pos-100-0") {
-		igt_require(gen >= 9);
-		data.rotation = IGT_ROTATION_90;
-		data.pos_x = 100,
-		data.pos_y = 0;
-		test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY, false);
-	}
-	data.pos_x = 0,
-	data.pos_y = 0;
-
-	igt_subtest_f("bad-pixel-format") {
-		 /* gen11 enables RGB565 rotation for 90/270 degrees.
-		  * so apart from this, any other gen11+ pixel format
-		  * can be used which doesn't support 90/270 degree
-		  * rotation */
-		igt_require(gen >= 9);
-		data.rotation = IGT_ROTATION_90;
-		data.override_fmt = gen < 11 ? DRM_FORMAT_RGB565 : DRM_FORMAT_Y212;
-		test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);
-	}
-	data.override_fmt = 0;
-
-	igt_subtest_f("bad-tiling") {
-		igt_require(gen >= 9);
-		data.rotation = IGT_ROTATION_90;
-		data.override_tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
-		test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);
-	}
-	data.override_tiling = 0;
-
-	for (reflect_x = reflect_x_subtests; reflect_x->tiling; reflect_x++) {
-		igt_subtest_f("primary-%s-reflect-x-%s",
-			      tiling_test_str(reflect_x->tiling),
-			      rot_test_str(reflect_x->rot)) {
-			igt_require(gen >= 10 ||
-				    (IS_CHERRYVIEW(data.devid) && reflect_x->rot == IGT_ROTATION_0
-				     && reflect_x->tiling == LOCAL_I915_FORMAT_MOD_X_TILED));
-			data.rotation = (IGT_REFLECT_X | reflect_x->rot);
-			data.override_tiling = reflect_x->tiling;
-			test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, false);
-		}
-	}
-
-	igt_subtest_f("multiplane-rotation") {
-		igt_require(gen >= 9);
-		cleanup_crtc(&data);
-		data.planepos[0].origo = p_top | p_left;
-		data.planepos[0].x = .2f;
-		data.planepos[0].y = .1f;
-		data.planepos[1].origo = p_top | p_right;
-		data.planepos[1].x = -.4f;
-		data.planepos[1].y = .1f;
-		test_multi_plane_rotation(&data, 0);
-	}
-
-	igt_subtest_f("multiplane-rotation-cropping-top") {
-		igt_require(gen >= 9);
-		cleanup_crtc(&data);
-		data.planepos[0].origo = p_top | p_left;
-		data.planepos[0].x = -.05f;
-		data.planepos[0].y = -.15f;
-		data.planepos[1].origo = p_top | p_right;
-		data.planepos[1].x = -.15f;
-		data.planepos[1].y = -.15f;
-		test_multi_plane_rotation(&data, 0);
-	}
-
-	igt_subtest_f("multiplane-rotation-cropping-bottom") {
-		igt_require(gen >= 9);
-		cleanup_crtc(&data);
-		data.planepos[0].origo = p_bottom | p_left;
-		data.planepos[0].x = -.05f;
-		data.planepos[0].y = -.20f;
-		data.planepos[1].origo = p_bottom | p_right;
-		data.planepos[1].x = -.15f;
-		data.planepos[1].y = -.20f;
-		test_multi_plane_rotation(&data, 0);
-	}
-
-	/*
-	 * exhaust-fences should be last test, if it fails we may OOM in
-	 * the following subtests otherwise.
-	 */
-	igt_subtest_f("exhaust-fences") {
-		enum pipe pipe;
-		igt_output_t *output;
-
-		igt_require(gen >= 9);
-		igt_display_require_output(&data.display);
-
-		for_each_pipe_with_valid_output(&data.display, pipe, output) {
-			igt_plane_t *primary = &data.display.pipes[pipe].planes[0];
-
-			test_plane_rotation_exhaust_fences(&data, pipe, output, primary);
-			break;
-		}
-	}
-
-	igt_fixture {
-		igt_display_fini(&data.display);
-	}
-}
+/*
+ * Copyright © 2013,2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "igt.h"
+#include "igt_vec.h"
+#include <math.h>
+
+#define MAX_FENCES 32
+#define MAXMULTIPLANESAMOUNT 2
+#define TEST_MAX_WIDTH 640
+#define TEST_MAX_HEIGHT 480
+
+struct p_struct {
+	igt_plane_t *plane;
+	struct igt_fb fb;
+};
+
+enum p_pointorigo {
+	p_top = 1 << 0,
+	p_bottom = 1 << 1,
+	p_left = 1 << 2,
+	p_right = 1 << 3
+};
+
+struct p_point{
+	enum p_pointorigo origo;
+	float_t x;
+	float_t y;
+};
+
+typedef struct {
+	int gfx_fd;
+	igt_display_t display;
+	struct igt_fb fb;
+	struct igt_fb fb_reference;
+	struct igt_fb fb_flip;
+	igt_crc_t ref_crc;
+	igt_crc_t flip_crc;
+	igt_pipe_crc_t *pipe_crc;
+	igt_rotation_t rotation;
+	int pos_x;
+	int pos_y;
+	uint32_t override_fmt;
+	uint64_t override_tiling;
+	int devid;
+
+	struct p_struct *multiplaneoldview;
+	struct p_point planepos[MAXMULTIPLANESAMOUNT];
+
+	bool use_native_resolution;
+	bool extended;
+} data_t;
+
+typedef struct {
+	float r;
+	float g;
+	float b;
+} rgb_color_t;
+
+static void set_color(rgb_color_t *color, float r, float g, float b)
+{
+	color->r = r;
+	color->g = g;
+	color->b = b;
+}
+
+static void rotate_colors(rgb_color_t *tl, rgb_color_t *tr, rgb_color_t *br,
+			  rgb_color_t *bl, igt_rotation_t rotation)
+{
+	rgb_color_t bl_tmp, br_tmp, tl_tmp, tr_tmp;
+
+	if (rotation & IGT_REFLECT_X) {
+		igt_swap(*tl, *tr);
+		igt_swap(*bl, *br);
+	}
+
+	if (rotation & IGT_ROTATION_90) {
+		bl_tmp = *bl;
+		br_tmp = *br;
+		tl_tmp = *tl;
+		tr_tmp = *tr;
+		*tl = tr_tmp;
+		*bl = tl_tmp;
+		*tr = br_tmp;
+		*br = bl_tmp;
+	} else if (rotation & IGT_ROTATION_180) {
+		igt_swap(*tl, *br);
+		igt_swap(*tr, *bl);
+	} else if (rotation & IGT_ROTATION_270) {
+		bl_tmp = *bl;
+		br_tmp = *br;
+		tl_tmp = *tl;
+		tr_tmp = *tr;
+		*tl = bl_tmp;
+		*bl = br_tmp;
+		*tr = tl_tmp;
+		*br = tr_tmp;
+	}
+}
+
+#define RGB_COLOR(color) \
+	color.r, color.g, color.b
+
+static void
+paint_squares(data_t *data, igt_rotation_t rotation,
+	      struct igt_fb *fb, float o)
+{
+	cairo_t *cr;
+	unsigned int w = fb->width;
+	unsigned int h = fb->height;
+	rgb_color_t tl, tr, bl, br;
+
+	igt_assert_f(!(w&1), "rotation image must be even width, now attempted %d\n", w);
+	igt_assert_f(!(h&1), "rotation image must be even height, now attempted %d\n", h);
+
+	cr = igt_get_cairo_ctx(data->gfx_fd, fb);
+
+	set_color(&tl, o, 0.0f, 0.0f);
+	set_color(&tr, 0.0f, o, 0.0f);
+	set_color(&br, o, o, o);
+	set_color(&bl, 0.0f, 0.0f, o);
+
+	rotate_colors(&tl, &tr, &br, &bl, rotation);
+
+	igt_paint_color(cr, 0, 0, w / 2, h / 2, RGB_COLOR(tl));
+	igt_paint_color(cr, w / 2, 0, w / 2, h / 2, RGB_COLOR(tr));
+	igt_paint_color(cr, 0, h / 2, w / 2, h / 2, RGB_COLOR(bl));
+	igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, RGB_COLOR(br));
+
+	igt_put_cairo_ctx(cr);
+}
+
+static void remove_fbs(data_t *data)
+{
+	igt_remove_fb(data->gfx_fd, &data->fb);
+	igt_remove_fb(data->gfx_fd, &data->fb_reference);
+	igt_remove_fb(data->gfx_fd, &data->fb_flip);
+}
+
+static void cleanup_crtc(data_t *data)
+{
+	igt_display_t *display = &data->display;
+
+	igt_pipe_crc_free(data->pipe_crc);
+	data->pipe_crc = NULL;
+
+	remove_fbs(data);
+
+	igt_display_reset(display);
+}
+
+static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
+			 igt_plane_t *plane, bool start_crc)
+{
+	igt_display_t *display = &data->display;
+
+	cleanup_crtc(data);
+
+	igt_output_set_pipe(output, pipe);
+	igt_plane_set_rotation(plane, IGT_ROTATION_0);
+
+	/* create the pipe_crc object for this pipe */
+	igt_pipe_crc_free(data->pipe_crc);
+
+	if (is_amdgpu_device(data->gfx_fd)) {
+		igt_fb_t fb_temp;
+
+		igt_create_fb(data->gfx_fd, 1280, 800, DRM_FORMAT_XRGB8888, 0, &fb_temp);
+		igt_plane_set_fb(plane, &fb_temp);
+	}
+	igt_display_commit2(display, COMMIT_ATOMIC);
+	data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	if (start_crc)
+		igt_pipe_crc_start(data->pipe_crc);
+}
+
+enum rectangle_type {
+	rectangle,
+	square,
+	portrait,
+	landscape,
+	num_rectangle_types /* must be last */
+};
+
+static void prepare_fbs(data_t *data, igt_output_t *output,
+			igt_plane_t *plane, enum rectangle_type rect, uint32_t format)
+{
+	drmModeModeInfo *mode;
+	igt_display_t *display = &data->display;
+	unsigned int w, h, ref_w, ref_h, min_w, min_h;
+	uint64_t tiling = data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE;
+	uint32_t pixel_format = data->override_fmt ?: DRM_FORMAT_XRGB8888;
+	const float flip_opacity = 0.75;
+	bool amd_gpu = is_amdgpu_device(data->gfx_fd);
+	bool intel_gpu = is_i915_device(data->gfx_fd);
+
+	remove_fbs(data);
+
+	igt_plane_set_rotation(plane, IGT_ROTATION_0);
+
+	mode = igt_output_get_mode(output);
+	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
+		if (amd_gpu) {
+			w = mode->hdisplay;
+			h = mode->vdisplay;
+		} else if (intel_gpu) {
+			if (data->use_native_resolution) {
+				w = mode->hdisplay;
+				h = mode->vdisplay;
+			} else {
+				w = min(TEST_MAX_WIDTH, mode->hdisplay);
+				h = min(TEST_MAX_HEIGHT, mode->vdisplay);
+			}
+
+			min_w = 256;
+			min_h = 256;
+		}
+	} else {
+		pixel_format = data->override_fmt ?: DRM_FORMAT_ARGB8888;
+
+		w = h = 256;
+		min_w = min_h = 64;
+	}
+
+	switch (rect) {
+	case rectangle:
+		break;
+	case square:
+		w = h = min(h, w);
+		break;
+	case portrait:
+		w = min_w;
+		break;
+	case landscape:
+		h = min_h;
+		break;
+	case num_rectangle_types:
+		igt_assert(0);
+	}
+
+	ref_w = w;
+	ref_h = h;
+
+	/*
+	 * For 90/270, we will use create smaller fb so that the rotated
+	 * frame can fit in
+	 */
+	if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270)) {
+		if (intel_gpu)
+			tiling = data->override_tiling ?: LOCAL_I915_FORMAT_MOD_Y_TILED;
+
+		igt_swap(w, h);
+	}
+
+	/*
+	 * Just try here if requested tiling format is generally available,
+	 * if one format fail it will skip entire subtest.
+	 */
+	igt_require(igt_display_has_format_mod(display, pixel_format, tiling));
+
+	if (intel_gpu) {
+		/*
+		 * Create a reference software rotated flip framebuffer.
+		 */
+		igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format, tiling,
+			      &data->fb_flip);
+		paint_squares(data, data->rotation, &data->fb_flip,
+			      flip_opacity);
+		igt_plane_set_fb(plane, &data->fb_flip);
+		if (plane->type != DRM_PLANE_TYPE_CURSOR)
+			igt_plane_set_position(plane, data->pos_x, data->pos_y);
+		igt_display_commit2(display, COMMIT_ATOMIC);
+
+		igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->flip_crc);
+
+		/*
+		  * Prepare the non-rotated flip fb.
+		  */
+		igt_remove_fb(data->gfx_fd, &data->fb_flip);
+		igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling,
+			      &data->fb_flip);
+		paint_squares(data, IGT_ROTATION_0, &data->fb_flip,
+			      flip_opacity);
+
+		/*
+		 * Create a reference CRC for a software-rotated fb.
+		 */
+		igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format,
+			      data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE, &data->fb_reference);
+	} else if (amd_gpu) {
+		tiling = 0x1900;
+		igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format,
+				  tiling, &data->fb_reference);
+	}
+	paint_squares(data, data->rotation, &data->fb_reference, 1.0);
+
+	igt_plane_set_fb(plane, &data->fb_reference);
+	if (plane->type != DRM_PLANE_TYPE_CURSOR)
+		igt_plane_set_position(plane, data->pos_x, data->pos_y);
+	igt_display_commit2(display, COMMIT_ATOMIC);
+
+	if (intel_gpu)
+		igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->ref_crc);
+	else if (amd_gpu)
+		igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
+
+	/*
+	 * Prepare the plane with an non-rotated fb let the hw rotate it.
+	 */
+	igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);
+	paint_squares(data, IGT_ROTATION_0, &data->fb, 1.0);
+	igt_plane_set_fb(plane, &data->fb);
+
+	if (plane->type != DRM_PLANE_TYPE_CURSOR)
+		igt_plane_set_position(plane, data->pos_x, data->pos_y);
+}
+
+static void test_single_case(data_t *data, enum pipe pipe,
+			     igt_output_t *output, igt_plane_t *plane,
+			     enum rectangle_type rect,
+			     uint32_t format, bool test_bad_format)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t crc_output;
+	int ret;
+
+	igt_debug("Testing case %i on pipe %s, format %s\n", rect, kmstest_pipe_name(pipe), igt_format_str(format));
+	prepare_fbs(data, output, plane, rect, format);
+
+	igt_plane_set_rotation(plane, data->rotation);
+	if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
+		igt_plane_set_size(plane, data->fb.height, data->fb.width);
+
+	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
+	if (test_bad_format) {
+		igt_assert_eq(ret, -EINVAL);
+		return;
+	}
+
+	/* Verify commit was ok. */
+	igt_assert_eq(ret, 0);
+
+	if (is_i915_device(data->gfx_fd)) {
+		/* Check CRC */
+		igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);
+		igt_assert_crc_equal(&data->ref_crc, &crc_output);
+
+		/*
+		 * If flips are requested flip to a different fb and
+		 * check CRC against that one as well.
+		 */
+		if (data->fb_flip.fb_id) {
+			igt_plane_set_fb(plane, &data->fb_flip);
+			if (data->rotation == IGT_ROTATION_90 || data->rotation == IGT_ROTATION_270)
+				igt_plane_set_size(plane, data->fb.height, data->fb.width);
+
+			if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
+				igt_display_commit_atomic(display, DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, NULL);
+			} else {
+				ret = drmModePageFlip(data->gfx_fd,
+						output->config.crtc->crtc_id,
+						data->fb_flip.fb_id,
+						DRM_MODE_PAGE_FLIP_EVENT,
+						NULL);
+				igt_assert_eq(ret, 0);
+			}
+			kmstest_wait_for_pageflip(data->gfx_fd);
+			igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);
+			igt_assert_crc_equal(&data->flip_crc,
+					     &crc_output);
+		}
+	} else if (is_amdgpu_device(data->gfx_fd)) {
+		igt_pipe_crc_collect_crc(data->pipe_crc, &crc_output);
+	}
+}
+
+static bool test_format(data_t *data,
+			struct igt_vec *tested_formats,
+			uint32_t format)
+{
+	if (!igt_fb_supported_format(format))
+		return false;
+
+	if (!is_i915_device(data->gfx_fd) ||
+	    data->extended)
+		return true;
+
+	format = igt_reduce_format(format);
+
+	/* only test each format "class" once */
+	if (igt_vec_index(tested_formats, &format) >= 0)
+		return false;
+
+	igt_vec_push(tested_formats, &format);
+
+	return true;
+}
+
+static void test_plane_rotation(data_t *data, int plane_type, bool test_bad_format)
+{
+	igt_display_t *display = &data->display;
+	igt_output_t *output;
+	enum pipe pipe;
+
+	if (plane_type == DRM_PLANE_TYPE_CURSOR)
+		igt_require(display->has_cursor_plane);
+
+	igt_display_require_output(display);
+
+	for_each_pipe_with_valid_output(display, pipe, output) {
+		igt_plane_t *plane;
+		int i, j;
+
+		if (is_i915_device(data->gfx_fd)) {
+			if (IS_CHERRYVIEW(data->devid) && pipe != PIPE_B)
+				continue;
+
+			igt_output_set_pipe(output, pipe);
+
+			plane = igt_output_get_plane_type(output, plane_type);
+			igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
+
+			prepare_crtc(data, output, pipe, plane, true);
+
+			for (i = 0; i < num_rectangle_types; i++) {
+				/* Unsupported on i915 */
+				if (plane_type == DRM_PLANE_TYPE_CURSOR &&
+				    i != square)
+					continue;
+
+				/* Only support partial covering primary plane on gen9+ */
+				if (plane_type == DRM_PLANE_TYPE_PRIMARY &&
+				    intel_gen(intel_get_drm_devid(data->gfx_fd)) < 9) {
+					if (i != rectangle)
+						continue;
+					else
+						data->use_native_resolution = true;
+				} else {
+					data->use_native_resolution = false;
+				}
+
+				if (!data->override_fmt) {
+					struct igt_vec tested_formats;
+
+					igt_vec_init(&tested_formats, sizeof(uint32_t));
+
+					for (j = 0; j < plane->drm_plane->count_formats; j++) {
+						uint32_t format = plane->drm_plane->formats[j];
+
+						if (!test_format(data, &tested_formats, format))
+							continue;
+
+						test_single_case(data, pipe, output, plane, i,
+								 format, test_bad_format);
+					}
+
+					igt_vec_fini(&tested_formats);
+				} else {
+					test_single_case(data, pipe, output, plane, i,
+							 data->override_fmt, test_bad_format);
+				}
+			}
+		} else if (is_amdgpu_device(data->gfx_fd)) {
+			uint32_t format = DRM_FORMAT_XRGB8888;
+
+			igt_output_set_pipe(output, pipe);
+
+			plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+			igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
+
+			prepare_crtc(data, output, pipe, plane, false);
+
+			if (plane_type != DRM_PLANE_TYPE_PRIMARY) {
+				plane = igt_output_get_plane_type(output, plane_type);
+				igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
+			}
+
+			test_single_case(data, pipe, output, plane,
+					 rectangle, format, test_bad_format);
+		}
+
+		igt_pipe_crc_stop(data->pipe_crc);
+	}
+}
+
+typedef struct {
+	int32_t x1, y1;
+	uint64_t width, height, tiling, planetype, format;
+	igt_rotation_t rotation_sw, rotation_hw;
+} planeinfos;
+
+static bool get_multiplane_crc(data_t *data, igt_output_t *output,
+			       igt_crc_t *crc_output, planeinfos *planeinfo,
+			       int numplanes)
+{
+	uint32_t w, h;
+	igt_display_t *display = &data->display;
+	struct p_struct *planes, *oldplanes;
+	int c, ret;
+
+	oldplanes = data->multiplaneoldview;
+	planes = calloc(sizeof(*planes), numplanes);
+
+	for (c = 0; c < numplanes; c++) {
+		planes[c].plane = igt_output_get_plane_type(output,
+							    planeinfo[c].planetype);
+
+		/*
+		 * make plane and fb width and height always divisible by 4
+		 * due to NV12 support and Intel hw workarounds.
+		 */
+		w = planeinfo[c].width & ~3;
+		h = planeinfo[c].height & ~3;
+
+		if (planeinfo[c].rotation_sw & (IGT_ROTATION_90 | IGT_ROTATION_270))
+			igt_swap(w, h);
+
+		if (!igt_plane_has_format_mod(planes[c].plane,
+					      planeinfo[c].format,
+					      planeinfo[c].tiling))
+			return false;
+
+		igt_create_fb(data->gfx_fd, w, h, planeinfo[c].format,
+			      planeinfo[c].tiling, &planes[c].fb);
+
+		paint_squares(data, planeinfo[c].rotation_sw, &planes[c].fb, 1.0f);
+		igt_plane_set_fb(planes[c].plane, &planes[c].fb);
+
+		if (planeinfo[c].rotation_hw & (IGT_ROTATION_90 | IGT_ROTATION_270))
+			igt_plane_set_size(planes[c].plane, h, w);
+
+		igt_plane_set_position(planes[c].plane, planeinfo[c].x1, planeinfo[c].y1);
+		igt_plane_set_rotation(planes[c].plane, planeinfo[c].rotation_hw);
+	}
+
+	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
+	igt_assert_eq(ret, 0);
+
+	igt_pipe_crc_get_current(data->gfx_fd, data->pipe_crc, crc_output);
+
+	for (c = 0; c < numplanes && oldplanes; c++)
+		igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);
+
+	free(oldplanes);
+	data->multiplaneoldview = (void*)planes;
+	return true;
+}
+
+static void pointlocation(data_t *data, planeinfos *p, drmModeModeInfo *mode,
+			  int c)
+{
+	if (data->planepos[c].origo & p_right) {
+		p[c].x1 = (int32_t)(data->planepos[c].x * min(TEST_MAX_WIDTH, mode->hdisplay)
+				+ mode->hdisplay);
+		p[c].x1 &= ~3;
+		/*
+		 * At this point is handled surface on right side. If display
+		 * mode is not divisible by 4 but with 2 point location is
+		 * fixed to match requirements. Because of YUV planes here is
+		 * intentionally ignored bit 1.
+		 */
+		p[c].x1 -= mode->hdisplay & 2;
+	} else {
+		p[c].x1 = (int32_t)(data->planepos[c].x * min(TEST_MAX_WIDTH, mode->hdisplay));
+		p[c].x1 &= ~3;
+	}
+
+	if (data->planepos[c].origo & p_bottom) {
+		p[c].y1 = (int32_t)(data->planepos[c].y * min(TEST_MAX_HEIGHT, mode->vdisplay)
+				+ mode->vdisplay);
+		p[c].y1 &= ~3;
+		p[c].y1 -= mode->vdisplay & 2;
+	} else {
+		p[c].y1 = (int32_t)(data->planepos[c].y * min(TEST_MAX_HEIGHT, mode->vdisplay));
+		p[c].y1 &= ~3;
+	}
+}
+
+/*
+ * Here is pipe parameter which is now used only for first pipe.
+ * It is left here if this test ever was wanted to be run on
+ * different pipes.
+ */
+static void test_multi_plane_rotation(data_t *data, enum pipe pipe)
+{
+	igt_display_t *display = &data->display;
+	igt_output_t *output;
+	igt_crc_t retcrc_sw, retcrc_hw;
+	planeinfos p[2];
+	int c, used_w, used_h;
+	struct p_struct *oldplanes;
+	drmModeModeInfo *mode;
+
+	static const struct {
+		igt_rotation_t rotation;
+		float_t width;
+		float_t height;
+		uint64_t tiling;
+	} planeconfigs[] = {
+	{IGT_ROTATION_0, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },
+	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },
+	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
+	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
+	{IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
+	{IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
+	{IGT_ROTATION_180, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },
+	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },
+	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
+	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
+	{IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
+	{IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
+	};
+
+	/*
+	* These are those modes which are tested. For testing feel interesting
+	* case with tiling are 2 bpp, 4 bpp and NV12.
+	*/
+	static const uint32_t formatlist[] = {DRM_FORMAT_RGB565,
+		DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12};
+
+	for_each_valid_output_on_pipe(display, pipe, output) {
+		int i, j, k, l;
+		igt_output_set_pipe(output, pipe);
+		mode = igt_output_get_mode(output);
+		igt_display_require_output(display);
+		igt_display_commit2(display, COMMIT_ATOMIC);
+
+		used_w = min(TEST_MAX_WIDTH, mode->hdisplay);
+		used_h = min(TEST_MAX_HEIGHT, mode->vdisplay);
+
+		data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe,
+						  INTEL_PIPE_CRC_SOURCE_AUTO);
+		igt_pipe_crc_start(data->pipe_crc);
+
+		for (i = 0; i < ARRAY_SIZE(planeconfigs); i++) {
+			p[0].planetype = DRM_PLANE_TYPE_PRIMARY;
+			p[0].width = (uint64_t)(planeconfigs[i].width * used_w);
+			p[0].height = (uint64_t)(planeconfigs[i].height * used_h);
+			p[0].tiling = planeconfigs[i].tiling;
+			pointlocation(data, (planeinfos *)&p, mode, 0);
+
+			for (k = 0; k < ARRAY_SIZE(formatlist); k++) {
+				p[0].format = formatlist[k];
+
+				for (j = 0; j < ARRAY_SIZE(planeconfigs); j++) {
+					p[1].planetype = DRM_PLANE_TYPE_OVERLAY;
+					p[1].width = (uint64_t)(planeconfigs[j].width * used_w);
+					p[1].height = (uint64_t)(planeconfigs[j].height * used_h);
+					p[1].tiling = planeconfigs[j].tiling;
+					pointlocation(data, (planeinfos *)&p,
+						      mode, 1);
+
+					for (l = 0; l < ARRAY_SIZE(formatlist); l++) {
+						p[1].format = formatlist[l];
+
+						/*
+						 * RGB565 90/270 degrees rotation is supported
+						 * from gen11 onwards.
+						 */
+						if (p[0].format == DRM_FORMAT_RGB565 &&
+						     (planeconfigs[i].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
+						     && intel_gen(data->devid) < 11)
+							continue;
+
+						if (p[1].format == DRM_FORMAT_RGB565 &&
+						     (planeconfigs[j].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
+						     && intel_gen(data->devid) < 11)
+							continue;
+
+						p[0].rotation_sw = planeconfigs[i].rotation;
+						p[0].rotation_hw = IGT_ROTATION_0;
+						p[1].rotation_sw = planeconfigs[j].rotation;
+						p[1].rotation_hw = IGT_ROTATION_0;
+						if (!get_multiplane_crc(data, output, &retcrc_sw,
+								   (planeinfos *)&p, MAXMULTIPLANESAMOUNT))
+							continue;
+
+						igt_swap(p[0].rotation_sw, p[0].rotation_hw);
+						igt_swap(p[1].rotation_sw, p[1].rotation_hw);
+						if (!get_multiplane_crc(data, output, &retcrc_hw,
+								   (planeinfos *)&p, MAXMULTIPLANESAMOUNT))
+							continue;
+
+						igt_assert_crc_equal(&retcrc_sw, &retcrc_hw);
+					}
+				}
+			}
+		}
+		igt_pipe_crc_stop(data->pipe_crc);
+		igt_pipe_crc_free(data->pipe_crc);
+		igt_output_set_pipe(output, PIPE_ANY);
+	}
+
+	/*
+	* Old fbs are deleted only after new ones are set on planes.
+	* This is done to speed up the test
+	*/
+	oldplanes = data->multiplaneoldview;
+	for (c = 0; c < MAXMULTIPLANESAMOUNT && oldplanes; c++)
+		igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);
+
+	free(oldplanes);
+	data->multiplaneoldview = NULL;
+	data->pipe_crc = NULL;
+}
+
+static void test_plane_rotation_exhaust_fences(data_t *data,
+					       enum pipe pipe,
+					       igt_output_t *output,
+					       igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+	uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
+	uint32_t format = DRM_FORMAT_XRGB8888;
+	int fd = data->gfx_fd;
+	drmModeModeInfo *mode;
+	struct igt_fb fb[MAX_FENCES+1] = {};
+	uint64_t size;
+	unsigned int stride, w, h;
+	uint64_t total_aperture_size, total_fbs_size;
+	int i;
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
+
+	prepare_crtc(data, output, pipe, plane, false);
+
+	mode = igt_output_get_mode(output);
+	w = mode->hdisplay;
+	h = mode->vdisplay;
+
+	igt_calc_fb_size(fd, w, h, format, tiling, &size, &stride);
+
+	/*
+	 * Make sure there is atleast 90% of the available GTT space left
+	 * for creating (MAX_FENCES+1) framebuffers.
+	 */
+	total_fbs_size = size * (MAX_FENCES + 1);
+	total_aperture_size = gem_available_aperture_size(fd);
+	igt_require(total_fbs_size < total_aperture_size * 0.9);
+
+	for (i = 0; i < MAX_FENCES + 1; i++) {
+		igt_create_fb(fd, w, h, format, tiling, &fb[i]);
+
+		igt_plane_set_fb(plane, &fb[i]);
+		igt_plane_set_rotation(plane, IGT_ROTATION_0);
+		igt_display_commit2(display, COMMIT_ATOMIC);
+
+		igt_plane_set_rotation(plane, IGT_ROTATION_90);
+		igt_plane_set_size(plane, h, w);
+		igt_display_commit2(display, COMMIT_ATOMIC);
+	}
+
+	for (i = 0; i < MAX_FENCES + 1; i++)
+		igt_remove_fb(fd, &fb[i]);
+}
+
+static const char *plane_test_str(unsigned plane)
+{
+	switch (plane) {
+	case DRM_PLANE_TYPE_PRIMARY:
+		return "primary";
+	case DRM_PLANE_TYPE_OVERLAY:
+		return "sprite";
+	case DRM_PLANE_TYPE_CURSOR:
+		return "cursor";
+	default:
+		igt_assert(0);
+	}
+}
+
+static const char *rot_test_str(igt_rotation_t rot)
+{
+	switch (rot) {
+	case IGT_ROTATION_0:
+		return "0";
+	case IGT_ROTATION_90:
+		return "90";
+	case IGT_ROTATION_180:
+		return "180";
+	case IGT_ROTATION_270:
+		return "270";
+	default:
+		igt_assert(0);
+	}
+}
+
+static const char *tiling_test_str(uint64_t tiling)
+{
+	switch (tiling) {
+	case LOCAL_I915_FORMAT_MOD_X_TILED:
+		return "x-tiled";
+	case LOCAL_I915_FORMAT_MOD_Y_TILED:
+		return "y-tiled";
+	case LOCAL_I915_FORMAT_MOD_Yf_TILED:
+		return "yf-tiled";
+	default:
+		igt_assert(0);
+	}
+}
+
+static int opt_handler(int opt, int opt_index, void *_data)
+{
+	data_t *data = _data;
+
+	switch (opt) {
+	case 'e':
+		data->extended = true;
+		break;
+	}
+
+	return IGT_OPT_HANDLER_SUCCESS;
+}
+
+static const struct option long_opts[] = {
+	{ .name = "extended", .has_arg = false, .val = 'e', },
+	{}
+};
+
+static const char help_str[] =
+	"  --extended\t\tRun the extended tests\n";
+
+static data_t data;
+
+igt_main_args("", long_opts, help_str, opt_handler, &data)
+{
+	struct rot_subtest {
+		unsigned plane;
+		igt_rotation_t rot;
+	} *subtest, subtests[] = {
+		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_90 },
+		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_180 },
+		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_270 },
+		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_90 },
+		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_180 },
+		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_270 },
+		{ DRM_PLANE_TYPE_CURSOR, IGT_ROTATION_180 },
+		{ 0, 0}
+	};
+
+	struct reflect_x {
+		uint64_t tiling;
+		igt_rotation_t rot;
+	} *reflect_x, reflect_x_subtests[] = {
+		{ LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0 },
+		{ LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180 },
+		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0 },
+		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90 },
+		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180 },
+		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270 },
+		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0 },
+		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90 },
+		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180 },
+		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270 },
+		{ 0, 0 }
+	};
+
+	int gen = 0;
+
+	igt_fixture {
+		data.gfx_fd = drm_open_driver_master(DRIVER_INTEL | DRIVER_AMDGPU);
+		if (is_i915_device(data.gfx_fd)) {
+			data.devid = intel_get_drm_devid(data.gfx_fd);
+			gen = intel_gen(data.devid);
+		}
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_require_pipe_crc(data.gfx_fd);
+
+		igt_display_require(&data.display, data.gfx_fd);
+		igt_require(data.display.is_atomic);
+	}
+
+	for (subtest = subtests; subtest->rot; subtest++) {
+		igt_subtest_f("%s-rotation-%s",
+			      plane_test_str(subtest->plane),
+			      rot_test_str(subtest->rot)) {
+			if (is_i915_device(data.gfx_fd)) {
+				igt_require(!(subtest->rot &
+					    (IGT_ROTATION_90 | IGT_ROTATION_270)) ||
+					    gen >= 9);
+			}
+			data.rotation = subtest->rot;
+			test_plane_rotation(&data, subtest->plane, false);
+		}
+	}
+
+	igt_subtest_f("sprite-rotation-90-pos-100-0") {
+		igt_require(gen >= 9);
+		data.rotation = IGT_ROTATION_90;
+		data.pos_x = 100,
+		data.pos_y = 0;
+		test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY, false);
+	}
+	data.pos_x = 0,
+	data.pos_y = 0;
+
+	igt_subtest_f("bad-pixel-format") {
+		 /* gen11 enables RGB565 rotation for 90/270 degrees.
+		  * so apart from this, any other gen11+ pixel format
+		  * can be used which doesn't support 90/270 degree
+		  * rotation */
+		igt_require(gen >= 9);
+		data.rotation = IGT_ROTATION_90;
+		data.override_fmt = gen < 11 ? DRM_FORMAT_RGB565 : DRM_FORMAT_Y212;
+		test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);
+	}
+	data.override_fmt = 0;
+
+	igt_subtest_f("bad-tiling") {
+		igt_require(gen >= 9);
+		data.rotation = IGT_ROTATION_90;
+		data.override_tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
+		test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);
+	}
+	data.override_tiling = 0;
+
+	for (reflect_x = reflect_x_subtests; reflect_x->tiling; reflect_x++) {
+		igt_subtest_f("primary-%s-reflect-x-%s",
+			      tiling_test_str(reflect_x->tiling),
+			      rot_test_str(reflect_x->rot)) {
+			igt_require(gen >= 10 ||
+				    (IS_CHERRYVIEW(data.devid) && reflect_x->rot == IGT_ROTATION_0
+				     && reflect_x->tiling == LOCAL_I915_FORMAT_MOD_X_TILED));
+			data.rotation = (IGT_REFLECT_X | reflect_x->rot);
+			data.override_tiling = reflect_x->tiling;
+			test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, false);
+		}
+	}
+
+	igt_subtest_f("multiplane-rotation") {
+		igt_require(gen >= 9);
+		cleanup_crtc(&data);
+		data.planepos[0].origo = p_top | p_left;
+		data.planepos[0].x = .2f;
+		data.planepos[0].y = .1f;
+		data.planepos[1].origo = p_top | p_right;
+		data.planepos[1].x = -.4f;
+		data.planepos[1].y = .1f;
+		test_multi_plane_rotation(&data, 0);
+	}
+
+	igt_subtest_f("multiplane-rotation-cropping-top") {
+		igt_require(gen >= 9);
+		cleanup_crtc(&data);
+		data.planepos[0].origo = p_top | p_left;
+		data.planepos[0].x = -.05f;
+		data.planepos[0].y = -.15f;
+		data.planepos[1].origo = p_top | p_right;
+		data.planepos[1].x = -.15f;
+		data.planepos[1].y = -.15f;
+		test_multi_plane_rotation(&data, 0);
+	}
+
+	igt_subtest_f("multiplane-rotation-cropping-bottom") {
+		igt_require(gen >= 9);
+		cleanup_crtc(&data);
+		data.planepos[0].origo = p_bottom | p_left;
+		data.planepos[0].x = -.05f;
+		data.planepos[0].y = -.20f;
+		data.planepos[1].origo = p_bottom | p_right;
+		data.planepos[1].x = -.15f;
+		data.planepos[1].y = -.20f;
+		test_multi_plane_rotation(&data, 0);
+	}
+
+	/*
+	 * exhaust-fences should be last test, if it fails we may OOM in
+	 * the following subtests otherwise.
+	 */
+	igt_subtest_f("exhaust-fences") {
+		enum pipe pipe;
+		igt_output_t *output;
+
+		igt_require(gen >= 9);
+		igt_display_require_output(&data.display);
+
+		for_each_pipe_with_valid_output(&data.display, pipe, output) {
+			igt_plane_t *primary = &data.display.pipes[pipe].planes[0];
+
+			test_plane_rotation_exhaust_fences(&data, pipe, output, primary);
+			break;
+		}
+	}
+
+	igt_fixture {
+		igt_display_fini(&data.display);
+	}
+}
Signature · 6 lines
2.25.1

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

A message that is not in the archive (sent off-list or not yet received): MN2PR12MB3054150157A5A6E90F904EF997C50@MN2PR12MB3054.namprd12.prod.outlook.com

#2 lore raw

Sorry this didn't send completely. I will send a new set.

-----Original Message-----
From: Kim, Sung joon <[email protected]>
Sent: Wednesday, December 16, 2020 5:13 PM
To: [email protected]
Cc: Kazlauskas, Nicholas <[email protected]>; [email protected]; Wentland, Harry <[email protected]>; Cornij, Nikola <[email protected]>; Kim, Sung joon <[email protected]>
Subject: [PATCH] kms_rotation_crc:Add HW rotation test case for amdgpu

Added Hw rotation case specifically for amdgpu. Currently, kms_rotation_crc tests intel gpus. Added conditions to bypass all the requirements needed for intel when testing amdgpu.

---
 tests/kms_rotation_crc.c | 1971 +++++++++++++++++++-------------------
 1 file changed, 1011 insertions(+), 960 deletions(-)
tests/kms_rotation_crc.c +1 -960
index ffcc2cc2..f4f36144 100644
@@ -1,960 +1,1011 @@
-/*
- * Copyright © 2013,2014 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- */
-
-#include "igt.h"
-#include "igt_vec.h"
-#include <math.h>
-
-#define MAX_FENCES 32
-#define MAXMULTIPLANESAMOUNT 2
-#define TEST_MAX_WIDTH 640
-#define TEST_MAX_HEIGHT 480
-
-struct p_struct {
-	igt_plane_t *plane;
-	struct igt_fb fb;
-};
-
-enum p_pointorigo {
-	p_top = 1 << 0,
-	p_bottom = 1 << 1,
-	p_left = 1 << 2,
-	p_right = 1 << 3
-};
-
-struct p_point{
-	enum p_pointorigo origo;
-	float_t x;
-	float_t y;
-};
-
-typedef struct {
-	int gfx_fd;
-	igt_display_t display;
-	struct igt_fb fb;
-	struct igt_fb fb_reference;
-	struct igt_fb fb_flip;
-	igt_crc_t ref_crc;
-	igt_crc_t flip_crc;
-	igt_pipe_crc_t *pipe_crc;
-	igt_rotation_t rotation;
-	int pos_x;
-	int pos_y;
-	uint32_t override_fmt;
-	uint64_t override_tiling;
-	int devid;
-
-	struct p_struct *multiplaneoldview;
-	struct p_point planepos[MAXMULTIPLANESAMOUNT];
-
-	bool use_native_resolution;
-	bool extended;
-} data_t;
-
-typedef struct {
-	float r;
-	float g;
-	float b;
-} rgb_color_t;
-
-static void set_color(rgb_color_t *color, float r, float g, float b)
-{
-	color->r = r;
-	color->g = g;
-	color->b = b;
-}
-
-static void rotate_colors(rgb_color_t *tl, rgb_color_t *tr, rgb_color_t *br,
-			  rgb_color_t *bl, igt_rotation_t rotation)
-{
-	rgb_color_t bl_tmp, br_tmp, tl_tmp, tr_tmp;
-
-	if (rotation & IGT_REFLECT_X) {
-		igt_swap(*tl, *tr);
-		igt_swap(*bl, *br);
-	}
-
-	if (rotation & IGT_ROTATION_90) {
-		bl_tmp = *bl;
-		br_tmp = *br;
-		tl_tmp = *tl;
-		tr_tmp = *tr;
-		*tl = tr_tmp;
-		*bl = tl_tmp;
-		*tr = br_tmp;
-		*br = bl_tmp;
-	} else if (rotation & IGT_ROTATION_180) {
-		igt_swap(*tl, *br);
-		igt_swap(*tr, *bl);
-	} else if (rotation & IGT_ROTATION_270) {
-		bl_tmp = *bl;
-		br_tmp = *br;
-		tl_tmp = *tl;
-		tr_tmp = *tr;
-		*tl = bl_tmp;
-		*bl = br_tmp;
-		*tr = tl_tmp;
-		*br = tr_tmp;
-	}
-}
-
-#define RGB_COLOR(color) \
-	color.r, color.g, color.b
-
-static void
-paint_squares(data_t *data, igt_rotation_t rotation,
-	      struct igt_fb *fb, float o)
-{
-	cairo_t *cr;
-	unsigned int w = fb->width;
-	unsigned int h = fb->height;
-	rgb_color_t tl, tr, bl, br;
-
-	igt_assert_f(!(w&1), "rotation image must be even width, now attempted %d\n", w);
-	igt_assert_f(!(h&1), "rotation image must be even height, now attempted %d\n", h);
-
-	cr = igt_get_cairo_ctx(data->gfx_fd, fb);
-
-	set_color(&tl, o, 0.0f, 0.0f);
-	set_color(&tr, 0.0f, o, 0.0f);
-	set_color(&br, o, o, o);
-	set_color(&bl, 0.0f, 0.0f, o);
-
-	rotate_colors(&tl, &tr, &br, &bl, rotation);
-
-	igt_paint_color(cr, 0, 0, w / 2, h / 2, RGB_COLOR(tl));
-	igt_paint_color(cr, w / 2, 0, w / 2, h / 2, RGB_COLOR(tr));
-	igt_paint_color(cr, 0, h / 2, w / 2, h / 2, RGB_COLOR(bl));
-	igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, RGB_COLOR(br));
-
-	igt_put_cairo_ctx(cr);
-}
-
-static void remove_fbs(data_t *data)
-{
-	igt_remove_fb(data->gfx_fd, &data->fb);
-	igt_remove_fb(data->gfx_fd, &data->fb_reference);
-	igt_remove_fb(data->gfx_fd, &data->fb_flip);
-}
-
-static void cleanup_crtc(data_t *data)
-{
-	igt_display_t *display = &data->display;
-
-	igt_pipe_crc_free(data->pipe_crc);
-	data->pipe_crc = NULL;
-
-	remove_fbs(data);
-
-	igt_display_reset(display);
-}
-
-static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
-			 igt_plane_t *plane, bool start_crc)
-{
-	igt_display_t *display = &data->display;
-
-	cleanup_crtc(data);
-
-	igt_output_set_pipe(output, pipe);
-	igt_plane_set_rotation(plane, IGT_ROTATION_0);
-
-	/* create the pipe_crc object for this pipe */
-	igt_pipe_crc_free(data->pipe_crc);
-
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
-
-	if (start_crc)
-		igt_pipe_crc_start(data->pipe_crc);
-}
-
-enum rectangle_type {
-	rectangle,
-	square,
-	portrait,
-	landscape,
-	num_rectangle_types /* must be last */
-};
-
-static void prepare_fbs(data_t *data, igt_output_t *output,
-			igt_plane_t *plane, enum rectangle_type rect, uint32_t format)
-{
-	drmModeModeInfo *mode;
-	igt_display_t *display = &data->display;
-	unsigned int w, h, ref_w, ref_h, min_w, min_h;
-	uint64_t tiling = data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE;
-	uint32_t pixel_format = data->override_fmt ?: DRM_FORMAT_XRGB8888;
-	const float flip_opacity = 0.75;
-
-	remove_fbs(data);
-
-	igt_plane_set_rotation(plane, IGT_ROTATION_0);
-
-	mode = igt_output_get_mode(output);
-	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
-		if (data->use_native_resolution) {
-			w = mode->hdisplay;
-			h = mode->vdisplay;
-		} else {
-			w = min(TEST_MAX_WIDTH, mode->hdisplay);
-			h = min(TEST_MAX_HEIGHT, mode->vdisplay);
-		}
-
-		min_w = 256;
-		min_h = 256;
-	} else {
-		pixel_format = data->override_fmt ?: DRM_FORMAT_ARGB8888;
-
-		w = h = 256;
-		min_w = min_h = 64;
-	}
-
-	switch (rect) {
-	case rectangle:
-		break;
-	case square:
-		w = h = min(h, w);
-		break;
-	case portrait:
-		w = min_w;
-		break;
-	case landscape:
-		h = min_h;
-		break;
-	case num_rectangle_types:
-		igt_assert(0);
-	}
-
-	ref_w = w;
-	ref_h = h;
-
-	/*
-	 * For 90/270, we will use create smaller fb so that the rotated
-	 * frame can fit in
-	 */
-	if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270)) {
-		tiling = data->override_tiling ?: LOCAL_I915_FORMAT_MOD_Y_TILED;
-
-		igt_swap(w, h);
-	}
-
-	/*
-	 * Just try here if requested tiling format is generally available,
-	 * if one format fail it will skip entire subtest.
-	 */
-	igt_require(igt_display_has_format_mod(display, pixel_format, tiling));
-
-	/*
-	 * Create a reference software rotated flip framebuffer.
-	 */
-	igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format, tiling,
-		      &data->fb_flip);
-	paint_squares(data, data->rotation, &data->fb_flip,
-		      flip_opacity);
-	igt_plane_set_fb(plane, &data->fb_flip);
-	if (plane->type != DRM_PLANE_TYPE_CURSOR)
-		igt_plane_set_position(plane, data->pos_x, data->pos_y);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-
-	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->flip_crc);
-
-	/*
-	  * Prepare the non-rotated flip fb.
-	  */
-	igt_remove_fb(data->gfx_fd, &data->fb_flip);
-	igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling,
-		      &data->fb_flip);
-	paint_squares(data, IGT_ROTATION_0, &data->fb_flip,
-		      flip_opacity);
-
-	/*
-	 * Create a reference CRC for a software-rotated fb.
-	 */
-	igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format,
-		      data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE, &data->fb_reference);
-	paint_squares(data, data->rotation, &data->fb_reference, 1.0);
-
-	igt_plane_set_fb(plane, &data->fb_reference);
-	if (plane->type != DRM_PLANE_TYPE_CURSOR)
-		igt_plane_set_position(plane, data->pos_x, data->pos_y);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-
-	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->ref_crc);
-
-	/*
-	 * Prepare the plane with an non-rotated fb let the hw rotate it.
-	 */
-	igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);
-	paint_squares(data, IGT_ROTATION_0, &data->fb, 1.0);
-	igt_plane_set_fb(plane, &data->fb);
-
-	if (plane->type != DRM_PLANE_TYPE_CURSOR)
-		igt_plane_set_position(plane, data->pos_x, data->pos_y);
-}
-
-static void test_single_case(data_t *data, enum pipe pipe,
-			     igt_output_t *output, igt_plane_t *plane,
-			     enum rectangle_type rect,
-			     uint32_t format, bool test_bad_format)
-{
-	igt_display_t *display = &data->display;
-	igt_crc_t crc_output;
-	int ret;
-
-	igt_debug("Testing case %i on pipe %s, format %s\n", rect, kmstest_pipe_name(pipe), igt_format_str(format));
-	prepare_fbs(data, output, plane, rect, format);
-
-	igt_plane_set_rotation(plane, data->rotation);
-	if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
-		igt_plane_set_size(plane, data->fb.height, data->fb.width);
-
-	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
-	if (test_bad_format) {
-		igt_assert_eq(ret, -EINVAL);
-		return;
-	}
-
-	/* Verify commit was ok. */
-	igt_assert_eq(ret, 0);
-
-	/* Check CRC */
-	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);
-	igt_assert_crc_equal(&data->ref_crc, &crc_output);
-
-	/*
-	 * If flips are requested flip to a different fb and
-	 * check CRC against that one as well.
-	 */
-	if (data->fb_flip.fb_id) {
-		igt_plane_set_fb(plane, &data->fb_flip);
-		if (data->rotation == IGT_ROTATION_90 || data->rotation == IGT_ROTATION_270)
-			igt_plane_set_size(plane, data->fb.height, data->fb.width);
-
-		if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
-			igt_display_commit_atomic(display, DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, NULL);
-		} else {
-			ret = drmModePageFlip(data->gfx_fd,
-					output->config.crtc->crtc_id,
-					data->fb_flip.fb_id,
-					DRM_MODE_PAGE_FLIP_EVENT,
-					NULL);
-			igt_assert_eq(ret, 0);
-		}
-		kmstest_wait_for_pageflip(data->gfx_fd);
-		igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);
-		igt_assert_crc_equal(&data->flip_crc,
-				     &crc_output);
-	}
-}
-
-static bool test_format(data_t *data,
-			struct igt_vec *tested_formats,
-			uint32_t format)
-{
-	if (!igt_fb_supported_format(format))
-		return false;
-
-	if (!is_i915_device(data->gfx_fd) ||
-	    data->extended)
-		return true;
-
-	format = igt_reduce_format(format);
-
-	/* only test each format "class" once */
-	if (igt_vec_index(tested_formats, &format) >= 0)
-		return false;
-
-	igt_vec_push(tested_formats, &format);
-
-	return true;
-}
-
-static void test_plane_rotation(data_t *data, int plane_type, bool test_bad_format)
-{
-	igt_display_t *display = &data->display;
-	igt_output_t *output;
-	enum pipe pipe;
-
-	if (plane_type == DRM_PLANE_TYPE_CURSOR)
-		igt_require(display->has_cursor_plane);
-
-	igt_display_require_output(display);
-
-	for_each_pipe_with_valid_output(display, pipe, output) {
-		igt_plane_t *plane;
-		int i, j;
-
-		if (IS_CHERRYVIEW(data->devid) && pipe != PIPE_B)
-			continue;
-
-		igt_output_set_pipe(output, pipe);
-
-		plane = igt_output_get_plane_type(output, plane_type);
-		igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
-
-		prepare_crtc(data, output, pipe, plane, true);
-
-		for (i = 0; i < num_rectangle_types; i++) {
-			/* Unsupported on i915 */
-			if (plane_type == DRM_PLANE_TYPE_CURSOR &&
-			    i != square)
-				continue;
-
-			/* Only support partial covering primary plane on gen9+ */
-			if (plane_type == DRM_PLANE_TYPE_PRIMARY &&
-			    intel_gen(intel_get_drm_devid(data->gfx_fd)) < 9) {
-				if (i != rectangle)
-					continue;
-				else
-					data->use_native_resolution = true;
-			} else {
-				data->use_native_resolution = false;
-			}
-
-			if (!data->override_fmt) {
-				struct igt_vec tested_formats;
-
-				igt_vec_init(&tested_formats, sizeof(uint32_t));
-
-				for (j = 0; j < plane->drm_plane->count_formats; j++) {
-					uint32_t format = plane->drm_plane->formats[j];
-
-					if (!test_format(data, &tested_formats, format))
-						continue;
-
-					test_single_case(data, pipe, output, plane, i,
-							 format, test_bad_format);
-				}
-
-				igt_vec_fini(&tested_formats);
-			} else {
-				test_single_case(data, pipe, output, plane, i,
-						 data->override_fmt, test_bad_format);
-			}
-		}
-		igt_pipe_crc_stop(data->pipe_crc);
-	}
-}
-
-typedef struct {
-	int32_t x1, y1;
-	uint64_t width, height, tiling, planetype, format;
-	igt_rotation_t rotation_sw, rotation_hw;
-} planeinfos;
-
-static bool get_multiplane_crc(data_t *data, igt_output_t *output,
-			       igt_crc_t *crc_output, planeinfos *planeinfo,
-			       int numplanes)
-{
-	uint32_t w, h;
-	igt_display_t *display = &data->display;
-	struct p_struct *planes, *oldplanes;
-	int c, ret;
-
-	oldplanes = data->multiplaneoldview;
-	planes = calloc(sizeof(*planes), numplanes);
-
-	for (c = 0; c < numplanes; c++) {
-		planes[c].plane = igt_output_get_plane_type(output,
-							    planeinfo[c].planetype);
-
-		/*
-		 * make plane and fb width and height always divisible by 4
-		 * due to NV12 support and Intel hw workarounds.
-		 */
-		w = planeinfo[c].width & ~3;
-		h = planeinfo[c].height & ~3;
-
-		if (planeinfo[c].rotation_sw & (IGT_ROTATION_90 | IGT_ROTATION_270))
-			igt_swap(w, h);
-
-		if (!igt_plane_has_format_mod(planes[c].plane,
-					      planeinfo[c].format,
-					      planeinfo[c].tiling))
-			return false;
-
-		igt_create_fb(data->gfx_fd, w, h, planeinfo[c].format,
-			      planeinfo[c].tiling, &planes[c].fb);
-
-		paint_squares(data, planeinfo[c].rotation_sw, &planes[c].fb, 1.0f);
-		igt_plane_set_fb(planes[c].plane, &planes[c].fb);
-
-		if (planeinfo[c].rotation_hw & (IGT_ROTATION_90 | IGT_ROTATION_270))
-			igt_plane_set_size(planes[c].plane, h, w);
-
-		igt_plane_set_position(planes[c].plane, planeinfo[c].x1, planeinfo[c].y1);
-		igt_plane_set_rotation(planes[c].plane, planeinfo[c].rotation_hw);
-	}
-
-	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
-	igt_assert_eq(ret, 0);
-
-	igt_pipe_crc_get_current(data->gfx_fd, data->pipe_crc, crc_output);
-
-	for (c = 0; c < numplanes && oldplanes; c++)
-		igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);
-
-	free(oldplanes);
-	data->multiplaneoldview = (void*)planes;
-	return true;
-}
-
-static void pointlocation(data_t *data, planeinfos *p, drmModeModeInfo *mode,
-			  int c)
-{
-	if (data->planepos[c].origo & p_right) {
-		p[c].x1 = (int32_t)(data->planepos[c].x * min(TEST_MAX_WIDTH, mode->hdisplay)
-				+ mode->hdisplay);
-		p[c].x1 &= ~3;
-		/*
-		 * At this point is handled surface on right side. If display
-		 * mode is not divisible by 4 but with 2 point location is
-		 * fixed to match requirements. Because of YUV planes here is
-		 * intentionally ignored bit 1.
-		 */
-		p[c].x1 -= mode->hdisplay & 2;
-	} else {
-		p[c].x1 = (int32_t)(data->planepos[c].x * min(TEST_MAX_WIDTH, mode->hdisplay));
-		p[c].x1 &= ~3;
-	}
-
-	if (data->planepos[c].origo & p_bottom) {
-		p[c].y1 = (int32_t)(data->planepos[c].y * min(TEST_MAX_HEIGHT, mode->vdisplay)
-				+ mode->vdisplay);
-		p[c].y1 &= ~3;
-		p[c].y1 -= mode->vdisplay & 2;
-	} else {
-		p[c].y1 = (int32_t)(data->planepos[c].y * min(TEST_MAX_HEIGHT, mode->vdisplay));
-		p[c].y1 &= ~3;
-	}
-}
-
-/*
- * Here is pipe parameter which is now used only for first pipe.
- * It is left here if this test ever was wanted to be run on
- * different pipes.
- */
-static void test_multi_plane_rotation(data_t *data, enum pipe pipe)
-{
-	igt_display_t *display = &data->display;
-	igt_output_t *output;
-	igt_crc_t retcrc_sw, retcrc_hw;
-	planeinfos p[2];
-	int c, used_w, used_h;
-	struct p_struct *oldplanes;
-	drmModeModeInfo *mode;
-
-	static const struct {
-		igt_rotation_t rotation;
-		float_t width;
-		float_t height;
-		uint64_t tiling;
-	} planeconfigs[] = {
-	{IGT_ROTATION_0, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },
-	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },
-	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
-	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
-	{IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
-	{IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
-	{IGT_ROTATION_180, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },
-	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },
-	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
-	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
-	{IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
-	{IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
-	};
-
-	/*
-	* These are those modes which are tested. For testing feel interesting
-	* case with tiling are 2 bpp, 4 bpp and NV12.
-	*/
-	static const uint32_t formatlist[] = {DRM_FORMAT_RGB565,
-		DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12};
-
-	for_each_valid_output_on_pipe(display, pipe, output) {
-		int i, j, k, l;
-		igt_output_set_pipe(output, pipe);
-		mode = igt_output_get_mode(output);
-		igt_display_require_output(display);
-		igt_display_commit2(display, COMMIT_ATOMIC);
-
-		used_w = min(TEST_MAX_WIDTH, mode->hdisplay);
-		used_h = min(TEST_MAX_HEIGHT, mode->vdisplay);
-
-		data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe,
-						  INTEL_PIPE_CRC_SOURCE_AUTO);
-		igt_pipe_crc_start(data->pipe_crc);
-
-		for (i = 0; i < ARRAY_SIZE(planeconfigs); i++) {
-			p[0].planetype = DRM_PLANE_TYPE_PRIMARY;
-			p[0].width = (uint64_t)(planeconfigs[i].width * used_w);
-			p[0].height = (uint64_t)(planeconfigs[i].height * used_h);
-			p[0].tiling = planeconfigs[i].tiling;
-			pointlocation(data, (planeinfos *)&p, mode, 0);
-
-			for (k = 0; k < ARRAY_SIZE(formatlist); k++) {
-				p[0].format = formatlist[k];
-
-				for (j = 0; j < ARRAY_SIZE(planeconfigs); j++) {
-					p[1].planetype = DRM_PLANE_TYPE_OVERLAY;
-					p[1].width = (uint64_t)(planeconfigs[j].width * used_w);
-					p[1].height = (uint64_t)(planeconfigs[j].height * used_h);
-					p[1].tiling = planeconfigs[j].tiling;
-					pointlocation(data, (planeinfos *)&p,
-						      mode, 1);
-
-					for (l = 0; l < ARRAY_SIZE(formatlist); l++) {
-						p[1].format = formatlist[l];
-
-						/*
-						 * RGB565 90/270 degrees rotation is supported
-						 * from gen11 onwards.
-						 */
-						if (p[0].format == DRM_FORMAT_RGB565 &&
-						     (planeconfigs[i].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
-						     && intel_gen(data->devid) < 11)
-							continue;
-
-						if (p[1].format == DRM_FORMAT_RGB565 &&
-						     (planeconfigs[j].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
-						     && intel_gen(data->devid) < 11)
-							continue;
-
-						p[0].rotation_sw = planeconfigs[i].rotation;
-						p[0].rotation_hw = IGT_ROTATION_0;
-						p[1].rotation_sw = planeconfigs[j].rotation;
-						p[1].rotation_hw = IGT_ROTATION_0;
-						if (!get_multiplane_crc(data, output, &retcrc_sw,
-								   (planeinfos *)&p, MAXMULTIPLANESAMOUNT))
-							continue;
-
-						igt_swap(p[0].rotation_sw, p[0].rotation_hw);
-						igt_swap(p[1].rotation_sw, p[1].rotation_hw);
-						if (!get_multiplane_crc(data, output, &retcrc_hw,
-								   (planeinfos *)&p, MAXMULTIPLANESAMOUNT))
-							continue;
-
-						igt_assert_crc_equal(&retcrc_sw, &retcrc_hw);
-					}
-				}
-			}
-		}
-		igt_pipe_crc_stop(data->pipe_crc);
-		igt_pipe_crc_free(data->pipe_crc);
-		igt_output_set_pipe(output, PIPE_ANY);
-	}
-
-	/*
-	* Old fbs are deleted only after new ones are set on planes.
-	* This is done to speed up the test
-	*/
-	oldplanes = data->multiplaneoldview;
-	for (c = 0; c < MAXMULTIPLANESAMOUNT && oldplanes; c++)
-		igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);
-
-	free(oldplanes);
-	data->multiplaneoldview = NULL;
-	data->pipe_crc = NULL;
-}
-
-static void test_plane_rotation_exhaust_fences(data_t *data,
-					       enum pipe pipe,
-					       igt_output_t *output,
-					       igt_plane_t *plane)
-{
-	igt_display_t *display = &data->display;
-	uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
-	uint32_t format = DRM_FORMAT_XRGB8888;
-	int fd = data->gfx_fd;
-	drmModeModeInfo *mode;
-	struct igt_fb fb[MAX_FENCES+1] = {};
-	uint64_t size;
-	unsigned int stride, w, h;
-	uint64_t total_aperture_size, total_fbs_size;
-	int i;
-
-	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
-
-	prepare_crtc(data, output, pipe, plane, false);
-
-	mode = igt_output_get_mode(output);
-	w = mode->hdisplay;
-	h = mode->vdisplay;
-
-	igt_calc_fb_size(fd, w, h, format, tiling, &size, &stride);
-
-	/*
-	 * Make sure there is atleast 90% of the available GTT space left
-	 * for creating (MAX_FENCES+1) framebuffers.
-	 */
-	total_fbs_size = size * (MAX_FENCES + 1);
-	total_aperture_size = gem_available_aperture_size(fd);
-	igt_require(total_fbs_size < total_aperture_size * 0.9);
-
-	for (i = 0; i < MAX_FENCES + 1; i++) {
-		igt_create_fb(fd, w, h, format, tiling, &fb[i]);
-
-		igt_plane_set_fb(plane, &fb[i]);
-		igt_plane_set_rotation(plane, IGT_ROTATION_0);
-		igt_display_commit2(display, COMMIT_ATOMIC);
-
-		igt_plane_set_rotation(plane, IGT_ROTATION_90);
-		igt_plane_set_size(plane, h, w);
-		igt_display_commit2(display, COMMIT_ATOMIC);
-	}
-
-	for (i = 0; i < MAX_FENCES + 1; i++)
-		igt_remove_fb(fd, &fb[i]);
-}
-
-static const char *plane_test_str(unsigned plane)
-{
-	switch (plane) {
-	case DRM_PLANE_TYPE_PRIMARY:
-		return "primary";
-	case DRM_PLANE_TYPE_OVERLAY:
-		return "sprite";
-	case DRM_PLANE_TYPE_CURSOR:
-		return "cursor";
-	default:
-		igt_assert(0);
-	}
-}
-
-static const char *rot_test_str(igt_rotation_t rot)
-{
-	switch (rot) {
-	case IGT_ROTATION_0:
-		return "0";
-	case IGT_ROTATION_90:
-		return "90";
-	case IGT_ROTATION_180:
-		return "180";
-	case IGT_ROTATION_270:
-		return "270";
-	default:
-		igt_assert(0);
-	}
-}
-
-static const char *tiling_test_str(uint64_t tiling)
-{
-	switch (tiling) {
-	case LOCAL_I915_FORMAT_MOD_X_TILED:
-		return "x-tiled";
-	case LOCAL_I915_FORMAT_MOD_Y_TILED:
-		return "y-tiled";
-	case LOCAL_I915_FORMAT_MOD_Yf_TILED:
-		return "yf-tiled";
-	default:
-		igt_assert(0);
-	}
-}
-
-static int opt_handler(int opt, int opt_index, void *_data)
-{
-	data_t *data = _data;
-
-	switch (opt) {
-	case 'e':
-		data->extended = true;
-		break;
-	}
-
-	return IGT_OPT_HANDLER_SUCCESS;
-}
-
-static const struct option long_opts[] = {
-	{ .name = "extended", .has_arg = false, .val = 'e', },
-	{}
-};
-
-static const char help_str[] =
-	"  --extended\t\tRun the extended tests\n";
-
-static data_t data;
-
-igt_main_args("", long_opts, help_str, opt_handler, &data)
-{
-	struct rot_subtest {
-		unsigned plane;
-		igt_rotation_t rot;
-	} *subtest, subtests[] = {
-		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_90 },
-		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_180 },
-		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_270 },
-		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_90 },
-		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_180 },
-		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_270 },
-		{ DRM_PLANE_TYPE_CURSOR, IGT_ROTATION_180 },
-		{ 0, 0}
-	};
-
-	struct reflect_x {
-		uint64_t tiling;
-		igt_rotation_t rot;
-	} *reflect_x, reflect_x_subtests[] = {
-		{ LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0 },
-		{ LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180 },
-		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0 },
-		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90 },
-		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180 },
-		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270 },
-		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0 },
-		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90 },
-		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180 },
-		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270 },
-		{ 0, 0 }
-	};
-
-	int gen = 0;
-
-	igt_fixture {
-		data.gfx_fd = drm_open_driver_master(DRIVER_INTEL);
-		data.devid = intel_get_drm_devid(data.gfx_fd);
-		gen = intel_gen(data.devid);
-
-		kmstest_set_vt_graphics_mode();
-
-		igt_require_pipe_crc(data.gfx_fd);
-
-		igt_display_require(&data.display, data.gfx_fd);
-		igt_require(data.display.is_atomic);
-	}
-
-	for (subtest = subtests; subtest->rot; subtest++) {
-		igt_subtest_f("%s-rotation-%s",
-			      plane_test_str(subtest->plane),
-			      rot_test_str(subtest->rot)) {
-			igt_require(!(subtest->rot &
-				    (IGT_ROTATION_90 | IGT_ROTATION_270)) ||
-				    gen >= 9);
-			data.rotation = subtest->rot;
-			test_plane_rotation(&data, subtest->plane, false);
-		}
-	}
-
-	igt_subtest_f("sprite-rotation-90-pos-100-0") {
-		igt_require(gen >= 9);
-		data.rotation = IGT_ROTATION_90;
-		data.pos_x = 100,
-		data.pos_y = 0;
-		test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY, false);
-	}
-	data.pos_x = 0,
-	data.pos_y = 0;
-
-	igt_subtest_f("bad-pixel-format") {
-		 /* gen11 enables RGB565 rotation for 90/270 degrees.
-		  * so apart from this, any other gen11+ pixel format
-		  * can be used which doesn't support 90/270 degree
-		  * rotation */
-		igt_require(gen >= 9);
-		data.rotation = IGT_ROTATION_90;
-		data.override_fmt = gen < 11 ? DRM_FORMAT_RGB565 : DRM_FORMAT_Y212;
-		test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);
-	}
-	data.override_fmt = 0;
-
-	igt_subtest_f("bad-tiling") {
-		igt_require(gen >= 9);
-		data.rotation = IGT_ROTATION_90;
-		data.override_tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
-		test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);
-	}
-	data.override_tiling = 0;
-
-	for (reflect_x = reflect_x_subtests; reflect_x->tiling; reflect_x++) {
-		igt_subtest_f("primary-%s-reflect-x-%s",
-			      tiling_test_str(reflect_x->tiling),
-			      rot_test_str(reflect_x->rot)) {
-			igt_require(gen >= 10 ||
-				    (IS_CHERRYVIEW(data.devid) && reflect_x->rot == IGT_ROTATION_0
-				     && reflect_x->tiling == LOCAL_I915_FORMAT_MOD_X_TILED));
-			data.rotation = (IGT_REFLECT_X | reflect_x->rot);
-			data.override_tiling = reflect_x->tiling;
-			test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, false);
-		}
-	}
-
-	igt_subtest_f("multiplane-rotation") {
-		igt_require(gen >= 9);
-		cleanup_crtc(&data);
-		data.planepos[0].origo = p_top | p_left;
-		data.planepos[0].x = .2f;
-		data.planepos[0].y = .1f;
-		data.planepos[1].origo = p_top | p_right;
-		data.planepos[1].x = -.4f;
-		data.planepos[1].y = .1f;
-		test_multi_plane_rotation(&data, 0);
-	}
-
-	igt_subtest_f("multiplane-rotation-cropping-top") {
-		igt_require(gen >= 9);
-		cleanup_crtc(&data);
-		data.planepos[0].origo = p_top | p_left;
-		data.planepos[0].x = -.05f;
-		data.planepos[0].y = -.15f;
-		data.planepos[1].origo = p_top | p_right;
-		data.planepos[1].x = -.15f;
-		data.planepos[1].y = -.15f;
-		test_multi_plane_rotation(&data, 0);
-	}
-
-	igt_subtest_f("multiplane-rotation-cropping-bottom") {
-		igt_require(gen >= 9);
-		cleanup_crtc(&data);
-		data.planepos[0].origo = p_bottom | p_left;
-		data.planepos[0].x = -.05f;
-		data.planepos[0].y = -.20f;
-		data.planepos[1].origo = p_bottom | p_right;
-		data.planepos[1].x = -.15f;
-		data.planepos[1].y = -.20f;
-		test_multi_plane_rotation(&data, 0);
-	}
-
-	/*
-	 * exhaust-fences should be last test, if it fails we may OOM in
-	 * the following subtests otherwise.
-	 */
-	igt_subtest_f("exhaust-fences") {
-		enum pipe pipe;
-		igt_output_t *output;
-
-		igt_require(gen >= 9);
-		igt_display_require_output(&data.display);
-
-		for_each_pipe_with_valid_output(&data.display, pipe, output) {
-			igt_plane_t *primary = &data.display.pipes[pipe].planes[0];
-
-			test_plane_rotation_exhaust_fences(&data, pipe, output, primary);
-			break;
-		}
-	}
-
-	igt_fixture {
-		igt_display_fini(&data.display);
-	}
-}
+/*

+ * Copyright © 2013,2014 Intel Corporation

+ *

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ *

+ * The above copyright notice and this permission notice (including the next

+ * paragraph) shall be included in all copies or substantial portions of the

+ * Software.

+ *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL

+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS

+ * IN THE SOFTWARE.

+ *

+ */

+

+#include "igt.h"

+#include "igt_vec.h"

+#include <math.h>

+

+#define MAX_FENCES 32

+#define MAXMULTIPLANESAMOUNT 2

+#define TEST_MAX_WIDTH 640

+#define TEST_MAX_HEIGHT 480

+

+struct p_struct {

+ igt_plane_t *plane;

+ struct igt_fb fb;

+};

+

+enum p_pointorigo {

+ p_top = 1 << 0,

+ p_bottom = 1 << 1,

+ p_left = 1 << 2,

+ p_right = 1 << 3

+};

+

+struct p_point{

+ enum p_pointorigo origo;

+ float_t x;

+ float_t y;

+};

+

+typedef struct {

+ int gfx_fd;

+ igt_display_t display;

+ struct igt_fb fb;

+ struct igt_fb fb_reference;

+ struct igt_fb fb_flip;

+ igt_crc_t ref_crc;

+ igt_crc_t flip_crc;

+ igt_pipe_crc_t *pipe_crc;

+ igt_rotation_t rotation;

+ int pos_x;

+ int pos_y;

+ uint32_t override_fmt;

+ uint64_t override_tiling;

+ int devid;

+

+ struct p_struct *multiplaneoldview;

+ struct p_point planepos[MAXMULTIPLANESAMOUNT];

+

+ bool use_native_resolution;

+ bool extended;

+} data_t;

+

+typedef struct {

+ float r;

+ float g;

+ float b;

+} rgb_color_t;

+

+static void set_color(rgb_color_t *color, float r, float g, float b)

+{

+ color->r = r;

+ color->g = g;

+ color->b = b;

+}

+

+static void rotate_colors(rgb_color_t *tl, rgb_color_t *tr, rgb_color_t *br,

+ rgb_color_t *bl, igt_rotation_t rotation)

+{

+ rgb_color_t bl_tmp, br_tmp, tl_tmp, tr_tmp;

+

+ if (rotation & IGT_REFLECT_X) {

+ igt_swap(*tl, *tr);

+ igt_swap(*bl, *br);

+ }

+

+ if (rotation & IGT_ROTATION_90) {

+ bl_tmp = *bl;

+ br_tmp = *br;

+ tl_tmp = *tl;

+ tr_tmp = *tr;

+ *tl = tr_tmp;

+ *bl = tl_tmp;

+ *tr = br_tmp;

+ *br = bl_tmp;

+ } else if (rotation & IGT_ROTATION_180) {

+ igt_swap(*tl, *br);

+ igt_swap(*tr, *bl);

+ } else if (rotation & IGT_ROTATION_270) {

+ bl_tmp = *bl;

+ br_tmp = *br;

+ tl_tmp = *tl;

+ tr_tmp = *tr;

+ *tl = bl_tmp;

+ *bl = br_tmp;

+ *tr = tl_tmp;

+ *br = tr_tmp;

+ }

+}

+

+#define RGB_COLOR(color) \

+ color.r, color.g, color.b

+

+static void

+paint_squares(data_t *data, igt_rotation_t rotation,

+ struct igt_fb *fb, float o)

+{

+ cairo_t *cr;

+ unsigned int w = fb->width;

+ unsigned int h = fb->height;

+ rgb_color_t tl, tr, bl, br;

+

+ igt_assert_f(!(w&1), "rotation image must be even width, now attempted %d\n", w);

+ igt_assert_f(!(h&1), "rotation image must be even height, now attempted %d\n", h);

+

+ cr = igt_get_cairo_ctx(data->gfx_fd, fb);

+

+ set_color(&tl, o, 0.0f, 0.0f);

+ set_color(&tr, 0.0f, o, 0.0f);

+ set_color(&br, o, o, o);

+ set_color(&bl, 0.0f, 0.0f, o);

+

+ rotate_colors(&tl, &tr, &br, &bl, rotation);

+

+ igt_paint_color(cr, 0, 0, w / 2, h / 2, RGB_COLOR(tl));

+ igt_paint_color(cr, w / 2, 0, w / 2, h / 2, RGB_COLOR(tr));

+ igt_paint_color(cr, 0, h / 2, w / 2, h / 2, RGB_COLOR(bl));

+ igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, RGB_COLOR(br));

+

+ igt_put_cairo_ctx(cr);

+}

+

+static void remove_fbs(data_t *data)

+{

+ igt_remove_fb(data->gfx_fd, &data->fb);

+ igt_remove_fb(data->gfx_fd, &data->fb_reference);

+ igt_remove_fb(data->gfx_fd, &data->fb_flip);

+}

+

+static void cleanup_crtc(data_t *data)

+{

+ igt_display_t *display = &data->display;

+

+ igt_pipe_crc_free(data->pipe_crc);

+ data->pipe_crc = NULL;

+

+ remove_fbs(data);

+

+ igt_display_reset(display);

+}

+

+static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,

+ igt_plane_t *plane, bool start_crc)

+{

+ igt_display_t *display = &data->display;

+

+ cleanup_crtc(data);

+

+ igt_output_set_pipe(output, pipe);

+ igt_plane_set_rotation(plane, IGT_ROTATION_0);

+

+ /* create the pipe_crc object for this pipe */

+ igt_pipe_crc_free(data->pipe_crc);

+

+ if (is_amdgpu_device(data->gfx_fd)) {

+ igt_fb_t fb_temp;

+

+ igt_create_fb(data->gfx_fd, 1280, 800, DRM_FORMAT_XRGB8888, 0, &fb_temp);

+ igt_plane_set_fb(plane, &fb_temp);

+ }

+ igt_display_commit2(display, COMMIT_ATOMIC);

+ data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);

+

+ if (start_crc)

+ igt_pipe_crc_start(data->pipe_crc);

+}

+

+enum rectangle_type {

+ rectangle,

+ square,

+ portrait,

+ landscape,

+ num_rectangle_types /* must be last */

+};

+

+static void prepare_fbs(data_t *data, igt_output_t *output,

+ igt_plane_t *plane, enum rectangle_type rect, uint32_t format)

+{

+ drmModeModeInfo *mode;

+ igt_display_t *display = &data->display;

+ unsigned int w, h, ref_w, ref_h, min_w, min_h;

+ uint64_t tiling = data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE;

+ uint32_t pixel_format = data->override_fmt ?: DRM_FORMAT_XRGB8888;

+ const float flip_opacity = 0.75;

+ bool amd_gpu = is_amdgpu_device(data->gfx_fd);

+ bool intel_gpu = is_i915_device(data->gfx_fd);

+

+ remove_fbs(data);

+

+ igt_plane_set_rotation(plane, IGT_ROTATION_0);

+

+ mode = igt_output_get_mode(output);

+ if (plane->type != DRM_PLANE_TYPE_CURSOR) {

+ if (amd_gpu) {

+ w = mode->hdisplay;

+ h = mode->vdisplay;

+ } else if (intel_gpu) {

+ if (data->use_native_resolution) {

+ w = mode->hdisplay;

+ h = mode->vdisplay;

+ } else {

+ w = min(TEST_MAX_WIDTH, mode->hdisplay);

+ h = min(TEST_MAX_HEIGHT, mode->vdisplay);

+ }

+

+ min_w = 256;

+ min_h = 256;

+ }

+ } else {

+ pixel_format = data->override_fmt ?: DRM_FORMAT_ARGB8888;

+

+ w = h = 256;

+ min_w = min_h = 64;

+ }

+

+ switch (rect) {

+ case rectangle:

+ break;

+ case square:

+ w = h = min(h, w);

+ break;

+ case portrait:

+ w = min_w;

+ break;

+ case landscape:

+ h = min_h;

+ break;

+ case num_rectangle_types:

+ igt_assert(0);

+ }

+

+ ref_w = w;

+ ref_h = h;

+

+ /*

+ * For 90/270, we will use create smaller fb so that the rotated

+ * frame can fit in

+ */

+ if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270)) {

+ if (intel_gpu)

+ tiling = data->override_tiling ?: LOCAL_I915_FORMAT_MOD_Y_TILED;

+

+ igt_swap(w, h);

+ }

+

+ /*

+ * Just try here if requested tiling format is generally available,

+ * if one format fail it will skip entire subtest.

+ */

+ igt_require(igt_display_has_format_mod(display, pixel_format, tiling));

+

+ if (intel_gpu) {

+ /*

+ * Create a reference software rotated flip framebuffer.

+ */

+ igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format, tiling,

+ &data->fb_flip);

+ paint_squares(data, data->rotation, &data->fb_flip,

+ flip_opacity);

+ igt_plane_set_fb(plane, &data->fb_flip);

+ if (plane->type != DRM_PLANE_TYPE_CURSOR)

+ igt_plane_set_position(plane, data->pos_x, data->pos_y);

+ igt_display_commit2(display, COMMIT_ATOMIC);

+

+ igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->flip_crc);

+

+ /*

+ * Prepare the non-rotated flip fb.

+ */

+ igt_remove_fb(data->gfx_fd, &data->fb_flip);

+ igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling,

+ &data->fb_flip);

+ paint_squares(data, IGT_ROTATION_0, &data->fb_flip,

+ flip_opacity);

+

+ /*

+ * Create a reference CRC for a software-rotated fb.

+ */

+ igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format,

+ data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE, &data->fb_reference);

+ } else if (amd_gpu) {

+ tiling = 0x1900;

+ igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format,

+ tiling, &data->fb_reference);

+ }

+ paint_squares(data, data->rotation, &data->fb_reference, 1.0);

+

+ igt_plane_set_fb(plane, &data->fb_reference);

+ if (plane->type != DRM_PLANE_TYPE_CURSOR)

+ igt_plane_set_position(plane, data->pos_x, data->pos_y);

+ igt_display_commit2(display, COMMIT_ATOMIC);

+

+ if (intel_gpu)

+ igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->ref_crc);

+ else if (amd_gpu)

+ igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);

+

+ /*

+ * Prepare the plane with an non-rotated fb let the hw rotate it.

+ */

+ igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);

+ paint_squares(data, IGT_ROTATION_0, &data->fb, 1.0);

+ igt_plane_set_fb(plane, &data->fb);

+

+ if (plane->type != DRM_PLANE_TYPE_CURSOR)

+ igt_plane_set_position(plane, data->pos_x, data->pos_y);

+}

+

+static void test_single_case(data_t *data, enum pipe pipe,

+ igt_output_t *output, igt_plane_t *plane,

+ enum rectangle_type rect,

+ uint32_t format, bool test_bad_format)

+{

+ igt_display_t *display = &data->display;

+ igt_crc_t crc_output;

+ int ret;

+

+ igt_debug("Testing case %i on pipe %s, format %s\n", rect, kmstest_pipe_name(pipe), igt_format_str(format));

+ prepare_fbs(data, output, plane, rect, format);

+

+ igt_plane_set_rotation(plane, data->rotation);

+ if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))

+ igt_plane_set_size(plane, data->fb.height, data->fb.width);

+

+ ret = igt_display_try_commit2(display, COMMIT_ATOMIC);

+ if (test_bad_format) {

+ igt_assert_eq(ret, -EINVAL);

+ return;

+ }

+

+ /* Verify commit was ok. */

+ igt_assert_eq(ret, 0);

+

+ if (is_i915_device(data->gfx_fd)) {

+ /* Check CRC */

+ igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);

+ igt_assert_crc_equal(&data->ref_crc, &crc_output);

+

+ /*

+ * If flips are requested flip to a different fb and

+ * check CRC against that one as well.

+ */

+ if (data->fb_flip.fb_id) {

+ igt_plane_set_fb(plane, &data->fb_flip);

+ if (data->rotation == IGT_ROTATION_90 || data->rotation == IGT_ROTATION_270)

+ igt_plane_set_size(plane, data->fb.height, data->fb.width);

+

+ if (plane->type != DRM_PLANE_TYPE_PRIMARY) {

+ igt_display_commit_atomic(display, DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, NULL);

+ } else {

+ ret = drmModePageFlip(data->gfx_fd,

+ output->config.crtc->crtc_id,

+ data->fb_flip.fb_id,

+ DRM_MODE_PAGE_FLIP_EVENT,

+ NULL);

+ igt_assert_eq(ret, 0);

+ }

+ kmstest_wait_for_pageflip(data->gfx_fd);

+ igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);

+ igt_assert_crc_equal(&data->flip_crc,

+ &crc_output);

+ }

+ } else if (is_amdgpu_device(data->gfx_fd)) {

+ igt_pipe_crc_collect_crc(data->pipe_crc, &crc_output);

+ }

+}

+

+static bool test_format(data_t *data,

+ struct igt_vec *tested_formats,

+ uint32_t format)

+{

+ if (!igt_fb_supported_format(format))

+ return false;

+

+ if (!is_i915_device(data->gfx_fd) ||

+ data->extended)

+ return true;

+

+ format = igt_reduce_format(format);

+

+ /* only test each format "class" once */

+ if (igt_vec_index(tested_formats, &format) >= 0)

+ return false;

+

+ igt_vec_push(tested_formats, &format);

+

+ return true;

+}

+

+static void test_plane_rotation(data_t *data, int plane_type, bool test_bad_format)

+{

+ igt_display_t *display = &data->display;

+ igt_output_t *output;

+ enum pipe pipe;

+

+ if (plane_type == DRM_PLANE_TYPE_CURSOR)

+ igt_require(display->has_cursor_plane);

+

+ igt_display_require_output(display);

+

+ for_each_pipe_with_valid_output(display, pipe, output) {

+ igt_plane_t *plane;

+ int i, j;

+

+ if (is_i915_device(data->gfx_fd)) {

+ if (IS_CHERRYVIEW(data->devid) && pipe != PIPE_B)

+ continue;

+

+ igt_output_set_pipe(output, pipe);

+

+ plane = igt_output_get_plane_type(output, plane_type);

+ igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));

+

+ prepare_crtc(data, output, pipe, plane, true);

+

+ for (i = 0; i < num_rectangle_types; i++) {

+ /* Unsupported on i915 */

+ if (plane_type == DRM_PLANE_TYPE_CURSOR &&

+ i != square)

+ continue;

+

+ /* Only support partial covering primary plane on gen9+ */

+ if (plane_type == DRM_PLANE_TYPE_PRIMARY &&

+ intel_gen(intel_get_drm_devid(data->gfx_fd)) < 9) {

+ if (i != rectangle)

+ continue;

+ else

+ data->use_native_resolution = true;

+ } else {

+ data->use_native_resolution = false;

+ }

+

+ if (!data->override_fmt) {

+ struct igt_vec tested_formats;

+

+ igt_vec_init(&tested_formats, sizeof(uint32_t));

+

+ for (j = 0; j < plane->drm_plane->count_formats; j++) {

+ uint32_t format = plane->drm_plane->formats[j];

+

+ if (!test_format(data, &tested_formats, format))

+ continue;

+

+ test_single_case(data, pipe, output, plane, i,

+ format, test_bad_format);

+ }

+

+ igt_vec_fini(&tested_formats);

+ } else {

+ test_single_case(data, pipe, output, plane, i,

+ data->override_fmt, test_bad_format);

+ }

+ }

+ } else if (is_amdgpu_device(data->gfx_fd)) {

+ uint32_t format = DRM_FORMAT_XRGB8888;

+

+ igt_output_set_pipe(output, pipe);

+

+ plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);

+ igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));

+

+ prepare_crtc(data, output, pipe, plane, false);

+

+ if (plane_type != DRM_PLANE_TYPE_PRIMARY) {

+ plane = igt_output_get_plane_type(output, plane_type);

+ igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));

+ }

+

+ test_single_case(data, pipe, output, plane,

+ rectangle, format, test_bad_format);

+ }

+

+ igt_pipe_crc_stop(data->pipe_crc);

+ }

+}

+

+typedef struct {

+ int32_t x1, y1;

+ uint64_t width, height, tiling, planetype, format;

+ igt_rotation_t rotation_sw, rotation_hw;

+} planeinfos;

+

+static bool get_multiplane_crc(data_t *data, igt_output_t *output,

+ igt_crc_t *crc_output, planeinfos *planeinfo,

+ int numplanes)

+{

+ uint32_t w, h;

+ igt_display_t *display = &data->display;

+ struct p_struct *planes, *oldplanes;

+ int c, ret;

+

+ oldplanes = data->multiplaneoldview;

+ planes = calloc(sizeof(*planes), numplanes);

+

+ for (c = 0; c < numplanes; c++) {

+ planes[c].plane = igt_output_get_plane_type(output,

+ planeinfo[c].planetype);

+

+ /*

+ * make plane and fb width and height always divisible by 4

+ * due to NV12 support and Intel hw workarounds.

+ */

+ w = planeinfo[c].width & ~3;

+ h = planeinfo[c].height & ~3;

+

+ if (planeinfo[c].rotation_sw & (IGT_ROTATION_90 | IGT_ROTATION_270))

+ igt_swap(w, h);

+

+ if (!igt_plane_has_format_mod(planes[c].plane,

+ planeinfo[c].format,

+ planeinfo[c].tiling))

+ return false;

+

+ igt_create_fb(data->gfx_fd, w, h, planeinfo[c].format,

+ planeinfo[c].tiling, &planes[c].fb);

+

+ paint_squares(data, planeinfo[c].rotation_sw, &planes[c].fb, 1.0f);

+ igt_plane_set_fb(planes[c].plane, &planes[c].fb);

+

+ if (planeinfo[c].rotation_hw & (IGT_ROTATION_90 | IGT_ROTATION_270))

+ igt_plane_set_size(planes[c].plane, h, w);

+

+ igt_plane_set_position(planes[c].plane, planeinfo[c].x1, planeinfo[c].y1);

+ igt_plane_set_rotation(planes[c].plane, planeinfo[c].rotation_hw);

+ }

+

+ ret = igt_display_try_commit2(display, COMMIT_ATOMIC);

+ igt_assert_eq(ret, 0);

+

+ igt_pipe_crc_get_current(data->gfx_fd, data->pipe_crc, crc_output);

+

+ for (c = 0; c < numplanes && oldplanes; c++)

+ igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);

+

+ free(oldplanes);

+ data->multiplaneoldview = (void*)planes;

+ return true;

+}

+

+static void pointlocation(data_t *data, planeinfos *p, drmModeModeInfo *mode,

+ int c)

+{

+ if (data->planepos[c].origo & p_right) {

+ p[c].x1 = (int32_t)(data->planepos[c].x * min(TEST_MAX_WIDTH, mode->hdisplay)

+ + mode->hdisplay);

+ p[c].x1 &= ~3;

+ /*

+ * At this point is handled surface on right side. If display

+ * mode is not divisible by 4 but with 2 point location is

+ * fixed to match requirements. Because of YUV planes here is

+ * intentionally ignored bit 1.

+ */

+ p[c].x1 -= mode->hdisplay & 2;

+ } else {

+ p[c].x1 = (int32_t)(data->planepos[c].x * min(TEST_MAX_WIDTH, mode->hdisplay));

+ p[c].x1 &= ~3;

+ }

+

+ if (data->planepos[c].origo & p_bottom) {

+ p[c].y1 = (int32_t)(data->planepos[c].y * min(TEST_MAX_HEIGHT, mode->vdisplay)

+ + mode->vdisplay);

+ p[c].y1 &= ~3;

+ p[c].y1 -= mode->vdisplay & 2;

+ } else {

+ p[c].y1 = (int32_t)(data->planepos[c].y * min(TEST_MAX_HEIGHT, mode->vdisplay));

+ p[c].y1 &= ~3;

+ }

+}

+

+/*

+ * Here is pipe parameter which is now used only for first pipe.

+ * It is left here if this test ever was wanted to be run on

+ * different pipes.

+ */

+static void test_multi_plane_rotation(data_t *data, enum pipe pipe)

+{

+ igt_display_t *display = &data->display;

+ igt_output_t *output;

+ igt_crc_t retcrc_sw, retcrc_hw;

+ planeinfos p[2];

+ int c, used_w, used_h;

+ struct p_struct *oldplanes;

+ drmModeModeInfo *mode;

+

+ static const struct {

+ igt_rotation_t rotation;

+ float_t width;

+ float_t height;

+ uint64_t tiling;

+ } planeconfigs[] = {

+ {IGT_ROTATION_0, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },

+ {IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },

+ {IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },

+ {IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },

+ {IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },

+ {IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },

+ {IGT_ROTATION_180, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },

+ {IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },

+ {IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },

+ {IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },

+ {IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },

+ {IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },

+ };

+

+ /*

+ * These are those modes which are tested. For testing feel interesting

+ * case with tiling are 2 bpp, 4 bpp and NV12.

+ */

+ static const uint32_t formatlist[] = {DRM_FORMAT_RGB565,

+ DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12};

+

+ for_each_valid_output_on_pipe(display, pipe, output) {

+ int i, j, k, l;

+ igt_output_set_pipe(output, pipe);

+ mode = igt_output_get_mode(output);

+ igt_display_require_output(display);

+ igt_display_commit2(display, COMMIT_ATOMIC);

+

+ used_w = min(TEST_MAX_WIDTH, mode->hdisplay);

+ used_h = min(TEST_MAX_HEIGHT, mode->vdisplay);

+

+ data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe,

+ INTEL_PIPE_CRC_SOURCE_AUTO);

+ igt_pipe_crc_start(data->pipe_crc);

+

+ for (i = 0; i < ARRAY_SIZE(planeconfigs); i++) {

+ p[0].planetype = DRM_PLANE_TYPE_PRIMARY;

+ p[0].width = (uint64_t)(planeconfigs[i].width * used_w);

+ p[0].height = (uint64_t)(planeconfigs[i].height * used_h);

+ p[0].tiling = planeconfigs[i].tiling;

+ pointlocation(data, (planeinfos *)&p, mode, 0);

+

+ for (k = 0; k < ARRAY_SIZE(formatlist); k++) {

+ p[0].format = formatlist[k];

+

+ for (j = 0; j < ARRAY_SIZE(planeconfigs); j++) {

+ p[1].planetype = DRM_PLANE_TYPE_OVERLAY;

+ p[1].width = (uint64_t)(planeconfigs[j].width * used_w);

+ p[1].height = (uint64_t)(planeconfigs[j].height * used_h);

+ p[1].tiling = planeconfigs[j].tiling;

+ pointlocation(data, (planeinfos *)&p,

+ mode, 1);

+

+ for (l = 0; l < ARRAY_SIZE(formatlist); l++) {

+ p[1].format = formatlist[l];

+

+ /*

+ * RGB565 90/270 degrees rotation is supported

+ * from gen11 onwards.

+ */

+ if (p[0].format == DRM_FORMAT_RGB565 &&

+ (planeconfigs[i].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))

+ && intel_gen(data->devid) < 11)

+ continue;

+

+ if (p[1].format == DRM_FORMAT_RGB565 &&

+ (planeconfigs[j].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))

+ && intel_gen(data->devid) < 11)

+ continue;

+

+ p[0].rotation_sw = planeconfigs[i].rotation;

+ p[0].rotation_hw = IGT_ROTATION_0;

+ p[1].rotation_sw = planeconfigs[j].rotation;

+ p[1].rotation_hw = IGT_ROTATION_0;

+ if (!get_multiplane_crc(data, output, &retcrc_sw,

+ (planeinfos *)&p, MAXMULTIPLANESAMOUNT))

+ continue;

+

+ igt_swap(p[0].rotation_sw, p[0].rotation_hw);

+ igt_swap(p[1].rotation_sw, p[1].rotation_hw);

+ if (!get_multiplane_crc(data, output, &retcrc_hw,

+ (planeinfos *)&p, MAXMULTIPLANESAMOUNT))

+ continue;

+

+ igt_assert_crc_equal(&retcrc_sw, &retcrc_hw);

+ }

+ }

+ }

+ }

+ igt_pipe_crc_stop(data->pipe_crc);

+ igt_pipe_crc_free(data->pipe_crc);

+ igt_output_set_pipe(output, PIPE_ANY);

+ }

+

+ /*

+ * Old fbs are deleted only after new ones are set on planes.

+ * This is done to speed up the test

+ */

+ oldplanes = data->multiplaneoldview;

+ for (c = 0; c < MAXMULTIPLANESAMOUNT && oldplanes; c++)

+ igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);

+

+ free(oldplanes);

+ data->multiplaneoldview = NULL;

+ data->pipe_crc = NULL;

+}

+

+static void test_plane_rotation_exhaust_fences(data_t *data,

+ enum pipe pipe,

+ igt_output_t *output,

+ igt_plane_t *plane)

+{

+ igt_display_t *display = &data->display;

+ uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;

+ uint32_t format = DRM_FORMAT_XRGB8888;

+ int fd = data->gfx_fd;

+ drmModeModeInfo *mode;

+ struct igt_fb fb[MAX_FENCES+1] = {};

+ uint64_t size;

+ unsigned int stride, w, h;

+ uint64_t total_aperture_size, total_fbs_size;

+ int i;

+

+ igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));

+

+ prepare_crtc(data, output, pipe, plane, false);

+

+ mode = igt_output_get_mode(output);

+ w = mode->hdisplay;

+ h = mode->vdisplay;

+

+ igt_calc_fb_size(fd, w, h, format, tiling, &size, &stride);

+

+ /*

+ * Make sure there is atleast 90% of the available GTT space left

+ * for creating (MAX_FENCES+1) framebuffers.

+ */

+ total_fbs_size = size * (MAX_FENCES + 1);

+ total_aperture_size = gem_available_aperture_size(fd);

+ igt_require(total_fbs_size < total_aperture_size * 0.9);

+

+ for (i = 0; i < MAX_FENCES + 1; i++) {

+ igt_create_fb(fd, w, h, format, tiling, &fb[i]);

+

+ igt_plane_set_fb(plane, &fb[i]);

+ igt_plane_set_rotation(plane, IGT_ROTATION_0);

+ igt_display_commit2(display, COMMIT_ATOMIC);

+

+ igt_plane_set_rotation(plane, IGT_ROTATION_90);

+ igt_plane_set_size(plane, h, w);

+ igt_display_commit2(display, COMMIT_ATOMIC);

+ }

+

+ for (i = 0; i < MAX_FENCES + 1; i++)

+ igt_remove_fb(fd, &fb[i]);

+}

+

+static const char *plane_test_str(unsigned plane)

+{

+ switch (plane) {

+ case DRM_PLANE_TYPE_PRIMARY:

+ return "primary";

+ case DRM_PLANE_TYPE_OVERLAY:

+ return "sprite";

+ case DRM_PLANE_TYPE_CURSOR:

+ return "cursor";

+ default:

+ igt_assert(0);

+ }

+}

+

+static const char *rot_test_str(igt_rotation_t rot)

+{

+ switch (rot) {

+ case IGT_ROTATION_0:

+ return "0";

+ case IGT_ROTATION_90:

+ return "90";

+ case IGT_ROTATION_180:

+ return "180";

+ case IGT_ROTATION_270:

+ return "270";

+ default:

+ igt_assert(0);

+ }

+}

+

+static const char *tiling_test_str(uint64_t tiling)

+{

+ switch (tiling) {

+ case LOCAL_I915_FORMAT_MOD_X_TILED:

+ return "x-tiled";

+ case LOCAL_I915_FORMAT_MOD_Y_TILED:

+ return "y-tiled";

+ case LOCAL_I915_FORMAT_MOD_Yf_TILED:

+ return "yf-tiled";

+ default:

+ igt_assert(0);

+ }

+}

+

+static int opt_handler(int opt, int opt_index, void *_data)

+{

+ data_t *data = _data;

+

+ switch (opt) {

+ case 'e':

+ data->extended = true;

+ break;

+ }

+

+ return IGT_OPT_HANDLER_SUCCESS;

+}

+

+static const struct option long_opts[] = {

+ { .name = "extended", .has_arg = false, .val = 'e', },

+ {}

+};

+

+static const char help_str[] =

+ " --extended\t\tRun the extended tests\n";

+

+static data_t data;

+

+igt_main_args("", long_opts, help_str, opt_handler, &data)

+{

+ struct rot_subtest {

+ unsigned plane;

+ igt_rotation_t rot;

+ } *subtest, subtests[] = {

+ { DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_90 },

+ { DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_180 },

+ { DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_270 },

+ { DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_90 },

+ { DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_180 },

+ { DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_270 },

+ { DRM_PLANE_TYPE_CURSOR, IGT_ROTATION_180 },

+ { 0, 0}

+ };

+

+ struct reflect_x {

+ uint64_t tiling;

+ igt_rotation_t rot;

+ } *reflect_x, reflect_x_subtests[] = {

+ { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0 },

+ { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180 },

+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0 },

+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90 },

+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180 },

+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270 },

+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0 },

+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90 },

+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180 },

+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270 },

+ { 0, 0 }

+ };

+

+ int gen = 0;

+

+ igt_fixture {

+ data.gfx_fd = drm_open_driver_master(DRIVER_INTEL | DRIVER_AMDGPU);

+ if (is_i915_device(data.gfx_fd)) {

+ data.devid = intel_get_drm_devid(data.gfx_fd);

+ gen = intel_gen(data.devid);

+ }

+

+ kmstest_set_vt_graphics_mode();

+

+ igt_require_pipe_crc(data.gfx_fd);

+

+ igt_display_require(&data.display, data.gfx_fd);

+ igt_require(data.display.is_atomic);

+ }

+

+ for (subtest = subtests; subtest->rot; subtest++) {

+ igt_subtest_f("%s-rotation-%s",

+ plane_test_str(subtest->plane),

+ rot_test_str(subtest->rot)) {

+ if (is_i915_device(data.gfx_fd)) {

+ igt_require(!(subtest->rot &

+ (IGT_ROTATION_90 | IGT_ROTATION_270)) ||

+ gen >= 9);

+ }

+ data.rotation = subtest->rot;

+ test_plane_rotation(&data, subtest->plane, false);

+ }

+ }

+

+ igt_subtest_f("sprite-rotation-90-pos-100-0") {

+ igt_require(gen >= 9);

+ data.rotation = IGT_ROTATION_90;

+ data.pos_x = 100,

+ data.pos_y = 0;

+ test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY, false);

+ }

+ data.pos_x = 0,

+ data.pos_y = 0;

+

+ igt_subtest_f("bad-pixel-format") {

+ /* gen11 enables RGB565 rotation for 90/270 degrees.

+ * so apart from this, any other gen11+ pixel format

+ * can be used which doesn't support 90/270 degree

+ * rotation */

+ igt_require(gen >= 9);

+ data.rotation = IGT_ROTATION_90;

+ data.override_fmt = gen < 11 ? DRM_FORMAT_RGB565 : DRM_FORMAT_Y212;

+ test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);

+ }

+ data.override_fmt = 0;

+

+ igt_subtest_f("bad-tiling") {

+ igt_require(gen >= 9);

+ data.rotation = IGT_ROTATION_90;

+ data.override_tiling = LOCAL_I915_FORMAT_MOD_X_TILED;

+ test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);

+ }

+ data.override_tiling = 0;

+

+ for (reflect_x = reflect_x_subtests; reflect_x->tiling; reflect_x++) {

+ igt_subtest_f("primary-%s-reflect-x-%s",

+ tiling_test_str(reflect_x->tiling),

+ rot_test_str(reflect_x->rot)) {

+ igt_require(gen >= 10 ||

+ (IS_CHERRYVIEW(data.devid) && reflect_x->rot == IGT_ROTATION_0

+ && reflect_x->tiling == LOCAL_I915_FORMAT_MOD_X_TILED));

+ data.rotation = (IGT_REFLECT_X | reflect_x->rot);

+ data.override_tiling = reflect_x->tiling;

+ test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, false);

+ }

+ }

+

+ igt_subtest_f("multiplane-rotation") {

+ igt_require(gen >= 9);

+ cleanup_crtc(&data);

+ data.planepos[0].origo = p_top | p_left;

+ data.planepos[0].x = .2f;

+ data.planepos[0].y = .1f;

+ data.planepos[1].origo = p_top | p_right;

+ data.planepos[1].x = -.4f;

+ data.planepos[1].y = .1f;

+ test_multi_plane_rotation(&data, 0);

+ }

+

+ igt_subtest_f("multiplane-rotation-cropping-top") {

+ igt_require(gen >= 9);

+ cleanup_crtc(&data);

+ data.planepos[0].origo = p_top | p_left;

+ data.planepos[0].x = -.05f;

+ data.planepos[0].y = -.15f;

+ data.planepos[1].origo = p_top | p_right;

+ data.planepos[1].x = -.15f;

+ data.planepos[1].y = -.15f;

+ test_multi_plane_rotation(&data, 0);

+ }

+

+ igt_subtest_f("multiplane-rotation-cropping-bottom") {

+ igt_require(gen >= 9);

+ cleanup_crtc(&data);

+ data.planepos[0].origo = p_bottom | p_left;

+ data.planepos[0].x = -.05f;

+ data.planepos[0].y = -.20f;

+ data.planepos[1].origo = p_bottom | p_right;

+ data.planepos[1].x = -.15f;

+ data.planepos[1].y = -.20f;

+ test_multi_plane_rotation(&data, 0);

+ }

+

+ /*

+ * exhaust-fences should be last test, if it fails we may OOM in

+ * the following subtests otherwise.

+ */

+ igt_subtest_f("exhaust-fences") {

+ enum pipe pipe;

+ igt_output_t *output;

+

+ igt_require(gen >= 9);

+ igt_display_require_output(&data.display);

+

+ for_each_pipe_with_valid_output(&data.display, pipe, output) {

+ igt_plane_t *primary = &data.display.pipes[pipe].planes[0];

+

+ test_plane_rotation_exhaust_fences(&data, pipe, output, primary);

+ break;

+ }

+ }

+

+ igt_fixture {

+ igt_display_fini(&data.display);

+ }

+}

Signature · 6 lines
2.25.1

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
#3 lore raw

[igt-dev] ✓ Fi.CI.BAT: success for kms_rotation_crc:Add HW rotation test case for amdgpu

In reply to Sung Joon Kim
== Series Details ==

== Series Details ==

Series: kms_rotation_crc:Add HW rotation test case for amdgpu
URL : https://patchwork.freedesktop.org/series/85018/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_9495 -> IGTPW_5302
====================================================

Summary
-------

**SUCCESS**

No regressions found.

External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/index.html

Known issues
------------

Here are the changes found in IGTPW_5302 that come from known issues:

### IGT changes ###

#### Issues hit ####

* igt@gem_flink_basic@bad-flink:
- fi-tgl-y: [PASS][1] -> [DMESG-WARN][2] ([i915#402])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/fi-tgl-y/igt@[email protected]
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/fi-tgl-y/igt@[email protected]

* igt@runner@aborted:
- fi-bdw-5557u: NOTRUN -> [FAIL][3] ([i915#2029] / [i915#2722])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/fi-bdw-5557u/igt@[email protected]

#### Possible fixes ####

* igt@gem_basic@create-close:
- fi-tgl-y: [DMESG-WARN][4] ([i915#402]) -> [PASS][5] +1 similar issue
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/fi-tgl-y/igt@[email protected]
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/fi-tgl-y/igt@[email protected]

[i915#2029]: https://gitlab.freedesktop.org/drm/intel/issues/2029
[i915#2722]: https://gitlab.freedesktop.org/drm/intel/issues/2722
[i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402

Participating hosts (42 -> 38)
------------------------------

Missing (4): fi-dg1-1 fi-bsw-cyan fi-bdw-samus fi-hsw-4200u

Build changes
-------------

* CI: CI-20190529 -> None
* IGT: IGT_5905 -> IGTPW_5302

CI-20190529: 20190529
CI_DRM_9495: 2960e86fd8fd7659400d05f40a1e06d3a97b6987 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_5302: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/index.html
IGT_5905: 3d0934900bddeb7a68f1abab4cd05077f0609e32 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/index.html

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

#4 lore raw

[igt-dev] ✗ Fi.CI.IGT: failure for kms_rotation_crc:Add HW rotation test case for amdgpu

In reply to Sung Joon Kim
== Series Details ==

== Series Details ==

Series: kms_rotation_crc:Add HW rotation test case for amdgpu
URL : https://patchwork.freedesktop.org/series/85018/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_9495_full -> IGTPW_5302_full
====================================================

Summary
-------

**FAILURE**

Serious unknown changes coming with IGTPW_5302_full absolutely need to be verified manually.

If you think the reported changes have nothing to do with the changes introduced in IGTPW_5302_full, please notify your bug team to allow them to document this new failure mode, which will reduce false positives in CI.

External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/index.html

Possible new issues
-------------------

Here are the unknown changes that may have been introduced in IGTPW_5302_full:

### IGT changes ###

#### Possible regressions ####

* igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
- shard-iclb: [PASS][1] -> [DMESG-WARN][2]
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb4/igt@[email protected]
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb5/igt@[email protected]

New tests
---------

New tests have been introduced between CI_DRM_9495_full and IGTPW_5302_full:

### New IGT tests (4) ###

* igt@kms_atomic_transition@modeset-transition:
- Statuses :
- Exec time: [None] s

* igt@kms_atomic_transition@modeset-transition-fencing:
- Statuses :
- Exec time: [None] s

* igt@kms_atomic_transition@modeset-transition-nonblocking:
- Statuses :
- Exec time: [None] s

* igt@kms_atomic_transition@modeset-transition-nonblocking-fencing:
- Statuses :
- Exec time: [None] s

Known issues
------------

Here are the changes found in IGTPW_5302_full that come from known issues:

### IGT changes ###

#### Issues hit ####

* igt@feature_discovery@psr2:
- shard-iclb: [PASS][3] -> [SKIP][4] ([i915#658])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb2/igt@[email protected]
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb8/igt@[email protected]

* igt@gem_exec_fence@basic-wait@bcs0:
- shard-glk: NOTRUN -> [SKIP][5] ([fdo#109271]) +9 similar issues
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-glk6/igt@gem_exec_fence@[email protected]

* igt@gem_exec_params@secure-non-master:
- shard-tglb: NOTRUN -> [SKIP][6] ([fdo#112283])
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb1/igt@[email protected]
- shard-iclb: NOTRUN -> [SKIP][7] ([fdo#112283])
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb8/igt@[email protected]

* igt@gem_exec_reloc@basic-many-active@rcs0:
- shard-apl: [PASS][8] -> [FAIL][9] ([i915#2389])
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl8/igt@gem_exec_reloc@[email protected]
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl8/igt@gem_exec_reloc@[email protected]

* igt@gem_exec_reloc@basic-many-active@vcs1:
- shard-iclb: NOTRUN -> [FAIL][10] ([i915#2389])
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb2/igt@gem_exec_reloc@[email protected]

* igt@gen7_exec_parse@basic-allowed:
- shard-tglb: NOTRUN -> [SKIP][11] ([fdo#109289]) +1 similar issue
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb5/igt@[email protected]

* igt@gen9_exec_parse@secure-batches:
- shard-tglb: NOTRUN -> [SKIP][12] ([fdo#112306])
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb5/igt@[email protected]

* igt@i915_pm_dc@dc3co-vpb-simulation:
- shard-tglb: [PASS][13] -> [FAIL][14] ([i915#1567])
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb7/igt@[email protected]
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb2/igt@[email protected]

* igt@kms_big_fb@linear-16bpp-rotate-90:
- shard-apl: NOTRUN -> [SKIP][15] ([fdo#109271]) +33 similar issues
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl8/igt@[email protected]
- shard-tglb: NOTRUN -> [SKIP][16] ([fdo#111614])
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb2/igt@[email protected]

* igt@kms_big_fb@yf-tiled-64bpp-rotate-270:
- shard-tglb: NOTRUN -> [SKIP][17] ([fdo#111615]) +1 similar issue
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb3/igt@[email protected]
- shard-iclb: NOTRUN -> [SKIP][18] ([fdo#110723])
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb4/igt@[email protected]

* igt@kms_chamelium@dp-audio-edid:
- shard-tglb: NOTRUN -> [SKIP][19] ([fdo#109284] / [fdo#111827]) +1 similar issue
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb7/igt@[email protected]

* igt@kms_chamelium@vga-hpd-enable-disable-mode:
- shard-apl: NOTRUN -> [SKIP][20] ([fdo#109271] / [fdo#111827]) +1 similar issue
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl6/igt@[email protected]
- shard-kbl: NOTRUN -> [SKIP][21] ([fdo#109271] / [fdo#111827]) +1 similar issue
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl7/igt@[email protected]

* igt@kms_content_protection@legacy:
- shard-kbl: NOTRUN -> [TIMEOUT][22] ([i915#1319])
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl3/igt@[email protected]
- shard-tglb: NOTRUN -> [SKIP][23] ([fdo#111828])
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb7/igt@[email protected]
- shard-apl: NOTRUN -> [TIMEOUT][24] ([i915#1319])
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl1/igt@[email protected]

* igt@kms_cursor_crc@pipe-a-cursor-64x21-random:
- shard-apl: [PASS][25] -> [FAIL][26] ([i915#54])
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl2/igt@[email protected]
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl3/igt@[email protected]

* igt@kms_cursor_crc@pipe-d-cursor-suspend:
- shard-kbl: NOTRUN -> [SKIP][27] ([fdo#109271]) +32 similar issues
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl2/igt@[email protected]

* igt@kms_cursor_legacy@pipe-d-torture-bo:
- shard-kbl: NOTRUN -> [SKIP][28] ([fdo#109271] / [i915#533]) +1 similar issue
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl2/igt@[email protected]
- shard-apl: NOTRUN -> [SKIP][29] ([fdo#109271] / [i915#533]) +1 similar issue
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl4/igt@[email protected]

* igt@kms_flip@2x-flip-vs-modeset-vs-hang:
- shard-iclb: NOTRUN -> [SKIP][30] ([fdo#109274]) +2 similar issues
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb4/igt@[email protected]

* igt@kms_flip@flip-vs-blocking-wf-vblank@a-edp1:
- shard-tglb: [PASS][31] -> [FAIL][32] ([i915#2122])
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb6/igt@kms_flip@[email protected]
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb8/igt@kms_flip@[email protected]

* igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-onoff:
- shard-tglb: NOTRUN -> [SKIP][33] ([fdo#111825]) +8 similar issues
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb8/igt@[email protected]
- shard-iclb: NOTRUN -> [SKIP][34] ([fdo#109280])
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb6/igt@[email protected]

* igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-msflip-blt:
- shard-hsw: NOTRUN -> [SKIP][35] ([fdo#109271]) +3 similar issues
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-hsw7/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-msflip-blt.html

* igt@kms_hdr@static-toggle-dpms:
- shard-tglb: NOTRUN -> [SKIP][36] ([i915#1187])
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb8/igt@[email protected]
- shard-iclb: NOTRUN -> [SKIP][37] ([i915#1187])
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb7/igt@[email protected]

* igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
- shard-glk: [PASS][38] -> [DMESG-WARN][39] ([i915#2635])
[38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-glk2/igt@[email protected]
[39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-glk5/igt@[email protected]
- shard-apl: [PASS][40] -> [DMESG-WARN][41] ([i915#2635])
[40]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl4/igt@[email protected]
[41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl4/igt@[email protected]
- shard-kbl: [PASS][42] -> [INCOMPLETE][43] ([i915#155])
[42]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-kbl7/igt@[email protected]
[43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl2/igt@[email protected]
- shard-tglb: [PASS][44] -> [INCOMPLETE][45] ([i915#1436] / [i915#1798] / [i915#1982] / [i915#456]) +1 similar issue
[44]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb1/igt@[email protected]
[45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb2/igt@[email protected]

* igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes:
- shard-iclb: [PASS][46] -> [INCOMPLETE][47] ([i915#1185] / [i915#1602] / [i915#250])
[46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb1/igt@[email protected]
[47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb5/igt@[email protected]
- shard-kbl: [PASS][48] -> [DMESG-WARN][49] ([i915#1602])
[48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-kbl7/igt@[email protected]
[49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl7/igt@[email protected]
- shard-hsw: [PASS][50] -> [DMESG-WARN][51] ([i915#2637]) +1 similar issue
[50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-hsw1/igt@[email protected]
[51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-hsw7/igt@[email protected]
- shard-glk: [PASS][52] -> [DMESG-WARN][53] ([i915#1602] / [i915#2635])
[52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-glk9/igt@[email protected]
[53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-glk6/igt@[email protected]
- shard-apl: [PASS][54] -> [DMESG-WARN][55] ([i915#1602] / [i915#2635])
[54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl1/igt@[email protected]
[55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl2/igt@[email protected]

* igt@kms_psr2_su@frontbuffer:
- shard-iclb: [PASS][56] -> [SKIP][57] ([fdo#109642] / [fdo#111068])
[56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb2/igt@[email protected]
[57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb4/igt@[email protected]

* igt@kms_psr@psr2_cursor_render:
- shard-iclb: [PASS][58] -> [SKIP][59] ([fdo#109441]) +1 similar issue
[58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb2/igt@kms_psr@psr2_cursor_render.html
[59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb1/igt@kms_psr@psr2_cursor_render.html

* igt@prime_nv_api@i915_nv_import_twice_check_flink_name:
- shard-tglb: NOTRUN -> [SKIP][60] ([fdo#109291])
[60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb6/igt@prime_nv_api@i915_nv_import_twice_check_flink_name.html

#### Possible fixes ####

* {igt@gem_exec_schedule@u-fairslice@rcs0}:
- shard-kbl: [DMESG-WARN][61] ([i915#1610]) -> [PASS][62]
[61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-kbl7/igt@gem_exec_schedule@[email protected]
[62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl6/igt@gem_exec_schedule@[email protected]
- shard-apl: [DMESG-WARN][63] ([i915#1610]) -> [PASS][64]
[63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl1/igt@gem_exec_schedule@[email protected]
[64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl8/igt@gem_exec_schedule@[email protected]

* {igt@gem_exec_schedule@u-fairslice@vecs0}:
- shard-tglb: [DMESG-WARN][65] ([i915#2803]) -> [PASS][66]
[65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb3/igt@gem_exec_schedule@[email protected]
[66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb6/igt@gem_exec_schedule@[email protected]

* igt@kms_concurrent@pipe-b:
- shard-kbl: [DMESG-WARN][67] ([i915#180] / [i915#78]) -> [PASS][68]
[67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-kbl2/igt@[email protected]
[68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl1/igt@[email protected]

* igt@kms_cursor_crc@pipe-b-cursor-suspend:
- shard-apl: [DMESG-WARN][69] ([i915#2635]) -> [PASS][70]
[69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl7/igt@[email protected]
[70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl7/igt@[email protected]
- shard-iclb: [DMESG-WARN][71] -> [PASS][72]
[71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb5/igt@[email protected]
[72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb2/igt@[email protected]
- shard-glk: [DMESG-WARN][73] ([i915#2635]) -> [PASS][74]
[73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-glk7/igt@[email protected]
[74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-glk3/igt@[email protected]
- shard-hsw: [DMESG-WARN][75] ([i915#2637]) -> [PASS][76]
[75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-hsw2/igt@[email protected]
[76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-hsw7/igt@[email protected]
- shard-kbl: [DMESG-WARN][77] -> [PASS][78]
[77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-kbl3/igt@[email protected]
[78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl7/igt@[email protected]
- shard-tglb: [INCOMPLETE][79] ([i915#1436] / [i915#1798] / [i915#1982] / [i915#456]) -> [PASS][80]
[79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb7/igt@[email protected]
[80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb1/igt@[email protected]

* igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic:
- shard-hsw: [FAIL][81] ([i915#96]) -> [PASS][82]
[81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-hsw1/igt@[email protected]
[82]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-hsw1/igt@[email protected]

* igt@kms_flip@flip-vs-expired-vblank-interruptible@a-edp1:
- shard-tglb: [FAIL][83] ([i915#2598]) -> [PASS][84]
[83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb7/igt@kms_flip@[email protected]
[84]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb2/igt@kms_flip@[email protected]

* igt@kms_psr2_su@page_flip:
- shard-iclb: [SKIP][85] ([fdo#109642] / [fdo#111068]) -> [PASS][86]
[85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb3/igt@kms_psr2_su@page_flip.html
[86]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb2/igt@kms_psr2_su@page_flip.html

* igt@kms_vblank@pipe-b-ts-continuation-dpms-rpm:
- shard-hsw: [SKIP][87] ([fdo#109271]) -> [PASS][88]
[87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-hsw8/igt@[email protected]
[88]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-hsw4/igt@[email protected]

#### Warnings ####

* igt@i915_pm_dc@dc3co-vpb-simulation:
- shard-iclb: [SKIP][89] ([i915#588]) -> [SKIP][90] ([i915#658])
[89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb2/igt@[email protected]
[90]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb5/igt@[email protected]

* igt@i915_pm_rpm@gem-execbuf-stress-pc8:
- shard-iclb: [SKIP][91] ([i915#579]) -> [SKIP][92] ([fdo#109293] / [fdo#109506])
[91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-iclb8/igt@[email protected]
[92]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-iclb2/igt@[email protected]
- shard-tglb: [SKIP][93] ([i915#579]) -> [SKIP][94] ([fdo#109506] / [i915#2411])
[93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb6/igt@[email protected]
[94]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb2/igt@[email protected]

* igt@runner@aborted:
- shard-hsw: [FAIL][95] ([i915#2295]) -> ([FAIL][96], [FAIL][97]) ([fdo#109271] / [i915#2295])
[95]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-hsw2/igt@[email protected]
[96]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-hsw7/igt@[email protected]
[97]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-hsw2/igt@[email protected]
- shard-kbl: ([FAIL][98], [FAIL][99], [FAIL][100]) ([i915#1814] / [i915#2295] / [i915#2426] / [i915#2722] / [i915#483]) -> ([FAIL][101], [FAIL][102]) ([i915#1814] / [i915#2295] / [i915#2722] / [i915#483])
[98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-kbl7/igt@[email protected]
[99]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-kbl3/igt@[email protected]
[100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-kbl2/igt@[email protected]
[101]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl4/igt@[email protected]
[102]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-kbl7/igt@[email protected]
- shard-apl: ([FAIL][103], [FAIL][104], [FAIL][105]) ([i915#1610] / [i915#1814] / [i915#2295] / [i915#2426] / [i915#2722]) -> ([FAIL][106], [FAIL][107], [FAIL][108]) ([fdo#109271] / [i915#1814] / [i915#2295] / [i915#2722])
[103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl7/igt@[email protected]
[104]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl1/igt@[email protected]
[105]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-apl6/igt@[email protected]
[106]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl3/igt@[email protected]
[107]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl4/igt@[email protected]
[108]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-apl2/igt@[email protected]
- shard-glk: ([FAIL][109], [FAIL][110]) ([i915#1814] / [i915#2295] / [i915#2722] / [i915#483] / [k.org#202321]) -> ([FAIL][111], [FAIL][112], [FAIL][113]) ([i915#1814] / [i915#2295] / [i915#2722] / [k.org#202321])
[109]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-glk7/igt@[email protected]
[110]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-glk3/igt@[email protected]
[111]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-glk6/igt@[email protected]
[112]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-glk5/igt@[email protected]
[113]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-glk5/igt@[email protected]
- shard-tglb: ([FAIL][114], [FAIL][115], [FAIL][116]) ([i915#1602] / [i915#1764] / [i915#2295] / [i915#2426] / [i915#2722]) -> ([FAIL][117], [FAIL][118], [FAIL][119]) ([i915#1602] / [i915#1814] / [i915#2295] / [i915#2722])
[114]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb3/igt@[email protected]
[115]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb6/igt@[email protected]
[116]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9495/shard-tglb7/igt@[email protected]
[117]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb2/igt@[email protected]
[118]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb8/igt@[email protected]
[119]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/shard-tglb2/igt@[email protected]

{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).

[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
[fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
[fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
[fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
[fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
[fdo#109293]: https://bugs.freedesktop.org/show_bug.cgi?id=109293
[fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
[fdo#109506]: https://bugs.freedesktop.org/show_bug.cgi?id=109506
[fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
[fdo#110723]: https://bugs.freedesktop.org/show_bug.cgi?id=110723
[fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
[fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
[fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
[fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
[fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
[fdo#111828]: https://bugs.freedesktop.org/show_bug.cgi?id=111828
[fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283
[fdo#112306]: https://bugs.freedesktop.org/show_bug.cgi?id=112306
[i915#1185]: https://gitlab.freedesktop.org/drm/intel/issues/1185
[i915#1187]: https://gitlab.freedesktop.org/drm/intel/issues/1187
[i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
[i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
[i915#155]: https://gitlab.freedesktop.org/drm/intel/issues/155
[i915#1567]: https://gitlab.freedesktop.org/drm/intel/issues/1567
[i915#1602]: https://gitlab.freedesktop.org/drm/intel/issues/1602
[i915#1610]: https://gitlab.freedesktop.org/drm/intel/issues/1610
[i915#1764]: https://gitlab.freedesktop.org/drm/intel/issues/1764
[i915#1798]: https://gitlab.freedesktop.org/drm/intel/issues/1798
[i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
[i915#1814]: https://gitlab.freedesktop.org/drm/intel/issues/1814
[i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
[i915#2122]: https://gitlab.freedesktop.org/drm/intel/issues/2122
[i915#2295]: https://gitlab.freedesktop.org/drm/intel/issues/2295
[i915#2389]: https://gitlab.freedesktop.org/drm/intel/issues/2389
[i915#2411]: https://gitlab.freedesktop.org/drm/intel/issues/2411
[i915#2426]: https://gitlab.freedesktop.org/drm/intel/issues/2426
[i915#250]: https://gitlab.freedesktop.org/drm/intel/issues/250
[i915#2598]: https://gitlab.freedesktop.org/drm/intel/issues/2598
[i915#2635]: https://gitlab.freedesktop.org/drm/intel/issues/2635
[i915#2637]: https://gitlab.freedesktop.org/drm/intel/issues/2637
[i915#2722]: https://gitlab.freedesktop.org/drm/intel/issues/2722
[i915#2795]: https://gitlab.freedesktop.org/drm/intel/issues/2795
[i915#2803]: https://gitlab.freedesktop.org/drm/intel/issues/2803
[i915#456]: https://gitlab.freedesktop.org/drm/intel/issues/456
[i915#483]: https://gitlab.freedesktop.org/drm/intel/issues/483
[i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
[i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
[i915#579]: https://gitlab.freedesktop.org/drm/intel/issues/579
[i915#588]: https://gitlab.freedesktop.org/drm/intel/issues/588
[i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
[i915#78]: https://gitlab.freedesktop.org/drm/intel/issues/78
[i915#96]: https://gitlab.freedesktop.org/drm/intel/issues/96
[k.org#202321]: https://bugzilla.kernel.org/show_bug.cgi?id=202321

Participating hosts (10 -> 8)
------------------------------

Missing (2): pig-skl-6260u pig-glk-j5005

Build changes
-------------

* CI: CI-20190529 -> None
* IGT: IGT_5905 -> IGTPW_5302
* Piglit: piglit_4509 -> None

CI-20190529: 20190529
CI_DRM_9495: 2960e86fd8fd7659400d05f40a1e06d3a97b6987 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_5302: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/index.html
IGT_5905: 3d0934900bddeb7a68f1abab4cd05077f0609e32 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5302/index.html

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

#5 lore raw

[igt-dev] ✗ Fi.CI.BUILD: failure for kms_rotation_crc:Add HW rotation test case for amdgpu (rev2)

In reply to Sung Joon Kim
== Series Details ==

== Series Details ==

Series: kms_rotation_crc:Add HW rotation test case for amdgpu (rev2)
URL : https://patchwork.freedesktop.org/series/85018/
State : failure

== Summary ==

Applying: kms_rotation_crc:Add HW rotation test case for amdgpu Patch failed at 0001 kms_rotation_crc:Add HW rotation test case for amdgpu When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort".

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev