All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH i-g-t 1/6] lib: Make 'extra_long_opts' const
@ 2015-12-18 17:25 ville.syrjala
  2015-12-18 17:25 ` [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers ville.syrjala
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: ville.syrjala @ 2015-12-18 17:25 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The extra_long_opts passed to igt_*_parse_opts() isn't modified,
so let's make it const.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 lib/igt_core.c | 6 +++---
 lib/igt_core.h | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/igt_core.c b/lib/igt_core.c
index 84cf8d2eec89..554f2f0ead42 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -540,7 +540,7 @@ static void oom_adjust_for_doom(void)
 
 static int common_init(int *argc, char **argv,
 		       const char *extra_short_opts,
-		       struct option *extra_long_opts,
+		       const struct option *extra_long_opts,
 		       const char *help_str,
 		       igt_opt_handler_t extra_opt_handler,
 		       void *handler_data)
@@ -746,7 +746,7 @@ out:
  */
 int igt_subtest_init_parse_opts(int *argc, char **argv,
 				const char *extra_short_opts,
-				struct option *extra_long_opts,
+				const struct option *extra_long_opts,
 				const char *help_str,
 				igt_opt_handler_t extra_opt_handler,
 				void *handler_data)
@@ -777,7 +777,7 @@ enum igt_log_level igt_log_level = IGT_LOG_INFO;
  */
 void igt_simple_init_parse_opts(int *argc, char **argv,
 				const char *extra_short_opts,
-				struct option *extra_long_opts,
+				const struct option *extra_long_opts,
 				const char *help_str,
 				igt_opt_handler_t extra_opt_handler,
 				void *handler_data)
diff --git a/lib/igt_core.h b/lib/igt_core.h
index a244fc391d38..8f297e06a068 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -121,7 +121,7 @@ struct option;
 #endif
 int igt_subtest_init_parse_opts(int *argc, char **argv,
 				const char *extra_short_opts,
-				struct option *extra_long_opts,
+				const struct option *extra_long_opts,
 				const char *help_str,
 				igt_opt_handler_t extra_opt_handler,
 				void *handler_data);
@@ -217,7 +217,7 @@ bool igt_only_list_subtests(void);
 const char *igt_test_name(void);
 void igt_simple_init_parse_opts(int *argc, char **argv,
 				const char *extra_short_opts,
-				struct option *extra_long_opts,
+				const struct option *extra_long_opts,
 				const char *help_str,
 				igt_opt_handler_t extra_opt_handler,
 				void *handler_data);
-- 
2.4.10

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers
  2015-12-18 17:25 [PATCH i-g-t 1/6] lib: Make 'extra_long_opts' const ville.syrjala
@ 2015-12-18 17:25 ` ville.syrjala
  2015-12-21 10:42   ` Thomas Wood
  2015-12-18 17:25 ` [PATCH i-g-t 3/6] lib: Use igt_assert_eq() to check for crc component count ville.syrjala
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: ville.syrjala @ 2015-12-18 17:25 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Several tests do one or more of the followin:
* igt_create_fb() + igt_paint_test_pattern()
* igt_create_color_fb() + igt_paint_test_pattern()
* igt_create_fb() + igt_paint_image()

Extract them into new helpes: igt_create_pattern_fb(),
igt_create_color_pattern_fb(), igt_create_image_fb().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 lib/igt_fb.c              | 124 ++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_fb.h              |  11 ++++
 tests/kms_atomic.c        |  30 ++++-------
 tests/kms_flip_tiling.c   |  25 +++-------
 tests/kms_panel_fitting.c |  42 ++++------------
 tests/kms_plane_scaling.c |  60 ++++++----------------
 tests/kms_pwrite_crc.c    |   9 +---
 tests/kms_setmode.c       |  11 ++--
 tests/pm_lpsp.c           |  11 +---
 tests/pm_rpm.c            |  10 ++--
 tests/testdisplay.c       |   8 ++-
 11 files changed, 188 insertions(+), 153 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 3ea9915c42c4..b3c7840a22ae 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -537,6 +537,130 @@ unsigned int igt_create_color_fb(int fd, int width, int height,
 	return fb_id;
 }
 
+/**
+ * igt_create_pattern_fb:
+ * @fd: open i915 drm file descriptor
+ * @width: width of the framebuffer in pixel
+ * @height: height of the framebuffer in pixel
+ * @format: drm fourcc pixel format code
+ * @tiling: tiling layout of the framebuffer
+ * @fb: pointer to an #igt_fb structure
+ *
+ * This function allocates a gem buffer object suitable to back a framebuffer
+ * with the requested properties and then wraps it up in a drm framebuffer
+ * object. All metadata is stored in @fb.
+ *
+ * Compared to igt_create_fb() this function also fills the entire framebuffer
+ * with the test pattern.
+ *
+ * Returns:
+ * The kms id of the created framebuffer on success or a negative error code on
+ * failure.
+ */
+unsigned int igt_create_pattern_fb(int fd, int width, int height,
+				   uint32_t format, uint64_t tiling,
+				   struct igt_fb *fb /* out */)
+{
+	unsigned int fb_id;
+	cairo_t *cr;
+
+	fb_id = igt_create_fb(fd, width, height, format, tiling, fb);
+	igt_assert(fb_id);
+
+	cr = igt_get_cairo_ctx(fd, fb);
+	igt_paint_test_pattern(cr, width, height);
+	igt_assert(cairo_status(cr) == 0);
+	cairo_destroy(cr);
+
+	return fb_id;
+}
+
+/**
+ * igt_create_pattern_fb:
+ * @fd: open i915 drm file descriptor
+ * @width: width of the framebuffer in pixel
+ * @height: height of the framebuffer in pixel
+ * @format: drm fourcc pixel format code
+ * @tiling: tiling layout of the framebuffer
+ * @r: red value to use as fill color
+ * @g: gree value to use as fill color
+ * @b: blue value to use as fill color
+ * @fb: pointer to an #igt_fb structure
+ *
+ * This function allocates a gem buffer object suitable to back a framebuffer
+ * with the requested properties and then wraps it up in a drm framebuffer
+ * object. All metadata is stored in @fb.
+ *
+ * Compared to igt_create_fb() this function also fills the entire framebuffer
+ * with the test pattern.
+ *
+ * Returns:
+ * The kms id of the created framebuffer on success or a negative error code on
+ * failure.
+ */
+unsigned int igt_create_color_pattern_fb(int fd, int width, int height,
+					 uint32_t format, uint64_t tiling,
+					 double r, double g, double b,
+					 struct igt_fb *fb /* out */)
+{
+	unsigned int fb_id;
+	cairo_t *cr;
+
+	fb_id = igt_create_fb(fd, width, height, format, tiling, fb);
+	igt_assert(fb_id);
+
+	cr = igt_get_cairo_ctx(fd, fb);
+	igt_paint_color(cr, 0, 0, width, height, r, g, b);
+	igt_paint_test_pattern(cr, width, height);
+	igt_assert(cairo_status(cr) == 0);
+	cairo_destroy(cr);
+
+	return fb_id;
+}
+
+/**
+ * igt_create_image_fb:
+ * @drm_fd: open i915 drm file descriptor
+ * @width: width of the framebuffer in pixel or 0
+ * @height: height of the framebuffer in pixel or 0
+ * @format: drm fourcc pixel format code
+ * @tiling: tiling layout of the framebuffer
+ * @filename: filename of the png image to draw
+ *
+ * Create a framebuffer with the specified image. If @width is zero the
+ * image width will be used. If @height is zero the image height will be used.
+ *
+ * Returns:
+ * The kms id of the created framebuffer on success or a negative error code on
+ * failure.
+ */
+unsigned int igt_create_image_fb(int fd, int width, int height,
+				 uint32_t format, uint64_t tiling,
+				 const char *filename,
+				 struct igt_fb *fb /* out */)
+{
+	cairo_surface_t *image;
+	uint32_t fb_id;
+	cairo_t *cr;
+
+	image = cairo_image_surface_create_from_png(filename);
+	igt_assert(cairo_surface_status(image) == CAIRO_STATUS_SUCCESS);
+	if (width == 0)
+		width = cairo_image_surface_get_width(image);
+	if (height == 0)
+		height = cairo_image_surface_get_height(image);
+	cairo_surface_destroy(image);
+
+	fb_id = igt_create_fb(fd, width, height, format, tiling, fb);
+
+	cr = igt_get_cairo_ctx(fd, fb);
+	igt_paint_image(cr, filename, 0, 0, width, height);
+	igt_assert(cairo_status(cr) == 0);
+	cairo_destroy(cr);
+
+	return fb_id;
+}
+
 struct box {
 	int x, y, width, height;
 };
diff --git a/lib/igt_fb.h b/lib/igt_fb.h
index 37892b50d495..5cc8644d01d4 100644
--- a/lib/igt_fb.h
+++ b/lib/igt_fb.h
@@ -80,6 +80,17 @@ unsigned int igt_create_color_fb(int fd, int width, int height,
 				 uint32_t format, uint64_t tiling,
 				 double r, double g, double b,
 				 struct igt_fb *fb /* out */);
+unsigned int igt_create_pattern_fb(int fd, int width, int height,
+				   uint32_t format, uint64_t tiling,
+				   struct igt_fb *fb /* out */);
+unsigned int igt_create_color_pattern_fb(int fd, int width, int height,
+					 uint32_t format, uint64_t tiling,
+					 double r, double g, double b,
+					 struct igt_fb *fb /* out */);
+unsigned int igt_create_image_fb(int drm_fd,  int width, int height,
+				 uint32_t format, uint64_t tiling,
+				 const char *filename,
+				 struct igt_fb *fb /* out */);
 unsigned int igt_create_stereo_fb(int drm_fd, drmModeModeInfo *mode,
 				  uint32_t format, uint64_t tiling);
 void igt_remove_fb(int fd, struct igt_fb *fb);
diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
index 7006e5eae411..501093cc3962 100644
--- a/tests/kms_atomic.c
+++ b/tests/kms_atomic.c
@@ -867,7 +867,6 @@ static void plane_overlay(struct kms_atomic_crtc_state *crtc,
 	uint32_t format = plane_get_igt_format(&plane);
 	drmModeAtomicReq *req = drmModeAtomicAlloc();
 	struct igt_fb fb;
-	cairo_t *cr;
 
 	igt_require(req);
 	igt_require(format != 0);
@@ -881,12 +880,9 @@ static void plane_overlay(struct kms_atomic_crtc_state *crtc,
 	plane.crtc_w = mode->hdisplay / 2;
 	plane.crtc_h = mode->vdisplay / 2;
 	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_fb(plane.state->desc->fd,
-				    plane.crtc_w, plane.crtc_h,
-				    format, I915_TILING_NONE, &fb);
-
-	cr = igt_get_cairo_ctx(plane.state->desc->fd, &fb);
-	igt_paint_test_pattern(cr, plane.crtc_w, plane.crtc_h);
+	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
+					    plane.crtc_w, plane.crtc_h,
+					    format, I915_TILING_NONE, &fb);
 
 	/* Enable the overlay plane using the atomic API, and double-check
 	 * state is what we think it should be. */
@@ -916,7 +912,6 @@ static void plane_primary(struct kms_atomic_crtc_state *crtc,
 	uint32_t *connectors;
 	int num_connectors;
 	struct igt_fb fb;
-	cairo_t *cr;
 	int i;
 
 	connectors = calloc(crtc->state->num_connectors, sizeof(*connectors));
@@ -939,12 +934,9 @@ static void plane_primary(struct kms_atomic_crtc_state *crtc,
 	plane.crtc_w = mode->hdisplay;
 	plane.crtc_h = mode->vdisplay;
 	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_fb(plane.state->desc->fd,
-				    plane.crtc_w, plane.crtc_h,
-				    format, I915_TILING_NONE, &fb);
-
-	cr = igt_get_cairo_ctx(plane.state->desc->fd, &fb);
-	igt_paint_test_pattern(cr, plane.crtc_w, plane.crtc_h);
+	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
+					    plane.crtc_w, plane.crtc_h,
+					    format, I915_TILING_NONE, &fb);
 
 	/* Flip the primary plane using the atomic API, and double-check
 	 * state is what we think it should be. */
@@ -1044,7 +1036,6 @@ static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
 	uint32_t format = plane_get_igt_format(&plane);
 	drmModeAtomicReq *req = drmModeAtomicAlloc();
 	struct igt_fb fb;
-	cairo_t *cr;
 
 	/* Pass a series of invalid object IDs for the FB ID. */
 	plane.fb_id = plane.obj;
@@ -1098,12 +1089,9 @@ static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
 	plane.crtc_w = mode->hdisplay;
 	plane.crtc_h = mode->vdisplay;
 	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_fb(plane.state->desc->fd,
-				    plane.crtc_w - 1, plane.crtc_h - 1,
-				    format, I915_TILING_NONE, &fb);
-
-	cr = igt_get_cairo_ctx(plane.state->desc->fd, &fb);
-	igt_paint_test_pattern(cr, plane.crtc_w - 1, plane.crtc_h - 1);
+	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
+					    plane.crtc_w - 1, plane.crtc_h - 1,
+					    format, I915_TILING_NONE, &fb);
 
 	plane_commit_atomic_err(&plane, plane_old, req,
 	                        ATOMIC_RELAX_NONE, ENOSPC);
diff --git a/tests/kms_flip_tiling.c b/tests/kms_flip_tiling.c
index 653a9706a700..4f7334de65fe 100644
--- a/tests/kms_flip_tiling.c
+++ b/tests/kms_flip_tiling.c
@@ -39,16 +39,6 @@ typedef struct {
 	int gen;
 } data_t;
 
-static void
-fill_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode)
-{
-	cairo_t *cr;
-
-	cr = igt_get_cairo_ctx(data->drm_fd, fb);
-	igt_paint_test_pattern(cr, mode->hdisplay, mode->vdisplay);
-	cairo_destroy(cr);
-}
-
 static igt_pipe_crc_t *_pipe_crc;
 
 static igt_pipe_crc_t *pipe_crc_new(int pipe)
@@ -121,20 +111,17 @@ test_flip_tiling(data_t *data, igt_output_t *output, uint64_t tiling[2])
 			width *= 2;
 	}
 
-	fb_id = igt_create_fb(data->drm_fd, width, mode->vdisplay,
-			      DRM_FORMAT_XRGB8888, tiling[0],
-			      &fb[0]);
+	fb_id = igt_create_pattern_fb(data->drm_fd, width, mode->vdisplay,
+				      DRM_FORMAT_XRGB8888, tiling[0],
+				      &fb[0]);
 	igt_assert(fb_id);
 
 	/* Second fb has different background so CRC does not match. */
-	fb_id = igt_create_color_fb(data->drm_fd, width, mode->vdisplay,
-				    DRM_FORMAT_XRGB8888, tiling[1],
-				    0.5, 0.5, 0.5, &fb[1]);
+	fb_id = igt_create_color_pattern_fb(data->drm_fd, width, mode->vdisplay,
+				      DRM_FORMAT_XRGB8888, tiling[1],
+				      0.5, 0.5, 0.5, &fb[1]);
 	igt_assert(fb_id);
 
-	fill_fb(&fb[0], data, mode);
-	fill_fb(&fb[1], data, mode);
-
 	/* Set the crtc and generate a reference CRC. */
 	igt_plane_set_fb(primary, &fb[1]);
 	igt_display_commit(&data->display);
diff --git a/tests/kms_panel_fitting.c b/tests/kms_panel_fitting.c
index f8726e277c9d..829d9cdd0631 100644
--- a/tests/kms_panel_fitting.c
+++ b/tests/kms_panel_fitting.c
@@ -53,26 +53,6 @@ typedef struct {
 
 #define FILE_NAME   "1080p-left.png"
 
-static void
-paint_color(data_t *d, struct igt_fb *fb, uint16_t w, uint16_t h)
-{
-	cairo_t *cr;
-
-	cr = igt_get_cairo_ctx(d->drm_fd, fb);
-	igt_paint_test_pattern(cr, w, h);
-	cairo_destroy(cr);
-}
-
-static void
-paint_image(data_t *d, struct igt_fb *fb, uint16_t w, uint16_t h)
-{
-	cairo_t *cr;
-
-	cr = igt_get_cairo_ctx(d->drm_fd, fb);
-	igt_paint_image(cr, FILE_NAME, 0, 0, w, h);
-	cairo_destroy(cr);
-}
-
 static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
 			igt_plane_t *plane, drmModeModeInfo *mode, enum igt_commit_style s)
 {
@@ -91,15 +71,13 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
 	}
 
 	/* allocate fb for plane 1 */
-	data->fb_id1 = igt_create_fb(data->drm_fd,
-			mode->hdisplay, mode->vdisplay,
-			DRM_FORMAT_XRGB8888,
-			LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
-			&data->fb1);
+	data->fb_id1 = igt_create_pattern_fb(data->drm_fd,
+					     mode->hdisplay, mode->vdisplay,
+					     DRM_FORMAT_XRGB8888,
+					     LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
+					     &data->fb1);
 	igt_assert(data->fb_id1);
 
-	paint_color(data, &data->fb1, mode->hdisplay, mode->vdisplay);
-
 	/*
 	 * We always set the primary plane to actually enable the pipe as
 	 * there's no way (that works) to light up a pipe with only a sprite
@@ -188,13 +166,11 @@ static void test_panel_fitting(data_t *d)
 		d->image_h = cairo_image_surface_get_height(image);
 		cairo_surface_destroy(image);
 
-		d->fb_id2 = igt_create_fb(d->drm_fd,
-				d->image_w, d->image_h,
-				DRM_FORMAT_XRGB8888,
-				LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
-				&d->fb2);
+		d->fb_id2 = igt_create_image_fb(d->drm_fd, 0, 0,
+						DRM_FORMAT_XRGB8888,
+						LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
+						FILE_NAME, &d->fb2);
 		igt_assert(d->fb_id2);
-		paint_image(d, &d->fb2, d->fb2.width, d->fb2.height);
 
 		/* Set up display to enable panel fitting */
 		mode->hdisplay = 640;
diff --git a/tests/kms_plane_scaling.c b/tests/kms_plane_scaling.c
index 74bc6f8c148e..ad5404d90bfa 100644
--- a/tests/kms_plane_scaling.c
+++ b/tests/kms_plane_scaling.c
@@ -55,26 +55,6 @@ typedef struct {
 
 #define FILE_NAME   "1080p-left.png"
 
-static void
-paint_color(data_t *d, struct igt_fb *fb, uint16_t w, uint16_t h)
-{
-	cairo_t *cr;
-
-	cr = igt_get_cairo_ctx(d->drm_fd, fb);
-	igt_paint_test_pattern(cr, w, h);
-	cairo_destroy(cr);
-}
-
-static void
-paint_image(data_t *d, struct igt_fb *fb, uint16_t w, uint16_t h)
-{
-	cairo_t *cr;
-
-	cr = igt_get_cairo_ctx(d->drm_fd, fb);
-	igt_paint_image(cr, FILE_NAME, 0, 0, w, h);
-	cairo_destroy(cr);
-}
-
 static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
 			igt_plane_t *plane, drmModeModeInfo *mode, enum igt_commit_style s)
 {
@@ -93,15 +73,13 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
 	}
 
 	/* allocate fb for plane 1 */
-	data->fb_id1 = igt_create_fb(data->drm_fd,
-			mode->hdisplay, mode->vdisplay,
-			DRM_FORMAT_XRGB8888,
-			LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
-			&data->fb1);
+	data->fb_id1 = igt_create_pattern_fb(data->drm_fd,
+					     mode->hdisplay, mode->vdisplay,
+					     DRM_FORMAT_XRGB8888,
+					     LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
+					     &data->fb1);
 	igt_assert(data->fb_id1);
 
-	paint_color(data, &data->fb1, mode->hdisplay, mode->vdisplay);
-
 	/*
 	 * We always set the primary plane to actually enable the pipe as
 	 * there's no way (that works) to light up a pipe with only a sprite
@@ -201,7 +179,6 @@ static void test_plane_scaling(data_t *d)
 {
 	igt_display_t *display = &d->display;
 	igt_output_t *output;
-	cairo_surface_t *image;
 	enum pipe pipe;
 	int valid_tests = 0;
 	int primary_plane_scaling = 0; /* For now */
@@ -218,27 +195,18 @@ static void test_plane_scaling(data_t *d)
 		mode = igt_output_get_mode(output);
 
 		/* allocate fb2 with image size */
-		image = cairo_image_surface_create_from_png(FILE_NAME);
-		igt_assert(cairo_surface_status(image) == CAIRO_STATUS_SUCCESS);
-		d->image_w = cairo_image_surface_get_width(image);
-		d->image_h = cairo_image_surface_get_height(image);
-		cairo_surface_destroy(image);
-
-		d->fb_id2 = igt_create_fb(d->drm_fd,
-				d->image_w, d->image_h,
-				DRM_FORMAT_XRGB8888,
-				LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
-				&d->fb2);
+		d->fb_id2 = igt_create_image_fb(d->drm_fd, 0, 0,
+						DRM_FORMAT_XRGB8888,
+						LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
+						FILE_NAME, &d->fb2);
 		igt_assert(d->fb_id2);
-		paint_image(d, &d->fb2, d->fb2.width, d->fb2.height);
 
-		d->fb_id3 = igt_create_fb(d->drm_fd,
-				mode->hdisplay, mode->vdisplay,
-				DRM_FORMAT_XRGB8888,
-				LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
-				&d->fb3);
+		d->fb_id3 = igt_create_pattern_fb(d->drm_fd,
+						  mode->hdisplay, mode->vdisplay,
+						  DRM_FORMAT_XRGB8888,
+						  LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
+						  &d->fb3);
 		igt_assert(d->fb_id3);
-		paint_color(d, &d->fb3, mode->hdisplay, mode->vdisplay);
 
 		/* Set up display with plane 1 */
 		d->plane1 = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
diff --git a/tests/kms_pwrite_crc.c b/tests/kms_pwrite_crc.c
index 983418f845cd..86292bda32b3 100644
--- a/tests/kms_pwrite_crc.c
+++ b/tests/kms_pwrite_crc.c
@@ -50,7 +50,6 @@ static void test(data_t *data)
 	igt_output_t *output = data->output;
 	struct igt_fb *fb = &data->fb[1];
 	drmModeModeInfo *mode;
-	cairo_t *cr;
 	uint32_t caching;
 	void *buf;
 	igt_crc_t crc;
@@ -58,12 +57,8 @@ static void test(data_t *data)
 	mode = igt_output_get_mode(output);
 
 	/* create a non-white fb where we can pwrite later */
-	igt_create_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
-		      DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE, fb);
-
-	cr = igt_get_cairo_ctx(data->drm_fd, fb);
-	igt_paint_test_pattern(cr, fb->width, fb->height);
-	cairo_destroy(cr);
+	igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+			      DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE, fb);
 
 	/* flip to it to make it UC/WC and fully flushed */
 	drmModeSetPlane(data->drm_fd,
diff --git a/tests/kms_setmode.c b/tests/kms_setmode.c
index d5ac8f931b55..531ce8391fa7 100644
--- a/tests/kms_setmode.c
+++ b/tests/kms_setmode.c
@@ -146,8 +146,6 @@ static int paint_fb(struct igt_fb *fb, const char *test_name,
 
 	cr = igt_get_cairo_ctx(drm_fd, fb);
 
-	igt_paint_test_pattern(cr, fb->width, fb->height);
-
 	cairo_move_to(cr, fb->width / 2, fb->height / 2);
 	cairo_set_font_size(cr, 24);
 	igt_cairo_printf_line(cr, align_hcenter, 40, "%s", test_name);
@@ -180,10 +178,11 @@ static void create_fb_for_crtc(struct crtc_config *crtc,
 
 	bpp = 32;
 	depth = 24;
-	fb_id = igt_create_fb(drm_fd, crtc->mode.hdisplay,
-				  crtc->mode.vdisplay,
-				  igt_bpp_depth_to_drm_format(bpp, depth),
-				  LOCAL_DRM_FORMAT_MOD_NONE, fb_info);
+	fb_id = igt_create_pattern_fb(drm_fd, crtc->mode.hdisplay,
+				      crtc->mode.vdisplay,
+				      igt_bpp_depth_to_drm_format(bpp, depth),
+				      LOCAL_DRM_FORMAT_MOD_NONE,
+				      fb_info);
 	igt_assert_lt(0, fb_id);
 }
 
diff --git a/tests/pm_lpsp.c b/tests/pm_lpsp.c
index 257ae1b8b1d9..a82420bf06de 100644
--- a/tests/pm_lpsp.c
+++ b/tests/pm_lpsp.c
@@ -78,16 +78,9 @@ static void screens_disabled_subtest(int drm_fd, drmModeResPtr drm_res)
 static uint32_t create_fb(int drm_fd, int width, int height)
 {
 	struct igt_fb fb;
-	cairo_t *cr;
-	uint32_t buffer_id;
 
-	buffer_id = igt_create_fb(drm_fd, width, height, DRM_FORMAT_XRGB8888,
-				  LOCAL_DRM_FORMAT_MOD_NONE, &fb);
-	cr = igt_get_cairo_ctx(drm_fd, &fb);
-	igt_paint_test_pattern(cr, width, height);
-	cairo_destroy(cr);
-
-	return buffer_id;
+	return igt_create_pattern_fb(drm_fd, width, height, DRM_FORMAT_XRGB8888,
+				     LOCAL_DRM_FORMAT_MOD_NONE, &fb);
 }
 
 static void edp_subtest(int drm_fd, drmModeResPtr drm_res,
diff --git a/tests/pm_rpm.c b/tests/pm_rpm.c
index 55fdb31cb723..3a5e8bafd3c7 100644
--- a/tests/pm_rpm.c
+++ b/tests/pm_rpm.c
@@ -233,7 +233,6 @@ static bool init_modeset_params_for_type(struct mode_set_data *data,
 	int i;
 	uint32_t connector_id = 0;
 	drmModeModeInfoPtr mode = NULL;
-	cairo_t *cr;
 
 	for (i = 0; i < data->res->count_connectors; i++) {
 		drmModeConnectorPtr c = data->connectors[i];
@@ -256,12 +255,9 @@ static bool init_modeset_params_for_type(struct mode_set_data *data,
 	if (!connector_id)
 		return false;
 
-	igt_create_fb(drm_fd, mode->hdisplay, mode->vdisplay,
-		      DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
-		      &params->fb);
-	cr = igt_get_cairo_ctx(drm_fd, &params->fb);
-	igt_paint_test_pattern(cr, mode->hdisplay, mode->vdisplay);
-	cairo_destroy(cr);
+	igt_create_pattern_fb(drm_fd, mode->hdisplay, mode->vdisplay,
+			      DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
+			      &params->fb);
 
 	params->crtc_id = data->res->crtcs[0];
 	params->connector_id = connector_id;
diff --git a/tests/testdisplay.c b/tests/testdisplay.c
index 74e60b6f4bda..ff49e23a972d 100644
--- a/tests/testdisplay.c
+++ b/tests/testdisplay.c
@@ -259,8 +259,6 @@ static void paint_output_info(struct connector *c, struct igt_fb *fb)
 	double max_width;
 	int i;
 
-	igt_paint_test_pattern(cr, l_width, l_height);
-
 	cairo_move_to(cr, l_width / 2, l_height / 2);
 
 	/* Print connector and mode name */
@@ -353,9 +351,9 @@ set_mode(struct connector *c)
 		width = c->mode.hdisplay;
 		height = c->mode.vdisplay;
 
-		fb_id = igt_create_fb(drm_fd, width, height,
-				      igt_bpp_depth_to_drm_format(bpp, depth),
-				      tiling, &fb_info[current_fb]);
+		fb_id = igt_create_pattern_fb(drm_fd, width, height,
+					      igt_bpp_depth_to_drm_format(bpp, depth),
+					      tiling, &fb_info[current_fb]);
 		paint_output_info(c, &fb_info[current_fb]);
 		paint_color_key(&fb_info[current_fb]);
 
-- 
2.4.10

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH i-g-t 3/6] lib: Use igt_assert_eq() to check for crc component count
  2015-12-18 17:25 [PATCH i-g-t 1/6] lib: Make 'extra_long_opts' const ville.syrjala
  2015-12-18 17:25 ` [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers ville.syrjala
@ 2015-12-18 17:25 ` ville.syrjala
  2015-12-21 15:55   ` Daniel Vetter
  2015-12-18 17:25 ` [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock() ville.syrjala
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: ville.syrjala @ 2015-12-18 17:25 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

It's nice to see just how many components the crc claims to have
when the count don't match what we expect.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 lib/igt_debugfs.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
index 4322e8eebb3c..a3d015267e15 100644
--- a/lib/igt_debugfs.c
+++ b/lib/igt_debugfs.c
@@ -280,11 +280,10 @@ char *igt_crc_to_string(igt_crc_t *crc)
 {
 	char buf[128];
 
-	if (crc->n_words == 5)
-		sprintf(buf, "%08x %08x %08x %08x %08x", crc->crc[0],
-			crc->crc[1], crc->crc[2], crc->crc[3], crc->crc[4]);
-	else
-		igt_assert(0);
+	igt_assert_eq(crc->n_words, 5);
+
+	sprintf(buf, "%08x %08x %08x %08x %08x", crc->crc[0],
+		crc->crc[1], crc->crc[2], crc->crc[3], crc->crc[4]);
 
 	return strdup(buf);
 }
-- 
2.4.10

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock()
  2015-12-18 17:25 [PATCH i-g-t 1/6] lib: Make 'extra_long_opts' const ville.syrjala
  2015-12-18 17:25 ` [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers ville.syrjala
  2015-12-18 17:25 ` [PATCH i-g-t 3/6] lib: Use igt_assert_eq() to check for crc component count ville.syrjala
@ 2015-12-18 17:25 ` ville.syrjala
  2015-12-21 15:53   ` Daniel Vetter
  2015-12-18 17:25 ` [PATCH i-g-t 5/6] tests/kms_pipe_crc_basic: Add tests for O_NONBLOCK CRC reads ville.syrjala
  2015-12-18 17:25 ` [PATCH i-g-t 6/6] tests/kms_chv_cursor_fail: Add a test to exercise CHV pipe C cursor fail ville.syrjala
  4 siblings, 1 reply; 13+ messages in thread
From: ville.syrjala @ 2015-12-18 17:25 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add support for reading the CRC in non-blocking mode. Useful for tests
that want to start the CRC capture, then do a bunch of operations, then
collect however many CRCs that got generated. The current
igt_pipe_crc_new() + igt_pipe_crc_get_crcs() method would block until
it gets the requested number of CRCs, whreas in non-blocking mode we
can just read as many as got generated thus far.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 lib/igt_debugfs.c | 136 +++++++++++++++++++++++++++++++++++-------------------
 lib/igt_debugfs.h |   4 +-
 2 files changed, 91 insertions(+), 49 deletions(-)

diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
index a3d015267e15..1d625ad4ba50 100644
--- a/lib/igt_debugfs.c
+++ b/lib/igt_debugfs.c
@@ -298,6 +298,7 @@ struct _igt_pipe_crc {
 	int crc_fd;
 	int line_len;
 	int buffer_len;
+	int flags;
 
 	enum pipe pipe;
 	enum intel_pipe_crc_source source;
@@ -389,19 +390,8 @@ void igt_require_pipe_crc(void)
 	fclose(ctl);
 }
 
-/**
- * igt_pipe_crc_new:
- * @pipe: display pipe to use as source
- * @source: CRC tap point to use as source
- *
- * This sets up a new pipe CRC capture object for the given @pipe and @source.
- *
- * Returns: A pipe CRC object if the given @pipe and @source. The library
- * assumes that the source is always available since recent kernels support at
- * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
- */
-igt_pipe_crc_t *
-igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
+static igt_pipe_crc_t *
+pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source, int flags)
 {
 	igt_pipe_crc_t *pipe_crc;
 	char buf[128];
@@ -414,18 +404,55 @@ igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
 	igt_assert(pipe_crc->ctl_fd != -1);
 
 	sprintf(buf, "i915_pipe_%s_crc", kmstest_pipe_name(pipe));
-	pipe_crc->crc_fd = igt_debugfs_open(buf, O_RDONLY);
+	pipe_crc->crc_fd = igt_debugfs_open(buf, flags);
 	igt_assert(pipe_crc->crc_fd != -1);
 
 	pipe_crc->line_len = PIPE_CRC_LINE_LEN;
 	pipe_crc->buffer_len = PIPE_CRC_BUFFER_LEN;
 	pipe_crc->pipe = pipe;
 	pipe_crc->source = source;
+	pipe_crc->flags = flags;
 
 	return pipe_crc;
 }
 
 /**
+ * igt_pipe_crc_new:
+ * @pipe: display pipe to use as source
+ * @source: CRC tap point to use as source
+ *
+ * This sets up a new pipe CRC capture object for the given @pipe and @source
+ * in blocking mode.
+ *
+ * Returns: A pipe CRC object if the given @pipe and @source. The library
+ * assumes that the source is always available since recent kernels support at
+ * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
+ */
+igt_pipe_crc_t *
+igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
+{
+	return pipe_crc_new(pipe, source, O_RDONLY);
+}
+
+/**
+ * igt_pipe_crc_new_nonblock:
+ * @pipe: display pipe to use as source
+ * @source: CRC tap point to use as source
+ *
+ * This sets up a new pipe CRC capture object for the given @pipe and @source
+ * in nonblocking mode.
+ *
+ * Returns: A pipe CRC object if the given @pipe and @source. The library
+ * assumes that the source is always available since recent kernels support at
+ * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
+ */
+igt_pipe_crc_t *
+igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source)
+{
+	return pipe_crc_new(pipe, source, O_RDONLY | O_NONBLOCK);
+}
+
+/**
  * igt_pipe_crc_free:
  * @pipe_crc: pipe CRC object
  *
@@ -441,6 +468,39 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
 	free(pipe_crc);
 }
 
+static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
+{
+	int n;
+
+	crc->n_words = 5;
+	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
+		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
+	return n == 6;
+}
+
+static int read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
+{
+	ssize_t bytes_read;
+	char buf[pipe_crc->buffer_len];
+
+	igt_set_timeout(5, "CRC reading");
+	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
+	igt_reset_timeout();
+
+	if (bytes_read < 0 && errno == EAGAIN) {
+		igt_assert(pipe_crc->flags & O_NONBLOCK);
+		bytes_read = 0;
+	} else {
+		igt_assert_eq(bytes_read, pipe_crc->line_len);
+	}
+	buf[bytes_read] = '\0';
+
+	if (bytes_read && !pipe_crc_init_from_string(out, buf))
+		return -EINVAL;
+
+	return bytes_read;
+}
+
 /**
  * igt_pipe_crc_start:
  * @pipe_crc: pipe CRC object
@@ -449,7 +509,7 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
  */
 void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
 {
-	igt_crc_t *crcs = NULL;
+	igt_crc_t crc;
 
 	igt_assert(igt_pipe_crc_do_start(pipe_crc));
 
@@ -460,8 +520,10 @@ void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
 	 * On CHV sometimes the second CRC is bonkers as well, so don't trust
 	 * that one either.
 	 */
-	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
-	free(crcs);
+	while (read_one_crc(pipe_crc, &crc) == 0)
+		usleep(1000);
+	while (read_one_crc(pipe_crc, &crc) == 0)
+		usleep(1000);
 }
 
 /**
@@ -478,34 +540,6 @@ void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc)
 	igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)), strlen(buf));
 }
 
-static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
-{
-	int n;
-
-	crc->n_words = 5;
-	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
-		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
-	return n == 6;
-}
-
-static bool read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
-{
-	ssize_t bytes_read;
-	char buf[pipe_crc->buffer_len];
-
-	igt_set_timeout(5, "CRC reading");
-	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
-	igt_reset_timeout();
-
-	igt_assert_eq(bytes_read, pipe_crc->line_len);
-	buf[bytes_read] = '\0';
-
-	if (!pipe_crc_init_from_string(out, buf))
-		return false;
-
-	return true;
-}
-
 /**
  * igt_pipe_crc_get_crcs:
  * @pipe_crc: pipe CRC object
@@ -519,7 +553,7 @@ static bool read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
  * Callers must start and stop the capturing themselves by calling
  * igt_pipe_crc_start() and igt_pipe_crc_stop().
  */
-void
+int
 igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
 		      igt_crc_t **out_crcs)
 {
@@ -530,14 +564,19 @@ igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
 
 	do {
 		igt_crc_t *crc = &crcs[n];
+		int ret;
 
-		if (!read_one_crc(pipe_crc, crc))
+		ret = read_one_crc(pipe_crc, crc);
+		if (ret < 0)
 			continue;
+		if (ret == 0)
+			break;
 
 		n++;
 	} while (n < n_crcs);
 
 	*out_crcs = crcs;
+	return n;
 }
 
 static void crc_sanity_checks(igt_crc_t *crc)
@@ -576,7 +615,8 @@ void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc)
 	igt_debug_wait_for_keypress("crc");
 
 	igt_pipe_crc_start(pipe_crc);
-	read_one_crc(pipe_crc, out_crc);
+	while (read_one_crc(pipe_crc, out_crc) == 0)
+		usleep(1000);
 	igt_pipe_crc_stop(pipe_crc);
 
 	crc_sanity_checks(out_crc);
diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
index 24018eb355e4..6c6e2858d8f6 100644
--- a/lib/igt_debugfs.h
+++ b/lib/igt_debugfs.h
@@ -115,10 +115,12 @@ char *igt_crc_to_string(igt_crc_t *crc);
 void igt_require_pipe_crc(void);
 igt_pipe_crc_t *
 igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source);
+igt_pipe_crc_t *
+igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source);
 void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc);
 void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc);
 void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc);
-void igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
+int igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
 			   igt_crc_t **out_crcs);
 void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc);
 
-- 
2.4.10

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH i-g-t 5/6] tests/kms_pipe_crc_basic: Add tests for O_NONBLOCK CRC reads
  2015-12-18 17:25 [PATCH i-g-t 1/6] lib: Make 'extra_long_opts' const ville.syrjala
                   ` (2 preceding siblings ...)
  2015-12-18 17:25 ` [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock() ville.syrjala
@ 2015-12-18 17:25 ` ville.syrjala
  2015-12-18 17:25 ` [PATCH i-g-t 6/6] tests/kms_chv_cursor_fail: Add a test to exercise CHV pipe C cursor fail ville.syrjala
  4 siblings, 0 replies; 13+ messages in thread
From: ville.syrjala @ 2015-12-18 17:25 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tests/kms_pipe_crc_basic.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/tests/kms_pipe_crc_basic.c b/tests/kms_pipe_crc_basic.c
index a3292c225203..eb8e15e7f413 100644
--- a/tests/kms_pipe_crc_basic.c
+++ b/tests/kms_pipe_crc_basic.c
@@ -110,6 +110,7 @@ static void test_bad_command(data_t *data, const char *cmd)
 #define N_CRCS	3
 
 #define TEST_SEQUENCE (1<<0)
+#define TEST_NONBLOCK (1<<1)
 
 static int
 test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output,
@@ -124,6 +125,7 @@ test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output,
 
 	for (c = 0; c < ARRAY_SIZE(colors); c++) {
 		char *crc_str;
+		int n_crcs;
 
 		igt_output_set_pipe(output, pipe);
 		igt_display_commit(display);
@@ -151,12 +153,29 @@ test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output,
 
 		igt_display_commit(display);
 
-		pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+		if (flags & TEST_NONBLOCK)
+			pipe_crc = igt_pipe_crc_new_nonblock(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+		else
+			pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
 
 		igt_pipe_crc_start(pipe_crc);
 
+		if (flags & TEST_NONBLOCK) {
+			int i;
+			for (i = 0; i < N_CRCS; i++)
+				igt_wait_for_vblank(data->drm_fd, pipe);
+		}
+
 		/* wait for N_CRCS vblanks and the corresponding N_CRCS CRCs */
-		igt_pipe_crc_get_crcs(pipe_crc, N_CRCS, &crcs);
+		if (flags & TEST_NONBLOCK) {
+			n_crcs = igt_pipe_crc_get_crcs(pipe_crc, N_CRCS * 3, &crcs);
+			/* allow a one frame difference */
+			igt_assert_lte(n_crcs, N_CRCS + 1);
+			igt_assert_lte(N_CRCS, n_crcs + 1);
+		} else {
+			n_crcs = igt_pipe_crc_get_crcs(pipe_crc, N_CRCS, &crcs);
+			igt_assert_eq(n_crcs, N_CRCS);
+		}
 
 		igt_pipe_crc_stop(pipe_crc);
 
@@ -171,11 +190,11 @@ test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output,
 		free(crc_str);
 
 		/* and ensure that they'are all equal, we haven't changed the fb */
-		for (j = 0; j < (N_CRCS - 1); j++)
+		for (j = 0; j < (n_crcs - 1); j++)
 			igt_assert_crc_equal(&crcs[j], &crcs[j + 1]);
 
 		if (flags & TEST_SEQUENCE)
-			for (j = 0; j < (N_CRCS - 1); j++)
+			for (j = 0; j < (n_crcs - 1); j++)
 				igt_assert(crcs[j].frame + 1 == crcs[j + 1].frame);
 
 		free(crcs);
@@ -246,6 +265,12 @@ igt_main
 		igt_subtest_f("read-crc-pipe-%c-frame-sequence", 'A'+i)
 			test_read_crc(&data, i, TEST_SEQUENCE);
 
+		igt_subtest_f("nonblocking-crc-pipe-%c", 'A'+i)
+			test_read_crc(&data, i, TEST_NONBLOCK);
+
+		igt_subtest_f("nonblocking-crc-pipe-%c-frame-sequence", 'A'+i)
+			test_read_crc(&data, i, TEST_SEQUENCE | TEST_NONBLOCK);
+
 		igt_subtest_f("suspend-read-crc-pipe-%c", 'A'+i) {
 			igt_system_suspend_autoresume();
 
-- 
2.4.10

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH i-g-t 6/6] tests/kms_chv_cursor_fail: Add a test to exercise CHV pipe C cursor fail
  2015-12-18 17:25 [PATCH i-g-t 1/6] lib: Make 'extra_long_opts' const ville.syrjala
                   ` (3 preceding siblings ...)
  2015-12-18 17:25 ` [PATCH i-g-t 5/6] tests/kms_pipe_crc_basic: Add tests for O_NONBLOCK CRC reads ville.syrjala
@ 2015-12-18 17:25 ` ville.syrjala
  2015-12-21 10:42   ` Thomas Wood
  4 siblings, 1 reply; 13+ messages in thread
From: ville.syrjala @ 2015-12-18 17:25 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The test tries to anger CHV pipe C cursor by walking the edges of the
screen while moving the cursor across the screen edge.

The actual hw issue only occurs on pipe C, and only on the left screen
edge. The testcase can walk all the edges though, and on all pipes, just
so I could make sure the failure doesn't occur there.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tests/Makefile.sources      |   1 +
 tests/kms_chv_cursor_fail.c | 425 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 426 insertions(+)
 create mode 100644 tests/kms_chv_cursor_fail.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index d5940388c483..104ed2be83ed 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -68,6 +68,7 @@ TESTS_progs_M = \
 	gem_write_read_ring_switch \
 	kms_addfb_basic \
 	kms_atomic \
+	kms_chv_cursor_fail \
 	kms_cursor_crc \
 	kms_draw_crc \
 	kms_fbc_crc \
diff --git a/tests/kms_chv_cursor_fail.c b/tests/kms_chv_cursor_fail.c
new file mode 100644
index 000000000000..2ccdd4106597
--- /dev/null
+++ b/tests/kms_chv_cursor_fail.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright © 2015 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 <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+IGT_TEST_DESCRIPTION("Exercise CHV pipe C cursor fail");
+
+#ifndef DRM_CAP_CURSOR_WIDTH
+#define DRM_CAP_CURSOR_WIDTH 0x8
+#endif
+#ifndef DRM_CAP_CURSOR_HEIGHT
+#define DRM_CAP_CURSOR_HEIGHT 0x9
+#endif
+
+typedef struct {
+	int drm_fd;
+	igt_display_t display;
+	struct igt_fb primary_fb;
+	struct igt_fb fb;
+	igt_output_t *output;
+	enum pipe pipe;
+	igt_crc_t ref_crc;
+	int curw, curh; /* cursor size */
+	igt_pipe_crc_t *pipe_crc;
+	uint32_t devid;
+	bool colored, jump, disable;
+	int jump_x, jump_y;
+} data_t;
+
+enum {
+	EDGE_LEFT = 0x1,
+	EDGE_RIGHT = 0x2,
+	EDGE_TOP = 0x4,
+	EDGE_BOTTOM = 0x8,
+};
+
+static void cursor_disable(data_t *data)
+{
+	igt_output_t *output = data->output;
+	igt_plane_t *cursor;
+
+	cursor = igt_output_get_plane(output, IGT_PLANE_CURSOR);
+	igt_plane_set_fb(cursor, NULL);
+}
+
+static void create_cursor_fb(data_t *data, int cur_w, int cur_h)
+{
+	cairo_t *cr;
+	uint32_t fb_id;
+
+	fb_id = igt_create_fb(data->drm_fd, cur_w, cur_h,
+			      DRM_FORMAT_ARGB8888,
+			      LOCAL_DRM_FORMAT_MOD_NONE,
+			      &data->fb);
+	igt_assert(fb_id);
+
+	cr = igt_get_cairo_ctx(data->drm_fd, &data->fb);
+	if (data->colored)
+		igt_paint_color_alpha(cr, 0, 0, data->fb.width, data->fb.height,
+				      1.0, 0.0, 0.0, 1.0);
+	else
+		igt_paint_color_alpha(cr, 0, 0, data->fb.width, data->fb.height,
+				      0.0, 0.0, 0.0, 0.0);
+	igt_assert(cairo_status(cr) == 0);
+	cairo_destroy(cr);
+}
+
+static void cursor_move(data_t *data, int x, int y, int i)
+{
+	int crtc_id = data->output->config.crtc->crtc_id;
+
+	igt_debug("[%d] x=%d, y=%d\n", i, x, y);
+
+	/*
+	 * The "fixed" kernel will refuse the ioctl when pipe C cursor
+	 * would straddle the left screen edge (which is when the hw
+	 * fails). So let's accept a failure from the ioctl in that case.
+	 */
+	igt_assert(drmModeMoveCursor(data->drm_fd, crtc_id, x, y) == 0 ||
+		   (IS_CHERRYVIEW(data->devid) && data->pipe == PIPE_C &&
+		    x < 0 && x > -data->curw));
+	igt_wait_for_vblank(data->drm_fd, data->pipe);
+}
+
+#define XSTEP 8
+#define YSTEP 32
+#define XOFF 0
+#define NCRC 128
+
+static void test_edge_pos(data_t *data, int sx, int ex, int y, bool swap_axis)
+{
+	igt_crc_t *crc = NULL;
+	int i, n, x, xdir;
+
+	if (sx > ex)
+		xdir = -1;
+	else
+		xdir = 1;
+
+	igt_pipe_crc_start(data->pipe_crc);
+
+	i = 0;
+	for (x = sx + XOFF; xdir * (x - ex - XOFF) <= 0; x += xdir * XSTEP) {
+		int xx, yy;
+
+		if (swap_axis) {
+			xx = y;
+			yy = x;
+		} else {
+			xx = x;
+			yy = y;
+		}
+
+		if (data->jump) {
+			cursor_move(data, data->jump_x, data->jump_y, i++);
+		}
+		if (data->disable) {
+			cursor_move(data, -data->curw, -data->curh, i++);
+		}
+		cursor_move(data, xx, yy, i++);
+		if (data->jump) {
+			cursor_move(data, data->jump_x, data->jump_y, i++);
+		}
+		if (data->disable) {
+			cursor_move(data, -data->curw, -data->curh, i++);
+		}
+	}
+
+	n = igt_pipe_crc_get_crcs(data->pipe_crc, NCRC, &crc);
+	igt_pipe_crc_stop(data->pipe_crc);
+
+	if (!data->colored) {
+		igt_debug("Checking CRCs: ");
+		for (i = 0; i < n; i++) {
+			igt_debug("[%d] ", i);
+			igt_assert_crc_equal(&data->ref_crc, &crc[i]);
+		}
+		igt_debug("\n");
+	}
+
+
+	igt_pipe_crc_start(data->pipe_crc);
+}
+
+static void test_edge(data_t *data, int sy, int ey, int sx, int ex, bool swap_axis)
+{
+	int crtc_id = data->output->config.crtc->crtc_id;
+	int y, ydir;
+
+	if (sy > ey)
+		ydir = -1;
+	else
+		ydir = 1;
+
+	igt_assert_eq(drmModeMoveCursor(data->drm_fd, crtc_id, -data->curw, -data->curh), 0);
+	igt_assert_eq(drmModeSetCursor(data->drm_fd, crtc_id, data->fb.gem_handle, data->curw, data->curh), 0);
+
+	for (y = sy; ydir * (y - ey) <= 0; ) {
+		test_edge_pos(data, sx, ex, y, swap_axis);
+		y += ydir * YSTEP;
+		test_edge_pos(data, ex, sx, y, swap_axis);
+		y += ydir * YSTEP;
+	}
+
+	igt_assert_eq(drmModeMoveCursor(data->drm_fd, crtc_id, -data->curw, -data->curh), 0);
+	igt_assert_eq(drmModeSetCursor(data->drm_fd, crtc_id, 0, data->curw, data->curh), 0);
+}
+
+static void test_edges(data_t *data, unsigned int edges)
+{
+	drmModeModeInfo *mode = igt_output_get_mode(data->output);
+
+	if (edges & EDGE_LEFT) {
+		test_edge(data, mode->vdisplay, -data->curh,
+			  -data->curw, 0, false);
+		test_edge(data, -data->curh, mode->vdisplay,
+			  -data->curw, 0, false);
+	}
+
+	if (edges & EDGE_RIGHT) {
+		test_edge(data, mode->vdisplay, -data->curh,
+			  mode->hdisplay - data->curw, mode->hdisplay, false);
+		test_edge(data, -data->curh, mode->vdisplay,
+			  mode->hdisplay - data->curw, mode->hdisplay, false);
+	}
+
+	if (edges & EDGE_TOP) {
+		test_edge(data, mode->hdisplay, -data->curw,
+			  -data->curh, 0, true);
+		test_edge(data, -data->curw, mode->hdisplay,
+			  -data->curh, 0, true);
+	}
+
+	if (edges & EDGE_BOTTOM) {
+		test_edge(data, mode->hdisplay, -data->curw,
+			  mode->vdisplay - data->curh, mode->vdisplay, true);
+		test_edge(data, -data->curw, mode->hdisplay,
+			  mode->vdisplay - data->curh, mode->vdisplay, true);
+	}
+}
+
+static bool prepare_crtc(data_t *data)
+{
+	drmModeModeInfo *mode;
+	igt_display_t *display = &data->display;
+	igt_plane_t *primary;
+
+	/* select the pipe we want to use */
+	igt_output_set_pipe(data->output, data->pipe);
+	cursor_disable(data);
+	igt_display_commit(display);
+
+	if (!data->output->valid) {
+		igt_output_set_pipe(data->output, PIPE_ANY);
+		igt_display_commit(display);
+		return false;
+	}
+
+	mode = igt_output_get_mode(data->output);
+	igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      LOCAL_DRM_FORMAT_MOD_NONE,
+			      &data->primary_fb);
+
+	primary = igt_output_get_plane(data->output, IGT_PLANE_PRIMARY);
+	igt_plane_set_fb(primary, &data->primary_fb);
+
+	igt_display_commit(display);
+
+	data->jump_x = (mode->hdisplay - data->curw) / 2;
+	data->jump_y = (mode->vdisplay - data->curh) / 2;
+
+	/* create the pipe_crc object for this pipe */
+	if (data->pipe_crc)
+		igt_pipe_crc_free(data->pipe_crc);
+
+	data->pipe_crc = igt_pipe_crc_new_nonblock(data->pipe,
+						   INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	/* make sure cursor is disabled */
+	cursor_disable(data);
+	igt_wait_for_vblank(data->drm_fd, data->pipe);
+
+	/* get reference crc w/o cursor */
+	igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
+	igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
+	igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
+
+	return true;
+}
+
+static void cleanup_crtc(data_t *data)
+{
+	igt_display_t *display = &data->display;
+	igt_plane_t *primary;
+
+	igt_pipe_crc_free(data->pipe_crc);
+	data->pipe_crc = NULL;
+
+	igt_remove_fb(data->drm_fd, &data->primary_fb);
+
+	primary = igt_output_get_plane(data->output, IGT_PLANE_PRIMARY);
+	igt_plane_set_fb(primary, NULL);
+
+	igt_output_set_pipe(data->output, PIPE_ANY);
+	igt_display_commit(display);
+}
+
+static void test_crtc(data_t *data, unsigned int edges)
+{
+	igt_display_t *display = &data->display;
+	int valid_tests = 0;
+
+	create_cursor_fb(data, data->curw, data->curh);
+
+	for_each_connected_output(display, data->output) {
+		if (!prepare_crtc(data))
+			continue;
+
+		valid_tests++;
+
+		igt_info("Beginning %s on pipe %s, connector %s\n",
+			 igt_subtest_name(),
+			 kmstest_pipe_name(data->pipe),
+			 igt_output_name(data->output));
+
+		test_edges(data, edges);
+
+		igt_info("\n%s on pipe %s, connector %s: PASSED\n\n",
+			 igt_subtest_name(),
+			 kmstest_pipe_name(data->pipe),
+			 igt_output_name(data->output));
+
+		/* cleanup what prepare_crtc() has done */
+		cleanup_crtc(data);
+	}
+
+	igt_remove_fb(data->drm_fd, &data->fb);
+
+	igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
+}
+
+static int opt_handler(int opt, int opt_index, void *_data)
+{
+	data_t *data = _data;
+
+	switch (opt) {
+	case 'c':
+		data->colored = true;
+		break;
+	case 'd':
+		data->disable = true;
+		break;
+	case 'j':
+		data->jump = true;
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static data_t data;
+static uint64_t max_curw = 64, max_curh = 64;
+
+int main(int argc, char **argv)
+{
+	static const struct option long_opts[] = {
+                { .name = "colored", .val = 'c' },
+                { .name = "disable", .val = 'd'},
+                { .name = "jump", .val = 'j' },
+                {}
+        };
+        static const char *help_str =
+		"  --colored\t\tUse a colored cursor (disables CRC checks)\n"
+		"  --disable\t\tDisable the cursor between each step\n"
+		"  --jump\t\tJump the cursor to middle of the screen between each step)\n";
+
+	igt_subtest_init_parse_opts(&argc, argv, "", long_opts, help_str,
+                                    opt_handler, &data);
+
+	igt_skip_on_simulation();
+
+	igt_fixture {
+		int ret;
+
+		data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
+
+		data.devid = intel_get_drm_devid(data.drm_fd);
+
+		ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_WIDTH, &max_curw);
+		igt_assert(ret == 0 || errno == EINVAL);
+		/* Not making use of cursor_height since it is same as width, still reading */
+		ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_HEIGHT, &max_curh);
+		igt_assert(ret == 0 || errno == EINVAL);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_require_pipe_crc();
+
+		igt_display_init(&data.display, data.drm_fd);
+	}
+
+	for (data.curw = 64; data.curw <= 256; data.curw *= 2) {
+		data.curh = data.curw;
+		for (data.pipe = PIPE_A; data.pipe <= PIPE_C; data.pipe++) {
+			igt_subtest_f("pipe-%s-%dx%d-left-edge",
+				      kmstest_pipe_name(data.pipe),
+				      data.curw, data.curh) {
+				igt_require(data.curw <= max_curw && data.curh <= max_curh);
+				test_crtc(&data, EDGE_LEFT);
+			}
+			igt_subtest_f("pipe-%s-%dx%d-right-edge",
+				      kmstest_pipe_name(data.pipe),
+				      data.curw, data.curh) {
+				igt_require(data.curw <= max_curw && data.curh <= max_curh);
+				test_crtc(&data, EDGE_RIGHT);
+			}
+			igt_subtest_f("pipe-%s-%dx%d-top-edge",
+				      kmstest_pipe_name(data.pipe),
+				      data.curw, data.curh) {
+				igt_require(data.curw <= max_curw && data.curh <= max_curh);
+				test_crtc(&data, EDGE_TOP);
+			}
+			igt_subtest_f("pipe-%s-%dx%d-bottom-edge",
+				      kmstest_pipe_name(data.pipe),
+				      data.curw, data.curh) {
+				igt_require(data.curw <= max_curw && data.curh <= max_curh);
+				test_crtc(&data, EDGE_BOTTOM);
+			}
+		}
+	}
+
+	igt_fixture
+		igt_display_fini(&data.display);
+
+	igt_exit();
+}
-- 
2.4.10

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers
  2015-12-18 17:25 ` [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers ville.syrjala
@ 2015-12-21 10:42   ` Thomas Wood
  2016-01-04 16:23     ` Ville Syrjälä
  0 siblings, 1 reply; 13+ messages in thread
From: Thomas Wood @ 2015-12-21 10:42 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Intel Graphics Development

On 18 December 2015 at 17:25,  <ville.syrjala@linux.intel.com> wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Several tests do one or more of the followin:
> * igt_create_fb() + igt_paint_test_pattern()
> * igt_create_color_fb() + igt_paint_test_pattern()
> * igt_create_fb() + igt_paint_image()
>
> Extract them into new helpes: igt_create_pattern_fb(),
> igt_create_color_pattern_fb(), igt_create_image_fb().

Couple of typos above: "ssme", "followin", "helpes"


>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  lib/igt_fb.c              | 124 ++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_fb.h              |  11 ++++
>  tests/kms_atomic.c        |  30 ++++-------
>  tests/kms_flip_tiling.c   |  25 +++-------
>  tests/kms_panel_fitting.c |  42 ++++------------
>  tests/kms_plane_scaling.c |  60 ++++++----------------
>  tests/kms_pwrite_crc.c    |   9 +---
>  tests/kms_setmode.c       |  11 ++--
>  tests/pm_lpsp.c           |  11 +---
>  tests/pm_rpm.c            |  10 ++--
>  tests/testdisplay.c       |   8 ++-
>  11 files changed, 188 insertions(+), 153 deletions(-)
>
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 3ea9915c42c4..b3c7840a22ae 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -537,6 +537,130 @@ unsigned int igt_create_color_fb(int fd, int width, int height,
>         return fb_id;
>  }
>
> +/**
> + * igt_create_pattern_fb:
> + * @fd: open i915 drm file descriptor
> + * @width: width of the framebuffer in pixel
> + * @height: height of the framebuffer in pixel
> + * @format: drm fourcc pixel format code
> + * @tiling: tiling layout of the framebuffer
> + * @fb: pointer to an #igt_fb structure
> + *
> + * This function allocates a gem buffer object suitable to back a framebuffer
> + * with the requested properties and then wraps it up in a drm framebuffer
> + * object. All metadata is stored in @fb.
> + *
> + * Compared to igt_create_fb() this function also fills the entire framebuffer
> + * with the test pattern.
> + *
> + * Returns:
> + * The kms id of the created framebuffer on success or a negative error code on
> + * failure.
> + */
> +unsigned int igt_create_pattern_fb(int fd, int width, int height,
> +                                  uint32_t format, uint64_t tiling,
> +                                  struct igt_fb *fb /* out */)
> +{
> +       unsigned int fb_id;
> +       cairo_t *cr;
> +
> +       fb_id = igt_create_fb(fd, width, height, format, tiling, fb);
> +       igt_assert(fb_id);
> +
> +       cr = igt_get_cairo_ctx(fd, fb);
> +       igt_paint_test_pattern(cr, width, height);
> +       igt_assert(cairo_status(cr) == 0);
> +       cairo_destroy(cr);
> +
> +       return fb_id;
> +}
> +
> +/**
> + * igt_create_pattern_fb:

This should be igt_create_color_pattern_fb.


> + * @fd: open i915 drm file descriptor
> + * @width: width of the framebuffer in pixel
> + * @height: height of the framebuffer in pixel
> + * @format: drm fourcc pixel format code
> + * @tiling: tiling layout of the framebuffer
> + * @r: red value to use as fill color
> + * @g: gree value to use as fill color

Typo of "green" here.


> + * @b: blue value to use as fill color
> + * @fb: pointer to an #igt_fb structure
> + *
> + * This function allocates a gem buffer object suitable to back a framebuffer
> + * with the requested properties and then wraps it up in a drm framebuffer
> + * object. All metadata is stored in @fb.
> + *
> + * Compared to igt_create_fb() this function also fills the entire framebuffer
> + * with the test pattern.
> + *
> + * Returns:
> + * The kms id of the created framebuffer on success or a negative error code on
> + * failure.
> + */
> +unsigned int igt_create_color_pattern_fb(int fd, int width, int height,
> +                                        uint32_t format, uint64_t tiling,
> +                                        double r, double g, double b,
> +                                        struct igt_fb *fb /* out */)
> +{
> +       unsigned int fb_id;
> +       cairo_t *cr;
> +
> +       fb_id = igt_create_fb(fd, width, height, format, tiling, fb);
> +       igt_assert(fb_id);
> +
> +       cr = igt_get_cairo_ctx(fd, fb);
> +       igt_paint_color(cr, 0, 0, width, height, r, g, b);
> +       igt_paint_test_pattern(cr, width, height);
> +       igt_assert(cairo_status(cr) == 0);
> +       cairo_destroy(cr);
> +
> +       return fb_id;
> +}
> +
> +/**
> + * igt_create_image_fb:
> + * @drm_fd: open i915 drm file descriptor
> + * @width: width of the framebuffer in pixel or 0
> + * @height: height of the framebuffer in pixel or 0
> + * @format: drm fourcc pixel format code
> + * @tiling: tiling layout of the framebuffer
> + * @filename: filename of the png image to draw

@fb missing here.


> + *
> + * Create a framebuffer with the specified image. If @width is zero the
> + * image width will be used. If @height is zero the image height will be used.
> + *
> + * Returns:
> + * The kms id of the created framebuffer on success or a negative error code on
> + * failure.
> + */
> +unsigned int igt_create_image_fb(int fd, int width, int height,
> +                                uint32_t format, uint64_t tiling,
> +                                const char *filename,
> +                                struct igt_fb *fb /* out */)
> +{
> +       cairo_surface_t *image;
> +       uint32_t fb_id;
> +       cairo_t *cr;
> +
> +       image = cairo_image_surface_create_from_png(filename);
> +       igt_assert(cairo_surface_status(image) == CAIRO_STATUS_SUCCESS);
> +       if (width == 0)
> +               width = cairo_image_surface_get_width(image);
> +       if (height == 0)
> +               height = cairo_image_surface_get_height(image);
> +       cairo_surface_destroy(image);
> +
> +       fb_id = igt_create_fb(fd, width, height, format, tiling, fb);
> +
> +       cr = igt_get_cairo_ctx(fd, fb);
> +       igt_paint_image(cr, filename, 0, 0, width, height);
> +       igt_assert(cairo_status(cr) == 0);
> +       cairo_destroy(cr);
> +
> +       return fb_id;
> +}
> +
>  struct box {
>         int x, y, width, height;
>  };
> diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> index 37892b50d495..5cc8644d01d4 100644
> --- a/lib/igt_fb.h
> +++ b/lib/igt_fb.h
> @@ -80,6 +80,17 @@ unsigned int igt_create_color_fb(int fd, int width, int height,
>                                  uint32_t format, uint64_t tiling,
>                                  double r, double g, double b,
>                                  struct igt_fb *fb /* out */);
> +unsigned int igt_create_pattern_fb(int fd, int width, int height,
> +                                  uint32_t format, uint64_t tiling,
> +                                  struct igt_fb *fb /* out */);
> +unsigned int igt_create_color_pattern_fb(int fd, int width, int height,
> +                                        uint32_t format, uint64_t tiling,
> +                                        double r, double g, double b,
> +                                        struct igt_fb *fb /* out */);
> +unsigned int igt_create_image_fb(int drm_fd,  int width, int height,
> +                                uint32_t format, uint64_t tiling,
> +                                const char *filename,
> +                                struct igt_fb *fb /* out */);
>  unsigned int igt_create_stereo_fb(int drm_fd, drmModeModeInfo *mode,
>                                   uint32_t format, uint64_t tiling);
>  void igt_remove_fb(int fd, struct igt_fb *fb);
> diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
> index 7006e5eae411..501093cc3962 100644
> --- a/tests/kms_atomic.c
> +++ b/tests/kms_atomic.c
> @@ -867,7 +867,6 @@ static void plane_overlay(struct kms_atomic_crtc_state *crtc,
>         uint32_t format = plane_get_igt_format(&plane);
>         drmModeAtomicReq *req = drmModeAtomicAlloc();
>         struct igt_fb fb;
> -       cairo_t *cr;
>
>         igt_require(req);
>         igt_require(format != 0);
> @@ -881,12 +880,9 @@ static void plane_overlay(struct kms_atomic_crtc_state *crtc,
>         plane.crtc_w = mode->hdisplay / 2;
>         plane.crtc_h = mode->vdisplay / 2;
>         plane.crtc_id = crtc->obj;
> -       plane.fb_id = igt_create_fb(plane.state->desc->fd,
> -                                   plane.crtc_w, plane.crtc_h,
> -                                   format, I915_TILING_NONE, &fb);
> -
> -       cr = igt_get_cairo_ctx(plane.state->desc->fd, &fb);
> -       igt_paint_test_pattern(cr, plane.crtc_w, plane.crtc_h);
> +       plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
> +                                           plane.crtc_w, plane.crtc_h,
> +                                           format, I915_TILING_NONE, &fb);
>
>         /* Enable the overlay plane using the atomic API, and double-check
>          * state is what we think it should be. */
> @@ -916,7 +912,6 @@ static void plane_primary(struct kms_atomic_crtc_state *crtc,
>         uint32_t *connectors;
>         int num_connectors;
>         struct igt_fb fb;
> -       cairo_t *cr;
>         int i;
>
>         connectors = calloc(crtc->state->num_connectors, sizeof(*connectors));
> @@ -939,12 +934,9 @@ static void plane_primary(struct kms_atomic_crtc_state *crtc,
>         plane.crtc_w = mode->hdisplay;
>         plane.crtc_h = mode->vdisplay;
>         plane.crtc_id = crtc->obj;
> -       plane.fb_id = igt_create_fb(plane.state->desc->fd,
> -                                   plane.crtc_w, plane.crtc_h,
> -                                   format, I915_TILING_NONE, &fb);
> -
> -       cr = igt_get_cairo_ctx(plane.state->desc->fd, &fb);
> -       igt_paint_test_pattern(cr, plane.crtc_w, plane.crtc_h);
> +       plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
> +                                           plane.crtc_w, plane.crtc_h,
> +                                           format, I915_TILING_NONE, &fb);
>
>         /* Flip the primary plane using the atomic API, and double-check
>          * state is what we think it should be. */
> @@ -1044,7 +1036,6 @@ static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
>         uint32_t format = plane_get_igt_format(&plane);
>         drmModeAtomicReq *req = drmModeAtomicAlloc();
>         struct igt_fb fb;
> -       cairo_t *cr;
>
>         /* Pass a series of invalid object IDs for the FB ID. */
>         plane.fb_id = plane.obj;
> @@ -1098,12 +1089,9 @@ static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
>         plane.crtc_w = mode->hdisplay;
>         plane.crtc_h = mode->vdisplay;
>         plane.crtc_id = crtc->obj;
> -       plane.fb_id = igt_create_fb(plane.state->desc->fd,
> -                                   plane.crtc_w - 1, plane.crtc_h - 1,
> -                                   format, I915_TILING_NONE, &fb);
> -
> -       cr = igt_get_cairo_ctx(plane.state->desc->fd, &fb);
> -       igt_paint_test_pattern(cr, plane.crtc_w - 1, plane.crtc_h - 1);
> +       plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
> +                                           plane.crtc_w - 1, plane.crtc_h - 1,
> +                                           format, I915_TILING_NONE, &fb);
>
>         plane_commit_atomic_err(&plane, plane_old, req,
>                                 ATOMIC_RELAX_NONE, ENOSPC);
> diff --git a/tests/kms_flip_tiling.c b/tests/kms_flip_tiling.c
> index 653a9706a700..4f7334de65fe 100644
> --- a/tests/kms_flip_tiling.c
> +++ b/tests/kms_flip_tiling.c
> @@ -39,16 +39,6 @@ typedef struct {
>         int gen;
>  } data_t;
>
> -static void
> -fill_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode)
> -{
> -       cairo_t *cr;
> -
> -       cr = igt_get_cairo_ctx(data->drm_fd, fb);
> -       igt_paint_test_pattern(cr, mode->hdisplay, mode->vdisplay);
> -       cairo_destroy(cr);
> -}
> -
>  static igt_pipe_crc_t *_pipe_crc;
>
>  static igt_pipe_crc_t *pipe_crc_new(int pipe)
> @@ -121,20 +111,17 @@ test_flip_tiling(data_t *data, igt_output_t *output, uint64_t tiling[2])
>                         width *= 2;
>         }
>
> -       fb_id = igt_create_fb(data->drm_fd, width, mode->vdisplay,
> -                             DRM_FORMAT_XRGB8888, tiling[0],
> -                             &fb[0]);
> +       fb_id = igt_create_pattern_fb(data->drm_fd, width, mode->vdisplay,
> +                                     DRM_FORMAT_XRGB8888, tiling[0],
> +                                     &fb[0]);
>         igt_assert(fb_id);
>
>         /* Second fb has different background so CRC does not match. */
> -       fb_id = igt_create_color_fb(data->drm_fd, width, mode->vdisplay,
> -                                   DRM_FORMAT_XRGB8888, tiling[1],
> -                                   0.5, 0.5, 0.5, &fb[1]);
> +       fb_id = igt_create_color_pattern_fb(data->drm_fd, width, mode->vdisplay,
> +                                     DRM_FORMAT_XRGB8888, tiling[1],
> +                                     0.5, 0.5, 0.5, &fb[1]);
>         igt_assert(fb_id);
>
> -       fill_fb(&fb[0], data, mode);
> -       fill_fb(&fb[1], data, mode);
> -
>         /* Set the crtc and generate a reference CRC. */
>         igt_plane_set_fb(primary, &fb[1]);
>         igt_display_commit(&data->display);
> diff --git a/tests/kms_panel_fitting.c b/tests/kms_panel_fitting.c
> index f8726e277c9d..829d9cdd0631 100644
> --- a/tests/kms_panel_fitting.c
> +++ b/tests/kms_panel_fitting.c
> @@ -53,26 +53,6 @@ typedef struct {
>
>  #define FILE_NAME   "1080p-left.png"
>
> -static void
> -paint_color(data_t *d, struct igt_fb *fb, uint16_t w, uint16_t h)
> -{
> -       cairo_t *cr;
> -
> -       cr = igt_get_cairo_ctx(d->drm_fd, fb);
> -       igt_paint_test_pattern(cr, w, h);
> -       cairo_destroy(cr);
> -}
> -
> -static void
> -paint_image(data_t *d, struct igt_fb *fb, uint16_t w, uint16_t h)
> -{
> -       cairo_t *cr;
> -
> -       cr = igt_get_cairo_ctx(d->drm_fd, fb);
> -       igt_paint_image(cr, FILE_NAME, 0, 0, w, h);
> -       cairo_destroy(cr);
> -}
> -
>  static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
>                         igt_plane_t *plane, drmModeModeInfo *mode, enum igt_commit_style s)
>  {
> @@ -91,15 +71,13 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
>         }
>
>         /* allocate fb for plane 1 */
> -       data->fb_id1 = igt_create_fb(data->drm_fd,
> -                       mode->hdisplay, mode->vdisplay,
> -                       DRM_FORMAT_XRGB8888,
> -                       LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> -                       &data->fb1);
> +       data->fb_id1 = igt_create_pattern_fb(data->drm_fd,
> +                                            mode->hdisplay, mode->vdisplay,
> +                                            DRM_FORMAT_XRGB8888,
> +                                            LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> +                                            &data->fb1);
>         igt_assert(data->fb_id1);
>
> -       paint_color(data, &data->fb1, mode->hdisplay, mode->vdisplay);
> -
>         /*
>          * We always set the primary plane to actually enable the pipe as
>          * there's no way (that works) to light up a pipe with only a sprite
> @@ -188,13 +166,11 @@ static void test_panel_fitting(data_t *d)
>                 d->image_h = cairo_image_surface_get_height(image);
>                 cairo_surface_destroy(image);
>
> -               d->fb_id2 = igt_create_fb(d->drm_fd,
> -                               d->image_w, d->image_h,
> -                               DRM_FORMAT_XRGB8888,
> -                               LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> -                               &d->fb2);
> +               d->fb_id2 = igt_create_image_fb(d->drm_fd, 0, 0,
> +                                               DRM_FORMAT_XRGB8888,
> +                                               LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> +                                               FILE_NAME, &d->fb2);
>                 igt_assert(d->fb_id2);
> -               paint_image(d, &d->fb2, d->fb2.width, d->fb2.height);
>
>                 /* Set up display to enable panel fitting */
>                 mode->hdisplay = 640;
> diff --git a/tests/kms_plane_scaling.c b/tests/kms_plane_scaling.c
> index 74bc6f8c148e..ad5404d90bfa 100644
> --- a/tests/kms_plane_scaling.c
> +++ b/tests/kms_plane_scaling.c
> @@ -55,26 +55,6 @@ typedef struct {
>
>  #define FILE_NAME   "1080p-left.png"
>
> -static void
> -paint_color(data_t *d, struct igt_fb *fb, uint16_t w, uint16_t h)
> -{
> -       cairo_t *cr;
> -
> -       cr = igt_get_cairo_ctx(d->drm_fd, fb);
> -       igt_paint_test_pattern(cr, w, h);
> -       cairo_destroy(cr);
> -}
> -
> -static void
> -paint_image(data_t *d, struct igt_fb *fb, uint16_t w, uint16_t h)
> -{
> -       cairo_t *cr;
> -
> -       cr = igt_get_cairo_ctx(d->drm_fd, fb);
> -       igt_paint_image(cr, FILE_NAME, 0, 0, w, h);
> -       cairo_destroy(cr);
> -}
> -
>  static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
>                         igt_plane_t *plane, drmModeModeInfo *mode, enum igt_commit_style s)
>  {
> @@ -93,15 +73,13 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
>         }
>
>         /* allocate fb for plane 1 */
> -       data->fb_id1 = igt_create_fb(data->drm_fd,
> -                       mode->hdisplay, mode->vdisplay,
> -                       DRM_FORMAT_XRGB8888,
> -                       LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> -                       &data->fb1);
> +       data->fb_id1 = igt_create_pattern_fb(data->drm_fd,
> +                                            mode->hdisplay, mode->vdisplay,
> +                                            DRM_FORMAT_XRGB8888,
> +                                            LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> +                                            &data->fb1);
>         igt_assert(data->fb_id1);
>
> -       paint_color(data, &data->fb1, mode->hdisplay, mode->vdisplay);
> -
>         /*
>          * We always set the primary plane to actually enable the pipe as
>          * there's no way (that works) to light up a pipe with only a sprite
> @@ -201,7 +179,6 @@ static void test_plane_scaling(data_t *d)
>  {
>         igt_display_t *display = &d->display;
>         igt_output_t *output;
> -       cairo_surface_t *image;
>         enum pipe pipe;
>         int valid_tests = 0;
>         int primary_plane_scaling = 0; /* For now */
> @@ -218,27 +195,18 @@ static void test_plane_scaling(data_t *d)
>                 mode = igt_output_get_mode(output);
>
>                 /* allocate fb2 with image size */
> -               image = cairo_image_surface_create_from_png(FILE_NAME);
> -               igt_assert(cairo_surface_status(image) == CAIRO_STATUS_SUCCESS);
> -               d->image_w = cairo_image_surface_get_width(image);
> -               d->image_h = cairo_image_surface_get_height(image);
> -               cairo_surface_destroy(image);
> -
> -               d->fb_id2 = igt_create_fb(d->drm_fd,
> -                               d->image_w, d->image_h,
> -                               DRM_FORMAT_XRGB8888,
> -                               LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> -                               &d->fb2);
> +               d->fb_id2 = igt_create_image_fb(d->drm_fd, 0, 0,
> +                                               DRM_FORMAT_XRGB8888,
> +                                               LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> +                                               FILE_NAME, &d->fb2);
>                 igt_assert(d->fb_id2);
> -               paint_image(d, &d->fb2, d->fb2.width, d->fb2.height);
>
> -               d->fb_id3 = igt_create_fb(d->drm_fd,
> -                               mode->hdisplay, mode->vdisplay,
> -                               DRM_FORMAT_XRGB8888,
> -                               LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> -                               &d->fb3);
> +               d->fb_id3 = igt_create_pattern_fb(d->drm_fd,
> +                                                 mode->hdisplay, mode->vdisplay,
> +                                                 DRM_FORMAT_XRGB8888,
> +                                                 LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
> +                                                 &d->fb3);
>                 igt_assert(d->fb_id3);
> -               paint_color(d, &d->fb3, mode->hdisplay, mode->vdisplay);
>
>                 /* Set up display with plane 1 */
>                 d->plane1 = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
> diff --git a/tests/kms_pwrite_crc.c b/tests/kms_pwrite_crc.c
> index 983418f845cd..86292bda32b3 100644
> --- a/tests/kms_pwrite_crc.c
> +++ b/tests/kms_pwrite_crc.c
> @@ -50,7 +50,6 @@ static void test(data_t *data)
>         igt_output_t *output = data->output;
>         struct igt_fb *fb = &data->fb[1];
>         drmModeModeInfo *mode;
> -       cairo_t *cr;
>         uint32_t caching;
>         void *buf;
>         igt_crc_t crc;
> @@ -58,12 +57,8 @@ static void test(data_t *data)
>         mode = igt_output_get_mode(output);
>
>         /* create a non-white fb where we can pwrite later */
> -       igt_create_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
> -                     DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE, fb);
> -
> -       cr = igt_get_cairo_ctx(data->drm_fd, fb);
> -       igt_paint_test_pattern(cr, fb->width, fb->height);
> -       cairo_destroy(cr);
> +       igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
> +                             DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE, fb);
>
>         /* flip to it to make it UC/WC and fully flushed */
>         drmModeSetPlane(data->drm_fd,
> diff --git a/tests/kms_setmode.c b/tests/kms_setmode.c
> index d5ac8f931b55..531ce8391fa7 100644
> --- a/tests/kms_setmode.c
> +++ b/tests/kms_setmode.c
> @@ -146,8 +146,6 @@ static int paint_fb(struct igt_fb *fb, const char *test_name,
>
>         cr = igt_get_cairo_ctx(drm_fd, fb);
>
> -       igt_paint_test_pattern(cr, fb->width, fb->height);
> -
>         cairo_move_to(cr, fb->width / 2, fb->height / 2);
>         cairo_set_font_size(cr, 24);
>         igt_cairo_printf_line(cr, align_hcenter, 40, "%s", test_name);
> @@ -180,10 +178,11 @@ static void create_fb_for_crtc(struct crtc_config *crtc,
>
>         bpp = 32;
>         depth = 24;
> -       fb_id = igt_create_fb(drm_fd, crtc->mode.hdisplay,
> -                                 crtc->mode.vdisplay,
> -                                 igt_bpp_depth_to_drm_format(bpp, depth),
> -                                 LOCAL_DRM_FORMAT_MOD_NONE, fb_info);
> +       fb_id = igt_create_pattern_fb(drm_fd, crtc->mode.hdisplay,
> +                                     crtc->mode.vdisplay,
> +                                     igt_bpp_depth_to_drm_format(bpp, depth),
> +                                     LOCAL_DRM_FORMAT_MOD_NONE,
> +                                     fb_info);
>         igt_assert_lt(0, fb_id);
>  }
>
> diff --git a/tests/pm_lpsp.c b/tests/pm_lpsp.c
> index 257ae1b8b1d9..a82420bf06de 100644
> --- a/tests/pm_lpsp.c
> +++ b/tests/pm_lpsp.c
> @@ -78,16 +78,9 @@ static void screens_disabled_subtest(int drm_fd, drmModeResPtr drm_res)
>  static uint32_t create_fb(int drm_fd, int width, int height)
>  {
>         struct igt_fb fb;
> -       cairo_t *cr;
> -       uint32_t buffer_id;
>
> -       buffer_id = igt_create_fb(drm_fd, width, height, DRM_FORMAT_XRGB8888,
> -                                 LOCAL_DRM_FORMAT_MOD_NONE, &fb);
> -       cr = igt_get_cairo_ctx(drm_fd, &fb);
> -       igt_paint_test_pattern(cr, width, height);
> -       cairo_destroy(cr);
> -
> -       return buffer_id;
> +       return igt_create_pattern_fb(drm_fd, width, height, DRM_FORMAT_XRGB8888,
> +                                    LOCAL_DRM_FORMAT_MOD_NONE, &fb);
>  }
>
>  static void edp_subtest(int drm_fd, drmModeResPtr drm_res,
> diff --git a/tests/pm_rpm.c b/tests/pm_rpm.c
> index 55fdb31cb723..3a5e8bafd3c7 100644
> --- a/tests/pm_rpm.c
> +++ b/tests/pm_rpm.c
> @@ -233,7 +233,6 @@ static bool init_modeset_params_for_type(struct mode_set_data *data,
>         int i;
>         uint32_t connector_id = 0;
>         drmModeModeInfoPtr mode = NULL;
> -       cairo_t *cr;
>
>         for (i = 0; i < data->res->count_connectors; i++) {
>                 drmModeConnectorPtr c = data->connectors[i];
> @@ -256,12 +255,9 @@ static bool init_modeset_params_for_type(struct mode_set_data *data,
>         if (!connector_id)
>                 return false;
>
> -       igt_create_fb(drm_fd, mode->hdisplay, mode->vdisplay,
> -                     DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
> -                     &params->fb);
> -       cr = igt_get_cairo_ctx(drm_fd, &params->fb);
> -       igt_paint_test_pattern(cr, mode->hdisplay, mode->vdisplay);
> -       cairo_destroy(cr);
> +       igt_create_pattern_fb(drm_fd, mode->hdisplay, mode->vdisplay,
> +                             DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
> +                             &params->fb);
>
>         params->crtc_id = data->res->crtcs[0];
>         params->connector_id = connector_id;
> diff --git a/tests/testdisplay.c b/tests/testdisplay.c
> index 74e60b6f4bda..ff49e23a972d 100644
> --- a/tests/testdisplay.c
> +++ b/tests/testdisplay.c
> @@ -259,8 +259,6 @@ static void paint_output_info(struct connector *c, struct igt_fb *fb)
>         double max_width;
>         int i;
>
> -       igt_paint_test_pattern(cr, l_width, l_height);
> -
>         cairo_move_to(cr, l_width / 2, l_height / 2);
>
>         /* Print connector and mode name */
> @@ -353,9 +351,9 @@ set_mode(struct connector *c)
>                 width = c->mode.hdisplay;
>                 height = c->mode.vdisplay;
>
> -               fb_id = igt_create_fb(drm_fd, width, height,
> -                                     igt_bpp_depth_to_drm_format(bpp, depth),
> -                                     tiling, &fb_info[current_fb]);
> +               fb_id = igt_create_pattern_fb(drm_fd, width, height,
> +                                             igt_bpp_depth_to_drm_format(bpp, depth),
> +                                             tiling, &fb_info[current_fb]);
>                 paint_output_info(c, &fb_info[current_fb]);
>                 paint_color_key(&fb_info[current_fb]);
>
> --
> 2.4.10
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH i-g-t 6/6] tests/kms_chv_cursor_fail: Add a test to exercise CHV pipe C cursor fail
  2015-12-18 17:25 ` [PATCH i-g-t 6/6] tests/kms_chv_cursor_fail: Add a test to exercise CHV pipe C cursor fail ville.syrjala
@ 2015-12-21 10:42   ` Thomas Wood
  2016-01-04 15:59     ` Ville Syrjälä
  0 siblings, 1 reply; 13+ messages in thread
From: Thomas Wood @ 2015-12-21 10:42 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Intel Graphics Development

On 18 December 2015 at 17:25,  <ville.syrjala@linux.intel.com> wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> The test tries to anger CHV pipe C cursor by walking the edges of the
> screen while moving the cursor across the screen edge.
>
> The actual hw issue only occurs on pipe C, and only on the left screen
> edge. The testcase can walk all the edges though, and on all pipes, just
> so I could make sure the failure doesn't occur there.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  tests/Makefile.sources      |   1 +
>  tests/kms_chv_cursor_fail.c | 425 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 426 insertions(+)
>  create mode 100644 tests/kms_chv_cursor_fail.c
>
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index d5940388c483..104ed2be83ed 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -68,6 +68,7 @@ TESTS_progs_M = \
>         gem_write_read_ring_switch \
>         kms_addfb_basic \
>         kms_atomic \
> +       kms_chv_cursor_fail \
>         kms_cursor_crc \
>         kms_draw_crc \
>         kms_fbc_crc \
> diff --git a/tests/kms_chv_cursor_fail.c b/tests/kms_chv_cursor_fail.c
> new file mode 100644
> index 000000000000..2ccdd4106597
> --- /dev/null
> +++ b/tests/kms_chv_cursor_fail.c
> @@ -0,0 +1,425 @@
> +/*
> + * Copyright © 2015 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 <errno.h>
> +#include <limits.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +IGT_TEST_DESCRIPTION("Exercise CHV pipe C cursor fail");
> +
> +#ifndef DRM_CAP_CURSOR_WIDTH
> +#define DRM_CAP_CURSOR_WIDTH 0x8
> +#endif
> +#ifndef DRM_CAP_CURSOR_HEIGHT
> +#define DRM_CAP_CURSOR_HEIGHT 0x9
> +#endif
> +
> +typedef struct {
> +       int drm_fd;
> +       igt_display_t display;
> +       struct igt_fb primary_fb;
> +       struct igt_fb fb;
> +       igt_output_t *output;
> +       enum pipe pipe;
> +       igt_crc_t ref_crc;
> +       int curw, curh; /* cursor size */
> +       igt_pipe_crc_t *pipe_crc;
> +       uint32_t devid;
> +       bool colored, jump, disable;
> +       int jump_x, jump_y;
> +} data_t;
> +
> +enum {
> +       EDGE_LEFT = 0x1,
> +       EDGE_RIGHT = 0x2,
> +       EDGE_TOP = 0x4,
> +       EDGE_BOTTOM = 0x8,
> +};
> +
> +static void cursor_disable(data_t *data)
> +{
> +       igt_output_t *output = data->output;
> +       igt_plane_t *cursor;
> +
> +       cursor = igt_output_get_plane(output, IGT_PLANE_CURSOR);
> +       igt_plane_set_fb(cursor, NULL);
> +}
> +
> +static void create_cursor_fb(data_t *data, int cur_w, int cur_h)
> +{
> +       cairo_t *cr;
> +       uint32_t fb_id;
> +
> +       fb_id = igt_create_fb(data->drm_fd, cur_w, cur_h,
> +                             DRM_FORMAT_ARGB8888,
> +                             LOCAL_DRM_FORMAT_MOD_NONE,
> +                             &data->fb);
> +       igt_assert(fb_id);
> +
> +       cr = igt_get_cairo_ctx(data->drm_fd, &data->fb);
> +       if (data->colored)
> +               igt_paint_color_alpha(cr, 0, 0, data->fb.width, data->fb.height,
> +                                     1.0, 0.0, 0.0, 1.0);
> +       else
> +               igt_paint_color_alpha(cr, 0, 0, data->fb.width, data->fb.height,
> +                                     0.0, 0.0, 0.0, 0.0);
> +       igt_assert(cairo_status(cr) == 0);
> +       cairo_destroy(cr);
> +}
> +
> +static void cursor_move(data_t *data, int x, int y, int i)
> +{
> +       int crtc_id = data->output->config.crtc->crtc_id;
> +
> +       igt_debug("[%d] x=%d, y=%d\n", i, x, y);
> +
> +       /*
> +        * The "fixed" kernel will refuse the ioctl when pipe C cursor
> +        * would straddle the left screen edge (which is when the hw
> +        * fails). So let's accept a failure from the ioctl in that case.
> +        */
> +       igt_assert(drmModeMoveCursor(data->drm_fd, crtc_id, x, y) == 0 ||
> +                  (IS_CHERRYVIEW(data->devid) && data->pipe == PIPE_C &&
> +                   x < 0 && x > -data->curw));
> +       igt_wait_for_vblank(data->drm_fd, data->pipe);
> +}
> +
> +#define XSTEP 8
> +#define YSTEP 32
> +#define XOFF 0
> +#define NCRC 128
> +
> +static void test_edge_pos(data_t *data, int sx, int ex, int y, bool swap_axis)
> +{
> +       igt_crc_t *crc = NULL;
> +       int i, n, x, xdir;
> +
> +       if (sx > ex)
> +               xdir = -1;
> +       else
> +               xdir = 1;
> +
> +       igt_pipe_crc_start(data->pipe_crc);
> +
> +       i = 0;
> +       for (x = sx + XOFF; xdir * (x - ex - XOFF) <= 0; x += xdir * XSTEP) {
> +               int xx, yy;
> +
> +               if (swap_axis) {
> +                       xx = y;
> +                       yy = x;
> +               } else {
> +                       xx = x;
> +                       yy = y;
> +               }
> +
> +               if (data->jump) {
> +                       cursor_move(data, data->jump_x, data->jump_y, i++);
> +               }
> +               if (data->disable) {
> +                       cursor_move(data, -data->curw, -data->curh, i++);
> +               }
> +               cursor_move(data, xx, yy, i++);
> +               if (data->jump) {
> +                       cursor_move(data, data->jump_x, data->jump_y, i++);
> +               }
> +               if (data->disable) {
> +                       cursor_move(data, -data->curw, -data->curh, i++);
> +               }
> +       }
> +
> +       n = igt_pipe_crc_get_crcs(data->pipe_crc, NCRC, &crc);
> +       igt_pipe_crc_stop(data->pipe_crc);
> +
> +       if (!data->colored) {
> +               igt_debug("Checking CRCs: ");
> +               for (i = 0; i < n; i++) {
> +                       igt_debug("[%d] ", i);
> +                       igt_assert_crc_equal(&data->ref_crc, &crc[i]);
> +               }
> +               igt_debug("\n");
> +       }
> +
> +
> +       igt_pipe_crc_start(data->pipe_crc);
> +}
> +
> +static void test_edge(data_t *data, int sy, int ey, int sx, int ex, bool swap_axis)
> +{
> +       int crtc_id = data->output->config.crtc->crtc_id;
> +       int y, ydir;
> +
> +       if (sy > ey)
> +               ydir = -1;
> +       else
> +               ydir = 1;
> +
> +       igt_assert_eq(drmModeMoveCursor(data->drm_fd, crtc_id, -data->curw, -data->curh), 0);
> +       igt_assert_eq(drmModeSetCursor(data->drm_fd, crtc_id, data->fb.gem_handle, data->curw, data->curh), 0);
> +
> +       for (y = sy; ydir * (y - ey) <= 0; ) {
> +               test_edge_pos(data, sx, ex, y, swap_axis);
> +               y += ydir * YSTEP;
> +               test_edge_pos(data, ex, sx, y, swap_axis);
> +               y += ydir * YSTEP;
> +       }
> +
> +       igt_assert_eq(drmModeMoveCursor(data->drm_fd, crtc_id, -data->curw, -data->curh), 0);
> +       igt_assert_eq(drmModeSetCursor(data->drm_fd, crtc_id, 0, data->curw, data->curh), 0);
> +}
> +
> +static void test_edges(data_t *data, unsigned int edges)
> +{
> +       drmModeModeInfo *mode = igt_output_get_mode(data->output);
> +
> +       if (edges & EDGE_LEFT) {
> +               test_edge(data, mode->vdisplay, -data->curh,
> +                         -data->curw, 0, false);
> +               test_edge(data, -data->curh, mode->vdisplay,
> +                         -data->curw, 0, false);
> +       }
> +
> +       if (edges & EDGE_RIGHT) {
> +               test_edge(data, mode->vdisplay, -data->curh,
> +                         mode->hdisplay - data->curw, mode->hdisplay, false);
> +               test_edge(data, -data->curh, mode->vdisplay,
> +                         mode->hdisplay - data->curw, mode->hdisplay, false);
> +       }
> +
> +       if (edges & EDGE_TOP) {
> +               test_edge(data, mode->hdisplay, -data->curw,
> +                         -data->curh, 0, true);
> +               test_edge(data, -data->curw, mode->hdisplay,
> +                         -data->curh, 0, true);
> +       }
> +
> +       if (edges & EDGE_BOTTOM) {
> +               test_edge(data, mode->hdisplay, -data->curw,
> +                         mode->vdisplay - data->curh, mode->vdisplay, true);
> +               test_edge(data, -data->curw, mode->hdisplay,
> +                         mode->vdisplay - data->curh, mode->vdisplay, true);
> +       }
> +}
> +
> +static bool prepare_crtc(data_t *data)
> +{
> +       drmModeModeInfo *mode;
> +       igt_display_t *display = &data->display;
> +       igt_plane_t *primary;
> +
> +       /* select the pipe we want to use */
> +       igt_output_set_pipe(data->output, data->pipe);
> +       cursor_disable(data);
> +       igt_display_commit(display);
> +
> +       if (!data->output->valid) {
> +               igt_output_set_pipe(data->output, PIPE_ANY);
> +               igt_display_commit(display);
> +               return false;
> +       }
> +
> +       mode = igt_output_get_mode(data->output);
> +       igt_create_pattern_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
> +                             DRM_FORMAT_XRGB8888,
> +                             LOCAL_DRM_FORMAT_MOD_NONE,
> +                             &data->primary_fb);
> +
> +       primary = igt_output_get_plane(data->output, IGT_PLANE_PRIMARY);
> +       igt_plane_set_fb(primary, &data->primary_fb);
> +
> +       igt_display_commit(display);
> +
> +       data->jump_x = (mode->hdisplay - data->curw) / 2;
> +       data->jump_y = (mode->vdisplay - data->curh) / 2;
> +
> +       /* create the pipe_crc object for this pipe */
> +       if (data->pipe_crc)
> +               igt_pipe_crc_free(data->pipe_crc);
> +
> +       data->pipe_crc = igt_pipe_crc_new_nonblock(data->pipe,
> +                                                  INTEL_PIPE_CRC_SOURCE_AUTO);
> +
> +       /* make sure cursor is disabled */
> +       cursor_disable(data);
> +       igt_wait_for_vblank(data->drm_fd, data->pipe);
> +
> +       /* get reference crc w/o cursor */
> +       igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
> +       igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
> +       igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
> +
> +       return true;
> +}
> +
> +static void cleanup_crtc(data_t *data)
> +{
> +       igt_display_t *display = &data->display;
> +       igt_plane_t *primary;
> +
> +       igt_pipe_crc_free(data->pipe_crc);
> +       data->pipe_crc = NULL;
> +
> +       igt_remove_fb(data->drm_fd, &data->primary_fb);
> +
> +       primary = igt_output_get_plane(data->output, IGT_PLANE_PRIMARY);
> +       igt_plane_set_fb(primary, NULL);
> +
> +       igt_output_set_pipe(data->output, PIPE_ANY);
> +       igt_display_commit(display);
> +}
> +
> +static void test_crtc(data_t *data, unsigned int edges)
> +{
> +       igt_display_t *display = &data->display;
> +       int valid_tests = 0;
> +
> +       create_cursor_fb(data, data->curw, data->curh);
> +
> +       for_each_connected_output(display, data->output) {
> +               if (!prepare_crtc(data))
> +                       continue;
> +
> +               valid_tests++;
> +
> +               igt_info("Beginning %s on pipe %s, connector %s\n",
> +                        igt_subtest_name(),
> +                        kmstest_pipe_name(data->pipe),
> +                        igt_output_name(data->output));
> +
> +               test_edges(data, edges);
> +
> +               igt_info("\n%s on pipe %s, connector %s: PASSED\n\n",
> +                        igt_subtest_name(),
> +                        kmstest_pipe_name(data->pipe),
> +                        igt_output_name(data->output));
> +
> +               /* cleanup what prepare_crtc() has done */
> +               cleanup_crtc(data);
> +       }
> +
> +       igt_remove_fb(data->drm_fd, &data->fb);
> +
> +       igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
> +}
> +
> +static int opt_handler(int opt, int opt_index, void *_data)
> +{
> +       data_t *data = _data;
> +
> +       switch (opt) {
> +       case 'c':
> +               data->colored = true;
> +               break;
> +       case 'd':
> +               data->disable = true;
> +               break;
> +       case 'j':
> +               data->jump = true;
> +               break;
> +       default:
> +               break;
> +       }
> +
> +       return 0;
> +}
> +
> +static data_t data;
> +static uint64_t max_curw = 64, max_curh = 64;
> +
> +int main(int argc, char **argv)
> +{
> +       static const struct option long_opts[] = {
> +                { .name = "colored", .val = 'c' },
> +                { .name = "disable", .val = 'd'},
> +                { .name = "jump", .val = 'j' },
> +                {}
> +        };
> +        static const char *help_str =
> +               "  --colored\t\tUse a colored cursor (disables CRC checks)\n"
> +               "  --disable\t\tDisable the cursor between each step\n"
> +               "  --jump\t\tJump the cursor to middle of the screen between each step)\n";
> +
> +       igt_subtest_init_parse_opts(&argc, argv, "", long_opts, help_str,
> +                                    opt_handler, &data);
> +
> +       igt_skip_on_simulation();
> +
> +       igt_fixture {
> +               int ret;
> +
> +               data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
> +
> +               data.devid = intel_get_drm_devid(data.drm_fd);

Should there be an igt_require(IS_CHERRYVIEW(data.devid)) check here?


> +
> +               ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_WIDTH, &max_curw);
> +               igt_assert(ret == 0 || errno == EINVAL);
> +               /* Not making use of cursor_height since it is same as width, still reading */
> +               ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_HEIGHT, &max_curh);
> +               igt_assert(ret == 0 || errno == EINVAL);
> +
> +               kmstest_set_vt_graphics_mode();
> +
> +               igt_require_pipe_crc();
> +
> +               igt_display_init(&data.display, data.drm_fd);
> +       }
> +
> +       for (data.curw = 64; data.curw <= 256; data.curw *= 2) {
> +               data.curh = data.curw;
> +               for (data.pipe = PIPE_A; data.pipe <= PIPE_C; data.pipe++) {

This test is just for pipes A and B?


> +                       igt_subtest_f("pipe-%s-%dx%d-left-edge",
> +                                     kmstest_pipe_name(data.pipe),
> +                                     data.curw, data.curh) {
> +                               igt_require(data.curw <= max_curw && data.curh <= max_curh);
> +                               test_crtc(&data, EDGE_LEFT);
> +                       }
> +                       igt_subtest_f("pipe-%s-%dx%d-right-edge",
> +                                     kmstest_pipe_name(data.pipe),
> +                                     data.curw, data.curh) {
> +                               igt_require(data.curw <= max_curw && data.curh <= max_curh);
> +                               test_crtc(&data, EDGE_RIGHT);
> +                       }
> +                       igt_subtest_f("pipe-%s-%dx%d-top-edge",
> +                                     kmstest_pipe_name(data.pipe),
> +                                     data.curw, data.curh) {
> +                               igt_require(data.curw <= max_curw && data.curh <= max_curh);
> +                               test_crtc(&data, EDGE_TOP);
> +                       }
> +                       igt_subtest_f("pipe-%s-%dx%d-bottom-edge",
> +                                     kmstest_pipe_name(data.pipe),
> +                                     data.curw, data.curh) {
> +                               igt_require(data.curw <= max_curw && data.curh <= max_curh);
> +                               test_crtc(&data, EDGE_BOTTOM);
> +                       }
> +               }
> +       }
> +
> +       igt_fixture
> +               igt_display_fini(&data.display);
> +
> +       igt_exit();
> +}
> --
> 2.4.10
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock()
  2015-12-18 17:25 ` [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock() ville.syrjala
@ 2015-12-21 15:53   ` Daniel Vetter
  2016-01-04 16:46     ` Ville Syrjälä
  0 siblings, 1 reply; 13+ messages in thread
From: Daniel Vetter @ 2015-12-21 15:53 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Fri, Dec 18, 2015 at 07:25:48PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Add support for reading the CRC in non-blocking mode. Useful for tests
> that want to start the CRC capture, then do a bunch of operations, then
> collect however many CRCs that got generated. The current
> igt_pipe_crc_new() + igt_pipe_crc_get_crcs() method would block until
> it gets the requested number of CRCs, whreas in non-blocking mode we
> can just read as many as got generated thus far.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  lib/igt_debugfs.c | 136 +++++++++++++++++++++++++++++++++++-------------------
>  lib/igt_debugfs.h |   4 +-
>  2 files changed, 91 insertions(+), 49 deletions(-)
> 
> diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
> index a3d015267e15..1d625ad4ba50 100644
> --- a/lib/igt_debugfs.c
> +++ b/lib/igt_debugfs.c
> @@ -298,6 +298,7 @@ struct _igt_pipe_crc {
>  	int crc_fd;
>  	int line_len;
>  	int buffer_len;
> +	int flags;
>  
>  	enum pipe pipe;
>  	enum intel_pipe_crc_source source;
> @@ -389,19 +390,8 @@ void igt_require_pipe_crc(void)
>  	fclose(ctl);
>  }
>  
> -/**
> - * igt_pipe_crc_new:
> - * @pipe: display pipe to use as source
> - * @source: CRC tap point to use as source
> - *
> - * This sets up a new pipe CRC capture object for the given @pipe and @source.
> - *
> - * Returns: A pipe CRC object if the given @pipe and @source. The library
> - * assumes that the source is always available since recent kernels support at
> - * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
> - */
> -igt_pipe_crc_t *
> -igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
> +static igt_pipe_crc_t *
> +pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source, int flags)
>  {
>  	igt_pipe_crc_t *pipe_crc;
>  	char buf[128];
> @@ -414,18 +404,55 @@ igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
>  	igt_assert(pipe_crc->ctl_fd != -1);
>  
>  	sprintf(buf, "i915_pipe_%s_crc", kmstest_pipe_name(pipe));
> -	pipe_crc->crc_fd = igt_debugfs_open(buf, O_RDONLY);
> +	pipe_crc->crc_fd = igt_debugfs_open(buf, flags);
>  	igt_assert(pipe_crc->crc_fd != -1);
>  
>  	pipe_crc->line_len = PIPE_CRC_LINE_LEN;
>  	pipe_crc->buffer_len = PIPE_CRC_BUFFER_LEN;
>  	pipe_crc->pipe = pipe;
>  	pipe_crc->source = source;
> +	pipe_crc->flags = flags;
>  
>  	return pipe_crc;
>  }
>  
>  /**
> + * igt_pipe_crc_new:
> + * @pipe: display pipe to use as source
> + * @source: CRC tap point to use as source
> + *
> + * This sets up a new pipe CRC capture object for the given @pipe and @source
> + * in blocking mode.
> + *
> + * Returns: A pipe CRC object if the given @pipe and @source. The library
> + * assumes that the source is always available since recent kernels support at
> + * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
> + */
> +igt_pipe_crc_t *
> +igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
> +{
> +	return pipe_crc_new(pipe, source, O_RDONLY);
> +}
> +
> +/**
> + * igt_pipe_crc_new_nonblock:
> + * @pipe: display pipe to use as source
> + * @source: CRC tap point to use as source
> + *
> + * This sets up a new pipe CRC capture object for the given @pipe and @source
> + * in nonblocking mode.
> + *
> + * Returns: A pipe CRC object if the given @pipe and @source. The library
> + * assumes that the source is always available since recent kernels support at
> + * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
> + */
> +igt_pipe_crc_t *
> +igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source)
> +{
> +	return pipe_crc_new(pipe, source, O_RDONLY | O_NONBLOCK);
> +}
> +
> +/**
>   * igt_pipe_crc_free:
>   * @pipe_crc: pipe CRC object
>   *
> @@ -441,6 +468,39 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
>  	free(pipe_crc);
>  }
>  
> +static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
> +{
> +	int n;
> +
> +	crc->n_words = 5;
> +	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
> +		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
> +	return n == 6;
> +}
> +
> +static int read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
> +{
> +	ssize_t bytes_read;
> +	char buf[pipe_crc->buffer_len];
> +
> +	igt_set_timeout(5, "CRC reading");
> +	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
> +	igt_reset_timeout();
> +
> +	if (bytes_read < 0 && errno == EAGAIN) {
> +		igt_assert(pipe_crc->flags & O_NONBLOCK);
> +		bytes_read = 0;
> +	} else {
> +		igt_assert_eq(bytes_read, pipe_crc->line_len);
> +	}
> +	buf[bytes_read] = '\0';
> +
> +	if (bytes_read && !pipe_crc_init_from_string(out, buf))
> +		return -EINVAL;
> +
> +	return bytes_read;
> +}
> +
>  /**
>   * igt_pipe_crc_start:
>   * @pipe_crc: pipe CRC object
> @@ -449,7 +509,7 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
>   */
>  void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
>  {
> -	igt_crc_t *crcs = NULL;
> +	igt_crc_t crc;
>  
>  	igt_assert(igt_pipe_crc_do_start(pipe_crc));
>  
> @@ -460,8 +520,10 @@ void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
>  	 * On CHV sometimes the second CRC is bonkers as well, so don't trust
>  	 * that one either.
>  	 */
> -	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
> -	free(crcs);
> +	while (read_one_crc(pipe_crc, &crc) == 0)
> +		usleep(1000);
> +	while (read_one_crc(pipe_crc, &crc) == 0)
> +		usleep(1000);
>  }
>  
>  /**
> @@ -478,34 +540,6 @@ void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc)
>  	igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)), strlen(buf));
>  }
>  
> -static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
> -{
> -	int n;
> -
> -	crc->n_words = 5;
> -	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
> -		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
> -	return n == 6;
> -}
> -
> -static bool read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
> -{
> -	ssize_t bytes_read;
> -	char buf[pipe_crc->buffer_len];
> -
> -	igt_set_timeout(5, "CRC reading");
> -	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
> -	igt_reset_timeout();
> -
> -	igt_assert_eq(bytes_read, pipe_crc->line_len);
> -	buf[bytes_read] = '\0';
> -
> -	if (!pipe_crc_init_from_string(out, buf))
> -		return false;
> -
> -	return true;
> -}
> -
>  /**
>   * igt_pipe_crc_get_crcs:
>   * @pipe_crc: pipe CRC object
> @@ -519,7 +553,7 @@ static bool read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
>   * Callers must start and stop the capturing themselves by calling
>   * igt_pipe_crc_start() and igt_pipe_crc_stop().

Please update the gtkdoc with the return value semantics.

>   */
> -void
> +int
>  igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
>  		      igt_crc_t **out_crcs)
>  {
> @@ -530,14 +564,19 @@ igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
>  
>  	do {
>  		igt_crc_t *crc = &crcs[n];
> +		int ret;
>  
> -		if (!read_one_crc(pipe_crc, crc))
> +		ret = read_one_crc(pipe_crc, crc);
> +		if (ret < 0)
>  			continue;
> +		if (ret == 0)
> +			break;
>  
>  		n++;
>  	} while (n < n_crcs);
>  
>  	*out_crcs = crcs;
> +	return n;
>  }
>  
>  static void crc_sanity_checks(igt_crc_t *crc)
> @@ -576,7 +615,8 @@ void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc)
>  	igt_debug_wait_for_keypress("crc");
>  
>  	igt_pipe_crc_start(pipe_crc);
> -	read_one_crc(pipe_crc, out_crc);
> +	while (read_one_crc(pipe_crc, out_crc) == 0)
> +		usleep(1000);
>  	igt_pipe_crc_stop(pipe_crc);
>  
>  	crc_sanity_checks(out_crc);
> diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
> index 24018eb355e4..6c6e2858d8f6 100644
> --- a/lib/igt_debugfs.h
> +++ b/lib/igt_debugfs.h
> @@ -115,10 +115,12 @@ char *igt_crc_to_string(igt_crc_t *crc);
>  void igt_require_pipe_crc(void);
>  igt_pipe_crc_t *
>  igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source);
> +igt_pipe_crc_t *
> +igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source);
>  void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc);
>  void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc);
>  void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc);
> -void igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
> +int igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
>  			   igt_crc_t **out_crcs);

__must_check here to make sure callers check that they have enough crcs or
do something else sensible. I think we should also update
kms_pipe_crc_basic.
-Daniel


>  void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc);
>  
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH i-g-t 3/6] lib: Use igt_assert_eq() to check for crc component count
  2015-12-18 17:25 ` [PATCH i-g-t 3/6] lib: Use igt_assert_eq() to check for crc component count ville.syrjala
@ 2015-12-21 15:55   ` Daniel Vetter
  0 siblings, 0 replies; 13+ messages in thread
From: Daniel Vetter @ 2015-12-21 15:55 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Fri, Dec 18, 2015 at 07:25:47PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> It's nice to see just how many components the crc claims to have
> when the count don't match what we expect.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Assuming that you're on vacation already merged patches 1&3.

Thanks, Daniel

> ---
>  lib/igt_debugfs.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
> index 4322e8eebb3c..a3d015267e15 100644
> --- a/lib/igt_debugfs.c
> +++ b/lib/igt_debugfs.c
> @@ -280,11 +280,10 @@ char *igt_crc_to_string(igt_crc_t *crc)
>  {
>  	char buf[128];
>  
> -	if (crc->n_words == 5)
> -		sprintf(buf, "%08x %08x %08x %08x %08x", crc->crc[0],
> -			crc->crc[1], crc->crc[2], crc->crc[3], crc->crc[4]);
> -	else
> -		igt_assert(0);
> +	igt_assert_eq(crc->n_words, 5);
> +
> +	sprintf(buf, "%08x %08x %08x %08x %08x", crc->crc[0],
> +		crc->crc[1], crc->crc[2], crc->crc[3], crc->crc[4]);
>  
>  	return strdup(buf);
>  }
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH i-g-t 6/6] tests/kms_chv_cursor_fail: Add a test to exercise CHV pipe C cursor fail
  2015-12-21 10:42   ` Thomas Wood
