[PATCH i-g-t] tests/kms_flip: Check crcs during basic flip test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>

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.

Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>
---
 tests/kms_flip.c | 126 +++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 91 insertions(+), 35 deletions(-)

diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index 6ec97d0a8534..5b4e27e49838 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,29 @@ 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) {
+		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++)
+				igt_require(!igt_crc_equal(&o->crc[i], &o->crc[j]));
+		}
+		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 +1289,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 +1317,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 +1388,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 +1691,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" },
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux