On Wed, Sep 30, 2020 at 01:31:50PM -0400, Lyude wrote: > From: Lyude Paul <lyude@xxxxxxxxxx> > > 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@xxxxxxxxxx> > --- > .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. _______________________________________________ Nouveau mailing list Nouveau@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/nouveau