[Intel-gfx] igt/kms_rotation_crc: Add horizontal flip subtest.
Joseph Garvey
joseph1.garvey at intel.com
Thu Sep 21 03:50:37 UTC 2017
Test that horizontal flip works with supported rotations. Includes
a fix for the unrotated fb which was not being positioned correctly
with portrait and landscape rectangles.
Signed-off-by: Joseph Garvey <joseph1.garvey at intel.com>
---
lib/igt_kms.c | 2 +-
lib/igt_kms.h | 4 +
tests/kms_rotation_crc.c | 197 ++++++++++++++++++++++++++++++++++++++---------
3 files changed, 166 insertions(+), 37 deletions(-)
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 7bcafc0..ec6ffd2 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -3054,7 +3054,7 @@ void igt_fb_set_size(struct igt_fb *fb, igt_plane_t *plane,
static const char *rotation_name(igt_rotation_t rotation)
{
- switch (rotation) {
+ switch (rotation & IGT_ROTATION_MASK) {
case IGT_ROTATION_0:
return "0°";
case IGT_ROTATION_90:
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 3d1061f..61393d1 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -281,8 +281,12 @@ typedef enum {
IGT_ROTATION_90 = 1 << 1,
IGT_ROTATION_180 = 1 << 2,
IGT_ROTATION_270 = 1 << 3,
+ IGT_REFLECT_X = 1 << 4,
} igt_rotation_t;
+#define IGT_ROTATION_MASK \
+ (IGT_ROTATION_0 | IGT_ROTATION_90 | IGT_ROTATION_180 | IGT_ROTATION_270)
+
typedef struct {
/*< private >*/
igt_pipe_t *pipe;
diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
index 21e264a..0e2df96 100644
--- a/tests/kms_rotation_crc.c
+++ b/tests/kms_rotation_crc.c
@@ -32,6 +32,7 @@ typedef struct {
igt_display_t display;
struct igt_fb fb;
struct igt_fb fb_reference;
+ struct igt_fb fb_unrotated;
struct igt_fb fb_modeset;
struct igt_fb fb_flip;
igt_crc_t ref_crc;
@@ -43,8 +44,62 @@ typedef struct {
uint32_t override_fmt;
uint64_t override_tiling;
bool flips;
+ int devid;
} 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) {
+ bl_tmp = *bl;
+ br_tmp = *br;
+ tl_tmp = *tl;
+ tr_tmp = *tr;
+ *tl = tr_tmp;
+ *bl = br_tmp;
+ *tr = tl_tmp;
+ *br = bl_tmp;
+ }
+
+ 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_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)
@@ -52,35 +107,26 @@ paint_squares(data_t *data, igt_rotation_t rotation,
cairo_t *cr;
unsigned int w = fb->width;
unsigned int h = fb->height;
+ rgb_color_t tl, tr, bl, br;
cr = igt_get_cairo_ctx(data->gfx_fd, fb);
- if (rotation == IGT_ROTATION_180) {
+ set_color(&tl, o, 0, 0);
+ set_color(&tr, 0, o, 0);
+ set_color(&br, o, o, o);
+ set_color(&bl, 0, 0, o);
+
+ rotate_colors(&tl, &tr, &br, &bl, rotation);
+
+ if (rotation & IGT_ROTATION_180) {
cairo_translate(cr, w, h);
cairo_rotate(cr, M_PI);
}
- if (rotation == IGT_ROTATION_90) {
- /* Paint 4 squares with width == height in Green, White,
- Blue, Red Clockwise order to look like 270 degree rotated*/
- igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, o, 0.0);
- igt_paint_color(cr, w / 2, 0, w / 2, h / 2, o, o, o);
- igt_paint_color(cr, 0, h / 2, w / 2, h / 2, o, 0.0, 0.0);
- igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 0.0, o);
- } else if (rotation == IGT_ROTATION_270) {
- /* Paint 4 squares with width == height in Blue, Red,
- Green, White Clockwise order to look like 90 degree rotated*/
- igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, o);
- igt_paint_color(cr, w / 2, 0, w / 2, h / 2, o, 0.0, 0.0);
- igt_paint_color(cr, 0, h / 2, w / 2, h / 2, o, o, o);
- igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, o, 0.0);
- } else {
- /* Paint with 4 squares of Red, Green, White, Blue Clockwise */
- igt_paint_color(cr, 0, 0, w / 2, h / 2, o, 0.0, 0.0);
- igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, o, 0.0);
- igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, o);
- igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, o, o, o);
- }
+ 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));
cairo_destroy(cr);
}
@@ -141,6 +187,7 @@ 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_unrotated);
if (data->fb_flip.fb_id)
igt_remove_fb(data->gfx_fd, &data->fb_flip);
@@ -212,17 +259,12 @@ static void prepare_fbs(data_t *data, igt_output_t *output,
* For 90/270, we will use create smaller fb so that the rotated
* frame can fit in
*/
- if (data->rotation == IGT_ROTATION_90 ||
- data->rotation == IGT_ROTATION_270) {
+ if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270)) {
tiling = data->override_tiling ?: LOCAL_I915_FORMAT_MOD_Y_TILED;
igt_swap(w, h);
}
- igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);
-
- igt_plane_set_rotation(plane, IGT_ROTATION_0);
-
/*
* Create a reference software rotated flip framebuffer.
*/
@@ -255,8 +297,20 @@ static void prepare_fbs(data_t *data, igt_output_t *output,
igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
/*
+ * Prepare the non-rotated reference fb.
+ */
+ igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format, tiling, &data->fb_unrotated);
+ paint_squares(data, IGT_ROTATION_0, &data->fb_unrotated, 1.0);
+ igt_plane_set_fb(plane, &data->fb_unrotated);
+ igt_plane_set_rotation(plane, IGT_ROTATION_0);
+ if (plane->type != DRM_PLANE_TYPE_CURSOR)
+ igt_plane_set_position(plane, data->pos_x, data->pos_y);
+ igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_UNIVERSAL);
+
+ /*
* 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);
@@ -322,7 +376,7 @@ static void wait_for_pageflip(int fd)
igt_assert(drmHandleEvent(fd, &evctx) == 0);
}
-static void test_plane_rotation(data_t *data, int plane_type)
+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;
@@ -345,6 +399,9 @@ static void test_plane_rotation(data_t *data, int plane_type)
igt_plane_t *plane;
int i;
+ if (IS_CHERRYVIEW(data->devid) && pipe != PIPE_B)
+ continue;
+
igt_output_set_pipe(output, pipe);
plane = igt_output_get_plane_type(output, plane_type);
@@ -366,14 +423,12 @@ static void test_plane_rotation(data_t *data, int plane_type)
igt_debug("Testing case %i on pipe %s\n", i, kmstest_pipe_name(pipe));
prepare_fbs(data, output, plane, i);
- igt_display_commit2(display, commit);
-
igt_plane_set_rotation(plane, data->rotation);
- if (data->rotation == IGT_ROTATION_90 || data->rotation == IGT_ROTATION_270)
+ 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);
- if (data->override_fmt || data->override_tiling) {
+ if (test_bad_format && (data->override_fmt || data->override_tiling)) {
igt_assert_eq(ret, -EINVAL);
continue;
}
@@ -410,6 +465,16 @@ static void test_plane_rotation(data_t *data, int plane_type)
igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
}
+static inline void test_bad_plane_rotation(data_t *data, int plane_type)
+{
+ __test_plane_rotation(data, plane_type, true);
+}
+
+static inline void test_plane_rotation(data_t *data, int plane_type)
+{
+ __test_plane_rotation(data, plane_type, false);
+}
+
static void test_plane_rotation_ytiled_obj(data_t *data,
igt_output_t *output,
int plane_type)
@@ -612,6 +677,8 @@ static const char *plane_test_str(unsigned plane)
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:
@@ -623,6 +690,20 @@ static const char *rot_test_str(igt_rotation_t rot)
}
}
+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 const char *flip_test_str(unsigned flips)
{
if (flips)
@@ -653,6 +734,35 @@ igt_main
{ DRM_PLANE_TYPE_CURSOR, IGT_ROTATION_180, 0 },
{ 0, 0, 0}
};
+
+ struct hflip {
+ uint64_t tiling;
+ igt_rotation_t rot;
+ unsigned flips;
+ } *hflip, hflip_subtests[] = {
+ { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0, 0 },
+ { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180, 0 },
+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0, 0 },
+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90, 0 },
+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180, 0 },
+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270, 0 },
+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0, 0},
+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90, 0},
+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180, 0},
+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270, 0},
+ { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0, 1 },
+ { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180, 1 },
+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0, 1 },
+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90, 1 },
+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180, 1 },
+ { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270, 1 },
+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0, 1},
+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90, 1},
+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180, 1},
+ { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270, 1},
+ { 0, 0, 0}
+ };
+
data_t data = {};
int gen = 0;
@@ -660,7 +770,8 @@ igt_main
igt_fixture {
data.gfx_fd = drm_open_driver_master(DRIVER_INTEL);
- gen = intel_gen(intel_get_drm_devid(data.gfx_fd));
+ data.devid = intel_get_drm_devid(data.gfx_fd);
+ gen = intel_gen(data.devid);
kmstest_set_vt_graphics_mode();
@@ -697,7 +808,7 @@ igt_main
data.pos_y = 0;
data.rotation = IGT_ROTATION_90;
data.override_fmt = DRM_FORMAT_RGB565;
- test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
+ test_bad_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
}
igt_subtest_f("bad-tiling") {
@@ -705,7 +816,7 @@ igt_main
data.override_fmt = 0;
data.rotation = IGT_ROTATION_90;
data.override_tiling = LOCAL_DRM_FORMAT_MOD_NONE;
- test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
+ test_bad_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
}
igt_subtest_f("primary-rotation-90-Y-tiled") {
@@ -728,6 +839,20 @@ igt_main
igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
}
+ for (hflip = hflip_subtests; hflip->tiling; hflip++) {
+ igt_subtest_f("primary-h-flip-%s-%s",
+ tiling_test_str(hflip->tiling),
+ rot_test_str(hflip->rot)) {
+ igt_require(gen >= 10 ||
+ (IS_CHERRYVIEW(data.devid) && hflip->rot == IGT_ROTATION_0 &&
+ hflip->tiling == LOCAL_I915_FORMAT_MOD_X_TILED));
+ data.rotation = (IGT_REFLECT_X | hflip->rot);
+ data.override_tiling = hflip->tiling;
+ data.flips = hflip->flips;
+ test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
+ }
+ }
+
igt_subtest_f("exhaust-fences") {
enum pipe pipe;
igt_output_t *output;
--
2.7.4
More information about the Intel-gfx
mailing list