Hi, On 04/05/16 13:10, Maarten Lankhorst wrote: > Add some tests to BAT to ensure rmfb/lastclose handling doesn't break again. > > The test will set framebuffers on each crtc, and then try rmfb or close. > Afterwards it rechecks to make sure the framebuffers are removed. > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com> > --- > diff --git a/tests/Makefile.sources b/tests/Makefile.sources > index b73f48d95568..92c84d697ded 100644 > --- a/tests/Makefile.sources > +++ b/tests/Makefile.sources > @@ -97,6 +97,7 @@ TESTS_progs_M = \ > kms_plane \ > kms_psr_sink_crc \ > kms_render \ > + kms_rmfb_basic \ > kms_rotation_crc \ > kms_setmode \ > kms_universal_plane \ > diff --git a/tests/kms_rmfb_basic.c b/tests/kms_rmfb_basic.c > new file mode 100644 > index 000000000000..a3fde9f43788 > --- /dev/null > +++ b/tests/kms_rmfb_basic.c > @@ -0,0 +1,180 @@ > +/* > + * Copyright © 2016 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > DEALINGS > + * IN THE SOFTWARE. > + */ > + > +#include "igt.h" > +#include "drmtest.h" > +#include <errno.h> > +#include <stdbool.h> > +#include <stdio.h> > +#include <string.h> > +#include <time.h> > + > +#ifndef DRM_CAP_CURSOR_WIDTH > +#define DRM_CAP_CURSOR_WIDTH 0x8 > +#endif > +#ifndef DRM_CAP_CURSOR_HEIGHT > +#define DRM_CAP_CURSOR_HEIGHT 0x9 > +#endif > + > +struct rmfb_data { > + int drm_fd; > + igt_display_t display; > +}; > + > +/* > + * 1. Set primary plane to a known fb. > + * 2. Make sure getcrtc returns the correct fb id. > + * 3. Call rmfb on the fb. > + * 4. Make sure getcrtc returns 0 fb id. > + * > + * RMFB is supposed to free the framebuffers from any and all planes, > + * so test this and make sure it works. > + */ > +static bool > +test_rmfb(struct rmfb_data *data, igt_output_t *output, enum pipe pipe, bool > reopen) > +{ > + struct igt_fb fb, argb_fb; > + drmModeModeInfo *mode; > + igt_plane_t *plane; > + drmModeCrtc *crtc; > + uint64_t cursor_width, cursor_height; > + > + igt_output_set_pipe(output, pipe); > + igt_display_commit(&data->display); > + > + if (!output->valid) { > + igt_output_set_pipe(output, PIPE_ANY); > + return false; > + } > + > + mode = igt_output_get_mode(output); > + > + igt_create_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, > + DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE, &fb); > + > + igt_create_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, > + DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE, &argb_fb); > + > + do_or_die(drmGetCap(data->drm_fd, DRM_CAP_CURSOR_WIDTH, &cursor_width)); > + if (cursor_width > mode->hdisplay) > + cursor_width = mode->hdisplay; > + > + do_or_die(drmGetCap(data->drm_fd, DRM_CAP_CURSOR_HEIGHT, > &cursor_height)); > + if (cursor_height > mode->vdisplay) > + cursor_height = mode->vdisplay; > + > + /* > + * Make sure these buffers are suited for display use > + * because most of the modeset operations must be fast > + * later on. > + */ > + for_each_plane_on_pipe(&data->display, pipe, plane) { > + if (plane->is_cursor) { > + igt_plane_set_fb(plane, &argb_fb); > + igt_fb_set_size(&argb_fb, plane, cursor_width, > cursor_height); > + igt_plane_set_size(plane, cursor_width, cursor_height); > + } else { > + igt_plane_set_fb(plane, &fb); > + } > + } > + > + igt_display_commit2(&data->display, data->display.is_atomic ? > COMMIT_ATOMIC : COMMIT_UNIVERSAL); > + > + crtc = drmModeGetCrtc(data->drm_fd, output->config.crtc->crtc_id); > + > + igt_assert_eq(crtc->buffer_id, fb.fb_id); > + > + drmModeFreeCrtc(crtc); > + > + if (reopen) { > + close(data->drm_fd); > + > + data->drm_fd = drm_open_driver_master(DRIVER_ANY); > + drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, > 1); > + drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ATOMIC, 1); > + } else { > + igt_remove_fb(data->drm_fd, &fb); > + igt_remove_fb(data->drm_fd, &argb_fb); > + } > + > + crtc = drmModeGetCrtc(data->drm_fd, output->config.crtc->crtc_id); > + > + igt_assert_eq(crtc->buffer_id, 0); > + > + drmModeFreeCrtc(crtc); > + > + for_each_plane_on_pipe(&data->display, pipe, plane) { > + drmModePlanePtr planeres = drmModeGetPlane(data->drm_fd, > plane->drm_plane->plane_id); > + > + igt_assert_eq(planeres->fb_id, 0); > + > + drmModeFreePlane(planeres); > + } > + > + igt_output_set_pipe(output, PIPE_ANY); > + igt_display_commit2(&data->display, data->display.is_atomic ? > COMMIT_ATOMIC : COMMIT_UNIVERSAL); > + > + return true; > +} > + > +static void > +run_rmfb_test(struct rmfb_data *data, bool reopen) > +{ > + igt_output_t *output; > + int valid_tests = 0; > + enum pipe pipe; > + > + for_each_connected_output(&data->display, output) { > + for_each_pipe(&data->display, pipe) { > + if (test_rmfb(data, output, pipe, reopen)) > + valid_tests++;
This test seems like a good candidate to do only one pipe per crtc, since it would be BAT. Alternatively, have basic-rmfb-ioctl and rmfb-ioctl subtests (and close) where the former does one (first valid?), and the other do all combos. This is something I proposed for other modesetting tests recently as well. Regards, Tvrtko > + } > + } > + > + igt_require_f(valid_tests, "no valid crtc/connector combinations > found\n"); > +} > + > +igt_main > +{ > + struct rmfb_data data = {}; > + > + igt_skip_on_simulation(); > + > + igt_fixture { > + data.drm_fd = drm_open_driver_master(DRIVER_ANY); > + > + kmstest_set_vt_graphics_mode(); > + > + igt_display_init(&data.display, data.drm_fd); > + } > + > + igt_subtest_f("rmfb-ioctl") > + run_rmfb_test(&data, false); > + > + igt_subtest_f("close-fd") > + run_rmfb_test(&data, true); > + > + igt_fixture { > + igt_display_fini(&data.display); > + } > +} > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx >