[Intel-gfx,v2] tests/kms_flip: Check crcs during basic flip test

Submitted by Ville Syrjälä on May 23, 2016, 12:42 p.m.

Details

Message ID 1464007366-7523-1-git-send-email-ville.syrjala@linux.intel.com
State New
Headers show
Series "tests/kms_flip: Check crcs during basic flip test" ( rev: 2 ) in IGT (deprecated)

Not browsing as part of any series.

Commit Message

Ville Syrjälä May 23, 2016, 12:42 p.m.
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Allocate 8 distinct looking fbs for the basic flip test, and while
flipping, check that the crc for each frame is as expected. If we
were to present the wrong framebuffer by accident, this should catch it.

v2: Just igt_warn() instead of igt_require() for unique crc check (Daniel)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tests/kms_flip.c | 132 ++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 97 insertions(+), 35 deletions(-)

Patch hide | download patch | download mbox

diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index 6ec97d0a8534..54e47e4b7b29 100644
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -75,6 +75,7 @@ 
 #define TEST_BO_TOOBIG		(1 << 28)
 #define TEST_HANG_ONCE		(1 << 29)
 #define TEST_BASIC		(1 << 30)
+#define TEST_CRC		(1U << 31)
 
 #define EVENT_FLIP		(1 << 0)
 #define EVENT_VBLANK		(1 << 1)
@@ -151,6 +152,8 @@  static void dump_event_state(const struct event_state *es)
 		  es->seq_step);
 }
 
+#define N_FRAMES 8
+
 struct test_output {
 	int mode_valid;
 	drmModeModeInfo kmode[4];
@@ -160,14 +163,16 @@  struct test_output {
 	uint32_t _crtc[4];
 	int _pipe[4];
 	int count; /* 1:1 mapping between crtc:connector */
-	int flags;
+	unsigned int flags;
 	int pipe; /* primary pipe for vblank */
 	unsigned int current_fb_id;
 	unsigned int fb_width;
 	unsigned int fb_height;
-	unsigned int fb_ids[3];
+	unsigned int fb_ids[N_FRAMES];
 	int bpp, depth;
-	struct igt_fb fb_info[3];
+	struct igt_fb fb_info[N_FRAMES];
+	igt_pipe_crc_t *pipe_crc;
+	igt_crc_t crc[N_FRAMES];
 
 	struct event_state flip_state;
 	struct event_state vblank_state;
@@ -853,7 +858,9 @@  static unsigned int run_test_step(struct test_output *o)
 	if (o->flags & TEST_DPMS_OFF_OTHERS)
 		dpms_off_other_outputs(o);
 
-	if (!(o->flags & TEST_SINGLE_BUFFER))
+	if (o->flags & TEST_CRC)
+		o->current_fb_id = (o->current_fb_id + 1) % N_FRAMES;
+	else if (!(o->flags & TEST_SINGLE_BUFFER))
 		o->current_fb_id = !o->current_fb_id;
 
 	if (o->flags & TEST_WITH_DUMMY_BCS)
@@ -1134,7 +1141,7 @@  found:
 	drmModeFreeCrtc(config[1].crtc);
 }
 
-static void paint_flip_mode(struct igt_fb *fb, bool odd_frame)
+static void paint_flip_mode(struct igt_fb *fb, int n_phases, int phase)
 {
 	cairo_t *cr = igt_get_cairo_ctx(drm_fd, fb);
 	int width = fb->width;
@@ -1142,10 +1149,7 @@  static void paint_flip_mode(struct igt_fb *fb, bool odd_frame)
 
 	igt_paint_test_pattern(cr, width, height);
 
-	if (odd_frame)
-		cairo_rectangle(cr, width/4, height/2, width/4, height/8);
-	else
-		cairo_rectangle(cr, width/2, height/2, width/4, height/8);
+	cairo_rectangle(cr, phase * width/n_phases, height/2, width/n_phases, height/8);
 
 	cairo_set_source_rgb(cr, 1, 1, 1);
 	cairo_fill(cr);
@@ -1251,6 +1255,35 @@  static unsigned event_loop(struct test_output *o, unsigned duration_ms)
 	if (o->flags & TEST_HANG_ONCE)
 		hang = hang_gpu(drm_fd);
 
+	if (o->pipe_crc) {
+		igt_pipe_crc_stop(o->pipe_crc);
+		igt_pipe_crc_free(o->pipe_crc);
+		o->pipe_crc = NULL;
+	}
+
+	if (o->flags & TEST_CRC) {
+		bool unique_crcs = true;
+
+		o->pipe_crc = igt_pipe_crc_new_nonblock(o->pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+
+		for (int i = 0; i <  N_FRAMES; i++) {
+			igt_assert_eq(set_mode(o, o->fb_ids[i], 0, 0), 0);
+			igt_pipe_crc_collect_crc(o->pipe_crc, &o->crc[i]);
+
+			/* We want each frame to have a unique crc */
+			for (int j = 0; j < i; j++) {
+				if (igt_crc_equal(&o->crc[i], &o->crc[j]))
+					unique_crcs = false;
+			}
+		}
+		if (!unique_crcs)
+			igt_warn("CRCs not unique, unable to detect all CRC mismatches\n");
+		igt_assert_eq(set_mode(o, o->fb_ids[0], 0, 0), 0);
+		o->current_fb_id = 0;
+
+		igt_pipe_crc_start(o->pipe_crc);
+	}
+
 	start = gettime_us();
 
 	while (1) {
@@ -1262,6 +1295,20 @@  static unsigned event_loop(struct test_output *o, unsigned duration_ms)
 		check_all_state(o, completed_events);
 		update_all_state(o, completed_events);
 
+		if (o->flags & TEST_CRC) {
+			igt_crc_t *crcs;
+			int n_crcs;
+			int prev_fb_id = (o->current_fb_id + N_FRAMES - 1) % N_FRAMES;
+
+			n_crcs = igt_pipe_crc_get_crcs(o->pipe_crc, 2, &crcs);
+			igt_assert_eq(n_crcs, 1);
+
+			/* crc will be for the previous frame */
+			igt_assert_crc_equal(&crcs[0], &o->crc[prev_fb_id]);
+			free(crcs);
+		}
+
+
 		if (count && (gettime_us() - start) / 1000 >= duration_ms)
 			break;
 
@@ -1276,6 +1323,12 @@  static unsigned event_loop(struct test_output *o, unsigned duration_ms)
 	if (o->pending_events)
 		wait_for_events(o);
 
+	if (o->pipe_crc) {
+		igt_pipe_crc_stop(o->pipe_crc);
+		igt_pipe_crc_free(o->pipe_crc);
+		o->pipe_crc = NULL;
+	}
+
 	return end - start;
 }
 
@@ -1341,37 +1394,46 @@  static void run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
 	if (o->flags & TEST_FENCE_STRESS)
 		tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
 
-	/* 256 MB is usually the maximum mappable aperture,
-	 * (make it 4x times that to ensure failure) */
-	if (o->flags & TEST_BO_TOOBIG)
-		bo_size = 4*256*1024*1024;
 
-	o->fb_ids[0] = igt_create_fb(drm_fd, o->fb_width, o->fb_height,
-					 igt_bpp_depth_to_drm_format(o->bpp, o->depth),
-					 tiling, &o->fb_info[0]);
-	o->fb_ids[1] = igt_create_fb_with_bo_size(drm_fd, o->fb_width, o->fb_height,
+	if (o->flags & TEST_CRC) {
+		for (i = 0; i < N_FRAMES; i++) {
+			o->fb_ids[i] = igt_create_fb(drm_fd, o->fb_width, o->fb_height,
+						     igt_bpp_depth_to_drm_format(o->bpp, o->depth),
+						     tiling, &o->fb_info[i]);
+			paint_flip_mode(&o->fb_info[i], N_FRAMES, i);
+		}
+	} else {
+		/* 256 MB is usually the maximum mappable aperture,
+		 * (make it 4x times that to ensure failure) */
+		if (o->flags & TEST_BO_TOOBIG)
+			bo_size = 4*256*1024*1024;
+
+		o->fb_ids[0] = igt_create_fb(drm_fd, o->fb_width, o->fb_height,
+					     igt_bpp_depth_to_drm_format(o->bpp, o->depth),
+					     tiling, &o->fb_info[0]);
+		o->fb_ids[1] = igt_create_fb_with_bo_size(drm_fd, o->fb_width, o->fb_height,
 					 igt_bpp_depth_to_drm_format(o->bpp, o->depth),
-					 tiling, &o->fb_info[1], bo_size, 0);
+							  tiling, &o->fb_info[1], bo_size, 0);
 
-	igt_assert(o->fb_ids[0]);
-	igt_assert(o->fb_ids[1]);
+		igt_assert(o->fb_ids[0]);
+		igt_assert(o->fb_ids[1]);
 
-	if (o->flags & TEST_FB_BAD_TILING) {
-		o->fb_ids[2] = igt_create_fb(drm_fd, o->fb_width, o->fb_height,
-				igt_bpp_depth_to_drm_format(o->bpp, o->depth),
-				LOCAL_I915_FORMAT_MOD_X_TILED, &o->fb_info[2]);
-		igt_require(o->fb_ids[2]);
+		if (o->flags & TEST_FB_BAD_TILING) {
+			o->fb_ids[2] = igt_create_fb(drm_fd, o->fb_width, o->fb_height,
+						     igt_bpp_depth_to_drm_format(o->bpp, o->depth),
+						     LOCAL_I915_FORMAT_MOD_X_TILED, &o->fb_info[2]);
+			igt_require(o->fb_ids[2]);
+		}
+		paint_flip_mode(&o->fb_info[0], 4, 1);
+		if (!(o->flags & TEST_BO_TOOBIG))
+			paint_flip_mode(&o->fb_info[1], 4, 2);
+		if (o->fb_ids[2])
+			paint_flip_mode(&o->fb_info[2], 4, 2);
+
+		if (o->flags & TEST_FB_BAD_TILING)
+			set_y_tiling(o, 2);
 	}
 
-	paint_flip_mode(&o->fb_info[0], false);
-	if (!(o->flags & TEST_BO_TOOBIG))
-		paint_flip_mode(&o->fb_info[1], true);
-	if (o->fb_ids[2])
-		paint_flip_mode(&o->fb_info[2], true);
-
-	if (o->flags & TEST_FB_BAD_TILING)
-		set_y_tiling(o, 2);
-
 	for (i = 0; i < o->count; i++)
 		kmstest_dump_mode(&o->kmode[i]);
 
@@ -1635,7 +1697,7 @@  int main(int argc, char **argv)
 					"blt-wf_vblank-vs-modeset" },
 		{ 60,  TEST_VBLANK | TEST_MODESET | TEST_WITH_DUMMY_RCS,
 					"rcs-wf_vblank-vs-modeset" },
-		{ 10, TEST_FLIP | TEST_BASIC, "plain-flip" },
+		{ 10, TEST_FLIP | TEST_BASIC | TEST_CRC, "plain-flip-crc" },
 		{ 30, TEST_FLIP | TEST_EBUSY , "busy-flip" },
 		{ 30, TEST_FLIP | TEST_FENCE_STRESS , "flip-vs-fences" },
 		{ 30, TEST_FLIP | TEST_CHECK_TS, "plain-flip-ts-check" },