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

Daniel Vetter daniel at ffwll.ch
Fri Sep 14 08:56:05 UTC 2018


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.

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


More information about the igt-dev mailing list