[igt-dev] [PATCH i-g-t] tests/kms_available_modes_crc: Test all modes on all planes

Mika Kahola mika.kahola at intel.com
Tue Mar 20 12:45:20 UTC 2018


On Tue, 2018-03-20 at 13:37 +0200, Juha-Pekka Heikkila wrote:
> On 19.03.2018 14:12, Mika Kahola wrote:
> > 
> > On Fri, 2018-03-16 at 15:39 +0200, Juha-Pekka Heikkila wrote:
> > > 
> > > Ask from kernel about supported modes for each plane and try
> > > setting
> > > them on display and verify functionality with crc.
> > > 
> > > DRM_FORMAT_ARGB8888 and DRM_FORMAT_ABGR8888 skip crc testing on
> > > primary and overlay planes because they produce incorrect crcs
> > > from
> > > hardware. DRM_FORMAT_ARGB8888 is tested on cursor plane.
> > > 
> > > Signed-off-by: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
> > > ---
> > >   tests/Makefile.sources          |   1 +
> > >   tests/kms_available_modes_crc.c | 574
> > > ++++++++++++++++++++++++++++++++++++++++
> > >   tests/meson.build               |   1 +
> > >   3 files changed, 576 insertions(+)
> > >   create mode 100644 tests/kms_available_modes_crc.c
> > > 
> > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > index f1d1cba..0622048 100644
> > > --- a/tests/Makefile.sources
> > > +++ b/tests/Makefile.sources
> > > @@ -173,6 +173,7 @@ TESTS_progs = \
> > >   	kms_atomic \
> > >   	kms_atomic_interruptible \
> > >   	kms_atomic_transition \
> > > +	kms_available_modes_crc \
> > >   	kms_busy \
> > >   	kms_ccs \
> > >   	kms_chv_cursor_fail \
> > > diff --git a/tests/kms_available_modes_crc.c
> > > b/tests/kms_available_modes_crc.c
> > > new file mode 100644
> > > index 0000000..9e31346
> > > --- /dev/null
> > > +++ b/tests/kms_available_modes_crc.c
> > > @@ -0,0 +1,574 @@
> > > +/*
> > > + * Copyright © 2018 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 "drm_mode.h"
> > > +#include "drm_fourcc.h"
> > > +#include "igt.h"
> > > +#include <sys/ioctl.h>
> > > +
> > > +IGT_TEST_DESCRIPTION("CRC test all different plane modes which
> > > kernel advertises.");
> > > +
> > > +#define testcrcamount 3
> > Would grabbing just one CRC be enough for this test? Any reason why
> > we
> > would need 3 CRC's?
> It is just magic number after discussing with Ville Syrjälä about it,
> he 
> once mentioned after starting crc first crc may have garbage if it's 
> started in mid-frame.
Maarten made some improvements on igt library routines and now you can
drain the pipe from garbage before reading it. This should clean up the
garbage if you add 'igt_pipe_crc_drain()'. Note, that you don't need
clean up the garbage right after 'igt_pipe_crc_start()'. 

> 
> > 
> >   
> > > 
> > > +
> > > +typedef struct {
> > > +	int gfx_fd;
> > > +	igt_display_t display;
> > > +	enum igt_commit_style commit;
> > > +
> > > +	struct igt_fb fb;
> > > +	struct igt_fb primary_fb;
> > > +
> > > +	char format_name[5];
> > > +	bool separateprimaryplane;
> > > +
> > > +	uint32_t gem_handle;
> > > +	uint32_t gem_handle_yuv;
> > > +	unsigned int size;
> > > +	unsigned char* buf;
> > > +
> > > +	/*
> > > +	 * comparison crcs
> > > +	 */
> > > +	igt_crc_t *cursor_crc;
> > > +	igt_crc_t *fullscreen_crc;
> > > +} data_t;
> > > +
> > > +
> > > +static int do_write(int fd, int handle, void *buf, int offset,
> > > int
> > > size)
> > > +{
> > > +	struct drm_i915_gem_pwrite write;
> > > +	memset(&write, 0x00, sizeof(write));
> > > +	write.handle = handle;
> > > +	write.data_ptr = (uintptr_t)buf;
> > > +	write.size = size;
> > > +	write.offset = offset;
> > > +	return ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &write);
> > > +}
> > > +
> > > +
> > > +static void generate_comparison_crc_list(data_t *data,
> > > igt_output_t
> > > *output,
> > > +					enum pipe pipe)
> > > +{
> > > +	drmModeModeInfo *mode;
> > > +	uint64_t w, h, c;
> > > +	int fbid;
> > > +	cairo_t *cr;
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	igt_plane_t *primary;
> > > +
> > > +
> > > +	igt_output_set_pipe(output, pipe);
> > > +
> > > +	mode = igt_output_get_mode(output);
> > > +	fbid = igt_create_color_fb(data->gfx_fd,
> > > +				   mode->hdisplay,
> > > +				   mode->vdisplay,
> > > +				   intel_gen(intel_get_drm_devid
> > > (dat
> > > a->gfx_fd)) < 9 ? DRM_FORMAT_XRGB8888 : DRM_FORMAT_ARGB8888,
> > > +				   LOCAL_DRM_FORMAT_MOD_NONE,
> > > +				   0, 0, 0,
> > > +				   &data->primary_fb);
> > > +
> > > +	igt_assert(fbid);
> > > +
> > > +	drmGetCap(data->gfx_fd, DRM_CAP_CURSOR_WIDTH, &w);
> > > +	drmGetCap(data->gfx_fd, DRM_CAP_CURSOR_HEIGHT, &h);
> > > +
> > > +	cr = igt_get_cairo_ctx(data->gfx_fd, &data->primary_fb);
> > > +	igt_paint_color(cr, 0, 0, mode->hdisplay, mode-
> > > >vdisplay,
> > > +			    0.0, 0.0, 0.0);
> > > +	igt_paint_color(cr, 0, 0, w, h, 1.0, 1.0, 1.0);
> > > +	igt_assert(cairo_status(cr) == 0);
> > > +
> > > +	primary = igt_output_get_plane_type(output,
> > > DRM_PLANE_TYPE_PRIMARY);
> > > +	igt_plane_set_fb(primary, &data->primary_fb);
> > > +	igt_display_commit2(&data->display, data->commit);
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe,
> > > INTEL_PIPE_CRC_SOURCE_AUTO);
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +	c = igt_pipe_crc_get_crcs(pipe_crc, testcrcamount,
> > > &data-
> > > > 
> > > > cursor_crc);
> > If one CRC would be enough, we could utilize Maarten's library
> > routine
> > 'igt_pipe_crc_get_single()'.
> I'll try this and see how it goes.
> 
> > 
> > > 
> > > +	igt_assert(c==testcrcamount);
> > > +	igt_pipe_crc_stop(pipe_crc);
> > I think we could keep crc going and if we are concerned that we may
> > have incorrect one in the pipe, we could drain them with
> > 'igt_igt_pipe_crc_drain()'
> In mid development I tried leaving crc running but it followed lot
> of 
> messages in dmesg about buffer full. I'll retry and see if it is
> still 
> an issue.
> 
> This test run as one single test going through all pipes, planes and 
> modes. I've been thinking if I should divide it in smaller pieces
> but 
> didn't go that way because it would cause there being different
> amount 
> of tests and different tests on different hw.
> 
> > 
> > 
> > > 
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	igt_plane_set_fb(primary, NULL);
> > > +	igt_display_commit2(&data->display, data->commit);
> > > +
> > > +	intel_gen(intel_get_drm_devid(data->gfx_fd)) < 9 ?
> > > +		  igt_paint_color(cr, 0, 0, mode->hdisplay,
> > > mode-
> > > > 
> > > > vdisplay, 1.0, 1.0, 1.0) :
> > > +		  igt_paint_color_alpha(cr, 0, 0, mode-
> > > >hdisplay,
> > > mode->vdisplay, 1.0, 1.0, 1.0, 1.0);
> > > +
> > > +	igt_plane_set_fb(primary, &data->primary_fb);
> > > +	igt_display_commit2(&data->display, data->commit);
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe,
> > > INTEL_PIPE_CRC_SOURCE_AUTO);
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +	c = igt_pipe_crc_get_crcs(pipe_crc, testcrcamount,
> > > &data-
> > > > 
> > > > fullscreen_crc);
> > > +	igt_assert(c==testcrcamount);
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +
> > > +	cairo_destroy(cr);
> > > +	igt_remove_fb(data->gfx_fd, &data->primary_fb);
> > > +}
> > > +
> > > +/*
> > > + * fill_in_fb tell in return value if selected mode should be
> > > + * proceed to crc check
> > > + */
> > > +static bool fill_in_fb(data_t *data, igt_output_t *output, enum
> > > pipe
> > > pipe,
> > > +			 igt_plane_t *plane, uint32_t format)
> > > +{
> > > +	signed i, c, writesize;
> > > +	unsigned short* ptemp_16_buf;
> > > +	unsigned int* ptemp_32_buf;
> > > +
> > > +	const struct {
> > > +		uint32_t	fourcc;
> > > +		char		zeropadding;
> > > +		enum		{ BYTES_PP_1=1,
> > > +				  BYTES_PP_2=2,
> > > +				  BYTES_PP_4=4,
> > > +				  NV12,
> > > +#if defined(DRM_FORMAT_P010) || defined(DRM_FORMAT_P012) ||
> > > defined(DRM_FORMAT_P016)
> > > +				  P010,
> > > +#endif
> > > +				  SKIP } bpp;
> > > +		uint32_t	value;
> > > +	} fillers[] = {
> > > +		{ DRM_FORMAT_C8, 0, BYTES_PP_1, 0xff},
> > > +		{ DRM_FORMAT_RGB565, 0, BYTES_PP_2, 0xffff},
> > > +		{ DRM_FORMAT_XRGB8888, 0, BYTES_PP_4,
> > > 0xffffffff},
> > > +		{ DRM_FORMAT_XBGR8888, 0, BYTES_PP_4,
> > > 0xffffffff},
> > > +
> > > +		/*
> > > +		 * following two are skipped because blending
> > > seems
> > > to work
> > > +		 * incorrectly with exception of AR24 on cursor
> > > plane.
> > > +		 * Test still creates the planes, just filling
> > > plane
> > > +		 * and getting crc is skipped.
> > > +		 */
> > > +		{ DRM_FORMAT_ARGB8888, 0, SKIP, 0xffffffff},
> > > +		{ DRM_FORMAT_ABGR8888, 0, SKIP, 0x00ffffff},
> > > +
> > > +		{ DRM_FORMAT_XRGB2101010, 0, BYTES_PP_4,
> > > 0xffffffff},
> > > +		{ DRM_FORMAT_XBGR2101010, 0, BYTES_PP_4,
> > > 0xffffffff},
> > > +
> > > +		{ DRM_FORMAT_YUYV, 0, BYTES_PP_4, 0x80eb80eb},
> > > +		{ DRM_FORMAT_YVYU, 0, BYTES_PP_4, 0x80eb80eb},
> > > +		{ DRM_FORMAT_VYUY, 0, BYTES_PP_4, 0xeb80eb80},
> > > +		{ DRM_FORMAT_UYVY, 0, BYTES_PP_4, 0xeb80eb80},
> > > +
> > > +		/*
> > > +		 * (semi-)planar formats
> > > +		 */
> > > +		{ DRM_FORMAT_NV12, 0, NV12, 0x80eb},
> > > +#ifdef DRM_FORMAT_P010
> > > +		{ DRM_FORMAT_P010, 0, P010, 0x8000eb00},
> > > +#endif
> > > +#ifdef DRM_FORMAT_P012
> > > +		{ DRM_FORMAT_P012, 0, P010, 0x8000eb00},
> > > +#endif
> > > +#ifdef DRM_FORMAT_P016
> > > +		{ DRM_FORMAT_P016, 0, P010, 0x8000eb00},
> > > +#endif
> > > +		{ 0, 0, 0, 0 }
> > > +	};
> > > +
> > > +	for( i = 0; fillers[i].fourcc != 0; i++ ) {
> > > +		if( fillers[i].fourcc == format )
> > > +			break;
> > > +	}
> > > +
> > > +	switch (fillers[i].bpp) {
> > > +	case BYTES_PP_4:
> > > +		ptemp_32_buf = (unsigned int*)data->buf;
> > > +		for (c = 0; c < data->size/4; c++)
> > > +			ptemp_32_buf[c] = fillers[i].value;
> > > +		writesize = data->size;
> > > +		break;
> > > +	case BYTES_PP_2:
> > > +		ptemp_16_buf = (unsigned short*)data->buf;
> > > +		for (c = 0; c < data->size/2; c++)
> > > +			ptemp_16_buf[c] = (unsigned
> > > short)fillers[i].value;
> > > +		writesize = data->size;
> > > +		break;
> > > +	case BYTES_PP_1:
> > > +		memset((void*)data->buf, fillers[i].value, data-
> > > > 
> > > > size);
> > > +		writesize = data->size;
> > > +		break;
> > > +	case NV12:
> > > +		memset((void*)data->buf, fillers[i].value&0xff,
> > > +		       data->size);
> > > +
> > > +		memset((void*)(data->buf+data->size),
> > > +		       (fillers[i].value>>8)&0xff, data-
> > > >size/2);
> > > +
> > > +		writesize = data->size+data->size/2;
> > > +		break;
> > > +#if defined(DRM_FORMAT_P010) || defined(DRM_FORMAT_P012) ||
> > > defined(DRM_FORMAT_P016)
> > > +	case P010:
> > > +		ptemp_16_buf = (unsigned short*)data->buf;
> > > +		for (c = 0; c < data->size/2; c++)
> > > +			ptemp_16_buf[c] = (unsigned
> > > short)fillers[i].value&0xffff;
> > > +
> > > +		ptemp_16_buf = (unsigned short*)(data->buf+data-
> > > > 
> > > > size);
> > > +		for (c = 0; c < data->size/2; c++)
> > > +			ptemp_16_buf[c] = (unsigned
> > > short)(fillers[i].value>>16)&0xffff;
> > > +
> > > +		writesize = data->size+data->size/2;
> > > +		break;
> > > +#endif
> > > +	case SKIP:
> > > +		if (fillers[i].fourcc == DRM_FORMAT_ARGB8888 &&
> > > +		    plane->type == DRM_PLANE_TYPE_CURSOR) {
> > > +		/*
> > > +		 * special for cursor plane where blending works
> > > correctly.
> > > +		 */
> > > +			ptemp_32_buf = (unsigned int*)data->buf;
> > > +			for (c = 0; c < data->size/4; c++)
> > > +				ptemp_32_buf[c] =
> > > fillers[i].value;
> > > +			writesize = data->size;
> > > +			break;
> > > +		}
> > > +		igt_info("Format %s CRC comparison skipped by
> > > design.\n",
> > > +			 (char*)&fillers[i].fourcc);
> > > +
> > > +		return false;
> > > +	default:
> > > +		igt_info("Unsupported mode for test %s\n",
> > > +			 (char*)&fillers[i].fourcc);
> > > +		return false;
> > > +	}
> > > +
> > > +	do_write(data->gfx_fd, data->gem_handle, (void*)data-
> > > >buf,
> > > 0,
> > > +		 writesize);
> > > +
> > > +	return true;
> > > +}
> > > +
> > > +
> > > +static bool setup_fb(data_t *data, igt_output_t *output, enum
> > > pipe
> > > pipe,
> > > +		     igt_plane_t *plane, uint32_t format)
> > > +{
> > > +	drmModeModeInfo *mode;
> > > +	uint64_t w, h;
> > > +	signed ret, gemsize = 0;
> > > +	unsigned tile_width, tile_height, stride;
> > > +	uint32_t offsets[4] = {};
> > > +	uint32_t* offsetpointer = NULL;
> > > +
> > > +	mode = igt_output_get_mode(output);
> > > +	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
> > > +		w = mode->hdisplay ;
> > > +		h = mode->vdisplay;
> > > +	} else {
> > > +		drmGetCap(data->gfx_fd, DRM_CAP_CURSOR_WIDTH,
> > > &w);
> > > +		drmGetCap(data->gfx_fd, DRM_CAP_CURSOR_HEIGHT,
> > > &h);
> > > +	}
> > > +
> > > +	switch(format) {
> > > +#ifdef DRM_FORMAT_P010
> > > +	case DRM_FORMAT_P010:
> > > +#endif
> > > +#ifdef DRM_FORMAT_P012
> > > +	case DRM_FORMAT_P012:
> > > +#endif
> > > +#ifdef DRM_FORMAT_P016
> > > +	case DRM_FORMAT_P016:
> > > +#endif
> > > +#if defined(DRM_FORMAT_P010) || defined(DRM_FORMAT_P012) ||
> > > defined(DRM_FORMAT_P016)
> > > +		tile_width = 512;
> > > +		tile_height = 8;
> > > +
> > > +		stride = ALIGN(w*2, tile_width);
> > > +		data->size = offsets[1] = stride*ALIGN(h,
> > > tile_height);
> > > +
> > > +		gemsize = data->size*2;
> > > +		offsetpointer = (uint32_t*)&offsets;
> > > +		break;
> > > +#endif
> > > +	case DRM_FORMAT_NV12:
> > > +		tile_width = 512;
> > > +		tile_height = 8;
> > The minimum height is 16 for NV12. This has been discussed in this
> > patch
> > 
> > https://patchwork.freedesktop.org/patch/208171/
> > 
> Thanks, I'll fix. I did this test on top of Vidya's set submitted on 
> feb22 where it still was 8. Same issue will apply for Pxxx formats.
> 
> > 
> > 
> > > 
> > > +
> > > +		stride = ALIGN(w, tile_width);
> > > +		data->size = offsets[1] = stride*ALIGN(h,
> > > tile_height);
> > > +
> > > +		gemsize = data->size*2;
> > > +		offsetpointer = (uint32_t*)&offsets;
> > > +		break;
> > > +	default:
> > > +		tile_width = 512;
> > > +		tile_height = 8;
> > > +
> > > +		/*
> > > +		 * w*4 so there's enough space
> > > +		 */
> > > +		stride = ALIGN(w*4, tile_width);
> > > +		data->size = stride*ALIGN(h, tile_height);
> > > +		offsetpointer = NULL;
> > > +
> > > +		gemsize = data->size;
> > > +		break;
> > > +	}
> > > +
> > > +	data->gem_handle = gem_create(data->gfx_fd, gemsize);
> > > +	ret = __gem_set_tiling(data->gfx_fd, data->gem_handle,
> > > +			       I915_TILING_NONE, stride);
> > > +
> > > +	igt_assert_eq(ret, 0);
> > > +
> > > +	ret = __kms_addfb(data->gfx_fd, data->gem_handle, w, h,
> > > +			  stride, format,
> > > LOCAL_DRM_FORMAT_MOD_NONE,
> > > +			  offsetpointer,
> > > LOCAL_DRM_MODE_FB_MODIFIERS,
> > > +			  &data->fb.fb_id);
> > > +
> > > +	if(ret < 0) {
> > > +		igt_info("Creating fb for format %s failed,
> > > return
> > > code %d\n",
> > > +			 (char*)&data->format_name, ret);
> > > +
> > > +		return false;
> > > +	}
> > > +
> > > +	data->fb.width = w;
> > > +	data->fb.height = h;
> > > +	data->fb.gem_handle = data->gem_handle;
> > > +	return true;
> > > +}
> > > +
> > > +
> > > +static void remove_fb(data_t* data, igt_output_t* output,
> > > igt_plane_t* plane)
> > > +{
> > > +	if (data->separateprimaryplane) {
> > > +		igt_plane_t* primary =
> > > igt_output_get_plane_type(output,
> > > +								
> > >  DRM
> > > _PLANE_TYPE_PRIMARY);
> > > +		igt_plane_set_fb(primary, NULL);
> > > +		igt_remove_fb(data->gfx_fd, &data->primary_fb);
> > > +		igt_display_commit2(&data->display, data-
> > > >commit);
> > > +		data->separateprimaryplane = false;
> > > +	}
> > > +
> > > +	igt_remove_fb(data->gfx_fd, &data->fb);
> > > +	igt_display_commit2(&data->display, data->commit);
> > > +	free(data->buf);
> > > +	data->buf = NULL;
> > > +}
> > > +
> > > +
> > > +static bool prepare_crtc(data_t *data, igt_output_t *output,
> > > enum
> > > pipe pipe,
> > > +			 igt_plane_t *plane, uint32_t format)
> > > +{
> > > +	drmModeModeInfo *mode;
> > > +	igt_plane_t *primary;
> > > +
> > > +	if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
> > > +		mode = igt_output_get_mode(output);
> > > +		igt_create_color_fb(data->gfx_fd,
> > > +				    mode->hdisplay, mode-
> > > >vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    LOCAL_DRM_FORMAT_MOD_NONE,
> > > +				    0, 0, 0,
> > > +				    &data->primary_fb);
> > > +
> > > +		primary = igt_output_get_plane_type(output,
> > > +						    DRM_PLANE_TY
> > > PE_P
> > > RIMARY);
> > > +
> > > +		igt_plane_set_fb(primary, &data->primary_fb);
> > > +		igt_display_commit2(&data->display, data-
> > > >commit);
> > > +		data->separateprimaryplane = true;
> > > +	}
> > > +
> > > +	if (!setup_fb(data, output, pipe, plane, format))
> > > +		return false;
> > > +
> > > +	if (data->buf != NULL) {
> > > +		free((void*)data->buf);
> > > +		data->buf = NULL;
> > > +	}
> > > +
> > > +	data->buf = (unsigned char*)calloc(data->size*2, 1);
> > > +	return true;
> > > +}
> > > +
> > > +
> > > +static int
> > > +test_one_mode(data_t* data, igt_output_t *output, igt_plane_t*
> > > plane,
> > > +	      enum pipe pipe, int mode)
> > > +{
> > > +
> > > +	igt_crc_t *crcs = NULL;
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	signed count, rVal = 0;
> > > +	bool do_crc;
> > > +	char* crccompare[2];
> > > +
> > > +	if (prepare_crtc(data, output, pipe, plane, mode)){
> > > +
> > > +		/*
> > > +		 * we have fb from prepare_crtc(..) so now fill
> > > it
> > > in
> > > +		 * correctly in fill_in_fb(..)
> > > +		 */
> > > +		do_crc = fill_in_fb(data, output, pipe, plane,
> > > mode);
> > > +
> > > +		igt_plane_set_fb(plane, &data->fb);
> > > +		igt_fb_set_size(&data->fb, plane, data-
> > > >fb.width,
> > > data->fb.height);
> > > +		igt_plane_set_size(plane, data->fb.width, data-
> > > > 
> > > > fb.height);
> > > +		igt_fb_set_position(&data->fb, plane, 0, 0);
> > > +		igt_display_commit2(&data->display, data-
> > > >commit);
> > > +
> > > +		if (do_crc) {
> > > +			pipe_crc = igt_pipe_crc_new(data-
> > > >gfx_fd,
> > > pipe,
> > > +						    INTEL_PIPE_C
> > > RC_S
> > > OURCE_AUTO);
> > > +
> > > +			igt_pipe_crc_start(pipe_crc);
> > > +
> > > +			count = igt_pipe_crc_get_crcs(pipe_crc,
> > > testcrcamount, &crcs);
> > > +			igt_assert( count==testcrcamount );
> > > +
> > > +			igt_pipe_crc_stop(pipe_crc);
> > > +			igt_pipe_crc_free(pipe_crc);
> > > +
> > > +			if (plane->type !=
> > > DRM_PLANE_TYPE_CURSOR) {
> > > +				if
> > > (!igt_check_crc_equal(&crcs[testcrcamount-1],
> > > +					&data-
> > > > 
> > > > fullscreen_crc[testcrcamount-1])) {
> > > +					crccompare[0] =
> > > igt_crc_to_string(&crcs[testcrcamount-1]);
> > > +					crccompare[1] =
> > > igt_crc_to_string(&data->fullscreen_crc[testcrcamount-1]);
> > > +					igt_warn("crc mismatch.
> > > target %.8s, result %.8s.\n", crccompare[0], crccompare[1]);
> > > +					free(crccompare[0]);
> > > +					free(crccompare[1]);
> > > +					rVal++;
> > > +				}
> > > +			} else {
> > > +				if
> > > (!igt_check_crc_equal(&crcs[testcrcamount-1],
> > > +					&data-
> > > > 
> > > > cursor_crc[testcrcamount-1])) {
> > > +					crccompare[0] =
> > > igt_crc_to_string(&crcs[testcrcamount-1]);
> > > +					crccompare[1] =
> > > igt_crc_to_string(&data->cursor_crc[testcrcamount-1]);
> > > +					igt_warn("crc mismatch.
> > > target %.8s, result %.8s.\n", crccompare[0], crccompare[1]);
> > > +					free(crccompare[0]);
> > > +					free(crccompare[1]);
> > > +					rVal++;
> > > +				}
> > > +			}
> > > +			free(crcs);
> > > +		}
> > > +		remove_fb(data, output, plane);
> > > +		return rVal;
> > > +	}
> > > +	return 1;
> > > +}
> > > +
> > > +
> > > +static void
> > > +test_available_modes(data_t* data)
> > > +{
> > > +	igt_output_t *output;
> > > +	igt_plane_t *plane;
> > > +	int* u32ptr_formats;
> > > +	int modeindex;
> > > +	enum pipe pipe;
> > > +	struct drm_mode_get_plane one_plane = {};
> > > +	int invalids = 0;
> > > +
> > > +	char planetype[3][8] = {"OVERLAY\0", "PRIMARY\0",
> > > "CURSOR\0"
> > > };
> > > +
> > > +	for_each_pipe_with_valid_output(&data->display, pipe,
> > > output) {
> > > +		igt_output_set_pipe(output, pipe);
> > > +
> > > +		/*
> > > +		 * regenerate comparison crcs for each pipe just
> > > in
> > > case.
> > > +		 */
> > > +		generate_comparison_crc_list(data, output,
> > > pipe);
> > > +
> > > +		for_each_plane_on_pipe(&data->display, pipe,
> > > plane)
> > > {
> > > +			memset((void*)&one_plane, 0,
> > > +			       sizeof(struct
> > > drm_mode_get_plane));
> > > +			one_plane.plane_id = plane->drm_plane-
> > > > 
> > > > plane_id;
> > > +			/*
> > > +			 * first call to know how much space
> > > needed,
> > > +			 * second call to get list of supported
> > > modes.
> > > +			 */
> > > +			igt_ioctl(data->gfx_fd,
> > > DRM_IOCTL_MODE_GETPLANE,
> > > +				  &one_plane);
> > > +			igt_assert(one_plane.count_format_types
> > > >
> > > 0);
> > > +
> > > +			u32ptr_formats =
> > > (int*)calloc(one_plane.count_format_types,
> > > +						      sizeof(int
> > > ));
> > > +
> > > +			one_plane.format_type_ptr =
> > > (__u64)u32ptr_formats;
> > > +			igt_ioctl(data->gfx_fd,
> > > DRM_IOCTL_MODE_GETPLANE,
> > > +				  &one_plane);
> > > +
> > > +			for (modeindex = 0;
> > > +			     modeindex <
> > > one_plane.count_format_types;
> > > +			     modeindex++) {
> > > +				data->format_name[0] =
> > > u32ptr_formats[modeindex]&0xff;
> > > +				data->format_name[1] =
> > > (u32ptr_formats[modeindex]>>8)&0xff;
> > > +				data->format_name[2] =
> > > (u32ptr_formats[modeindex]>>16)&0xff;
> > > +				data->format_name[3] =
> > > (u32ptr_formats[modeindex]>>24)&0xff;
> > > +
> > > +				igt_info("Testing connector %s
> > > using
> > > pipe %s" \
> > > +					 " plane index %d type
> > > %s
> > > mode %s\n",
> > > +					 igt_output_name(output)
> > > ,
> > > +					 kmstest_pipe_name(pipe)
> > > ,
> > > +					 plane->index,
> > > +					 planetype[plane->type],
> > > +					 (char*)&data-
> > > >format_name);
> > > +
> > > +				invalids += test_one_mode(data,
> > > output,
> > > +							  plane,
> > > pipe,
> > > +							  u32ptr
> > > _for
> > > mats[modeindex]);
> > > +			}
> > > +			free((void*)one_plane.format_type_ptr);
> > > +		}
> > > +		free(data->cursor_crc);
> > > +		free(data->fullscreen_crc);
> > > +	}
> > > +	igt_assert(invalids == 0);
> > > +}
> > > +
> > > +
> > > +igt_main
> > > +{
> > > +	data_t data = {};
> > > +
> > > +	igt_skip_on_simulation();
> > > +
> > > +	igt_fixture {
> > > +		data.gfx_fd =
> > > drm_open_driver_master(DRIVER_INTEL);
> > > +		kmstest_set_vt_graphics_mode();
> > > +
> > > +		igt_display_init(&data.display, data.gfx_fd);
> > > +
> > > +		igt_require_pipe_crc(data.gfx_fd);
> > > +	}
> > > +
> > > +	data.commit = data.display.is_atomic ? COMMIT_ATOMIC :
> > > COMMIT_LEGACY;
> > > +
> > > +	igt_subtest("available_mode_test_crc") {
> > > +		test_available_modes(&data);
> > > +	}
> > > +
> > > +	igt_fixture {
> > > +		kmstest_restore_vt_mode();
> > > +		igt_display_fini(&data.display);
> > > +	}
> > > +}
> > > diff --git a/tests/meson.build b/tests/meson.build
> > > index 22e4ac9..6a5bd96 100644
> > > --- a/tests/meson.build
> > > +++ b/tests/meson.build
> > > @@ -150,6 +150,7 @@ test_progs = [
> > >   	'kms_atomic',
> > >   	'kms_atomic_interruptible',
> > >   	'kms_atomic_transition',
> > > +	'kms_available_modes_crc',
> > >   	'kms_busy',
> > >   	'kms_ccs',
> > >   	'kms_chv_cursor_fail',
-- 
Mika Kahola - Intel OTC



More information about the igt-dev mailing list