[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