@ 2016-01-04 15:59     ` Ville Syrjälä
  0 siblings, 0 replies; 13+ messages in thread
From: Ville Syrjälä @ 2016-01-04 15:59 UTC (permalink / raw)
  To: Thomas Wood; +Cc: Intel Graphics Development

On Mon, Dec 21, 2015 at 10:42:53AM +0000, Thomas Wood wrote:
> On 18 December 2015 at 17:25,  <ville.syrjala@linux.intel.com> wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > The test tries to anger CHV pipe C cursor by walking the edges of the
> > screen while moving the cursor across the screen edge.
> >
> > The actual hw issue only occurs on pipe C, and only on the left screen
> > edge. The testcase can walk all the edges though, and on all pipes, just
> > so I could make sure the failure doesn't occur there.
> >
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  tests/Makefile.sources      |   1 +
> >  tests/kms_chv_cursor_fail.c | 425 ++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 426 insertions(+)
> >  create mode 100644 tests/kms_chv_cursor_fail.c
> >
> > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > index d5940388c483..104ed2be83ed 100644
> > --- a/tests/Makefile.sources
> > +++ b/tests/Makefile.sources
> > @@ -68,6 +68,7 @@ TESTS_progs_M = \
> >         gem_write_read_ring_switch \
> >         kms_addfb_basic \
> >         kms_atomic \
> > +       kms_chv_cursor_fail \
> >         kms_cursor_crc \
> >         kms_draw_crc \
> >         kms_fbc_crc \
> > diff --git a/tests/kms_chv_cursor_fail.c b/tests/kms_chv_cursor_fail.c
> > new file mode 100644
> > index 000000000000..2ccdd4106597
> > --- /dev/null
> > +++ b/tests/kms_chv_cursor_fail.c
<snip>
> > +int main(int argc, char **argv)
> > +{
> > +       static const struct option long_opts[] = {
> > +                { .name = "colored", .val = 'c' },
> > +                { .name = "disable", .val = 'd'},
> > +                { .name = "jump", .val = 'j' },
> > +                {}
> > +        };
> > +        static const char *help_str =
> > +               "  --colored\t\tUse a colored cursor (disables CRC checks)\n"
> > +               "  --disable\t\tDisable the cursor between each step\n"
> > +               "  --jump\t\tJump the cursor to middle of the screen between each step)\n";
> > +
> > +       igt_subtest_init_parse_opts(&argc, argv, "", long_opts, help_str,
> > +                                    opt_handler, &data);
> > +
> > +       igt_skip_on_simulation();
> > +
> > +       igt_fixture {
> > +               int ret;
> > +
> > +               data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
> > +
> > +               data.devid = intel_get_drm_devid(data.drm_fd);
> 
> Should there be an igt_require(IS_CHERRYVIEW(data.devid)) check here?

The test can be run on any hardware.

> 
> 
> > +
> > +               ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_WIDTH, &max_curw);
> > +               igt_assert(ret == 0 || errno == EINVAL);
> > +               /* Not making use of cursor_height since it is same as width, still reading */
> > +               ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_HEIGHT, &max_curh);
> > +               igt_assert(ret == 0 || errno == EINVAL);
> > +
> > +               kmstest_set_vt_graphics_mode();
> > +
> > +               igt_require_pipe_crc();
> > +
> > +               igt_display_init(&data.display, data.drm_fd);
> > +       }
> > +
> > +       for (data.curw = 64; data.curw <= 256; data.curw *= 2) {
> > +               data.curh = data.curw;
> > +               for (data.pipe = PIPE_A; data.pipe <= PIPE_C; data.pipe++) {
> 
> This test is just for pipes A and B?

A,B,C

> 
> 
> > +                       igt_subtest_f("pipe-%s-%dx%d-left-edge",
> > +                                     kmstest_pipe_name(data.pipe),
> > +                                     data.curw, data.curh) {
> > +                               igt_require(data.curw <= max_curw && data.curh <= max_curh);
> > +                               test_crtc(&data, EDGE_LEFT);
> > +                       }
> > +                       igt_subtest_f("pipe-%s-%dx%d-right-edge",
> > +                                     kmstest_pipe_name(data.pipe),
> > +                                     data.curw, data.curh) {
> > +                               igt_require(data.curw <= max_curw && data.curh <= max_curh);
> > +                               test_crtc(&data, EDGE_RIGHT);
> > +                       }
> > +                       igt_subtest_f("pipe-%s-%dx%d-top-edge",
> > +                                     kmstest_pipe_name(data.pipe),
> > +                                     data.curw, data.curh) {
> > +                               igt_require(data.curw <= max_curw && data.curh <= max_curh);
> > +                               test_crtc(&data, EDGE_TOP);
> > +                       }
> > +                       igt_subtest_f("pipe-%s-%dx%d-bottom-edge",
> > +                                     kmstest_pipe_name(data.pipe),
> > +                                     data.curw, data.curh) {
> > +                               igt_require(data.curw <= max_curw && data.curh <= max_curh);
> > +                               test_crtc(&data, EDGE_BOTTOM);
> > +                       }
> > +               }
> > +       }
> > +
> > +       igt_fixture
> > +               igt_display_fini(&data.display);
> > +
> > +       igt_exit();
> > +}
> > --
> > 2.4.10
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers
  2015-12-21 10:42   ` Thomas Wood
@ 2016-01-04 16:23     ` Ville Syrjälä
  0 siblings, 0 replies; 13+ messages in thread
From: Ville Syrjälä @ 2016-01-04 16:23 UTC (permalink / raw)
  To: Thomas Wood; +Cc: Intel Graphics Development

On Mon, Dec 21, 2015 at 10:42:46AM +0000, Thomas Wood wrote:
> On 18 December 2015 at 17:25,  <ville.syrjala@linux.intel.com> wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > Several tests do one or more of the followin:
> > * igt_create_fb() + igt_paint_test_pattern()
> > * igt_create_color_fb() + igt_paint_test_pattern()
> > * igt_create_fb() + igt_paint_image()
> >
> > Extract them into new helpes: igt_create_pattern_fb(),
> > igt_create_color_pattern_fb(), igt_create_image_fb().
> 
> Couple of typos above: "ssme", "followin", "helpes"
> 
> 
> >
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  lib/igt_fb.c              | 124 ++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/igt_fb.h              |  11 ++++
> >  tests/kms_atomic.c        |  30 ++++-------
> >  tests/kms_flip_tiling.c   |  25 +++-------
> >  tests/kms_panel_fitting.c |  42 ++++------------
> >  tests/kms_plane_scaling.c |  60 ++++++----------------
> >  tests/kms_pwrite_crc.c    |   9 +---
> >  tests/kms_setmode.c       |  11 ++--
> >  tests/pm_lpsp.c           |  11 +---
> >  tests/pm_rpm.c            |  10 ++--
> >  tests/testdisplay.c       |   8 ++-
> >  11 files changed, 188 insertions(+), 153 deletions(-)
> >
> > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > index 3ea9915c42c4..b3c7840a22ae 100644
> > --- a/lib/igt_fb.c
> > +++ b/lib/igt_fb.c
> > @@ -537,6 +537,130 @@ unsigned int igt_create_color_fb(int fd, int width, int height,
> >         return fb_id;
> >  }
> >
> > +/**
> > + * igt_create_pattern_fb:
> > + * @fd: open i915 drm file descriptor
> > + * @width: width of the framebuffer in pixel
> > + * @height: height of the framebuffer in pixel
> > + * @format: drm fourcc pixel format code
> > + * @tiling: tiling layout of the framebuffer
> > + * @fb: pointer to an #igt_fb structure
> > + *
> > + * This function allocates a gem buffer object suitable to back a framebuffer
> > + * with the requested properties and then wraps it up in a drm framebuffer
> > + * object. All metadata is stored in @fb.
> > + *
> > + * Compared to igt_create_fb() this function also fills the entire framebuffer
> > + * with the test pattern.
> > + *
> > + * Returns:
> > + * The kms id of the created framebuffer on success or a negative error code on
> > + * failure.
> > + */
> > +unsigned int igt_create_pattern_fb(int fd, int width, int height,
> > +                                  uint32_t format, uint64_t tiling,
> > +                                  struct igt_fb *fb /* out */)
> > +{
> > +       unsigned int fb_id;
> > +       cairo_t *cr;
> > +
> > +       fb_id = igt_create_fb(fd, width, height, format, tiling, fb);
> > +       igt_assert(fb_id);
> > +
> > +       cr = igt_get_cairo_ctx(fd, fb);
> > +       igt_paint_test_pattern(cr, width, height);
> > +       igt_assert(cairo_status(cr) == 0);
> > +       cairo_destroy(cr);
> > +
> > +       return fb_id;
> > +}
> > +
> > +/**
> > + * igt_create_pattern_fb:
> 
> This should be igt_create_color_pattern_fb.
> 
> 
> > + * @fd: open i915 drm file descriptor
> > + * @width: width of the framebuffer in pixel
> > + * @height: height of the framebuffer in pixel
> > + * @format: drm fourcc pixel format code
> > + * @tiling: tiling layout of the framebuffer
> > + * @r: red value to use as fill color
> > + * @g: gree value to use as fill color
> 
> Typo of "green" here.

I think this was copy pasted from somewhere else. I'll fix up the
original as well.


-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock()
  2015-12-21 15:53   ` Daniel Vetter
