[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