[igt-dev] [PATCH i-g-t v5 5/5] tests: Add nouveau-crc tests
Jeremy Cline
jcline at redhat.com
Wed Sep 30 18:32:19 UTC 2020
On Wed, Sep 30, 2020 at 01:31:50PM -0400, Lyude wrote:
> From: Lyude Paul <lyude at redhat.com>
>
> We're finally getting CRC support in nouveau, so let's start testing
> this in igt as well! While the normal CRC capture tests are nice,
> there's a number of Nvidia-specific hardware characteristics that we
> need to test as well.
>
> The most important one is known as a "notifier context flip". Basically,
> Nvidia GPUs store generated CRCs in an allocated memory region, referred
> to as the notifier context, that the driver programs itself. Strangely,
> this region can only hold a limited number of CRC entries, and once it
> runs out of available entries the hardware simply sets an overrun bit
> and stops writing any new CRC entries.
>
> Since igt-gpu-tools doesn't really have an expectation of only being
> able to grab a limited number of CRCs, we work around this in nouveau by
> allocating two separate CRC notifier regions each time we start
> capturing CRCs, and then flip between them whenever we get close to
> filling our currently programmed notifier context. While this keeps the
> number of CRC entries we lose to an absolute minimum, we are guaranteed
> to lose exactly one CRC entry between context flips. Thus, we add some
> tests to ensure that nouveau handles these flips correctly
> (pipe-[A-F]-ctx-flip-detection), and that igt itself is also able to
> handle them correctly (pipe-[A-F]-ctx-flip-skip-current-frame). Since
> these tests use a debugfs interface to manually control the notifier
> context flip threshold, we also add one test to ensure that any flip
> thresholds we set are cleared after a single CRC capture
> (ctx-flip-threshold-reset-after-capture).
>
> In addition, we also add some simple tests to test Nvidia-specific CRC
> sources.
>
> Changes since v4:
> * Don't clear the currently set display pipe at the end of each iteration of
> pipe tests, otherwise we'll accidentally leave ourselves with no configured
> CRTCs when the test exits. Instead clear it at the start of each iteration of
> pipe tests but only if we just finished testing a different pipe.
> * Get rid of outdated comment about test_ctx_flip_detection() being limited to a
> single pipe
> * Clarify comments describing guarding against CRC collisions in
> test_ctx_flip_detection()
> * Make a small doc blurb for test_ctx_flip_detection(), it's a rather unusual
> and nvidia-specific behavior
> * Mention in test_ctx_flip_detection() that we also explicitly check that we've
> skipped -exactly- one frame. tl;dr more then one frame is too slow, less then
> one frame means a context flip just didn't happen when it should have.
> * Also check that the flip threshold we set in
> test_ctx_flip_threshold_reset_after_capture() isn't ignored by the driver
> * s/(create|destroy)_colors()/\1_crc_colors/g
> Changes since v3:
> * Update .gitlab-ci.yml to make nouveau exempt from the test-list-diff
> test, since all the cool kids are doing it and we don't care about
> autotools for nouveau
> Changes since v2:
> * Fix missing include in tests/nouveau_crc.c, this should fix builds for
> aarch64
> Changes since v1:
> * Fix copyright year in nouveau_crc.c
>
> Signed-off-by: Lyude Paul <lyude at redhat.com>
> ---
> .gitlab-ci.yml | 2 +-
> lib/drmtest.c | 10 ++
> lib/drmtest.h | 2 +
> tests/meson.build | 1 +
> tests/nouveau_crc.c | 414 ++++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 428 insertions(+), 1 deletion(-)
> create mode 100644 tests/nouveau_crc.c
>
> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
> index d7fdbfde..e226d9d7 100644
> --- a/.gitlab-ci.yml
> +++ b/.gitlab-ci.yml
> @@ -241,7 +241,7 @@ test:test-list-diff:
> - build:tests-debian-autotools
> - build:tests-debian-meson
> stage: test
> - script: diff <(sed "s/ /\n/g" meson-test-list.txt| grep -v 'vc4\|v3d\|panfrost' | sort) <(sed "s/ /\n/g" autotools-test-list.txt | sort)
> + script: diff <(sed "s/ /\n/g" meson-test-list.txt| grep -v 'vc4\|v3d\|panfrost\|nouveau' | sort) <(sed "s/ /\n/g" autotools-test-list.txt | sort)
>
> test:list-undocumented-tests:
> dependencies:
> diff --git a/lib/drmtest.c b/lib/drmtest.c
> index c732d1dd..447f5435 100644
> --- a/lib/drmtest.c
> +++ b/lib/drmtest.c
> @@ -114,6 +114,11 @@ bool is_i915_device(int fd)
> return __is_device(fd, "i915");
> }
>
> +bool is_nouveau_device(int fd)
> +{
> + return __is_device(fd, "nouveau");
> +}
> +
> bool is_vc4_device(int fd)
> {
> return __is_device(fd, "vc4");
> @@ -622,6 +627,11 @@ void igt_require_intel(int fd)
> igt_require(is_i915_device(fd));
> }
>
> +void igt_require_nouveau(int fd)
> +{
> + igt_require(is_nouveau_device(fd));
> +}
> +
> void igt_require_vc4(int fd)
> {
> igt_require(is_vc4_device(fd));
> diff --git a/lib/drmtest.h b/lib/drmtest.h
> index c56bfafa..dd4cd384 100644
> --- a/lib/drmtest.h
> +++ b/lib/drmtest.h
> @@ -96,10 +96,12 @@ int __drm_open_driver_render(int chipset);
>
> void igt_require_amdgpu(int fd);
> void igt_require_intel(int fd);
> +void igt_require_nouveau(int fd);
> void igt_require_vc4(int fd);
>
> bool is_amdgpu_device(int fd);
> bool is_i915_device(int fd);
> +bool is_nouveau_device(int fd);
> bool is_vc4_device(int fd);
>
> /**
> diff --git a/tests/meson.build b/tests/meson.build
> index 515f7528..32f011e9 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -76,6 +76,7 @@ test_progs = [
> 'kms_vrr',
> 'kms_writeback',
> 'meta_test',
> + 'nouveau_crc',
> 'panfrost_get_param',
> 'panfrost_gem_new',
> 'panfrost_prime',
> diff --git a/tests/nouveau_crc.c b/tests/nouveau_crc.c
> new file mode 100644
> index 00000000..f8705b5e
> --- /dev/null
> +++ b/tests/nouveau_crc.c
> @@ -0,0 +1,414 @@
> +/*
> + * Copyright © 2020 Red Hat Inc.
> + *
> + * 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 <fcntl.h>
> +#include "igt.h"
> +#include "igt_sysfs.h"
> +
> +IGT_TEST_DESCRIPTION(
> +"Tests certain aspects of CRC capture that are exclusive to nvidia hardware, "
> +"such as context flipping.");
> +
> +typedef struct {
> + int pipe;
> + int drm_fd;
> + int nv_crc_dir;
> + igt_display_t display;
> + igt_output_t *output;
> + igt_plane_t *primary;
> + drmModeModeInfo *mode;
> + igt_fb_t default_fb;
> +} data_t;
> +
> +struct color_fb {
> + double r, g, b;
> + igt_crc_t crc;
> + igt_fb_t fb;
> +};
> +
> +#define HEX_COLOR(r_, g_, b_) \
> + { .r = (r_ / 255.0), .g = (g_ / 255.0), .b = (b_ / 255.0) }
> +
> +static void set_crc_flip_threshold(data_t *data, unsigned int threshold)
> +{
> + igt_debug("Setting CRC notifier flip threshold to %d\n", threshold);
> + igt_assert_lt(0, igt_sysfs_printf(data->nv_crc_dir, "flip_threshold", "%d", threshold));
> +}
> +
> +/* Initialize each color_fb along with its respective CRC */
> +static void create_crc_colors(data_t *data,
> + struct color_fb *colors,
> + size_t len,
> + igt_pipe_crc_t *pipe_crc)
> +{
> + char *crc_str;
> +
> + igt_pipe_crc_start(pipe_crc);
> +
> + for (int i = 0; i < len; i++) {
> + igt_create_color_fb(data->drm_fd,
> + data->mode->hdisplay,
> + data->mode->vdisplay,
> + DRM_FORMAT_XRGB8888,
> + LOCAL_DRM_FORMAT_MOD_NONE,
> + colors[i].r, colors[i].g, colors[i].b,
> + &colors[i].fb);
> +
> + igt_plane_set_fb(data->primary, &colors[i].fb);
> + igt_display_commit(&data->display);
> + igt_pipe_crc_get_current(data->drm_fd, pipe_crc, &colors[i].crc);
> +
> + crc_str = igt_crc_to_string(&colors[i].crc);
> + igt_debug("CRC for frame %d of pattern: %s\n",
> + i, crc_str);
> + free(crc_str);
> + }
> +
> + igt_pipe_crc_stop(pipe_crc);
> +}
> +
> +static void destroy_crc_colors(data_t *data, struct color_fb *colors, size_t len)
> +{
> + /* So we don't turn off the pipe if we remove it's current fb */
> + igt_plane_set_fb(data->primary, &data->default_fb);
> +
> + for (int i = 0; i < len; i++)
> + igt_remove_fb(data->drm_fd, &colors[i].fb);
> +}
> +
> +/*
> + * Nvidia GPUs store CRCs in a limited memory tregion called the CRC notifier context. When this
s/tregion/region/. Not sure it's worth the email traffic required to fix
it, though.
More information about the igt-dev
mailing list