@ 2016-01-04 16:46     ` Ville Syrjälä
  0 siblings, 0 replies; 13+ messages in thread
From: Ville Syrjälä @ 2016-01-04 16:46 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Mon, Dec 21, 2015 at 04:53:34PM +0100, Daniel Vetter wrote:
> On Fri, Dec 18, 2015 at 07:25:48PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Add support for reading the CRC in non-blocking mode. Useful for tests
> > that want to start the CRC capture, then do a bunch of operations, then
> > collect however many CRCs that got generated. The current
> > igt_pipe_crc_new() + igt_pipe_crc_get_crcs() method would block until
> > it gets the requested number of CRCs, whreas in non-blocking mode we
> > can just read as many as got generated thus far.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  lib/igt_debugfs.c | 136 +++++++++++++++++++++++++++++++++++-------------------
> >  lib/igt_debugfs.h |   4 +-
> >  2 files changed, 91 insertions(+), 49 deletions(-)
> > 
> > diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
> > index a3d015267e15..1d625ad4ba50 100644
> > --- a/lib/igt_debugfs.c
> > +++ b/lib/igt_debugfs.c
> > @@ -298,6 +298,7 @@ struct _igt_pipe_crc {
> >  	int crc_fd;
> >  	int line_len;
> >  	int buffer_len;
> > +	int flags;
> >  
> >  	enum pipe pipe;
> >  	enum intel_pipe_crc_source source;
> > @@ -389,19 +390,8 @@ void igt_require_pipe_crc(void)
> >  	fclose(ctl);
> >  }
> >  
> > -/**
> > - * igt_pipe_crc_new:
> > - * @pipe: display pipe to use as source
> > - * @source: CRC tap point to use as source
> > - *
> > - * This sets up a new pipe CRC capture object for the given @pipe and @source.
> > - *
> > - * Returns: A pipe CRC object if the given @pipe and @source. The library
> > - * assumes that the source is always available since recent kernels support at
> > - * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
> > - */
> > -igt_pipe_crc_t *
> > -igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
> > +static igt_pipe_crc_t *
> > +pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source, int flags)
> >  {
> >  	igt_pipe_crc_t *pipe_crc;
> >  	char buf[128];
> > @@ -414,18 +404,55 @@ igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
> >  	igt_assert(pipe_crc->ctl_fd != -1);
> >  
> >  	sprintf(buf, "i915_pipe_%s_crc", kmstest_pipe_name(pipe));
> > -	pipe_crc->crc_fd = igt_debugfs_open(buf, O_RDONLY);
> > +	pipe_crc->crc_fd = igt_debugfs_open(buf, flags);
> >  	igt_assert(pipe_crc->crc_fd != -1);
> >  
> >  	pipe_crc->line_len = PIPE_CRC_LINE_LEN;
> >  	pipe_crc->buffer_len = PIPE_CRC_BUFFER_LEN;
> >  	pipe_crc->pipe = pipe;
> >  	pipe_crc->source = source;
> > +	pipe_crc->flags = flags;
> >  
> >  	return pipe_crc;
> >  }
> >  
> >  /**
> > + * igt_pipe_crc_new:
> > + * @pipe: display pipe to use as source
> > + * @source: CRC tap point to use as source
> > + *
> > + * This sets up a new pipe CRC capture object for the given @pipe and @source
> > + * in blocking mode.
> > + *
> > + * Returns: A pipe CRC object if the given @pipe and @source. The library
> > + * assumes that the source is always available since recent kernels support at
> > + * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
> > + */
> > +igt_pipe_crc_t *
> > +igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
> > +{
> > +	return pipe_crc_new(pipe, source, O_RDONLY);
> > +}
> > +
> > +/**
> > + * igt_pipe_crc_new_nonblock:
> > + * @pipe: display pipe to use as source
> > + * @source: CRC tap point to use as source
> > + *
> > + * This sets up a new pipe CRC capture object for the given @pipe and @source
> > + * in nonblocking mode.
> > + *
> > + * Returns: A pipe CRC object if the given @pipe and @source. The library
> > + * assumes that the source is always available since recent kernels support at
> > + * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
> > + */
> > +igt_pipe_crc_t *
> > +igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source)
> > +{
> > +	return pipe_crc_new(pipe, source, O_RDONLY | O_NONBLOCK);
> > +}
> > +
> > +/**
> >   * igt_pipe_crc_free:
> >   * @pipe_crc: pipe CRC object
> >   *
> > @@ -441,6 +468,39 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
> >  	free(pipe_crc);
> >  }
> >  
> > +static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
> > +{
> > +	int n;
> > +
> > +	crc->n_words = 5;
> > +	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
> > +		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
> > +	return n == 6;
> > +}
> > +
> > +static int read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
> > +{
> > +	ssize_t bytes_read;
> > +	char buf[pipe_crc->buffer_len];
> > +
> > +	igt_set_timeout(5, "CRC reading");
> > +	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
> > +	igt_reset_timeout();
> > +
> > +	if (bytes_read < 0 && errno == EAGAIN) {
> > +		igt_assert(pipe_crc->flags & O_NONBLOCK);
> > +		bytes_read = 0;
> > +	} else {
> > +		igt_assert_eq(bytes_read, pipe_crc->line_len);
> > +	}
> > +	buf[bytes_read] = '\0';
> > +
> > +	if (bytes_read && !pipe_crc_init_from_string(out, buf))
> > +		return -EINVAL;
> > +
> > +	return bytes_read;
> > +}
> > +
> >  /**
> >   * igt_pipe_crc_start:
> >   * @pipe_crc: pipe CRC object
> > @@ -449,7 +509,7 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
> >   */
> >  void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
> >  {
> > -	igt_crc_t *crcs = NULL;
> > +	igt_crc_t crc;
> >  
> >  	igt_assert(igt_pipe_crc_do_start(pipe_crc));
> >  
> > @@ -460,8 +520,10 @@ void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
> >  	 * On CHV sometimes the second CRC is bonkers as well, so don't trust
> >  	 * that one either.
> >  	 */
> > -	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
> > -	free(crcs);
> > +	while (read_one_crc(pipe_crc, &crc) == 0)
> > +		usleep(1000);
> > +	while (read_one_crc(pipe_crc, &crc) == 0)
> > +		usleep(1000);
> >  }
> >  
> >  /**
> > @@ -478,34 +540,6 @@ void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc)
> >  	igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)), strlen(buf));
> >  }
> >  
> > -static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
> > -{
> > -	int n;
> > -
> > -	crc->n_words = 5;
> > -	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
> > -		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
> > -	return n == 6;
> > -}
> > -
> > -static bool read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
> > -{
> > -	ssize_t bytes_read;
> > -	char buf[pipe_crc->buffer_len];
> > -
> > -	igt_set_timeout(5, "CRC reading");
> > -	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
> > -	igt_reset_timeout();
> > -
> > -	igt_assert_eq(bytes_read, pipe_crc->line_len);
> > -	buf[bytes_read] = '\0';
> > -
> > -	if (!pipe_crc_init_from_string(out, buf))
> > -		return false;
> > -
> > -	return true;
> > -}
> > -
> >  /**
> >   * igt_pipe_crc_get_crcs:
> >   * @pipe_crc: pipe CRC object
> > @@ -519,7 +553,7 @@ static bool read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
> >   * Callers must start and stop the capturing themselves by calling
> >   * igt_pipe_crc_start() and igt_pipe_crc_stop().
> 
> Please update the gtkdoc with the return value semantics.

done

> 
> >   */
> > -void
> > +int
> >  igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
> >  		      igt_crc_t **out_crcs)
> >  {
> > @@ -530,14 +564,19 @@ igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
> >  
> >  	do {
> >  		igt_crc_t *crc = &crcs[n];
> > +		int ret;
> >  
> > -		if (!read_one_crc(pipe_crc, crc))
> > +		ret = read_one_crc(pipe_crc, crc);
> > +		if (ret < 0)
> >  			continue;
> > +		if (ret == 0)
> > +			break;
> >  
> >  		n++;
> >  	} while (n < n_crcs);
> >  
> >  	*out_crcs = crcs;
> > +	return n;
> >  }
> >  
> >  static void crc_sanity_checks(igt_crc_t *crc)
> > @@ -576,7 +615,8 @@ void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc)
> >  	igt_debug_wait_for_keypress("crc");
> >  
> >  	igt_pipe_crc_start(pipe_crc);
> > -	read_one_crc(pipe_crc, out_crc);
> > +	while (read_one_crc(pipe_crc, out_crc) == 0)
> > +		usleep(1000);
> >  	igt_pipe_crc_stop(pipe_crc);
> >  
> >  	crc_sanity_checks(out_crc);
> > diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
> > index 24018eb355e4..6c6e2858d8f6 100644
> > --- a/lib/igt_debugfs.h
> > +++ b/lib/igt_debugfs.h
> > @@ -115,10 +115,12 @@ char *igt_crc_to_string(igt_crc_t *crc);
> >  void igt_require_pipe_crc(void);
> >  igt_pipe_crc_t *
> >  igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source);
> > +igt_pipe_crc_t *
> > +igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source);
> >  void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc);
> >  void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc);
> >  void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc);
> > -void igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
> > +int igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
> >  			   igt_crc_t **out_crcs);
> 
> __must_check here to make sure callers check that they have enough crcs or
> do something else sensible. I think we should also update
> kms_pipe_crc_basic.

and done

> -Daniel
> 
> 
> >  void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc);
> >  
> > -- 
> > 2.4.10
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-01-04 16:46 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-18 17:25 [PATCH i-g-t 1/6] lib: Make 'extra_long_opts' const ville.syrjala
2015-12-18 17:25 ` [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers ville.syrjala
2015-12-21 10:42   ` Thomas Wood
2016-01-04 16:23     ` Ville Syrjälä
2015-12-18 17:25 ` [PATCH i-g-t 3/6] lib: Use igt_assert_eq() to check for crc component count ville.syrjala
2015-12-21 15:55   ` Daniel Vetter
2015-12-18 17:25 ` [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock() ville.syrjala
2015-12-21 15:53   ` Daniel Vetter
2016-01-04 16:46     ` Ville Syrjälä
2015-12-18 17:25 ` [PATCH i-g-t 5/6] tests/kms_pipe_crc_basic: Add tests for O_NONBLOCK CRC reads ville.syrjala
2015-12-18 17:25 ` [PATCH i-g-t 6/6] tests/kms_chv_cursor_fail: Add a test to exercise CHV pipe C cursor fail ville.syrjala
2015-12-21 10:42   ` Thomas Wood
2016-01-04 15:59     ` Ville Syrjälä

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.