@@ -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" },