[igt-dev] [i-g-t,v4 4/4] kms_plane: Add clipping subtests

Daniel Vetter daniel at ffwll.ch
Fri Sep 14 09:25:59 UTC 2018


On Fri, Sep 14, 2018 at 10:56:05AM +0200, Daniel Vetter wrote:
> On Fri, Sep 07, 2018 at 06:51:57PM +0300, Gwan-gyeong Mun wrote:
> > From: Imre Deak <imre.deak at intel.com>
> > 
> > Add plane clipping subtests displaying a single clipped plane, with the
> > following test cases:
> > a) plane covering the whole screen, so that clipping is done at all 4
> >    screen edges
> > b) plane at either of the 4 corners of the screen clipped, so that a
> >    4x4 pixel part of the plane is visible
> > c) plane at either of the 4 corners of the screen clipped, so that a
> >    2x2 pixel part of the plane is visible
> > 
> > Each of the above cases are tested with all supported tiling modes,
> > rotation degrees, differing pixel format sizes (only 16 bpp and 32 bpp
> > for now) and certain planes. While the a) and b) cases above are
> > supported on all platforms c) is not fully supported on GLK and CNL
> > (which was the primary motivation for this testcase).
> > 
> > v2:
> > - Add missing reset for the output pipe after finishing the test for a
> >   given output, fixing the
> >   "DP-1 and eDP-1 are both trying to use pipe A" type of errors.
> > - Use -ERANGE instead of -EINVAL to check the return code for
> >   unsupported plane X positions, based on the latest kernel code.
> > - Add comment explaining the dependencies when doing a universal
> >   commit.
> > 
> > v3: (Gwan-gyeong)
> > - Add missing release of framebuffer on create_fb_for_mode__clipping_display()
> >   function.
> > - Add using multi planes per single display commit on clipping test of
> >   4 corners. (Daniel)
> >   It enables the improving of test speed. If number of planes is over
> >   than 4, it uses four planes from first plane to next four planes.
> >   (4 planes make testing of 4 corners possible as 1 display commit.)
> >   If number of planes is over than 2 and less than 4, it uses two planes
> >   from first plane to next two planes. (2 planes make testing of 4 corners
> >   possible as 2 display commit.) Rest of cases it uses only first plane.
> >   (1 plane makes testing of 4 corners possible as 4 display commit.)
> >   It changes to using of certain planes from using of all supported planes.
> >   And a cursor plane can be one of test planes.
> > 
> > v4: (Imre)
> > - Change a commit style to legacy from universal when this grabs a crc for
> >   framebuffer. The universal commit has issues with multiple outputs. As
> >   the legacy style commit does not allow changing of primary plane rotation
> >   on non-first commit, this calls igt_display_reset() to make a first
> >   commit state prior to call test_grab_crc_for_fb().
> 
> Just an aside: Why not atomic? Atomic should be a notch faster still,
> since it applies all the changes in one go.
> 
> I think we should also have a non-committing version of
> igt_display_reset(), to cut away even more modesets.
> 
> Also, is the plan to remove the corresponding cursor tests?
> 
> > - Update variable naming more clearly
> >   clip_squares_cnt -> plane_cnt
> > - Optimize test_plane_clipping_squares() function
> > - Update indentation as kernel style
> > 
> > Signed-off-by: Imre Deak <imre.deak at intel.com>
> > Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun at intel.com>
> > Cc: Mika Kahola <mika.kahola at intel.com>
> > Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> > Cc: Juha-Pekka Heikkilä <juha-pekka.heikkila at intel.com>
> > Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler at intel.com> (v1)
> > ---
> >  tests/kms_plane.c | 516 ++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 516 insertions(+)
> > 
> > diff --git a/tests/kms_plane.c b/tests/kms_plane.c
> > index 3f48c821..ac475358 100644
> > --- a/tests/kms_plane.c
> > +++ b/tests/kms_plane.c
> > @@ -41,11 +41,40 @@ typedef struct {
> >  	int drm_fd;
> >  	igt_display_t display;
> >  	igt_pipe_crc_t *pipe_crc;
> > +	uint32_t devid;
> > +	uint64_t max_curw;
> > +	uint64_t max_curh;
> >  } data_t;
> >  
> > +typedef struct {
> > +	int x;
> > +	int y;
> > +	int size;
> > +} square_t;
> > +
> >  static color_t red   = { 1.0f, 0.0f, 0.0f };
> >  static color_t green = { 0.0f, 1.0f, 0.0f };
> > +static color_t yellow = { 1.0f, 1.0f, 0.0f };
> >  static color_t blue  = { 0.0f, 0.0f, 1.0f };
> > +static color_t white = { 1.0f, 1.0f, 1.0f };
> > +static square_t clip_squares[4];
> > +
> > +/*
> > + * Size of a square plane used to test clipping at the 4 courners of the
> > + * display.
> > + */
> > +#define CLIPPED_PLANE_SMALL_SIZE	64
> > +
> > +/*
> > + * Visible plane size after clipping that works on all platforms for all plane
> > + * positions.
> > + * The exceptions are GLK/CNL where there must be at least this many pixels
> > + * visible from the plane after it's clipped to the left/right edge of the
> > + * screen. Not meeting this condition may trigger FIFO underflows and screen
> > + * corruption. The cursor plane is an exception that doesn't have this problem
> > + * even on GLK/CNL.
> > + */
> > +#define CLIPPED_PLANE_MIN_VALID		4
> >  
> >  /*
> >   * Common code across all tests, acting on data_t
> > @@ -142,6 +171,69 @@ create_fb_for_mode__position(data_t *data, drmModeModeInfo *mode,
> >  	igt_put_cairo_ctx(data->drm_fd, fb, cr);
> >  }
> >  
> > +/*
> > + * Create a square FB for the plane in the clipping test, divided into 4
> > + * quarters solid filled with different colors. Use the given tiling, format
> > + * and size and rotate the FB clockwise with the given rotation degrees, so
> > + * that the counterclockwise rotation with the same degrees done by the HW
> > + * will always result in the same reference FB image.
> > + */
> > +static void
> > +create_fb_for_mode__clipping_plane(data_t *data, igt_rotation_t rotation,
> > +				   uint64_t tiling,
> > +				   uint32_t format,
> > +				   int size,
> > +				   struct igt_fb *fb /* out */)
> > +{
> > +	color_t corners[] = { red, white, yellow, blue };
> > +	color_t color;
> > +	unsigned int fb_id;
> > +	cairo_t *cr;
> > +	const int qsize = size / 2;
> > +	int idx;
> > +
> > +	fb_id = igt_create_fb(data->drm_fd, size, size, format, tiling, fb);
> > +	igt_assert(fb_id);
> > +
> > +	cr = igt_get_cairo_ctx(data->drm_fd, fb);
> > +
> > +	switch (rotation) {
> > +	case IGT_ROTATION_0:
> > +		idx = 0;
> > +		break;
> > +	case IGT_ROTATION_90:
> > +		idx = 3;
> > +		break;
> > +	case IGT_ROTATION_180:
> > +		idx = 2;
> > +		break;
> > +	case IGT_ROTATION_270:
> > +		idx = 1;
> > +		break;
> > +	default:
> > +		igt_assert(0);
> > +	}
> > +
> > +	color = corners[idx];
> > +	igt_paint_color(cr, 0, 0, qsize, qsize,
> > +			color.red, color.green, color.blue);
> > +
> > +	color = corners[(++idx) % 4];
> > +	igt_paint_color(cr, qsize, 0, qsize, qsize,
> > +			color.red, color.green, color.blue);
> > +
> > +	color = corners[(++idx) % 4];
> > +	igt_paint_color(cr, qsize, qsize, qsize, qsize,
> > +			color.red, color.green, color.blue);
> > +
> > +	color = corners[(++idx) % 4];
> > +	igt_paint_color(cr, 0, qsize, qsize, qsize,
> > +			color.red, color.green, color.blue);
> > +
> > +	igt_assert(cairo_status(cr) == 0);
> > +	cairo_destroy(cr);
> > +}
> > +
> >  enum {
> >  	TEST_POSITION_FULLY_COVERED = 1 << 0,
> >  	TEST_DPMS = 1 << 1,
> > @@ -545,6 +637,414 @@ test_pixel_formats(data_t *data, enum pipe pipe)
> >  	}
> >  }
> >  
> > +static bool
> > +bogus_plane_conf(uint32_t devid, igt_plane_t *plane_obj,
> > +		 int hdisplay, int plane_x, int plane_width)
> > +{
> > +	if (!(IS_GEMINILAKE(devid) || IS_CANNONLAKE(devid)))
> > +		return false;
> > +
> > +	if (plane_obj->type == DRM_PLANE_TYPE_CURSOR)
> > +		return false;
> > +
> > +	if (plane_x + plane_width >= CLIPPED_PLANE_MIN_VALID &&
> > +	    plane_x <= hdisplay - CLIPPED_PLANE_MIN_VALID)
> > +		return false;
> > +
> > +	return true;
> > +}
> > +
> > +static bool
> > +supported_plane_conf(data_t *data, int plane_type, uint64_t tiling,
> > +		     uint32_t format, igt_rotation_t rotation,
> > +		     drmModeModeInfo *mode,
> > +		     int plane_x, int plane_y, int plane_size)
> > +{
> > +	if (intel_gen(data->devid) < 9 &&
> > +	    tiling != LOCAL_DRM_FORMAT_MOD_NONE)
> > +		return false;
> > +
> > +	/* On GEN<9 the primary plane must cover the full screen. */
> > +	if (intel_gen(data->devid) < 9 &&
> > +	    plane_type == DRM_PLANE_TYPE_PRIMARY &&
> > +	    (plane_x > 0 || plane_y > 0 ||
> > +	     (plane_x + plane_size < mode->hdisplay) ||
> > +	     (plane_y + plane_size < mode->vdisplay)))
> > +		return false;
> > +
> > +	if (plane_type == DRM_PLANE_TYPE_CURSOR) {
> > +		/* For cursor planes only linear/alpha format is supported. */
> > +		if (tiling != LOCAL_DRM_FORMAT_MOD_NONE ||
> > +		    format != DRM_FORMAT_ARGB8888)
> > +			return false;
> > +
> > +		if (plane_size > data->max_curw || plane_size > data->max_curh)
> > +			return false;
> > +	} else {
> > +		/*
> > +		 * For non-cursor planes formats with alpha may result in
> > +		 * undeterministic CRCs, we use the same sized
> > +		 * non-alpha XRGB8888 format instead.
> > +		 */
> > +		if (format == DRM_FORMAT_ARGB8888)
> > +			return false;
> > +
> > +		if (format == DRM_FORMAT_RGB565 &&
> > +		    intel_gen(data->devid) < 9 &&
> > +		    !IS_VALLEYVIEW(data->devid) && !IS_CHERRYVIEW(data->devid))
> > +			return false;
> > +	}
> > +
> > +	/* RGB565 with rotation is not supported for now. */
> > +	if (format == DRM_FORMAT_RGB565 && rotation != IGT_ROTATION_0)
> > +		return false;
> > +
> > +	return true;
> > +}
> > +
> > +/*
> > + * Create a square reference FB for the whole screen in the clipping test,
> > + * with the given test plane position and size. See
> > + * create_fb_for_mode__clipping_plane() for the layout of the test plane.
> > + */
> > +static void
> > +create_fb_for_mode__clipping_display(data_t *data, drmModeModeInfo *mode,
> > +				     square_t *clip_squares,
> > +				     int plane_cnt,
> > +				     struct igt_fb *fb /* out */)
> > +{
> > +	int plane;
> > +	struct igt_fb plane_fbs[4];
> > +	unsigned int fb_id;
> > +	cairo_t *cr;
> > +	cairo_surface_t *srcs[4];
> > +
> > +	fb_id = igt_create_fb(data->drm_fd,
> > +			      mode->hdisplay, mode->vdisplay,
> > +			      DRM_FORMAT_XRGB8888,
> > +			      LOCAL_DRM_FORMAT_MOD_NONE,
> > +			      fb);
> > +	igt_assert(fb_id);
> > +
> > +	cr = igt_get_cairo_ctx(data->drm_fd, fb);
> > +	igt_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay,
> > +			0, 0, 0);
> > +
> > +	for (plane = 0; plane < plane_cnt; plane++) {
> > +		create_fb_for_mode__clipping_plane(data, IGT_ROTATION_0,
> > +						   LOCAL_DRM_FORMAT_MOD_NONE,
> > +						   DRM_FORMAT_XRGB8888,
> > +						   clip_squares[plane].size,
> > +						   &plane_fbs[plane]);
> > +
> > +		srcs[plane] = igt_get_cairo_surface(data->drm_fd,
> > +						   &plane_fbs[plane]);
> > +		cairo_set_source_surface(cr, srcs[plane],
> > +					 clip_squares[plane].x,
> > +					 clip_squares[plane].y);
> > +		cairo_rectangle(cr,
> > +				clip_squares[plane].x,
> > +				clip_squares[plane].y,
> > +				clip_squares[plane].size,
> > +				clip_squares[plane].size);
> > +		cairo_fill(cr);
> > +	}
> > +
> > +	igt_assert(cairo_status(cr) == 0);
> > +	cairo_destroy(cr);
> > +
> > +	for (plane = 0; plane < plane_cnt; plane++) {
> > +		cairo_surface_destroy(srcs[plane]);
> > +		igt_remove_fb(data->drm_fd, &plane_fbs[plane]);
> > +	}
> > +}
> > +
> > +static void
> > +test_plane_clipping_format(data_t *data,
> > +			   enum pipe pipe,
> > +			   igt_output_t *output,
> > +			   drmModeModeInfo *mode,
> > +			   square_t *clip_squares,
> > +			   int plane_cnt,
> > +			   uint64_t tiling,
> > +			   igt_rotation_t rotation,
> > +			   uint32_t format,
> > +			   igt_crc_t *reference_crc)
> > +{
> > +	int plane;
> > +	igt_plane_t *plane_objs[4];
> > +	struct igt_fb plane_fbs[4];
> > +	igt_crc_t crc;
> > +	int ret;
> > +	bool bogus_planes = false;
> > +
> > +	memset(plane_objs, 0, sizeof(plane_objs));
> > +
> > +	igt_debug("rotation %s tiling %s format %s\n",
> > +		  igt_rotation_degrees_str(rotation),
> > +		  igt_tiling_str(tiling),
> > +		  igt_format_str(format));
> > +
> > +	igt_output_set_pipe(output, pipe);
> > +
> > +	for (plane = 0; plane < plane_cnt ; plane++) {
> > +		igt_plane_t *obj = igt_output_get_plane(output, plane);
> > +		struct igt_fb *fb = &plane_fbs[plane];
> > +		int x = clip_squares[plane].x;
> > +		int y = clip_squares[plane].y;
> > +		int size = clip_squares[plane].size;
> > +		uint64_t _tiling = tiling;
> > +		uint32_t _format = format;
> > +
> > +		if (obj->type == DRM_PLANE_TYPE_CURSOR) {
> > +			_tiling = LOCAL_DRM_FORMAT_MOD_NONE;
> > +			_format = DRM_FORMAT_ARGB8888;
> > +		}
> > +
> > +		if (!supported_plane_conf(data, obj->type, _tiling, _format,
> > +					  rotation, mode, x, y, size))
> > +			goto out;
> > +
> > +		create_fb_for_mode__clipping_plane(data, rotation,_tiling,
> > +						   _format, size, fb);
> > +
> > +		igt_plane_set_fb(obj, fb);
> > +		igt_fb_set_position(fb, obj, 0, 0);
> > +
> > +		igt_plane_set_size(obj, size, size);
> > +		igt_plane_set_rotation(obj, rotation);
> > +		igt_plane_set_position(obj, x, y);
> > +
> > +		plane_objs[plane] = obj;
> > +	}
> > +
> > +	/*
> > +	 * Note that a universal commit doesn't support full modesets, so we
> > +	 * have to make sure that the following only needs to commit changes
> > +	 * that are compatible with a fastset. This should be guaranteed,
> > +	 * since before calling this function we took the reference CRC which
> > +	 * left the display enabled with the mode we require here and
> > +	 * afterwards we only change plane parameters (FB, position, rotation
> > +	 * etc.).
> > +	 */
> > +	ret = igt_display_try_commit2(&data->display, COMMIT_UNIVERSAL);
> > +
> > +	for (plane = 0; plane < plane_cnt; plane++) {
> > +		if(!bogus_plane_conf(data->devid, plane_objs[plane],
> > +				     mode->hdisplay, clip_squares[plane].x,
> > +				     clip_squares[plane].size)) {
> 
> Putting that function call into the if looks a bit funny, I'd put it
> outside.

To clarify: All the above comments are imo nice-to-have improvements, best
done in follow-up patches.
 
Only thing that must be fixed before merging is that testcases actually
pass.
-Daniel

> I also looked at your results:
> 
> https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_1813/shards-all.html
> 
> (Yes you need to know to replace shards.html with shards-all.html). Your
> new testcases are failing, so there's a bug somewhere. Need to get that
> fixed first.
> 
> -Daniel
> > +			bogus_planes = true;
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (bogus_planes) {
> > +		igt_assert(ret == 0);
> > +		igt_pipe_crc_collect_crc(data->pipe_crc, &crc);
> > +		igt_assert_crc_equal(reference_crc, &crc);
> > +	} else {
> > +		igt_assert(ret == -ERANGE);
> > +	}
> > +
> > +out:
> > +	for (plane = 0; plane < plane_cnt; plane++) {
> > +		if (!plane_objs[plane])
> > +			continue;
> > +		igt_plane_set_fb(plane_objs[plane], NULL);
> > +		igt_plane_set_rotation(plane_objs[plane], IGT_ROTATION_0);
> > +		igt_plane_set_position(plane_objs[plane], 0, 0);
> > +
> > +		igt_remove_fb(data->drm_fd, &plane_fbs[plane]);
> > +	}
> > +
> > +	igt_output_set_pipe(output, PIPE_ANY);
> > +}
> > +
> > +static void
> > +test_plane_clipping_square(data_t *data, enum pipe pipe,
> > +			   igt_output_t *output, drmModeModeInfo *mode,
> > +			   square_t *clip_squares, int plane_cnt)
> > +{
> > +	const struct {
> > +		uint64_t tiling;
> > +		igt_rotation_t rotation;
> > +	} rotations[] = {
> > +		{ LOCAL_DRM_FORMAT_MOD_NONE,		IGT_ROTATION_0 },
> > +
> > +		{ LOCAL_I915_FORMAT_MOD_X_TILED,	IGT_ROTATION_0 },
> > +
> > +		{ LOCAL_I915_FORMAT_MOD_Y_TILED,	IGT_ROTATION_0 },
> > +		{ LOCAL_I915_FORMAT_MOD_Y_TILED,	IGT_ROTATION_90 },
> > +		{ LOCAL_I915_FORMAT_MOD_Y_TILED,	IGT_ROTATION_180 },
> > +		{ LOCAL_I915_FORMAT_MOD_Y_TILED,	IGT_ROTATION_270 },
> > +
> > +		{ LOCAL_I915_FORMAT_MOD_Yf_TILED,	IGT_ROTATION_0 },
> > +		{ LOCAL_I915_FORMAT_MOD_Yf_TILED,	IGT_ROTATION_90 },
> > +		{ LOCAL_I915_FORMAT_MOD_Yf_TILED,	IGT_ROTATION_180 },
> > +		{ LOCAL_I915_FORMAT_MOD_Yf_TILED,	IGT_ROTATION_270 },
> > +	};
> > +	const uint32_t formats[] = {
> > +		DRM_FORMAT_RGB565,
> > +		DRM_FORMAT_XRGB8888,
> > +		DRM_FORMAT_ARGB8888,
> > +	};
> > +
> > +	igt_fb_t reference_fb;
> > +	igt_crc_t reference_crc;
> > +
> > +	for (int plane = 0; plane < plane_cnt; plane++) {
> > +		igt_info("Testing connector %s mode %dx%d using pipe %s: %dx%d@%d,%d\n",
> > +			 igt_output_name(output),
> > +			 mode->hdisplay, mode->vdisplay,
> > +			 kmstest_pipe_name(pipe),
> > +			 clip_squares[plane].size, clip_squares[plane].size,
> > +			 clip_squares[plane].x, clip_squares[plane].y);
> > +	}
> > +
> > +	test_init(data, pipe);
> > +
> > +	create_fb_for_mode__clipping_display(data, mode,
> > +					     clip_squares,
> > +					     plane_cnt,
> > +					     &reference_fb);
> > +
> > +	/*
> > +	 * As a test_grab_crc_for_fb() function uses a legacy style commit
> > +	 * which does not allow changing of primary plane rotation on non-first
> > +	 * commit, we call igt_display_reset() to make it as a first commit
> > +	 * prior to call test_grab_crc_for_fb().
> > +	 */
> > +	igt_display_reset(&data->display);
> > +	test_grab_crc_for_fb(data, output, pipe, &reference_fb, &reference_crc);
> > +	igt_remove_fb(data->drm_fd, &reference_fb);
> > +
> > +	for (int rotation = 0; rotation < ARRAY_SIZE(rotations); rotation++)
> > +		for (int format = 0; format < ARRAY_SIZE(formats); format++)
> > +			test_plane_clipping_format(data, pipe, output,
> > +						   mode,
> > +						   clip_squares,
> > +						   plane_cnt,
> > +						   rotations[rotation].tiling,
> > +						   rotations[rotation].rotation,
> > +						   formats[format],
> > +						   &reference_crc);
> > +
> > +	test_fini(data);
> > +}
> > +
> > +static void
> > +test_plane_clipping_squares(data_t *data, enum pipe pipe,
> > +			    igt_output_t *output, drmModeModeInfo *mode,
> > +			    square_t *clip_squares, int plane_cnt)
> > +{
> > +	for (int i = 0; i < 4; i += plane_cnt)
> > +		test_plane_clipping_square(data, pipe, output, mode,
> > +					   clip_squares + i,
> > +					   plane_cnt);
> > +}
> > +
> > +static void
> > +test_plane_clipping(data_t *data, enum pipe pipe)
> > +{
> > +	igt_output_t *output;
> > +	int connected_outs = 0;
> > +
> > +	for_each_valid_output_on_pipe(&data->display, pipe, output) {
> > +		drmModeModeInfo *mode;
> > +		int sq_size;
> > +		int max_planes = data->display.pipes[pipe].n_planes;
> > +		int plane_cnt;
> > +
> > +		plane_cnt = max_planes >= 4 ? 4 : max_planes >= 2 ? 2 : 1;
> > +
> > +		igt_output_set_pipe(output, pipe);
> > +		mode = igt_output_get_mode(output);
> > +
> > +		/*
> > +		 * Test with a square plane bigger than either the width or
> > +		 * height of the mode. This should pass on all platforms.
> > +		 */
> > +		sq_size = mode->hdisplay > mode->vdisplay ?
> > +			  mode->hdisplay : mode->vdisplay;
> > +
> > +		clip_squares[0].x = -2;
> > +		clip_squares[0].y = -2;
> > +		clip_squares[0].size = sq_size + 4;
> > +
> > +		test_plane_clipping_square(data, pipe, output, mode,
> > +					   clip_squares, 1);
> > +
> > +		/*
> > +		 * Test positions in the 4 corners of the screen with a
> > +		 * CLIPPED_PLANE_MIN_VALID x CLIPPED_PLANE_MIN_VALID square
> > +		 * visible from the plane. These should pass on all platforms.
> > +		 */
> > +		clip_squares[0].x = -CLIPPED_PLANE_SMALL_SIZE +
> > +				     CLIPPED_PLANE_MIN_VALID;
> > +		clip_squares[0].y = -CLIPPED_PLANE_SMALL_SIZE +
> > +				     CLIPPED_PLANE_MIN_VALID;
> > +		clip_squares[0].size = CLIPPED_PLANE_SMALL_SIZE;
> > +
> > +		clip_squares[1].x = -CLIPPED_PLANE_SMALL_SIZE +
> > +				     CLIPPED_PLANE_MIN_VALID;
> > +		clip_squares[1].y = mode->vdisplay -
> > +				    CLIPPED_PLANE_MIN_VALID;
> > +		clip_squares[1].size = CLIPPED_PLANE_SMALL_SIZE;
> > +
> > +		clip_squares[2].x = mode->hdisplay -
> > +				    CLIPPED_PLANE_MIN_VALID;
> > +		clip_squares[2].y = -CLIPPED_PLANE_SMALL_SIZE +
> > +				     CLIPPED_PLANE_MIN_VALID;
> > +		clip_squares[2].size = CLIPPED_PLANE_SMALL_SIZE;
> > +
> > +		clip_squares[3].x = mode->hdisplay -
> > +				    CLIPPED_PLANE_MIN_VALID;
> > +		clip_squares[3].y = mode->vdisplay -
> > +				    CLIPPED_PLANE_MIN_VALID;
> > +		clip_squares[3].size = CLIPPED_PLANE_SMALL_SIZE;
> > +
> > +		test_plane_clipping_squares(data, pipe, output, mode,
> > +					    clip_squares, plane_cnt);
> > +
> > +		/*
> > +		 * Test positions in the 4 corners of the screen with a
> > +		 * 2 x 2 square visible from the plane. These are valid on all
> > +		 * platforms except on GLK/CNL where less than
> > +		 * CLIPPED_PLANE_MIN_VALID pixels visible on the left/right
> > +		 * edges of the screen may cause FIFO underflow and display
> > +		 * corruption.
> > +		 *
> > +		 * The cursor plane is an exception without this problem.
> > +		 *
> > +		 * Use 2 x 2 size as other (odd) sizes may result in an
> > +		 * incorrect CRC for the cursor plane even though it displays
> > +		 * correctly and causes no underflow.
> > +		 */
> > +		clip_squares[0].x = -CLIPPED_PLANE_SMALL_SIZE + 2;
> > +		clip_squares[0].y = -CLIPPED_PLANE_SMALL_SIZE + 2;
> > +		clip_squares[0].size = CLIPPED_PLANE_SMALL_SIZE;
> > +
> > +		clip_squares[1].x = -CLIPPED_PLANE_SMALL_SIZE + 2;
> > +		clip_squares[1].y = mode->vdisplay - 2;
> > +		clip_squares[1].size = CLIPPED_PLANE_SMALL_SIZE;
> > +
> > +		clip_squares[2].x = mode->hdisplay - 2;
> > +		clip_squares[2].y = -CLIPPED_PLANE_SMALL_SIZE + 2;
> > +		clip_squares[2].size = CLIPPED_PLANE_SMALL_SIZE;
> > +
> > +		clip_squares[3].x = mode->hdisplay - 2;
> > +		clip_squares[3].y = mode->vdisplay - 2;
> > +		clip_squares[3].size = CLIPPED_PLANE_SMALL_SIZE;
> > +
> > +		test_plane_clipping_squares(data, pipe, output, mode,
> > +					    clip_squares, plane_cnt);
> > +
> > +		connected_outs++;
> > +	}
> > +
> > +	igt_skip_on(connected_outs == 0);
> > +}
> > +
> >  static void
> >  run_tests_for_pipe_plane(data_t *data, enum pipe pipe)
> >  {
> > @@ -581,6 +1081,9 @@ run_tests_for_pipe_plane(data_t *data, enum pipe pipe)
> >  		      kmstest_pipe_name(pipe))
> >  		test_plane_panning(data, pipe, TEST_PANNING_BOTTOM_RIGHT |
> >  					       TEST_SUSPEND_RESUME);
> > +	igt_subtest_f("plane-clipping-pipe-%s-planes",
> > +		      kmstest_pipe_name(pipe))
> > +		test_plane_clipping(data, pipe);
> >  }
> >  
> >  
> > @@ -593,8 +1096,21 @@ igt_main
> >  	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);
> > +
> > +		data.max_curw = 64;
> > +		data.max_curh = 64;
> > +		ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_WIDTH,
> > +				&data.max_curw);
> > +		igt_assert(ret == 0 || errno == EINVAL);
> > +		ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_HEIGHT,
> > +				&data.max_curh);
> > +		igt_assert(ret == 0 || errno == EINVAL);
> > +
> >  		kmstest_set_vt_graphics_mode();
> >  
> >  		igt_require_pipe_crc(data.drm_fd);
> > -- 
> > 2.18.0
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the igt-dev mailing list