All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH i-g-t v3 0/5] Add nouveau-crc tests
@ 2020-04-17 21:10 ` Lyude
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Nouveau has finally gotten CRC support, hooray! Well, it's under review
at least:

https://patchwork.freedesktop.org/series/74804/
(it has a cover letter, but nouveau's mailing list configuration has
blocked the email so I'm waiting for a moderator to fix that)

So, this series adds the relevant tests for it since nvidia's CRC
implementation has some rather interesting design choices that needed to
be worked around.

Changes since v2:
* Fix build errors on mips/arm/aarch64
Changes since v1:
* fix documentation errors Petri pointed out
* Fix documentation for igt_require_fd()
* Fix copyright year in tests/nouveau_crc.c

Lyude Paul (5):
  lib/igt_core: Fix igt_assert_fd() documentation
  lib/igt_core: Add igt_require_fd()
  lib/igt_debugfs: Add igt_debugfs_pipe_dir()
  lib/igt_kms: Hook up connector dithering prop
  tests: Add nouveau-crc tests

 lib/drmtest.c       |  10 ++
 lib/drmtest.h       |   2 +
 lib/igt_core.h      |  16 +-
 lib/igt_debugfs.c   |  29 ++++
 lib/igt_debugfs.h   |   1 +
 lib/igt_kms.c       |   6 +
 lib/igt_kms.h       |   1 +
 tests/meson.build   |   1 +
 tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 461 insertions(+), 2 deletions(-)
 create mode 100644 tests/nouveau_crc.c

-- 
2.25.1

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [igt-dev] [PATCH i-g-t v3 0/5] Add nouveau-crc tests
@ 2020-04-17 21:10 ` Lyude
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau, igt-dev

From: Lyude Paul <lyude@redhat.com>

Nouveau has finally gotten CRC support, hooray! Well, it's under review
at least:

https://patchwork.freedesktop.org/series/74804/
(it has a cover letter, but nouveau's mailing list configuration has
blocked the email so I'm waiting for a moderator to fix that)

So, this series adds the relevant tests for it since nvidia's CRC
implementation has some rather interesting design choices that needed to
be worked around.

Changes since v2:
* Fix build errors on mips/arm/aarch64
Changes since v1:
* fix documentation errors Petri pointed out
* Fix documentation for igt_require_fd()
* Fix copyright year in tests/nouveau_crc.c

Lyude Paul (5):
  lib/igt_core: Fix igt_assert_fd() documentation
  lib/igt_core: Add igt_require_fd()
  lib/igt_debugfs: Add igt_debugfs_pipe_dir()
  lib/igt_kms: Hook up connector dithering prop
  tests: Add nouveau-crc tests

 lib/drmtest.c       |  10 ++
 lib/drmtest.h       |   2 +
 lib/igt_core.h      |  16 +-
 lib/igt_debugfs.c   |  29 ++++
 lib/igt_debugfs.h   |   1 +
 lib/igt_kms.c       |   6 +
 lib/igt_kms.h       |   1 +
 tests/meson.build   |   1 +
 tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 461 insertions(+), 2 deletions(-)
 create mode 100644 tests/nouveau_crc.c

-- 
2.25.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH i-g-t v3 1/5] lib/igt_core: Fix igt_assert_fd() documentation
  2020-04-17 21:10 ` [igt-dev] " Lyude
@ 2020-04-17 21:10     ` Lyude
  -1 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

As Petri Latvala pointed out, some of the documentation in this macro is
mistakenly copied from the other igt_assert*() macros. Let's fix that.

Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 lib/igt_core.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/igt_core.h b/lib/igt_core.h
index b97fa2fa..3f69b072 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -966,8 +966,8 @@ void igt_describe_f(const char *fmt, ...);
  *
  * Fails (sub-) test if the given file descriptor is invalid.
  *
- * Like igt_assert(), but displays the values being compared on failure instead
- * of simply printing the stringified expression.
+ * Like igt_assert(), but displays the stringified identifier that was supposed
+ * to contain a valid fd on failure.
  */
 #define igt_assert_fd(fd) \
 	igt_assert_f(fd >= 0, "file descriptor " #fd " failed\n");
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [igt-dev] [PATCH i-g-t v3 1/5] lib/igt_core: Fix igt_assert_fd() documentation
@ 2020-04-17 21:10     ` Lyude
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau, igt-dev

From: Lyude Paul <lyude@redhat.com>

As Petri Latvala pointed out, some of the documentation in this macro is
mistakenly copied from the other igt_assert*() macros. Let's fix that.

Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 lib/igt_core.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/igt_core.h b/lib/igt_core.h
index b97fa2fa..3f69b072 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -966,8 +966,8 @@ void igt_describe_f(const char *fmt, ...);
  *
  * Fails (sub-) test if the given file descriptor is invalid.
  *
- * Like igt_assert(), but displays the values being compared on failure instead
- * of simply printing the stringified expression.
+ * Like igt_assert(), but displays the stringified identifier that was supposed
+ * to contain a valid fd on failure.
  */
 #define igt_assert_fd(fd) \
 	igt_assert_f(fd >= 0, "file descriptor " #fd " failed\n");
-- 
2.25.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH i-g-t v3 2/5] lib/igt_core: Add igt_require_fd()
  2020-04-17 21:10 ` [igt-dev] " Lyude
@ 2020-04-17 21:10     ` Lyude
  -1 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Like igt_assert_fd(), but using igt_require() instead

Changes since v1:
* Fix documentation error in igt_require_fd() - Petri Latvala

Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 lib/igt_core.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/lib/igt_core.h b/lib/igt_core.h
index 3f69b072..8f68b2dd 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -1021,6 +1021,18 @@ void igt_describe_f(const char *fmt, ...);
 	else igt_debug("Test requirement passed: %s\n", #expr); \
 } while (0)
 
+/**
+ * igt_require_fd:
+ * @fd: file descriptor
+ *
+ * Skips (sub-) test if the given file descriptor is invalid.
+ *
+ * Like igt_require(), but displays the stringified identifier that was supposed
+ * to contain a valid fd on failure.
+ */
+#define igt_require_fd(fd) \
+	igt_require_f(fd >= 0, "file descriptor " #fd " failed\n");
+
 /**
  * igt_skip_on_f:
  * @expr: condition to test
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [igt-dev] [PATCH i-g-t v3 2/5] lib/igt_core: Add igt_require_fd()
@ 2020-04-17 21:10     ` Lyude
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau, igt-dev

From: Lyude Paul <lyude@redhat.com>

Like igt_assert_fd(), but using igt_require() instead

Changes since v1:
* Fix documentation error in igt_require_fd() - Petri Latvala

Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 lib/igt_core.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/lib/igt_core.h b/lib/igt_core.h
index 3f69b072..8f68b2dd 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -1021,6 +1021,18 @@ void igt_describe_f(const char *fmt, ...);
 	else igt_debug("Test requirement passed: %s\n", #expr); \
 } while (0)
 
+/**
+ * igt_require_fd:
+ * @fd: file descriptor
+ *
+ * Skips (sub-) test if the given file descriptor is invalid.
+ *
+ * Like igt_require(), but displays the stringified identifier that was supposed
+ * to contain a valid fd on failure.
+ */
+#define igt_require_fd(fd) \
+	igt_require_f(fd >= 0, "file descriptor " #fd " failed\n");
+
 /**
  * igt_skip_on_f:
  * @expr: condition to test
-- 
2.25.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH i-g-t v3 3/5] lib/igt_debugfs: Add igt_debugfs_pipe_dir()
  2020-04-17 21:10 ` [igt-dev] " Lyude
@ 2020-04-17 21:10     ` Lyude
  -1 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Like igt_debugfs_connector_dir(), but for pipes instead.

Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 lib/igt_debugfs.c | 29 +++++++++++++++++++++++++++++
 lib/igt_debugfs.h |  1 +
 2 files changed, 30 insertions(+)

diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
index bf6be552..3c3b11e1 100644
--- a/lib/igt_debugfs.c
+++ b/lib/igt_debugfs.c
@@ -260,6 +260,35 @@ int igt_debugfs_connector_dir(int device, char *conn_name, int mode)
 	return ret;
 }
 
+/**
+ * igt_debugfs_pipe_dir:
+ * @device: fd of the device
+ * @pipe: index of pipe
+ * @mode: mode bits as used by open()
+ *
+ * This opens the debugfs directory corresponding to the pipe index on the
+ * device for use with igt_sysfs_get() and related functions.
+ *
+ * Returns:
+ * The directory fd, or -1 on failure.
+ */
+int igt_debugfs_pipe_dir(int device, int pipe, int mode)
+{
+	char buf[128];
+	int dir, ret;
+
+	dir = igt_debugfs_dir(device);
+	if (dir < 0)
+		return dir;
+
+	snprintf(buf, sizeof(buf), "crtc-%d", pipe);
+	ret = openat(dir, buf, mode);
+
+	close(dir);
+
+	return ret;
+}
+
 /**
  * igt_debugfs_open:
  * @filename: name of the debugfs node to open
diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
index 7d1a6175..15741a40 100644
--- a/lib/igt_debugfs.h
+++ b/lib/igt_debugfs.h
@@ -36,6 +36,7 @@ char *igt_debugfs_path(int device, char *path, int pathlen);
 
 int igt_debugfs_dir(int device);
 int igt_debugfs_connector_dir(int device, char *conn_name, int mode);
+int igt_debugfs_pipe_dir(int device, int pipe, int mode);
 
 int igt_debugfs_open(int fd, const char *filename, int mode);
 void __igt_debugfs_read(int fd, const char *filename, char *buf, int size);
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [igt-dev] [PATCH i-g-t v3 3/5] lib/igt_debugfs: Add igt_debugfs_pipe_dir()
@ 2020-04-17 21:10     ` Lyude
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau, igt-dev

From: Lyude Paul <lyude@redhat.com>

Like igt_debugfs_connector_dir(), but for pipes instead.

Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 lib/igt_debugfs.c | 29 +++++++++++++++++++++++++++++
 lib/igt_debugfs.h |  1 +
 2 files changed, 30 insertions(+)

diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
index bf6be552..3c3b11e1 100644
--- a/lib/igt_debugfs.c
+++ b/lib/igt_debugfs.c
@@ -260,6 +260,35 @@ int igt_debugfs_connector_dir(int device, char *conn_name, int mode)
 	return ret;
 }
 
+/**
+ * igt_debugfs_pipe_dir:
+ * @device: fd of the device
+ * @pipe: index of pipe
+ * @mode: mode bits as used by open()
+ *
+ * This opens the debugfs directory corresponding to the pipe index on the
+ * device for use with igt_sysfs_get() and related functions.
+ *
+ * Returns:
+ * The directory fd, or -1 on failure.
+ */
+int igt_debugfs_pipe_dir(int device, int pipe, int mode)
+{
+	char buf[128];
+	int dir, ret;
+
+	dir = igt_debugfs_dir(device);
+	if (dir < 0)
+		return dir;
+
+	snprintf(buf, sizeof(buf), "crtc-%d", pipe);
+	ret = openat(dir, buf, mode);
+
+	close(dir);
+
+	return ret;
+}
+
 /**
  * igt_debugfs_open:
  * @filename: name of the debugfs node to open
diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
index 7d1a6175..15741a40 100644
--- a/lib/igt_debugfs.h
+++ b/lib/igt_debugfs.h
@@ -36,6 +36,7 @@ char *igt_debugfs_path(int device, char *path, int pathlen);
 
 int igt_debugfs_dir(int device);
 int igt_debugfs_connector_dir(int device, char *conn_name, int mode);
+int igt_debugfs_pipe_dir(int device, int pipe, int mode);
 
 int igt_debugfs_open(int fd, const char *filename, int mode);
 void __igt_debugfs_read(int fd, const char *filename, char *buf, int size);
-- 
2.25.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH i-g-t v3 4/5] lib/igt_kms: Hook up connector dithering prop
  2020-04-17 21:10 ` [igt-dev] " Lyude
@ 2020-04-17 21:10     ` Lyude
  -1 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Nvidia display hardware provides a set of flexible dithering options for
CRTCs. This dithering is actually noticeable in the CRC output for all
available tap points, and can be seen as CRC values for identical frames
cycling between either 2 or 4 values repeatedly (each one of these
values is a different dithering phase applied to the source output). Of
course, this is very likely to break tests using CRC readback since we
don't expect the CRC to change if the source content hasn't changed.

So, hook up support for configuring the dithering property and reset it
to off from igt_display_reset() when applicable.

Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 lib/igt_kms.c | 6 ++++++
 lib/igt_kms.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index e9621e7e..d45adfaf 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -421,6 +421,7 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
 	[IGT_CONNECTOR_LINK_STATUS] = "link-status",
 	[IGT_CONNECTOR_MAX_BPC] = "max bpc",
 	[IGT_CONNECTOR_HDR_OUTPUT_METADATA] = "HDR_OUTPUT_METADATA",
+	[IGT_CONNECTOR_DITHERING_MODE] = "dithering mode",
 };
 
 /*
@@ -1802,6 +1803,10 @@ static void igt_output_reset(igt_output_t *output)
 	if (igt_output_has_prop(output, IGT_CONNECTOR_HDR_OUTPUT_METADATA))
 		igt_output_set_prop_value(output,
 					  IGT_CONNECTOR_HDR_OUTPUT_METADATA, 0);
+
+	if (igt_output_has_prop(output, IGT_CONNECTOR_DITHERING_MODE))
+		igt_output_set_prop_enum(output, IGT_CONNECTOR_DITHERING_MODE,
+					 "off");
 }
 
 /**
@@ -1816,6 +1821,7 @@ static void igt_output_reset(igt_output_t *output)
  * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
  *   %IGT_CONNECTOR_CONTENT_PROTECTION (if applicable)
  *   %IGT_CONNECTOR_HDR_OUTPUT_METADATA (if applicable)
+ * - %IGT_CONNECTOR_DITHERING_MODE (if applicable)
  * - igt_output_override_mode() to default.
  *
  * For pipes:
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index adca59ac..4899e765 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -127,6 +127,7 @@ enum igt_atomic_connector_properties {
        IGT_CONNECTOR_LINK_STATUS,
        IGT_CONNECTOR_MAX_BPC,
        IGT_CONNECTOR_HDR_OUTPUT_METADATA,
+       IGT_CONNECTOR_DITHERING_MODE,
        IGT_NUM_CONNECTOR_PROPS
 };
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [igt-dev] [PATCH i-g-t v3 4/5] lib/igt_kms: Hook up connector dithering prop
@ 2020-04-17 21:10     ` Lyude
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau, igt-dev

From: Lyude Paul <lyude@redhat.com>

Nvidia display hardware provides a set of flexible dithering options for
CRTCs. This dithering is actually noticeable in the CRC output for all
available tap points, and can be seen as CRC values for identical frames
cycling between either 2 or 4 values repeatedly (each one of these
values is a different dithering phase applied to the source output). Of
course, this is very likely to break tests using CRC readback since we
don't expect the CRC to change if the source content hasn't changed.

So, hook up support for configuring the dithering property and reset it
to off from igt_display_reset() when applicable.

Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 lib/igt_kms.c | 6 ++++++
 lib/igt_kms.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index e9621e7e..d45adfaf 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -421,6 +421,7 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
 	[IGT_CONNECTOR_LINK_STATUS] = "link-status",
 	[IGT_CONNECTOR_MAX_BPC] = "max bpc",
 	[IGT_CONNECTOR_HDR_OUTPUT_METADATA] = "HDR_OUTPUT_METADATA",
+	[IGT_CONNECTOR_DITHERING_MODE] = "dithering mode",
 };
 
 /*
@@ -1802,6 +1803,10 @@ static void igt_output_reset(igt_output_t *output)
 	if (igt_output_has_prop(output, IGT_CONNECTOR_HDR_OUTPUT_METADATA))
 		igt_output_set_prop_value(output,
 					  IGT_CONNECTOR_HDR_OUTPUT_METADATA, 0);
+
+	if (igt_output_has_prop(output, IGT_CONNECTOR_DITHERING_MODE))
+		igt_output_set_prop_enum(output, IGT_CONNECTOR_DITHERING_MODE,
+					 "off");
 }
 
 /**
@@ -1816,6 +1821,7 @@ static void igt_output_reset(igt_output_t *output)
  * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
  *   %IGT_CONNECTOR_CONTENT_PROTECTION (if applicable)
  *   %IGT_CONNECTOR_HDR_OUTPUT_METADATA (if applicable)
+ * - %IGT_CONNECTOR_DITHERING_MODE (if applicable)
  * - igt_output_override_mode() to default.
  *
  * For pipes:
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index adca59ac..4899e765 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -127,6 +127,7 @@ enum igt_atomic_connector_properties {
        IGT_CONNECTOR_LINK_STATUS,
        IGT_CONNECTOR_MAX_BPC,
        IGT_CONNECTOR_HDR_OUTPUT_METADATA,
+       IGT_CONNECTOR_DITHERING_MODE,
        IGT_NUM_CONNECTOR_PROPS
 };
 
-- 
2.25.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH i-g-t v3 5/5] tests: Add nouveau-crc tests
  2020-04-17 21:10 ` [igt-dev] " Lyude
@ 2020-04-17 21:10     ` Lyude
  -1 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Lyude Paul <lyude@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 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@redhat.com>
---
 lib/drmtest.c       |  10 ++
 lib/drmtest.h       |   2 +
 tests/meson.build   |   1 +
 tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 410 insertions(+)
 create mode 100644 tests/nouveau_crc.c

diff --git a/lib/drmtest.c b/lib/drmtest.c
index 1fc39925..53c01754 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -112,6 +112,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");
@@ -537,6 +542,11 @@ void igt_require_intel(int fd)
 	igt_require(is_i915_device(fd) && has_known_intel_chipset(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 632c616b..4937e9d2 100644
--- a/lib/drmtest.h
+++ b/lib/drmtest.h
@@ -97,10 +97,12 @@ void gem_quiescent_gpu(int fd);
 
 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 0bdcfbe4..39f1362e 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -71,6 +71,7 @@ test_progs = [
 	'kms_vblank',
 	'kms_vrr',
 	'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..05c2f4de
--- /dev/null
+++ b/tests/nouveau_crc.c
@@ -0,0 +1,397 @@
+/*
+ * 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));
+}
+
+static void create_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_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);
+}
+
+/* Hard-coded to PIPE_A for now, we don't really need to test this on more then
+ * one head
+ */
+static void test_ctx_flip_detection(data_t *data)
+{
+	struct color_fb colors[] = {
+		HEX_COLOR(0xFF, 0x00, 0x18),
+		HEX_COLOR(0xFF, 0xA5, 0x2C),
+		HEX_COLOR(0xFF, 0xFF, 0x41),
+		HEX_COLOR(0x00, 0x80, 0x18),
+		HEX_COLOR(0x00, 0x00, 0xF9),
+		HEX_COLOR(0x86, 0x00, 0x7D),
+	};
+	igt_output_t *output = data->output;
+	igt_plane_t *primary = data->primary;
+	igt_pipe_crc_t *pipe_crc;
+	const int n_colors = ARRAY_SIZE(colors);
+	const int n_crcs = 20;
+	igt_crc_t *crcs = NULL;
+	int start = -1, frame, start_color = -1, i;
+	bool found_skip = false;
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
+
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	set_crc_flip_threshold(data, n_crcs / 2);
+	igt_pipe_crc_start(pipe_crc);
+
+	for (i = 0; i < n_crcs; i++) {
+		const int color_idx = i % n_colors;
+
+		igt_plane_set_fb(primary, &colors[color_idx].fb);
+		do_or_die(drmModePageFlip(data->drm_fd,
+					  output->config.crtc->crtc_id,
+					  colors[color_idx].fb.fb_id,
+					  DRM_MODE_PAGE_FLIP_EVENT,
+					  NULL));
+		kmstest_wait_for_pageflip(data->drm_fd);
+	}
+
+	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	/*
+	 * Find the first color in our pattern with a CRC that differs from the
+	 * last CRC, so we can use it to find the start of the pattern
+	 */
+	for (i = 0; i < n_colors - 1; i++) {
+		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors - 1].crc))
+			continue;
+
+		igt_debug("Using frame %d of pattern for finding start\n", i);
+		start_color = i;
+		break;
+	}
+	igt_assert_lte(0, start_color);
+
+	/* Now, figure out where the pattern starts */
+	for (i = 0; i < n_crcs; i++) {
+		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
+			continue;
+
+		start = i - start_color;
+		frame = crcs[i].frame;
+		igt_debug("Pattern started on frame %d\n", frame);
+		break;
+	}
+	igt_assert_lte(0, start);
+
+	/* And finally, assert that according to the CRCs exactly all but one
+	 * frame was displayed in order. The missing frame comes from
+	 * (inevitably) losing a single CRC event when nouveau switches notifier
+	 * contexts
+	 */
+	for (i = start; i < n_crcs; i++, frame++) {
+		igt_crc_t *crc = &crcs[i];
+		char *crc_str;
+		int color_idx;
+
+		crc_str = igt_crc_to_string(crc);
+		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
+		free(crc_str);
+
+		if (!found_skip && crc->frame != frame) {
+			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
+				  crc->frame - 1);
+			found_skip = true;
+			frame++;
+		}
+
+		/* We should never skip more then one frame */
+		if (found_skip) {
+			igt_assert_eq(crc->frame, frame);
+			color_idx = (i - start + 1) % n_colors;
+		} else {
+			color_idx = (i - start) % n_colors;
+		}
+
+		igt_assert_crc_equal(crc, &colors[color_idx].crc);
+	}
+	igt_assert(found_skip);
+
+	free(crcs);
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, ARRAY_SIZE(colors));
+}
+
+/* Test whether or not IGT is able to handle frame skips when requesting the
+ * CRC for the current frame
+ */
+static void test_ctx_flip_skip_current_frame(data_t *data)
+{
+	struct color_fb colors[] = {
+		{ .r = 1.0, .g = 0.0, .b = 0.0 },
+		{ .r = 0.0, .g = 1.0, .b = 0.0 },
+		{ .r = 0.0, .g = 0.0, .b = 1.0 },
+	};
+	igt_output_t *output = data->output;
+	igt_pipe_crc_t *pipe_crc;
+	igt_plane_t *primary = data->primary;
+	const int fd = data->drm_fd;
+	const int n_colors = ARRAY_SIZE(colors);
+	const int n_crcs = 30;
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	set_crc_flip_threshold(data, 5);
+	igt_pipe_crc_start(pipe_crc);
+
+	for (int i = 0; i < n_crcs; i++) {
+		igt_crc_t crc;
+		const int color_idx = i % n_colors;
+
+		igt_plane_set_fb(primary, &colors[color_idx].fb);
+		do_or_die(drmModePageFlip(fd,
+					  output->config.crtc->crtc_id,
+					  colors[color_idx].fb.fb_id,
+					  DRM_MODE_PAGE_FLIP_EVENT,
+					  NULL));
+		kmstest_wait_for_pageflip(fd);
+
+		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
+		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
+	}
+
+	igt_pipe_crc_stop(pipe_crc);
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, n_colors);
+}
+
+static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
+{
+	igt_pipe_crc_t *pipe_crc;
+	const int fd = data->drm_fd;
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
+
+	set_crc_flip_threshold(data, 5);
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_stop(pipe_crc);
+
+	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"), 5);
+	igt_pipe_crc_free(pipe_crc);
+}
+
+static void test_source(data_t *data, const char *source)
+{
+	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, source);
+	igt_crc_t *crcs;
+
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	/* The CRC shouldn't change if the source content hasn't changed */
+	igt_assert_crc_equal(&crcs[0], &crcs[1]);
+
+	igt_pipe_crc_free(pipe_crc);
+	free(crcs);
+}
+
+static void test_source_outp_inactive(data_t *data)
+{
+	struct color_fb colors[] = {
+		{ .r = 1.0, .g = 0.0, .b = 0.0 },
+		{ .r = 0.0, .g = 1.0, .b = 0.0 },
+	};
+	igt_pipe_crc_t *pipe_crc;
+	const int fd = data->drm_fd;
+	const int n_colors = ARRAY_SIZE(colors);
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	/* Changing the color should not change what's outside the active raster */
+	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
+
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, n_colors);
+}
+
+data_t data = {0, };
+
+#define pipe_test(name) igt_subtest_f("pipe-%s-" name, kmstest_pipe_name(pipe))
+igt_main
+{
+	int pipe;
+
+	igt_fixture {
+		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
+		igt_require_nouveau(data.drm_fd);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_require_pipe_crc(data.drm_fd);
+		igt_display_require(&data.display, data.drm_fd);
+		igt_display_reset(&data.display);
+	}
+
+	for_each_pipe_static(pipe) {
+		igt_fixture {
+			int dir;
+
+			data.pipe = pipe;
+			igt_display_require_output_on_pipe(&data.display, pipe);
+			data.output = igt_get_single_output_for_pipe(&data.display, pipe);
+			data.mode = igt_output_get_mode(data.output);
+
+			/* None of these tests need to perform modesets,
+			 * just page flips. So running display setup
+			 * here is fine
+			 */
+			igt_output_set_pipe(data.output, pipe);
+			data.primary = igt_output_get_plane(data.output, 0);
+			igt_create_color_fb(data.drm_fd,
+					    data.mode->hdisplay,
+					    data.mode->vdisplay,
+					    DRM_FORMAT_XRGB8888,
+					    LOCAL_DRM_FORMAT_MOD_NONE,
+					    0.0, 0.0, 0.0,
+					    &data.default_fb);
+			igt_plane_set_fb(data.primary, &data.default_fb);
+			igt_display_commit(&data.display);
+
+			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe, O_DIRECTORY);
+			igt_require_fd(dir);
+			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
+			close(dir);
+			igt_require_fd(data.nv_crc_dir);
+		}
+
+		/* We don't need to test this on every pipe, but the
+		 * setup is the same */
+		if (pipe == PIPE_A) {
+			igt_describe("Make sure that the CRC notifier context flip threshold "
+				     "is reset to its default value after a single capture.");
+			igt_subtest("ctx-flip-threshold-reset-after-capture")
+				test_ctx_flip_threshold_reset_after_capture(&data);
+		}
+
+		igt_describe("Make sure the association between each CRC and its "
+			     "respective frame index is not broken when the driver "
+			     "performs a notifier context flip.");
+		pipe_test("ctx-flip-detection")
+			test_ctx_flip_detection(&data);
+
+		igt_describe("Make sure that igt_pipe_crc_get_current() works even "
+			     "when the CRC for the current frame index is lost.");
+		pipe_test("ctx-flip-skip-current-frame")
+			test_ctx_flip_skip_current_frame(&data);
+
+		igt_describe("Check that basic CRC readback using the outp-complete "
+			     "source works.");
+		pipe_test("source-outp-complete")
+			test_source(&data, "outp-complete");
+
+		igt_describe("Check that basic CRC readback using the rg source "
+			     "works.");
+		pipe_test("source-rg")
+			test_source(&data, "rg");
+
+		igt_describe("Make sure that the outp-inactive source is actually "
+			     "capturing the inactive raster.");
+		pipe_test("source-outp-inactive")
+			test_source_outp_inactive(&data);
+
+		igt_fixture {
+			igt_output_set_pipe(data.output, PIPE_NONE);
+			igt_display_commit(&data.display);
+			igt_remove_fb(data.drm_fd, &data.default_fb);
+			close(data.nv_crc_dir);
+		}
+	}
+	igt_fixture
+		igt_display_fini(&data.display);
+
+}
-- 
2.25.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [igt-dev] [PATCH i-g-t v3 5/5] tests: Add nouveau-crc tests
@ 2020-04-17 21:10     ` Lyude
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-04-17 21:10 UTC (permalink / raw)
  To: nouveau, igt-dev

From: Lyude Paul <lyude@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 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@redhat.com>
---
 lib/drmtest.c       |  10 ++
 lib/drmtest.h       |   2 +
 tests/meson.build   |   1 +
 tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 410 insertions(+)
 create mode 100644 tests/nouveau_crc.c

diff --git a/lib/drmtest.c b/lib/drmtest.c
index 1fc39925..53c01754 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -112,6 +112,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");
@@ -537,6 +542,11 @@ void igt_require_intel(int fd)
 	igt_require(is_i915_device(fd) && has_known_intel_chipset(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 632c616b..4937e9d2 100644
--- a/lib/drmtest.h
+++ b/lib/drmtest.h
@@ -97,10 +97,12 @@ void gem_quiescent_gpu(int fd);
 
 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 0bdcfbe4..39f1362e 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -71,6 +71,7 @@ test_progs = [
 	'kms_vblank',
 	'kms_vrr',
 	'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..05c2f4de
--- /dev/null
+++ b/tests/nouveau_crc.c
@@ -0,0 +1,397 @@
+/*
+ * 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));
+}
+
+static void create_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_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);
+}
+
+/* Hard-coded to PIPE_A for now, we don't really need to test this on more then
+ * one head
+ */
+static void test_ctx_flip_detection(data_t *data)
+{
+	struct color_fb colors[] = {
+		HEX_COLOR(0xFF, 0x00, 0x18),
+		HEX_COLOR(0xFF, 0xA5, 0x2C),
+		HEX_COLOR(0xFF, 0xFF, 0x41),
+		HEX_COLOR(0x00, 0x80, 0x18),
+		HEX_COLOR(0x00, 0x00, 0xF9),
+		HEX_COLOR(0x86, 0x00, 0x7D),
+	};
+	igt_output_t *output = data->output;
+	igt_plane_t *primary = data->primary;
+	igt_pipe_crc_t *pipe_crc;
+	const int n_colors = ARRAY_SIZE(colors);
+	const int n_crcs = 20;
+	igt_crc_t *crcs = NULL;
+	int start = -1, frame, start_color = -1, i;
+	bool found_skip = false;
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
+
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	set_crc_flip_threshold(data, n_crcs / 2);
+	igt_pipe_crc_start(pipe_crc);
+
+	for (i = 0; i < n_crcs; i++) {
+		const int color_idx = i % n_colors;
+
+		igt_plane_set_fb(primary, &colors[color_idx].fb);
+		do_or_die(drmModePageFlip(data->drm_fd,
+					  output->config.crtc->crtc_id,
+					  colors[color_idx].fb.fb_id,
+					  DRM_MODE_PAGE_FLIP_EVENT,
+					  NULL));
+		kmstest_wait_for_pageflip(data->drm_fd);
+	}
+
+	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	/*
+	 * Find the first color in our pattern with a CRC that differs from the
+	 * last CRC, so we can use it to find the start of the pattern
+	 */
+	for (i = 0; i < n_colors - 1; i++) {
+		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors - 1].crc))
+			continue;
+
+		igt_debug("Using frame %d of pattern for finding start\n", i);
+		start_color = i;
+		break;
+	}
+	igt_assert_lte(0, start_color);
+
+	/* Now, figure out where the pattern starts */
+	for (i = 0; i < n_crcs; i++) {
+		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
+			continue;
+
+		start = i - start_color;
+		frame = crcs[i].frame;
+		igt_debug("Pattern started on frame %d\n", frame);
+		break;
+	}
+	igt_assert_lte(0, start);
+
+	/* And finally, assert that according to the CRCs exactly all but one
+	 * frame was displayed in order. The missing frame comes from
+	 * (inevitably) losing a single CRC event when nouveau switches notifier
+	 * contexts
+	 */
+	for (i = start; i < n_crcs; i++, frame++) {
+		igt_crc_t *crc = &crcs[i];
+		char *crc_str;
+		int color_idx;
+
+		crc_str = igt_crc_to_string(crc);
+		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
+		free(crc_str);
+
+		if (!found_skip && crc->frame != frame) {
+			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
+				  crc->frame - 1);
+			found_skip = true;
+			frame++;
+		}
+
+		/* We should never skip more then one frame */
+		if (found_skip) {
+			igt_assert_eq(crc->frame, frame);
+			color_idx = (i - start + 1) % n_colors;
+		} else {
+			color_idx = (i - start) % n_colors;
+		}
+
+		igt_assert_crc_equal(crc, &colors[color_idx].crc);
+	}
+	igt_assert(found_skip);
+
+	free(crcs);
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, ARRAY_SIZE(colors));
+}
+
+/* Test whether or not IGT is able to handle frame skips when requesting the
+ * CRC for the current frame
+ */
+static void test_ctx_flip_skip_current_frame(data_t *data)
+{
+	struct color_fb colors[] = {
+		{ .r = 1.0, .g = 0.0, .b = 0.0 },
+		{ .r = 0.0, .g = 1.0, .b = 0.0 },
+		{ .r = 0.0, .g = 0.0, .b = 1.0 },
+	};
+	igt_output_t *output = data->output;
+	igt_pipe_crc_t *pipe_crc;
+	igt_plane_t *primary = data->primary;
+	const int fd = data->drm_fd;
+	const int n_colors = ARRAY_SIZE(colors);
+	const int n_crcs = 30;
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	set_crc_flip_threshold(data, 5);
+	igt_pipe_crc_start(pipe_crc);
+
+	for (int i = 0; i < n_crcs; i++) {
+		igt_crc_t crc;
+		const int color_idx = i % n_colors;
+
+		igt_plane_set_fb(primary, &colors[color_idx].fb);
+		do_or_die(drmModePageFlip(fd,
+					  output->config.crtc->crtc_id,
+					  colors[color_idx].fb.fb_id,
+					  DRM_MODE_PAGE_FLIP_EVENT,
+					  NULL));
+		kmstest_wait_for_pageflip(fd);
+
+		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
+		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
+	}
+
+	igt_pipe_crc_stop(pipe_crc);
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, n_colors);
+}
+
+static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
+{
+	igt_pipe_crc_t *pipe_crc;
+	const int fd = data->drm_fd;
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
+
+	set_crc_flip_threshold(data, 5);
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_stop(pipe_crc);
+
+	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"), 5);
+	igt_pipe_crc_free(pipe_crc);
+}
+
+static void test_source(data_t *data, const char *source)
+{
+	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, source);
+	igt_crc_t *crcs;
+
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	/* The CRC shouldn't change if the source content hasn't changed */
+	igt_assert_crc_equal(&crcs[0], &crcs[1]);
+
+	igt_pipe_crc_free(pipe_crc);
+	free(crcs);
+}
+
+static void test_source_outp_inactive(data_t *data)
+{
+	struct color_fb colors[] = {
+		{ .r = 1.0, .g = 0.0, .b = 0.0 },
+		{ .r = 0.0, .g = 1.0, .b = 0.0 },
+	};
+	igt_pipe_crc_t *pipe_crc;
+	const int fd = data->drm_fd;
+	const int n_colors = ARRAY_SIZE(colors);
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	/* Changing the color should not change what's outside the active raster */
+	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
+
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, n_colors);
+}
+
+data_t data = {0, };
+
+#define pipe_test(name) igt_subtest_f("pipe-%s-" name, kmstest_pipe_name(pipe))
+igt_main
+{
+	int pipe;
+
+	igt_fixture {
+		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
+		igt_require_nouveau(data.drm_fd);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_require_pipe_crc(data.drm_fd);
+		igt_display_require(&data.display, data.drm_fd);
+		igt_display_reset(&data.display);
+	}
+
+	for_each_pipe_static(pipe) {
+		igt_fixture {
+			int dir;
+
+			data.pipe = pipe;
+			igt_display_require_output_on_pipe(&data.display, pipe);
+			data.output = igt_get_single_output_for_pipe(&data.display, pipe);
+			data.mode = igt_output_get_mode(data.output);
+
+			/* None of these tests need to perform modesets,
+			 * just page flips. So running display setup
+			 * here is fine
+			 */
+			igt_output_set_pipe(data.output, pipe);
+			data.primary = igt_output_get_plane(data.output, 0);
+			igt_create_color_fb(data.drm_fd,
+					    data.mode->hdisplay,
+					    data.mode->vdisplay,
+					    DRM_FORMAT_XRGB8888,
+					    LOCAL_DRM_FORMAT_MOD_NONE,
+					    0.0, 0.0, 0.0,
+					    &data.default_fb);
+			igt_plane_set_fb(data.primary, &data.default_fb);
+			igt_display_commit(&data.display);
+
+			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe, O_DIRECTORY);
+			igt_require_fd(dir);
+			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
+			close(dir);
+			igt_require_fd(data.nv_crc_dir);
+		}
+
+		/* We don't need to test this on every pipe, but the
+		 * setup is the same */
+		if (pipe == PIPE_A) {
+			igt_describe("Make sure that the CRC notifier context flip threshold "
+				     "is reset to its default value after a single capture.");
+			igt_subtest("ctx-flip-threshold-reset-after-capture")
+				test_ctx_flip_threshold_reset_after_capture(&data);
+		}
+
+		igt_describe("Make sure the association between each CRC and its "
+			     "respective frame index is not broken when the driver "
+			     "performs a notifier context flip.");
+		pipe_test("ctx-flip-detection")
+			test_ctx_flip_detection(&data);
+
+		igt_describe("Make sure that igt_pipe_crc_get_current() works even "
+			     "when the CRC for the current frame index is lost.");
+		pipe_test("ctx-flip-skip-current-frame")
+			test_ctx_flip_skip_current_frame(&data);
+
+		igt_describe("Check that basic CRC readback using the outp-complete "
+			     "source works.");
+		pipe_test("source-outp-complete")
+			test_source(&data, "outp-complete");
+
+		igt_describe("Check that basic CRC readback using the rg source "
+			     "works.");
+		pipe_test("source-rg")
+			test_source(&data, "rg");
+
+		igt_describe("Make sure that the outp-inactive source is actually "
+			     "capturing the inactive raster.");
+		pipe_test("source-outp-inactive")
+			test_source_outp_inactive(&data);
+
+		igt_fixture {
+			igt_output_set_pipe(data.output, PIPE_NONE);
+			igt_display_commit(&data.display);
+			igt_remove_fb(data.drm_fd, &data.default_fb);
+			close(data.nv_crc_dir);
+		}
+	}
+	igt_fixture
+		igt_display_fini(&data.display);
+
+}
-- 
2.25.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [igt-dev] ✗ GitLab.Pipeline: warning for Add nouveau-crc tests (rev3)
  2020-04-17 21:10 ` [igt-dev] " Lyude
  (?)
  (?)
@ 2020-04-17 23:16 ` Patchwork
  -1 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2020-04-17 23:16 UTC (permalink / raw)
  To: Lyude Paul; +Cc: igt-dev

== Series Details ==

Series: Add nouveau-crc tests (rev3)
URL   : https://patchwork.freedesktop.org/series/74811/
State : warning

== Summary ==

Did not get list of undocumented tests for this run, something is wrong!

Other than that, pipeline status: FAILED.

see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/pipelines/133829 for the overview.

test:test-list-diff has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/2329325):
  Downloading artifacts for build:tests-debian-autotools (2329318)...
  Downloading artifacts from coordinator... ok        id=2329318 responseStatus=200 OK token=4i_2hxzG
  Downloading artifacts for build:tests-debian-meson (2329313)...
  Downloading artifacts from coordinator... ok        id=2329313 responseStatus=200 OK token=6sAFzKxE
  section_end:1587165119:download_artifacts
  section_start:1587165119:build_script
  Running before_script and script
  Authenticating with credentials from job payload (GitLab Registry)
  $ diff <(sed "s/ /\n/g" meson-test-list.txt| grep -v 'vc4\|v3d\|panfrost' | sort) <(sed "s/ /\n/g" autotools-test-list.txt | sort)
  217d216
  < nouveau_crc
  section_end:1587165120:build_script
  section_start:1587165120:after_script
  Running after_script
  section_end:1587165121:after_script
  section_start:1587165121:upload_artifacts_on_failure
  Uploading artifacts for failed job
  section_end:1587165123:upload_artifacts_on_failure
  ERROR: Job failed: exit code 1

== Logs ==

For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/pipelines/133829
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [igt-dev] ✓ Fi.CI.BAT: success for Add nouveau-crc tests (rev3)
  2020-04-17 21:10 ` [igt-dev] " Lyude
                   ` (2 preceding siblings ...)
  (?)
@ 2020-04-17 23:29 ` Patchwork
  -1 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2020-04-17 23:29 UTC (permalink / raw)
  To: Lyude Paul; +Cc: igt-dev

== Series Details ==

Series: Add nouveau-crc tests (rev3)
URL   : https://patchwork.freedesktop.org/series/74811/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8322 -> IGTPW_4485
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/index.html

Known issues
------------

  Here are the changes found in IGTPW_4485 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live@sanitycheck:
    - fi-bwr-2160:        [PASS][1] -> [INCOMPLETE][2] ([i915#489])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/fi-bwr-2160/igt@i915_selftest@live@sanitycheck.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/fi-bwr-2160/igt@i915_selftest@live@sanitycheck.html

  
  [i915#489]: https://gitlab.freedesktop.org/drm/intel/issues/489


Participating hosts (51 -> 45)
------------------------------

  Additional (1): fi-cml-u2 
  Missing    (7): fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-kbl-7560u fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5599 -> IGTPW_4485

  CI-20190529: 20190529
  CI_DRM_8322: fd447e6b1ee13e6a9731bddc7694552640e8a01e @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_4485: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/index.html
  IGT_5599: cdb07101dda33e2fcb0f4c2aa199c47159d88f35 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+igt@nouveau_crc@ctx-flip-threshold-reset-after-capture
+igt@nouveau_crc@pipe-a-ctx-flip-detection
+igt@nouveau_crc@pipe-a-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-a-source-outp-complete
+igt@nouveau_crc@pipe-a-source-outp-inactive
+igt@nouveau_crc@pipe-a-source-rg
+igt@nouveau_crc@pipe-b-ctx-flip-detection
+igt@nouveau_crc@pipe-b-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-b-source-outp-complete
+igt@nouveau_crc@pipe-b-source-outp-inactive
+igt@nouveau_crc@pipe-b-source-rg
+igt@nouveau_crc@pipe-c-ctx-flip-detection
+igt@nouveau_crc@pipe-c-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-c-source-outp-complete
+igt@nouveau_crc@pipe-c-source-outp-inactive
+igt@nouveau_crc@pipe-c-source-rg
+igt@nouveau_crc@pipe-d-ctx-flip-detection
+igt@nouveau_crc@pipe-d-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-d-source-outp-complete
+igt@nouveau_crc@pipe-d-source-outp-inactive
+igt@nouveau_crc@pipe-d-source-rg
+igt@nouveau_crc@pipe-e-ctx-flip-detection
+igt@nouveau_crc@pipe-e-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-e-source-outp-complete
+igt@nouveau_crc@pipe-e-source-outp-inactive
+igt@nouveau_crc@pipe-e-source-rg
+igt@nouveau_crc@pipe-f-ctx-flip-detection
+igt@nouveau_crc@pipe-f-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-f-source-outp-complete
+igt@nouveau_crc@pipe-f-source-outp-inactive
+igt@nouveau_crc@pipe-f-source-rg

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [igt-dev] ✓ Fi.CI.IGT: success for Add nouveau-crc tests (rev3)
  2020-04-17 21:10 ` [igt-dev] " Lyude
                   ` (3 preceding siblings ...)
  (?)
@ 2020-04-19 20:33 ` Patchwork
  -1 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2020-04-19 20:33 UTC (permalink / raw)
  To: Lyude Paul; +Cc: igt-dev

== Series Details ==

Series: Add nouveau-crc tests (rev3)
URL   : https://patchwork.freedesktop.org/series/74811/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8322_full -> IGTPW_4485_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_4485_full:

### IGT changes ###

#### Possible regressions ####

  * {igt@nouveau_crc@pipe-a-source-rg} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][1] +14 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-iclb3/igt@nouveau_crc@pipe-a-source-rg.html

  * {igt@nouveau_crc@pipe-d-ctx-flip-detection} (NEW):
    - shard-tglb:         NOTRUN -> [SKIP][2] +20 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-tglb1/igt@nouveau_crc@pipe-d-ctx-flip-detection.html

  
New tests
---------

  New tests have been introduced between CI_DRM_8322_full and IGTPW_4485_full:

### New IGT tests (21) ###

  * igt@nouveau_crc@ctx-flip-threshold-reset-after-capture:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-ctx-flip-detection:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-ctx-flip-skip-current-frame:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-source-outp-complete:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-source-outp-inactive:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-source-rg:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-ctx-flip-detection:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-ctx-flip-skip-current-frame:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-source-outp-complete:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-source-outp-inactive:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-source-rg:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-ctx-flip-detection:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-ctx-flip-skip-current-frame:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-source-outp-complete:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-source-outp-inactive:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-source-rg:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-ctx-flip-detection:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-ctx-flip-skip-current-frame:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-source-outp-complete:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-source-outp-inactive:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-source-rg:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  

Known issues
------------

  Here are the changes found in IGTPW_4485_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_eio@in-flight-suspend:
    - shard-apl:          [PASS][3] -> [DMESG-WARN][4] ([i915#180])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl7/igt@gem_eio@in-flight-suspend.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl1/igt@gem_eio@in-flight-suspend.html

  * igt@i915_pm_rc6_residency@rc6-idle:
    - shard-snb:          [PASS][5] -> [FAIL][6] ([i915#1066])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-snb6/igt@i915_pm_rc6_residency@rc6-idle.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-snb6/igt@i915_pm_rc6_residency@rc6-idle.html

  * igt@i915_suspend@sysfs-reader:
    - shard-kbl:          [PASS][7] -> [INCOMPLETE][8] ([CI#80] / [i915#155])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl4/igt@i915_suspend@sysfs-reader.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl4/igt@i915_suspend@sysfs-reader.html

  * igt@kms_cursor_crc@pipe-a-cursor-128x128-random:
    - shard-kbl:          [PASS][9] -> [FAIL][10] ([i915#54] / [i915#93] / [i915#95])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl7/igt@kms_cursor_crc@pipe-a-cursor-128x128-random.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl7/igt@kms_cursor_crc@pipe-a-cursor-128x128-random.html

  * igt@kms_cursor_legacy@flip-vs-cursor-legacy:
    - shard-hsw:          [PASS][11] -> [FAIL][12] ([IGT#5])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-hsw6/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-hsw6/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html

  * igt@kms_cursor_legacy@pipe-b-torture-bo:
    - shard-iclb:         [PASS][13] -> [DMESG-WARN][14] ([i915#128])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-iclb6/igt@kms_cursor_legacy@pipe-b-torture-bo.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-iclb1/igt@kms_cursor_legacy@pipe-b-torture-bo.html

  * igt@kms_draw_crc@draw-method-rgb565-mmap-wc-untiled:
    - shard-glk:          [PASS][15] -> [FAIL][16] ([i915#52] / [i915#54]) +3 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-glk5/igt@kms_draw_crc@draw-method-rgb565-mmap-wc-untiled.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-glk1/igt@kms_draw_crc@draw-method-rgb565-mmap-wc-untiled.html

  * igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-untiled:
    - shard-apl:          [PASS][17] -> [FAIL][18] ([fdo#108145] / [i915#52] / [i915#54] / [i915#95])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl8/igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-untiled.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl7/igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-untiled.html

  * igt@kms_draw_crc@draw-method-xrgb8888-pwrite-untiled:
    - shard-kbl:          [PASS][19] -> [FAIL][20] ([i915#177] / [i915#52] / [i915#54] / [i915#93] / [i915#95])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl3/igt@kms_draw_crc@draw-method-xrgb8888-pwrite-untiled.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl7/igt@kms_draw_crc@draw-method-xrgb8888-pwrite-untiled.html
    - shard-apl:          [PASS][21] -> [FAIL][22] ([i915#52] / [i915#54] / [i915#95])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl8/igt@kms_draw_crc@draw-method-xrgb8888-pwrite-untiled.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl2/igt@kms_draw_crc@draw-method-xrgb8888-pwrite-untiled.html

  * igt@kms_flip_tiling@flip-changes-tiling:
    - shard-apl:          [PASS][23] -> [FAIL][24] ([i915#95]) +2 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl2/igt@kms_flip_tiling@flip-changes-tiling.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl8/igt@kms_flip_tiling@flip-changes-tiling.html

  * igt@kms_flip_tiling@flip-changes-tiling-yf:
    - shard-kbl:          [PASS][25] -> [FAIL][26] ([i915#699] / [i915#93] / [i915#95])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl7/igt@kms_flip_tiling@flip-changes-tiling-yf.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl3/igt@kms_flip_tiling@flip-changes-tiling-yf.html

  * igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
    - shard-apl:          [PASS][27] -> [FAIL][28] ([fdo#108145] / [i915#265] / [i915#95])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl2/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl3/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html

  * igt@kms_psr@psr2_cursor_render:
    - shard-iclb:         [PASS][29] -> [SKIP][30] ([fdo#109441]) +1 similar issue
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-iclb2/igt@kms_psr@psr2_cursor_render.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-iclb4/igt@kms_psr@psr2_cursor_render.html

  * igt@kms_setmode@basic:
    - shard-kbl:          [PASS][31] -> [FAIL][32] ([i915#31])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl6/igt@kms_setmode@basic.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl7/igt@kms_setmode@basic.html

  
#### Possible fixes ####

  * igt@gem_eio@in-flight-suspend:
    - shard-kbl:          [INCOMPLETE][33] ([i915#155]) -> [PASS][34] +1 similar issue
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl3/igt@gem_eio@in-flight-suspend.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl4/igt@gem_eio@in-flight-suspend.html

  * igt@gem_workarounds@suspend-resume-context:
    - shard-tglb:         [INCOMPLETE][35] ([i915#456]) -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-tglb7/igt@gem_workarounds@suspend-resume-context.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-tglb8/igt@gem_workarounds@suspend-resume-context.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-glk:          [DMESG-WARN][37] ([i915#716]) -> [PASS][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-glk8/igt@gen9_exec_parse@allowed-all.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-glk1/igt@gen9_exec_parse@allowed-all.html

  * igt@kms_cursor_crc@pipe-a-cursor-128x42-offscreen:
    - shard-apl:          [FAIL][39] ([i915#54] / [i915#95]) -> [PASS][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl6/igt@kms_cursor_crc@pipe-a-cursor-128x42-offscreen.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl6/igt@kms_cursor_crc@pipe-a-cursor-128x42-offscreen.html

  * igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen:
    - shard-kbl:          [FAIL][41] ([i915#54] / [i915#93] / [i915#95]) -> [PASS][42] +2 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl3/igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl3/igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen.html

  * igt@kms_cursor_crc@pipe-b-cursor-alpha-opaque:
    - shard-apl:          [FAIL][43] ([i915#54]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl4/igt@kms_cursor_crc@pipe-b-cursor-alpha-opaque.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl7/igt@kms_cursor_crc@pipe-b-cursor-alpha-opaque.html
    - shard-kbl:          [FAIL][45] ([i915#54]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl2/igt@kms_cursor_crc@pipe-b-cursor-alpha-opaque.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl6/igt@kms_cursor_crc@pipe-b-cursor-alpha-opaque.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic:
    - shard-hsw:          [FAIL][47] ([i915#96]) -> [PASS][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-hsw1/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-hsw1/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html

  * igt@kms_cursor_legacy@cursor-vs-flip-toggle:
    - shard-hsw:          [FAIL][49] ([i915#57]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-hsw1/igt@kms_cursor_legacy@cursor-vs-flip-toggle.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-hsw6/igt@kms_cursor_legacy@cursor-vs-flip-toggle.html

  * igt@kms_draw_crc@draw-method-rgb565-render-ytiled:
    - shard-glk:          [FAIL][51] ([i915#52] / [i915#54]) -> [PASS][52] +2 similar issues
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-glk6/igt@kms_draw_crc@draw-method-rgb565-render-ytiled.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-glk1/igt@kms_draw_crc@draw-method-rgb565-render-ytiled.html

  * {igt@kms_flip@flip-vs-suspend-interruptible@c-dp1}:
    - shard-apl:          [DMESG-WARN][53] ([i915#180]) -> [PASS][54] +3 similar issues
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl3/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl1/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-kbl:          [DMESG-WARN][55] ([i915#180]) -> [PASS][56]
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl4/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_psr@psr2_cursor_mmap_cpu:
    - shard-iclb:         [SKIP][57] ([fdo#109441]) -> [PASS][58] +2 similar issues
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-iclb8/igt@kms_psr@psr2_cursor_mmap_cpu.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-iclb2/igt@kms_psr@psr2_cursor_mmap_cpu.html

  * igt@kms_setmode@basic:
    - shard-apl:          [FAIL][59] ([i915#31]) -> [PASS][60]
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl1/igt@kms_setmode@basic.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl6/igt@kms_setmode@basic.html

  * {igt@perf@polling-parameterized}:
    - shard-tglb:         [FAIL][61] ([i915#1542]) -> [PASS][62]
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-tglb6/igt@perf@polling-parameterized.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-tglb1/igt@perf@polling-parameterized.html

  * {igt@perf@polling-small-buf}:
    - shard-iclb:         [FAIL][63] -> [PASS][64]
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-iclb3/igt@perf@polling-small-buf.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-iclb2/igt@perf@polling-small-buf.html

  * {igt@sysfs_timeslice_duration@timeout@vecs0}:
    - shard-apl:          [FAIL][65] -> [PASS][66]
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl2/igt@sysfs_timeslice_duration@timeout@vecs0.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl3/igt@sysfs_timeslice_duration@timeout@vecs0.html

  
#### Warnings ####

  * igt@kms_plane_alpha_blend@pipe-a-alpha-basic:
    - shard-apl:          [FAIL][67] ([fdo#108145] / [i915#265]) -> [FAIL][68] ([fdo#108145] / [i915#265] / [i915#95])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl3/igt@kms_plane_alpha_blend@pipe-a-alpha-basic.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl2/igt@kms_plane_alpha_blend@pipe-a-alpha-basic.html
    - shard-kbl:          [FAIL][69] ([fdo#108145] / [i915#265]) -> [FAIL][70] ([fdo#108145] / [i915#265] / [i915#93] / [i915#95])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl4/igt@kms_plane_alpha_blend@pipe-a-alpha-basic.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl7/igt@kms_plane_alpha_blend@pipe-a-alpha-basic.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-7efc:
    - shard-kbl:          [FAIL][71] ([fdo#108145] / [i915#265] / [i915#93] / [i915#95]) -> [FAIL][72] ([fdo#108145] / [i915#265])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-kbl2/igt@kms_plane_alpha_blend@pipe-c-alpha-7efc.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-kbl6/igt@kms_plane_alpha_blend@pipe-c-alpha-7efc.html
    - shard-apl:          [FAIL][73] ([fdo#108145] / [i915#265] / [i915#95]) -> [FAIL][74] ([fdo#108145] / [i915#265])
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8322/shard-apl4/igt@kms_plane_alpha_blend@pipe-c-alpha-7efc.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/shard-apl8/igt@kms_plane_alpha_blend@pipe-c-alpha-7efc.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [CI#80]: https://gitlab.freedesktop.org/gfx-ci/i915-infra/issues/80
  [IGT#5]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/5
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [i915#1066]: https://gitlab.freedesktop.org/drm/intel/issues/1066
  [i915#128]: https://gitlab.freedesktop.org/drm/intel/issues/128
  [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
  [i915#155]: https://gitlab.freedesktop.org/drm/intel/issues/155
  [i915#177]: https://gitlab.freedesktop.org/drm/intel/issues/177
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#31]: https://gitlab.freedesktop.org/drm/intel/issues/31
  [i915#456]: https://gitlab.freedesktop.org/drm/intel/issues/456
  [i915#52]: https://gitlab.freedesktop.org/drm/intel/issues/52
  [i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
  [i915#57]: https://gitlab.freedesktop.org/drm/intel/issues/57
  [i915#61]: https://gitlab.freedesktop.org/drm/intel/issues/61
  [i915#699]: https://gitlab.freedesktop.org/drm/intel/issues/699
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#93]: https://gitlab.freedesktop.org/drm/intel/issues/93
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95
  [i915#96]: https://gitlab.freedesktop.org/drm/intel/issues/96


Participating hosts (10 -> 8)
------------------------------

  Missing    (2): pig-skl-6260u pig-glk-j5005 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5599 -> IGTPW_4485
  * Piglit: piglit_4509 -> None

  CI-20190529: 20190529
  CI_DRM_8322: fd447e6b1ee13e6a9731bddc7694552640e8a01e @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_4485: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/index.html
  IGT_5599: cdb07101dda33e2fcb0f4c2aa199c47159d88f35 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4485/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v3 1/5] lib/igt_core: Fix igt_assert_fd() documentation
  2020-04-17 21:10     ` [igt-dev] " Lyude
@ 2020-04-20  9:29         ` Petri Latvala
  -1 siblings, 0 replies; 33+ messages in thread
From: Petri Latvala @ 2020-04-20  9:29 UTC (permalink / raw)
  To: Lyude
  Cc: igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, Apr 17, 2020 at 05:10:21PM -0400, Lyude wrote:
> From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 
> As Petri Latvala pointed out, some of the documentation in this macro is
> mistakenly copied from the other igt_assert*() macros. Let's fix that.
> 
> Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  lib/igt_core.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/igt_core.h b/lib/igt_core.h
> index b97fa2fa..3f69b072 100644
> --- a/lib/igt_core.h
> +++ b/lib/igt_core.h
> @@ -966,8 +966,8 @@ void igt_describe_f(const char *fmt, ...);
>   *
>   * Fails (sub-) test if the given file descriptor is invalid.
>   *
> - * Like igt_assert(), but displays the values being compared on failure instead
> - * of simply printing the stringified expression.
> + * Like igt_assert(), but displays the stringified identifier that was supposed
> + * to contain a valid fd on failure.


For some values of "like" this is like igt_assert, but for some it's
not. I don't have enough coffee to suggest a better wording though.


Reviewed-by: Petri Latvala <petri.latvala-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>


>   */
>  #define igt_assert_fd(fd) \
>  	igt_assert_f(fd >= 0, "file descriptor " #fd " failed\n");
> -- 
> 2.25.1
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v3 1/5] lib/igt_core: Fix igt_assert_fd() documentation
@ 2020-04-20  9:29         ` Petri Latvala
  0 siblings, 0 replies; 33+ messages in thread
From: Petri Latvala @ 2020-04-20  9:29 UTC (permalink / raw)
  To: Lyude; +Cc: igt-dev, nouveau

On Fri, Apr 17, 2020 at 05:10:21PM -0400, Lyude wrote:
> From: Lyude Paul <lyude@redhat.com>
> 
> As Petri Latvala pointed out, some of the documentation in this macro is
> mistakenly copied from the other igt_assert*() macros. Let's fix that.
> 
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
>  lib/igt_core.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/igt_core.h b/lib/igt_core.h
> index b97fa2fa..3f69b072 100644
> --- a/lib/igt_core.h
> +++ b/lib/igt_core.h
> @@ -966,8 +966,8 @@ void igt_describe_f(const char *fmt, ...);
>   *
>   * Fails (sub-) test if the given file descriptor is invalid.
>   *
> - * Like igt_assert(), but displays the values being compared on failure instead
> - * of simply printing the stringified expression.
> + * Like igt_assert(), but displays the stringified identifier that was supposed
> + * to contain a valid fd on failure.


For some values of "like" this is like igt_assert, but for some it's
not. I don't have enough coffee to suggest a better wording though.


Reviewed-by: Petri Latvala <petri.latvala@intel.com>


>   */
>  #define igt_assert_fd(fd) \
>  	igt_assert_f(fd >= 0, "file descriptor " #fd " failed\n");
> -- 
> 2.25.1
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v3 2/5] lib/igt_core: Add igt_require_fd()
  2020-04-17 21:10     ` [igt-dev] " Lyude
@ 2020-04-20  9:29         ` Petri Latvala
  -1 siblings, 0 replies; 33+ messages in thread
From: Petri Latvala @ 2020-04-20  9:29 UTC (permalink / raw)
  To: Lyude
  Cc: igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, Apr 17, 2020 at 05:10:22PM -0400, Lyude wrote:
> From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 
> Like igt_assert_fd(), but using igt_require() instead
> 
> Changes since v1:
> * Fix documentation error in igt_require_fd() - Petri Latvala
> 
> Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>


Reviewed-by: Petri Latvala <petri.latvala-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>



> ---
>  lib/igt_core.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/lib/igt_core.h b/lib/igt_core.h
> index 3f69b072..8f68b2dd 100644
> --- a/lib/igt_core.h
> +++ b/lib/igt_core.h
> @@ -1021,6 +1021,18 @@ void igt_describe_f(const char *fmt, ...);
>  	else igt_debug("Test requirement passed: %s\n", #expr); \
>  } while (0)
>  
> +/**
> + * igt_require_fd:
> + * @fd: file descriptor
> + *
> + * Skips (sub-) test if the given file descriptor is invalid.
> + *
> + * Like igt_require(), but displays the stringified identifier that was supposed
> + * to contain a valid fd on failure.
> + */
> +#define igt_require_fd(fd) \
> +	igt_require_f(fd >= 0, "file descriptor " #fd " failed\n");
> +
>  /**
>   * igt_skip_on_f:
>   * @expr: condition to test
> -- 
> 2.25.1
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v3 2/5] lib/igt_core: Add igt_require_fd()
@ 2020-04-20  9:29         ` Petri Latvala
  0 siblings, 0 replies; 33+ messages in thread
From: Petri Latvala @ 2020-04-20  9:29 UTC (permalink / raw)
  To: Lyude; +Cc: igt-dev, nouveau

On Fri, Apr 17, 2020 at 05:10:22PM -0400, Lyude wrote:
> From: Lyude Paul <lyude@redhat.com>
> 
> Like igt_assert_fd(), but using igt_require() instead
> 
> Changes since v1:
> * Fix documentation error in igt_require_fd() - Petri Latvala
> 
> Signed-off-by: Lyude Paul <lyude@redhat.com>


Reviewed-by: Petri Latvala <petri.latvala@intel.com>



> ---
>  lib/igt_core.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/lib/igt_core.h b/lib/igt_core.h
> index 3f69b072..8f68b2dd 100644
> --- a/lib/igt_core.h
> +++ b/lib/igt_core.h
> @@ -1021,6 +1021,18 @@ void igt_describe_f(const char *fmt, ...);
>  	else igt_debug("Test requirement passed: %s\n", #expr); \
>  } while (0)
>  
> +/**
> + * igt_require_fd:
> + * @fd: file descriptor
> + *
> + * Skips (sub-) test if the given file descriptor is invalid.
> + *
> + * Like igt_require(), but displays the stringified identifier that was supposed
> + * to contain a valid fd on failure.
> + */
> +#define igt_require_fd(fd) \
> +	igt_require_f(fd >= 0, "file descriptor " #fd " failed\n");
> +
>  /**
>   * igt_skip_on_f:
>   * @expr: condition to test
> -- 
> 2.25.1
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH i-g-t v4] tests: Add nouveau-crc tests
  2020-04-17 21:10     ` [igt-dev] " Lyude
@ 2020-08-18 21:00         ` Lyude
  -1 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-08-18 21:00 UTC (permalink / raw)
  To: igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Lyude Paul <lyude@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 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@redhat.com>
---
 .gitlab-ci.yml      |   2 +-
 lib/drmtest.c       |  10 ++
 lib/drmtest.h       |   2 +
 tests/meson.build   |   1 +
 tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 411 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 684de043..92647991 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -74,6 +74,7 @@ test_progs = [
 	'kms_vblank',
 	'kms_vrr',
 	'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..05c2f4de
--- /dev/null
+++ b/tests/nouveau_crc.c
@@ -0,0 +1,397 @@
+/*
+ * 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));
+}
+
+static void create_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_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);
+}
+
+/* Hard-coded to PIPE_A for now, we don't really need to test this on more then
+ * one head
+ */
+static void test_ctx_flip_detection(data_t *data)
+{
+	struct color_fb colors[] = {
+		HEX_COLOR(0xFF, 0x00, 0x18),
+		HEX_COLOR(0xFF, 0xA5, 0x2C),
+		HEX_COLOR(0xFF, 0xFF, 0x41),
+		HEX_COLOR(0x00, 0x80, 0x18),
+		HEX_COLOR(0x00, 0x00, 0xF9),
+		HEX_COLOR(0x86, 0x00, 0x7D),
+	};
+	igt_output_t *output = data->output;
+	igt_plane_t *primary = data->primary;
+	igt_pipe_crc_t *pipe_crc;
+	const int n_colors = ARRAY_SIZE(colors);
+	const int n_crcs = 20;
+	igt_crc_t *crcs = NULL;
+	int start = -1, frame, start_color = -1, i;
+	bool found_skip = false;
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
+
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	set_crc_flip_threshold(data, n_crcs / 2);
+	igt_pipe_crc_start(pipe_crc);
+
+	for (i = 0; i < n_crcs; i++) {
+		const int color_idx = i % n_colors;
+
+		igt_plane_set_fb(primary, &colors[color_idx].fb);
+		do_or_die(drmModePageFlip(data->drm_fd,
+					  output->config.crtc->crtc_id,
+					  colors[color_idx].fb.fb_id,
+					  DRM_MODE_PAGE_FLIP_EVENT,
+					  NULL));
+		kmstest_wait_for_pageflip(data->drm_fd);
+	}
+
+	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	/*
+	 * Find the first color in our pattern with a CRC that differs from the
+	 * last CRC, so we can use it to find the start of the pattern
+	 */
+	for (i = 0; i < n_colors - 1; i++) {
+		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors - 1].crc))
+			continue;
+
+		igt_debug("Using frame %d of pattern for finding start\n", i);
+		start_color = i;
+		break;
+	}
+	igt_assert_lte(0, start_color);
+
+	/* Now, figure out where the pattern starts */
+	for (i = 0; i < n_crcs; i++) {
+		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
+			continue;
+
+		start = i - start_color;
+		frame = crcs[i].frame;
+		igt_debug("Pattern started on frame %d\n", frame);
+		break;
+	}
+	igt_assert_lte(0, start);
+
+	/* And finally, assert that according to the CRCs exactly all but one
+	 * frame was displayed in order. The missing frame comes from
+	 * (inevitably) losing a single CRC event when nouveau switches notifier
+	 * contexts
+	 */
+	for (i = start; i < n_crcs; i++, frame++) {
+		igt_crc_t *crc = &crcs[i];
+		char *crc_str;
+		int color_idx;
+
+		crc_str = igt_crc_to_string(crc);
+		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
+		free(crc_str);
+
+		if (!found_skip && crc->frame != frame) {
+			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
+				  crc->frame - 1);
+			found_skip = true;
+			frame++;
+		}
+
+		/* We should never skip more then one frame */
+		if (found_skip) {
+			igt_assert_eq(crc->frame, frame);
+			color_idx = (i - start + 1) % n_colors;
+		} else {
+			color_idx = (i - start) % n_colors;
+		}
+
+		igt_assert_crc_equal(crc, &colors[color_idx].crc);
+	}
+	igt_assert(found_skip);
+
+	free(crcs);
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, ARRAY_SIZE(colors));
+}
+
+/* Test whether or not IGT is able to handle frame skips when requesting the
+ * CRC for the current frame
+ */
+static void test_ctx_flip_skip_current_frame(data_t *data)
+{
+	struct color_fb colors[] = {
+		{ .r = 1.0, .g = 0.0, .b = 0.0 },
+		{ .r = 0.0, .g = 1.0, .b = 0.0 },
+		{ .r = 0.0, .g = 0.0, .b = 1.0 },
+	};
+	igt_output_t *output = data->output;
+	igt_pipe_crc_t *pipe_crc;
+	igt_plane_t *primary = data->primary;
+	const int fd = data->drm_fd;
+	const int n_colors = ARRAY_SIZE(colors);
+	const int n_crcs = 30;
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	set_crc_flip_threshold(data, 5);
+	igt_pipe_crc_start(pipe_crc);
+
+	for (int i = 0; i < n_crcs; i++) {
+		igt_crc_t crc;
+		const int color_idx = i % n_colors;
+
+		igt_plane_set_fb(primary, &colors[color_idx].fb);
+		do_or_die(drmModePageFlip(fd,
+					  output->config.crtc->crtc_id,
+					  colors[color_idx].fb.fb_id,
+					  DRM_MODE_PAGE_FLIP_EVENT,
+					  NULL));
+		kmstest_wait_for_pageflip(fd);
+
+		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
+		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
+	}
+
+	igt_pipe_crc_stop(pipe_crc);
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, n_colors);
+}
+
+static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
+{
+	igt_pipe_crc_t *pipe_crc;
+	const int fd = data->drm_fd;
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
+
+	set_crc_flip_threshold(data, 5);
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_stop(pipe_crc);
+
+	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"), 5);
+	igt_pipe_crc_free(pipe_crc);
+}
+
+static void test_source(data_t *data, const char *source)
+{
+	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, source);
+	igt_crc_t *crcs;
+
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	/* The CRC shouldn't change if the source content hasn't changed */
+	igt_assert_crc_equal(&crcs[0], &crcs[1]);
+
+	igt_pipe_crc_free(pipe_crc);
+	free(crcs);
+}
+
+static void test_source_outp_inactive(data_t *data)
+{
+	struct color_fb colors[] = {
+		{ .r = 1.0, .g = 0.0, .b = 0.0 },
+		{ .r = 0.0, .g = 1.0, .b = 0.0 },
+	};
+	igt_pipe_crc_t *pipe_crc;
+	const int fd = data->drm_fd;
+	const int n_colors = ARRAY_SIZE(colors);
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	/* Changing the color should not change what's outside the active raster */
+	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
+
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, n_colors);
+}
+
+data_t data = {0, };
+
+#define pipe_test(name) igt_subtest_f("pipe-%s-" name, kmstest_pipe_name(pipe))
+igt_main
+{
+	int pipe;
+
+	igt_fixture {
+		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
+		igt_require_nouveau(data.drm_fd);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_require_pipe_crc(data.drm_fd);
+		igt_display_require(&data.display, data.drm_fd);
+		igt_display_reset(&data.display);
+	}
+
+	for_each_pipe_static(pipe) {
+		igt_fixture {
+			int dir;
+
+			data.pipe = pipe;
+			igt_display_require_output_on_pipe(&data.display, pipe);
+			data.output = igt_get_single_output_for_pipe(&data.display, pipe);
+			data.mode = igt_output_get_mode(data.output);
+
+			/* None of these tests need to perform modesets,
+			 * just page flips. So running display setup
+			 * here is fine
+			 */
+			igt_output_set_pipe(data.output, pipe);
+			data.primary = igt_output_get_plane(data.output, 0);
+			igt_create_color_fb(data.drm_fd,
+					    data.mode->hdisplay,
+					    data.mode->vdisplay,
+					    DRM_FORMAT_XRGB8888,
+					    LOCAL_DRM_FORMAT_MOD_NONE,
+					    0.0, 0.0, 0.0,
+					    &data.default_fb);
+			igt_plane_set_fb(data.primary, &data.default_fb);
+			igt_display_commit(&data.display);
+
+			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe, O_DIRECTORY);
+			igt_require_fd(dir);
+			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
+			close(dir);
+			igt_require_fd(data.nv_crc_dir);
+		}
+
+		/* We don't need to test this on every pipe, but the
+		 * setup is the same */
+		if (pipe == PIPE_A) {
+			igt_describe("Make sure that the CRC notifier context flip threshold "
+				     "is reset to its default value after a single capture.");
+			igt_subtest("ctx-flip-threshold-reset-after-capture")
+				test_ctx_flip_threshold_reset_after_capture(&data);
+		}
+
+		igt_describe("Make sure the association between each CRC and its "
+			     "respective frame index is not broken when the driver "
+			     "performs a notifier context flip.");
+		pipe_test("ctx-flip-detection")
+			test_ctx_flip_detection(&data);
+
+		igt_describe("Make sure that igt_pipe_crc_get_current() works even "
+			     "when the CRC for the current frame index is lost.");
+		pipe_test("ctx-flip-skip-current-frame")
+			test_ctx_flip_skip_current_frame(&data);
+
+		igt_describe("Check that basic CRC readback using the outp-complete "
+			     "source works.");
+		pipe_test("source-outp-complete")
+			test_source(&data, "outp-complete");
+
+		igt_describe("Check that basic CRC readback using the rg source "
+			     "works.");
+		pipe_test("source-rg")
+			test_source(&data, "rg");
+
+		igt_describe("Make sure that the outp-inactive source is actually "
+			     "capturing the inactive raster.");
+		pipe_test("source-outp-inactive")
+			test_source_outp_inactive(&data);
+
+		igt_fixture {
+			igt_output_set_pipe(data.output, PIPE_NONE);
+			igt_display_commit(&data.display);
+			igt_remove_fb(data.drm_fd, &data.default_fb);
+			close(data.nv_crc_dir);
+		}
+	}
+	igt_fixture
+		igt_display_fini(&data.display);
+
+}
-- 
2.26.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [igt-dev] [PATCH i-g-t v4] tests: Add nouveau-crc tests
@ 2020-08-18 21:00         ` Lyude
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude @ 2020-08-18 21:00 UTC (permalink / raw)
  To: igt-dev; +Cc: nouveau

From: Lyude Paul <lyude@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 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@redhat.com>
---
 .gitlab-ci.yml      |   2 +-
 lib/drmtest.c       |  10 ++
 lib/drmtest.h       |   2 +
 tests/meson.build   |   1 +
 tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 411 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 684de043..92647991 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -74,6 +74,7 @@ test_progs = [
 	'kms_vblank',
 	'kms_vrr',
 	'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..05c2f4de
--- /dev/null
+++ b/tests/nouveau_crc.c
@@ -0,0 +1,397 @@
+/*
+ * 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));
+}
+
+static void create_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_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);
+}
+
+/* Hard-coded to PIPE_A for now, we don't really need to test this on more then
+ * one head
+ */
+static void test_ctx_flip_detection(data_t *data)
+{
+	struct color_fb colors[] = {
+		HEX_COLOR(0xFF, 0x00, 0x18),
+		HEX_COLOR(0xFF, 0xA5, 0x2C),
+		HEX_COLOR(0xFF, 0xFF, 0x41),
+		HEX_COLOR(0x00, 0x80, 0x18),
+		HEX_COLOR(0x00, 0x00, 0xF9),
+		HEX_COLOR(0x86, 0x00, 0x7D),
+	};
+	igt_output_t *output = data->output;
+	igt_plane_t *primary = data->primary;
+	igt_pipe_crc_t *pipe_crc;
+	const int n_colors = ARRAY_SIZE(colors);
+	const int n_crcs = 20;
+	igt_crc_t *crcs = NULL;
+	int start = -1, frame, start_color = -1, i;
+	bool found_skip = false;
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
+
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	set_crc_flip_threshold(data, n_crcs / 2);
+	igt_pipe_crc_start(pipe_crc);
+
+	for (i = 0; i < n_crcs; i++) {
+		const int color_idx = i % n_colors;
+
+		igt_plane_set_fb(primary, &colors[color_idx].fb);
+		do_or_die(drmModePageFlip(data->drm_fd,
+					  output->config.crtc->crtc_id,
+					  colors[color_idx].fb.fb_id,
+					  DRM_MODE_PAGE_FLIP_EVENT,
+					  NULL));
+		kmstest_wait_for_pageflip(data->drm_fd);
+	}
+
+	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	/*
+	 * Find the first color in our pattern with a CRC that differs from the
+	 * last CRC, so we can use it to find the start of the pattern
+	 */
+	for (i = 0; i < n_colors - 1; i++) {
+		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors - 1].crc))
+			continue;
+
+		igt_debug("Using frame %d of pattern for finding start\n", i);
+		start_color = i;
+		break;
+	}
+	igt_assert_lte(0, start_color);
+
+	/* Now, figure out where the pattern starts */
+	for (i = 0; i < n_crcs; i++) {
+		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
+			continue;
+
+		start = i - start_color;
+		frame = crcs[i].frame;
+		igt_debug("Pattern started on frame %d\n", frame);
+		break;
+	}
+	igt_assert_lte(0, start);
+
+	/* And finally, assert that according to the CRCs exactly all but one
+	 * frame was displayed in order. The missing frame comes from
+	 * (inevitably) losing a single CRC event when nouveau switches notifier
+	 * contexts
+	 */
+	for (i = start; i < n_crcs; i++, frame++) {
+		igt_crc_t *crc = &crcs[i];
+		char *crc_str;
+		int color_idx;
+
+		crc_str = igt_crc_to_string(crc);
+		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
+		free(crc_str);
+
+		if (!found_skip && crc->frame != frame) {
+			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
+				  crc->frame - 1);
+			found_skip = true;
+			frame++;
+		}
+
+		/* We should never skip more then one frame */
+		if (found_skip) {
+			igt_assert_eq(crc->frame, frame);
+			color_idx = (i - start + 1) % n_colors;
+		} else {
+			color_idx = (i - start) % n_colors;
+		}
+
+		igt_assert_crc_equal(crc, &colors[color_idx].crc);
+	}
+	igt_assert(found_skip);
+
+	free(crcs);
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, ARRAY_SIZE(colors));
+}
+
+/* Test whether or not IGT is able to handle frame skips when requesting the
+ * CRC for the current frame
+ */
+static void test_ctx_flip_skip_current_frame(data_t *data)
+{
+	struct color_fb colors[] = {
+		{ .r = 1.0, .g = 0.0, .b = 0.0 },
+		{ .r = 0.0, .g = 1.0, .b = 0.0 },
+		{ .r = 0.0, .g = 0.0, .b = 1.0 },
+	};
+	igt_output_t *output = data->output;
+	igt_pipe_crc_t *pipe_crc;
+	igt_plane_t *primary = data->primary;
+	const int fd = data->drm_fd;
+	const int n_colors = ARRAY_SIZE(colors);
+	const int n_crcs = 30;
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	set_crc_flip_threshold(data, 5);
+	igt_pipe_crc_start(pipe_crc);
+
+	for (int i = 0; i < n_crcs; i++) {
+		igt_crc_t crc;
+		const int color_idx = i % n_colors;
+
+		igt_plane_set_fb(primary, &colors[color_idx].fb);
+		do_or_die(drmModePageFlip(fd,
+					  output->config.crtc->crtc_id,
+					  colors[color_idx].fb.fb_id,
+					  DRM_MODE_PAGE_FLIP_EVENT,
+					  NULL));
+		kmstest_wait_for_pageflip(fd);
+
+		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
+		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
+	}
+
+	igt_pipe_crc_stop(pipe_crc);
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, n_colors);
+}
+
+static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
+{
+	igt_pipe_crc_t *pipe_crc;
+	const int fd = data->drm_fd;
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
+
+	set_crc_flip_threshold(data, 5);
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_stop(pipe_crc);
+
+	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"), 5);
+	igt_pipe_crc_free(pipe_crc);
+}
+
+static void test_source(data_t *data, const char *source)
+{
+	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, source);
+	igt_crc_t *crcs;
+
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	/* The CRC shouldn't change if the source content hasn't changed */
+	igt_assert_crc_equal(&crcs[0], &crcs[1]);
+
+	igt_pipe_crc_free(pipe_crc);
+	free(crcs);
+}
+
+static void test_source_outp_inactive(data_t *data)
+{
+	struct color_fb colors[] = {
+		{ .r = 1.0, .g = 0.0, .b = 0.0 },
+		{ .r = 0.0, .g = 1.0, .b = 0.0 },
+	};
+	igt_pipe_crc_t *pipe_crc;
+	const int fd = data->drm_fd;
+	const int n_colors = ARRAY_SIZE(colors);
+
+	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
+	create_colors(data, colors, n_colors, pipe_crc);
+
+	/* Changing the color should not change what's outside the active raster */
+	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
+
+	igt_pipe_crc_free(pipe_crc);
+	destroy_colors(data, colors, n_colors);
+}
+
+data_t data = {0, };
+
+#define pipe_test(name) igt_subtest_f("pipe-%s-" name, kmstest_pipe_name(pipe))
+igt_main
+{
+	int pipe;
+
+	igt_fixture {
+		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
+		igt_require_nouveau(data.drm_fd);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_require_pipe_crc(data.drm_fd);
+		igt_display_require(&data.display, data.drm_fd);
+		igt_display_reset(&data.display);
+	}
+
+	for_each_pipe_static(pipe) {
+		igt_fixture {
+			int dir;
+
+			data.pipe = pipe;
+			igt_display_require_output_on_pipe(&data.display, pipe);
+			data.output = igt_get_single_output_for_pipe(&data.display, pipe);
+			data.mode = igt_output_get_mode(data.output);
+
+			/* None of these tests need to perform modesets,
+			 * just page flips. So running display setup
+			 * here is fine
+			 */
+			igt_output_set_pipe(data.output, pipe);
+			data.primary = igt_output_get_plane(data.output, 0);
+			igt_create_color_fb(data.drm_fd,
+					    data.mode->hdisplay,
+					    data.mode->vdisplay,
+					    DRM_FORMAT_XRGB8888,
+					    LOCAL_DRM_FORMAT_MOD_NONE,
+					    0.0, 0.0, 0.0,
+					    &data.default_fb);
+			igt_plane_set_fb(data.primary, &data.default_fb);
+			igt_display_commit(&data.display);
+
+			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe, O_DIRECTORY);
+			igt_require_fd(dir);
+			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
+			close(dir);
+			igt_require_fd(data.nv_crc_dir);
+		}
+
+		/* We don't need to test this on every pipe, but the
+		 * setup is the same */
+		if (pipe == PIPE_A) {
+			igt_describe("Make sure that the CRC notifier context flip threshold "
+				     "is reset to its default value after a single capture.");
+			igt_subtest("ctx-flip-threshold-reset-after-capture")
+				test_ctx_flip_threshold_reset_after_capture(&data);
+		}
+
+		igt_describe("Make sure the association between each CRC and its "
+			     "respective frame index is not broken when the driver "
+			     "performs a notifier context flip.");
+		pipe_test("ctx-flip-detection")
+			test_ctx_flip_detection(&data);
+
+		igt_describe("Make sure that igt_pipe_crc_get_current() works even "
+			     "when the CRC for the current frame index is lost.");
+		pipe_test("ctx-flip-skip-current-frame")
+			test_ctx_flip_skip_current_frame(&data);
+
+		igt_describe("Check that basic CRC readback using the outp-complete "
+			     "source works.");
+		pipe_test("source-outp-complete")
+			test_source(&data, "outp-complete");
+
+		igt_describe("Check that basic CRC readback using the rg source "
+			     "works.");
+		pipe_test("source-rg")
+			test_source(&data, "rg");
+
+		igt_describe("Make sure that the outp-inactive source is actually "
+			     "capturing the inactive raster.");
+		pipe_test("source-outp-inactive")
+			test_source_outp_inactive(&data);
+
+		igt_fixture {
+			igt_output_set_pipe(data.output, PIPE_NONE);
+			igt_display_commit(&data.display);
+			igt_remove_fb(data.drm_fd, &data.default_fb);
+			close(data.nv_crc_dir);
+		}
+	}
+	igt_fixture
+		igt_display_fini(&data.display);
+
+}
-- 
2.26.2

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [i-g-t, v3, 3/5] lib/igt_debugfs: Add igt_debugfs_pipe_dir()
  2020-04-17 21:10     ` [igt-dev] " Lyude
@ 2020-08-18 21:01         ` Jeremy Cline
  -1 siblings, 0 replies; 33+ messages in thread
From: Jeremy Cline @ 2020-08-18 21:01 UTC (permalink / raw)
  To: Lyude
  Cc: igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Hi,

On Fri, Apr 17, 2020 at 05:10:23PM -0400, Lyude wrote:
> From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 
> Like igt_debugfs_connector_dir(), but for pipes instead.
> 
> Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  lib/igt_debugfs.c | 29 +++++++++++++++++++++++++++++
>  lib/igt_debugfs.h |  1 +
>  2 files changed, 30 insertions(+)
> 
> diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
> index bf6be552..3c3b11e1 100644
> --- a/lib/igt_debugfs.c
> +++ b/lib/igt_debugfs.c
> @@ -260,6 +260,35 @@ int igt_debugfs_connector_dir(int device, char *conn_name, int mode)
>  	return ret;
>  }
>  
> +/**
> + * igt_debugfs_pipe_dir:
> + * @device: fd of the device
> + * @pipe: index of pipe
> + * @mode: mode bits as used by open()
> + *
> + * This opens the debugfs directory corresponding to the pipe index on the
> + * device for use with igt_sysfs_get() and related functions.
> + *
> + * Returns:
> + * The directory fd, or -1 on failure.
> + */
> +int igt_debugfs_pipe_dir(int device, int pipe, int mode)
> +{
> +	char buf[128];
> +	int dir, ret;
> +
> +	dir = igt_debugfs_dir(device);
> +	if (dir < 0)
> +		return dir;
> +
> +	snprintf(buf, sizeof(buf), "crtc-%d", pipe);
> +	ret = openat(dir, buf, mode);
> +
> +	close(dir);
> +
> +	return ret;
> +}
> +

There seems to be a lot of overlap between this,
igt_debugfs_connector_dir(), and igt_debugfs_open(). As far as I can
tell, the latter two functions are completely identical so it's unclear
to me what the advantage of using one over the other is.

If I'm not mistaken igt_debugfs_pipe_dir() could be reduced to:

{
    char buf[128];
    snprintf(buf, sizeof(buf), "crtc-%d", pipe);
    return igt_debugfs_open(device, buf, mode);
}

and the docblock could just note it's sugar for igt_debugfs_open().

- Jeremy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [i-g-t, v3, 3/5] lib/igt_debugfs: Add igt_debugfs_pipe_dir()
@ 2020-08-18 21:01         ` Jeremy Cline
  0 siblings, 0 replies; 33+ messages in thread
From: Jeremy Cline @ 2020-08-18 21:01 UTC (permalink / raw)
  To: Lyude; +Cc: igt-dev, nouveau

Hi,

On Fri, Apr 17, 2020 at 05:10:23PM -0400, Lyude wrote:
> From: Lyude Paul <lyude@redhat.com>
> 
> Like igt_debugfs_connector_dir(), but for pipes instead.
> 
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
>  lib/igt_debugfs.c | 29 +++++++++++++++++++++++++++++
>  lib/igt_debugfs.h |  1 +
>  2 files changed, 30 insertions(+)
> 
> diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
> index bf6be552..3c3b11e1 100644
> --- a/lib/igt_debugfs.c
> +++ b/lib/igt_debugfs.c
> @@ -260,6 +260,35 @@ int igt_debugfs_connector_dir(int device, char *conn_name, int mode)
>  	return ret;
>  }
>  
> +/**
> + * igt_debugfs_pipe_dir:
> + * @device: fd of the device
> + * @pipe: index of pipe
> + * @mode: mode bits as used by open()
> + *
> + * This opens the debugfs directory corresponding to the pipe index on the
> + * device for use with igt_sysfs_get() and related functions.
> + *
> + * Returns:
> + * The directory fd, or -1 on failure.
> + */
> +int igt_debugfs_pipe_dir(int device, int pipe, int mode)
> +{
> +	char buf[128];
> +	int dir, ret;
> +
> +	dir = igt_debugfs_dir(device);
> +	if (dir < 0)
> +		return dir;
> +
> +	snprintf(buf, sizeof(buf), "crtc-%d", pipe);
> +	ret = openat(dir, buf, mode);
> +
> +	close(dir);
> +
> +	return ret;
> +}
> +

There seems to be a lot of overlap between this,
igt_debugfs_connector_dir(), and igt_debugfs_open(). As far as I can
tell, the latter two functions are completely identical so it's unclear
to me what the advantage of using one over the other is.

If I'm not mistaken igt_debugfs_pipe_dir() could be reduced to:

{
    char buf[128];
    snprintf(buf, sizeof(buf), "crtc-%d", pipe);
    return igt_debugfs_open(device, buf, mode);
}

and the docblock could just note it's sugar for igt_debugfs_open().

- Jeremy

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [i-g-t, v3, 4/5] lib/igt_kms: Hook up connector dithering prop
  2020-04-17 21:10     ` [igt-dev] " Lyude
@ 2020-08-18 21:18         ` Jeremy Cline
  -1 siblings, 0 replies; 33+ messages in thread
From: Jeremy Cline @ 2020-08-18 21:18 UTC (permalink / raw)
  To: Lyude
  Cc: igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Hi,

On Fri, Apr 17, 2020 at 05:10:24PM -0400, Lyude wrote:
> From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 
> Nvidia display hardware provides a set of flexible dithering options for
> CRTCs. This dithering is actually noticeable in the CRC output for all
> available tap points, and can be seen as CRC values for identical frames
> cycling between either 2 or 4 values repeatedly (each one of these
> values is a different dithering phase applied to the source output). Of
> course, this is very likely to break tests using CRC readback since we
> don't expect the CRC to change if the source content hasn't changed.
> 
> So, hook up support for configuring the dithering property and reset it
> to off from igt_display_reset() when applicable.
> 
> Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---

I'm not in a position to speak to the correctness of the change, but
from a pure code point of view it looks good to me, so for whatever it's
worth:

Reviewed-by: Jeremy Cline <jcline-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

>  lib/igt_kms.c | 6 ++++++
>  lib/igt_kms.h | 1 +
>  2 files changed, 7 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index e9621e7e..d45adfaf 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -421,6 +421,7 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>  	[IGT_CONNECTOR_LINK_STATUS] = "link-status",
>  	[IGT_CONNECTOR_MAX_BPC] = "max bpc",
>  	[IGT_CONNECTOR_HDR_OUTPUT_METADATA] = "HDR_OUTPUT_METADATA",
> +	[IGT_CONNECTOR_DITHERING_MODE] = "dithering mode",
>  };
>  
>  /*
> @@ -1802,6 +1803,10 @@ static void igt_output_reset(igt_output_t *output)
>  	if (igt_output_has_prop(output, IGT_CONNECTOR_HDR_OUTPUT_METADATA))
>  		igt_output_set_prop_value(output,
>  					  IGT_CONNECTOR_HDR_OUTPUT_METADATA, 0);
> +
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_DITHERING_MODE))
> +		igt_output_set_prop_enum(output, IGT_CONNECTOR_DITHERING_MODE,
> +					 "off");
>  }
>  
>  /**
> @@ -1816,6 +1821,7 @@ static void igt_output_reset(igt_output_t *output)
>   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
>   *   %IGT_CONNECTOR_CONTENT_PROTECTION (if applicable)
>   *   %IGT_CONNECTOR_HDR_OUTPUT_METADATA (if applicable)
> + * - %IGT_CONNECTOR_DITHERING_MODE (if applicable)
>   * - igt_output_override_mode() to default.
>   *
>   * For pipes:
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index adca59ac..4899e765 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -127,6 +127,7 @@ enum igt_atomic_connector_properties {
>         IGT_CONNECTOR_LINK_STATUS,
>         IGT_CONNECTOR_MAX_BPC,
>         IGT_CONNECTOR_HDR_OUTPUT_METADATA,
> +       IGT_CONNECTOR_DITHERING_MODE,
>         IGT_NUM_CONNECTOR_PROPS
>  };
>  

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [i-g-t, v3, 4/5] lib/igt_kms: Hook up connector dithering prop
@ 2020-08-18 21:18         ` Jeremy Cline
  0 siblings, 0 replies; 33+ messages in thread
From: Jeremy Cline @ 2020-08-18 21:18 UTC (permalink / raw)
  To: Lyude; +Cc: igt-dev, nouveau

Hi,

On Fri, Apr 17, 2020 at 05:10:24PM -0400, Lyude wrote:
> From: Lyude Paul <lyude@redhat.com>
> 
> Nvidia display hardware provides a set of flexible dithering options for
> CRTCs. This dithering is actually noticeable in the CRC output for all
> available tap points, and can be seen as CRC values for identical frames
> cycling between either 2 or 4 values repeatedly (each one of these
> values is a different dithering phase applied to the source output). Of
> course, this is very likely to break tests using CRC readback since we
> don't expect the CRC to change if the source content hasn't changed.
> 
> So, hook up support for configuring the dithering property and reset it
> to off from igt_display_reset() when applicable.
> 
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---

I'm not in a position to speak to the correctness of the change, but
from a pure code point of view it looks good to me, so for whatever it's
worth:

Reviewed-by: Jeremy Cline <jcline@redhat.com>

>  lib/igt_kms.c | 6 ++++++
>  lib/igt_kms.h | 1 +
>  2 files changed, 7 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index e9621e7e..d45adfaf 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -421,6 +421,7 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>  	[IGT_CONNECTOR_LINK_STATUS] = "link-status",
>  	[IGT_CONNECTOR_MAX_BPC] = "max bpc",
>  	[IGT_CONNECTOR_HDR_OUTPUT_METADATA] = "HDR_OUTPUT_METADATA",
> +	[IGT_CONNECTOR_DITHERING_MODE] = "dithering mode",
>  };
>  
>  /*
> @@ -1802,6 +1803,10 @@ static void igt_output_reset(igt_output_t *output)
>  	if (igt_output_has_prop(output, IGT_CONNECTOR_HDR_OUTPUT_METADATA))
>  		igt_output_set_prop_value(output,
>  					  IGT_CONNECTOR_HDR_OUTPUT_METADATA, 0);
> +
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_DITHERING_MODE))
> +		igt_output_set_prop_enum(output, IGT_CONNECTOR_DITHERING_MODE,
> +					 "off");
>  }
>  
>  /**
> @@ -1816,6 +1821,7 @@ static void igt_output_reset(igt_output_t *output)
>   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
>   *   %IGT_CONNECTOR_CONTENT_PROTECTION (if applicable)
>   *   %IGT_CONNECTOR_HDR_OUTPUT_METADATA (if applicable)
> + * - %IGT_CONNECTOR_DITHERING_MODE (if applicable)
>   * - igt_output_override_mode() to default.
>   *
>   * For pipes:
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index adca59ac..4899e765 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -127,6 +127,7 @@ enum igt_atomic_connector_properties {
>         IGT_CONNECTOR_LINK_STATUS,
>         IGT_CONNECTOR_MAX_BPC,
>         IGT_CONNECTOR_HDR_OUTPUT_METADATA,
> +       IGT_CONNECTOR_DITHERING_MODE,
>         IGT_NUM_CONNECTOR_PROPS
>  };
>  

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [igt-dev] ✓ Fi.CI.BAT: success for Add nouveau-crc tests (rev4)
  2020-04-17 21:10 ` [igt-dev] " Lyude
                   ` (4 preceding siblings ...)
  (?)
@ 2020-08-18 21:57 ` Patchwork
  -1 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2020-08-18 21:57 UTC (permalink / raw)
  To: Lyude; +Cc: igt-dev


[-- Attachment #1.1: Type: text/plain, Size: 4579 bytes --]

== Series Details ==

Series: Add nouveau-crc tests (rev4)
URL   : https://patchwork.freedesktop.org/series/74811/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8901 -> IGTPW_4890
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/index.html

Known issues
------------

  Here are the changes found in IGTPW_4890 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-bsw-kefka:       [PASS][1] -> [DMESG-WARN][2] ([i915#1982])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  
#### Warnings ####

  * igt@i915_pm_rpm@module-reload:
    - fi-kbl-x1275:       [SKIP][3] ([fdo#109271]) -> [DMESG-FAIL][4] ([i915#62])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/fi-kbl-x1275/igt@i915_pm_rpm@module-reload.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/fi-kbl-x1275/igt@i915_pm_rpm@module-reload.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-varying-size:
    - fi-kbl-x1275:       [DMESG-WARN][5] ([i915#62] / [i915#92]) -> [DMESG-WARN][6] ([i915#62] / [i915#92] / [i915#95]) +2 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/fi-kbl-x1275/igt@kms_cursor_legacy@basic-flip-before-cursor-varying-size.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/fi-kbl-x1275/igt@kms_cursor_legacy@basic-flip-before-cursor-varying-size.html

  * igt@kms_flip@basic-flip-vs-dpms@a-dp1:
    - fi-kbl-x1275:       [DMESG-WARN][7] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][8] ([i915#62] / [i915#92]) +2 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-dpms@a-dp1.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-dpms@a-dp1.html

  
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (39 -> 34)
------------------------------

  Missing    (5): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5769 -> IGTPW_4890

  CI-20190529: 20190529
  CI_DRM_8901: 39e63f96cd9438015d6204a3ca33819447e4c066 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_4890: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/index.html
  IGT_5769: 4e5f76be680b65780204668e302026cf638decc9 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+igt@nouveau_crc@ctx-flip-threshold-reset-after-capture
+igt@nouveau_crc@pipe-a-ctx-flip-detection
+igt@nouveau_crc@pipe-a-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-a-source-outp-complete
+igt@nouveau_crc@pipe-a-source-outp-inactive
+igt@nouveau_crc@pipe-a-source-rg
+igt@nouveau_crc@pipe-b-ctx-flip-detection
+igt@nouveau_crc@pipe-b-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-b-source-outp-complete
+igt@nouveau_crc@pipe-b-source-outp-inactive
+igt@nouveau_crc@pipe-b-source-rg
+igt@nouveau_crc@pipe-c-ctx-flip-detection
+igt@nouveau_crc@pipe-c-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-c-source-outp-complete
+igt@nouveau_crc@pipe-c-source-outp-inactive
+igt@nouveau_crc@pipe-c-source-rg
+igt@nouveau_crc@pipe-d-ctx-flip-detection
+igt@nouveau_crc@pipe-d-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-d-source-outp-complete
+igt@nouveau_crc@pipe-d-source-outp-inactive
+igt@nouveau_crc@pipe-d-source-rg
+igt@nouveau_crc@pipe-e-ctx-flip-detection
+igt@nouveau_crc@pipe-e-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-e-source-outp-complete
+igt@nouveau_crc@pipe-e-source-outp-inactive
+igt@nouveau_crc@pipe-e-source-rg
+igt@nouveau_crc@pipe-f-ctx-flip-detection
+igt@nouveau_crc@pipe-f-ctx-flip-skip-current-frame
+igt@nouveau_crc@pipe-f-source-outp-complete
+igt@nouveau_crc@pipe-f-source-outp-inactive
+igt@nouveau_crc@pipe-f-source-rg

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/index.html

[-- Attachment #1.2: Type: text/html, Size: 5952 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [igt-dev] ✗ Fi.CI.IGT: failure for Add nouveau-crc tests (rev4)
  2020-04-17 21:10 ` [igt-dev] " Lyude
                   ` (5 preceding siblings ...)
  (?)
@ 2020-08-19  4:40 ` Patchwork
  -1 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2020-08-19  4:40 UTC (permalink / raw)
  To: Lyude Paul; +Cc: igt-dev


[-- Attachment #1.1: Type: text/plain, Size: 20862 bytes --]

== Series Details ==

Series: Add nouveau-crc tests (rev4)
URL   : https://patchwork.freedesktop.org/series/74811/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_8901_full -> IGTPW_4890_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_4890_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_4890_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_4890_full:

### IGT changes ###

#### Possible regressions ####

  * igt@kms_cursor_legacy@all-pipes-single-move:
    - shard-glk:          [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-glk9/igt@kms_cursor_legacy@all-pipes-single-move.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-glk6/igt@kms_cursor_legacy@all-pipes-single-move.html

  * {igt@nouveau_crc@pipe-b-source-rg} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][3] +13 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb5/igt@nouveau_crc@pipe-b-source-rg.html

  * {igt@nouveau_crc@pipe-d-ctx-flip-detection} (NEW):
    - shard-tglb:         NOTRUN -> [SKIP][4] +19 similar issues
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-tglb1/igt@nouveau_crc@pipe-d-ctx-flip-detection.html

  
New tests
---------

  New tests have been introduced between CI_DRM_8901_full and IGTPW_4890_full:

### New IGT tests (21) ###

  * igt@nouveau_crc@ctx-flip-threshold-reset-after-capture:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-ctx-flip-detection:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-ctx-flip-skip-current-frame:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-source-outp-complete:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-source-outp-inactive:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-a-source-rg:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-ctx-flip-detection:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-ctx-flip-skip-current-frame:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-source-outp-complete:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-source-outp-inactive:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-b-source-rg:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-ctx-flip-detection:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-ctx-flip-skip-current-frame:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-source-outp-complete:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-source-outp-inactive:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-c-source-rg:
    - Statuses :
    - Exec time: [None] s

  * igt@nouveau_crc@pipe-d-ctx-flip-detection:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-ctx-flip-skip-current-frame:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-source-outp-complete:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-source-outp-inactive:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@nouveau_crc@pipe-d-source-rg:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  

Known issues
------------

  Here are the changes found in IGTPW_4890_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_whisper@basic-fds-all:
    - shard-glk:          [PASS][5] -> [DMESG-WARN][6] ([i915#118] / [i915#95]) +1 similar issue
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-glk5/igt@gem_exec_whisper@basic-fds-all.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-glk6/igt@gem_exec_whisper@basic-fds-all.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-glk:          [PASS][7] -> [DMESG-WARN][8] ([i915#1436] / [i915#716])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-glk6/igt@gen9_exec_parse@allowed-all.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-glk1/igt@gen9_exec_parse@allowed-all.html

  * igt@i915_pm_rc6_residency@rc6-fence:
    - shard-iclb:         [PASS][9] -> [WARN][10] ([i915#1515])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-iclb4/igt@i915_pm_rc6_residency@rc6-fence.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb6/igt@i915_pm_rc6_residency@rc6-fence.html
    - shard-hsw:          [PASS][11] -> [WARN][12] ([i915#1519])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-hsw7/igt@i915_pm_rc6_residency@rc6-fence.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-hsw2/igt@i915_pm_rc6_residency@rc6-fence.html

  * igt@i915_query@query-topology-unsupported:
    - shard-snb:          [PASS][13] -> [TIMEOUT][14] ([i915#1958]) +2 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-snb2/igt@i915_query@query-topology-unsupported.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-snb2/igt@i915_query@query-topology-unsupported.html

  * igt@kms_cursor_crc@pipe-a-cursor-64x64-sliding:
    - shard-snb:          [PASS][15] -> [SKIP][16] ([fdo#109271]) +3 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-snb5/igt@kms_cursor_crc@pipe-a-cursor-64x64-sliding.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-snb2/igt@kms_cursor_crc@pipe-a-cursor-64x64-sliding.html

  * igt@kms_cursor_legacy@short-flip-before-cursor-toggle:
    - shard-tglb:         [PASS][17] -> [DMESG-WARN][18] ([i915#1982]) +2 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-tglb1/igt@kms_cursor_legacy@short-flip-before-cursor-toggle.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-tglb8/igt@kms_cursor_legacy@short-flip-before-cursor-toggle.html

  * igt@kms_draw_crc@draw-method-xrgb8888-blt-xtiled:
    - shard-hsw:          [PASS][19] -> [TIMEOUT][20] ([i915#1958]) +1 similar issue
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-hsw7/igt@kms_draw_crc@draw-method-xrgb8888-blt-xtiled.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-hsw1/igt@kms_draw_crc@draw-method-xrgb8888-blt-xtiled.html

  * igt@kms_flip_tiling@flip-x-tiled:
    - shard-kbl:          [PASS][21] -> [DMESG-WARN][22] ([i915#1982])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-kbl4/igt@kms_flip_tiling@flip-x-tiled.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-kbl4/igt@kms_flip_tiling@flip-x-tiled.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-kbl:          [PASS][23] -> [DMESG-WARN][24] ([i915#180]) +10 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-kbl7/igt@kms_hdr@bpc-switch-suspend.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-kbl4/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_panel_fitting@atomic-fastset:
    - shard-iclb:         [PASS][25] -> [FAIL][26] ([i915#83])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-iclb8/igt@kms_panel_fitting@atomic-fastset.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb7/igt@kms_panel_fitting@atomic-fastset.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes:
    - shard-iclb:         [PASS][27] -> [INCOMPLETE][28] ([i915#1185] / [i915#250])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-iclb3/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb3/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html

  * igt@kms_psr@no_drrs:
    - shard-iclb:         [PASS][29] -> [FAIL][30] ([i915#173])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-iclb5/igt@kms_psr@no_drrs.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb1/igt@kms_psr@no_drrs.html

  * igt@kms_psr@psr2_suspend:
    - shard-iclb:         [PASS][31] -> [SKIP][32] ([fdo#109441])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-iclb2/igt@kms_psr@psr2_suspend.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb5/igt@kms_psr@psr2_suspend.html

  * igt@kms_setmode@basic:
    - shard-apl:          [PASS][33] -> [FAIL][34] ([i915#1635] / [i915#31])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-apl1/igt@kms_setmode@basic.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-apl1/igt@kms_setmode@basic.html

  * igt@prime_busy@before@vecs0:
    - shard-apl:          [PASS][35] -> [DMESG-WARN][36] ([i915#1635] / [i915#1982])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-apl1/igt@prime_busy@before@vecs0.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-apl4/igt@prime_busy@before@vecs0.html

  
#### Possible fixes ####

  * igt@gem_exec_reloc@basic-concurrent0:
    - shard-glk:          [FAIL][37] ([i915#1930]) -> [PASS][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-glk1/igt@gem_exec_reloc@basic-concurrent0.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-glk9/igt@gem_exec_reloc@basic-concurrent0.html

  * igt@gem_exec_suspend@basic-s3:
    - shard-snb:          [TIMEOUT][39] ([i915#1958]) -> [PASS][40] +2 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-snb4/igt@gem_exec_suspend@basic-s3.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-snb4/igt@gem_exec_suspend@basic-s3.html

  * igt@gem_mmap_gtt@fault-concurrent:
    - shard-snb:          [DMESG-WARN][41] -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-snb4/igt@gem_mmap_gtt@fault-concurrent.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-snb5/igt@gem_mmap_gtt@fault-concurrent.html

  * igt@i915_selftest@mock@contexts:
    - shard-apl:          [INCOMPLETE][43] ([i915#1635] / [i915#2278]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-apl6/igt@i915_selftest@mock@contexts.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-apl8/igt@i915_selftest@mock@contexts.html

  * igt@kms_big_fb@linear-64bpp-rotate-180:
    - shard-glk:          [DMESG-FAIL][45] ([i915#118] / [i915#95]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-glk8/igt@kms_big_fb@linear-64bpp-rotate-180.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-glk3/igt@kms_big_fb@linear-64bpp-rotate-180.html

  * igt@kms_flip@2x-wf_vblank-ts-check-interruptible@ab-hdmi-a1-hdmi-a2:
    - shard-glk:          [DMESG-WARN][47] ([i915#1982]) -> [PASS][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-glk1/igt@kms_flip@2x-wf_vblank-ts-check-interruptible@ab-hdmi-a1-hdmi-a2.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-glk8/igt@kms_flip@2x-wf_vblank-ts-check-interruptible@ab-hdmi-a1-hdmi-a2.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible@b-edp1:
    - shard-tglb:         [FAIL][49] ([i915#79]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-tglb1/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-edp1.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-tglb7/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-edp1.html

  * igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-blt:
    - shard-kbl:          [DMESG-WARN][51] ([i915#1982]) -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-kbl2/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-blt.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-kbl2/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-cpu:
    - shard-tglb:         [DMESG-WARN][53] ([i915#1982]) -> [PASS][54] +6 similar issues
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-tglb5/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-cpu.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-tglb1/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-cpu.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes:
    - shard-kbl:          [DMESG-WARN][55] ([i915#180]) -> [PASS][56] +1 similar issue
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-kbl4/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-kbl7/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [SKIP][57] ([fdo#109441]) -> [PASS][58] +1 similar issue
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-iclb3/igt@kms_psr@psr2_sprite_plane_move.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@kms_setmode@basic:
    - shard-kbl:          [FAIL][59] ([i915#31]) -> [PASS][60]
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-kbl1/igt@kms_setmode@basic.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-kbl1/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-c-wait-idle-hang:
    - shard-apl:          [DMESG-WARN][61] ([i915#1635] / [i915#1982]) -> [PASS][62]
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-apl8/igt@kms_vblank@pipe-c-wait-idle-hang.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-apl2/igt@kms_vblank@pipe-c-wait-idle-hang.html

  * igt@perf@blocking-parameterized:
    - shard-iclb:         [FAIL][63] ([i915#1542]) -> [PASS][64]
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-iclb5/igt@perf@blocking-parameterized.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb3/igt@perf@blocking-parameterized.html

  * igt@perf@oa-exponents:
    - shard-hsw:          [INCOMPLETE][65] ([i915#1958]) -> [PASS][66]
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-hsw6/igt@perf@oa-exponents.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-hsw2/igt@perf@oa-exponents.html

  * igt@prime_busy@hang-wait@bcs0:
    - shard-hsw:          [FAIL][67] ([i915#2258]) -> [PASS][68] +8 similar issues
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-hsw7/igt@prime_busy@hang-wait@bcs0.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-hsw7/igt@prime_busy@hang-wait@bcs0.html

  
#### Warnings ####

  * igt@gem_exec_schedule@preemptive-hang:
    - shard-snb:          [TIMEOUT][69] ([i915#1958]) -> [SKIP][70] ([fdo#109271]) +1 similar issue
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-snb4/igt@gem_exec_schedule@preemptive-hang.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-snb5/igt@gem_exec_schedule@preemptive-hang.html

  * igt@kms_ccs@pipe-c-bad-pixel-format:
    - shard-hsw:          [SKIP][71] ([fdo#109271]) -> [TIMEOUT][72] ([i915#1958]) +2 similar issues
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-hsw6/igt@kms_ccs@pipe-c-bad-pixel-format.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-hsw1/igt@kms_ccs@pipe-c-bad-pixel-format.html

  * igt@kms_content_protection@lic:
    - shard-kbl:          [TIMEOUT][73] ([i915#1319]) -> [TIMEOUT][74] ([i915#1319] / [i915#1958])
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-kbl1/igt@kms_content_protection@lic.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-kbl1/igt@kms_content_protection@lic.html

  * igt@kms_dp_dsc@basic-dsc-enable-edp:
    - shard-iclb:         [DMESG-WARN][75] ([i915#1226]) -> [SKIP][76] ([fdo#109349])
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-iclb2/igt@kms_dp_dsc@basic-dsc-enable-edp.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-iclb1/igt@kms_dp_dsc@basic-dsc-enable-edp.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [INCOMPLETE][77] ([i915#155]) -> [DMESG-WARN][78] ([i915#180])
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-kbl6/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-kbl1/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-render:
    - shard-snb:          [SKIP][79] ([fdo#109271]) -> [TIMEOUT][80] ([i915#1958]) +1 similar issue
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-snb5/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-render.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-snb2/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-render.html

  * igt@runner@aborted:
    - shard-hsw:          ([FAIL][81], [FAIL][82]) ([i915#1958] / [i915#2283]) -> [FAIL][83] ([i915#2283])
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-hsw6/igt@runner@aborted.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8901/shard-hsw7/igt@runner@aborted.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/shard-hsw8/igt@runner@aborted.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109349]: https://bugs.freedesktop.org/show_bug.cgi?id=109349
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118
  [i915#1185]: https://gitlab.freedesktop.org/drm/intel/issues/1185
  [i915#1226]: https://gitlab.freedesktop.org/drm/intel/issues/1226
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#1515]: https://gitlab.freedesktop.org/drm/intel/issues/1515
  [i915#1519]: https://gitlab.freedesktop.org/drm/intel/issues/1519
  [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
  [i915#155]: https://gitlab.freedesktop.org/drm/intel/issues/155
  [i915#1635]: https://gitlab.freedesktop.org/drm/intel/issues/1635
  [i915#173]: https://gitlab.freedesktop.org/drm/intel/issues/173
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1930]: https://gitlab.freedesktop.org/drm/intel/issues/1930
  [i915#1958]: https://gitlab.freedesktop.org/drm/intel/issues/1958
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2258]: https://gitlab.freedesktop.org/drm/intel/issues/2258
  [i915#2278]: https://gitlab.freedesktop.org/drm/intel/issues/2278
  [i915#2283]: https://gitlab.freedesktop.org/drm/intel/issues/2283
  [i915#250]: https://gitlab.freedesktop.org/drm/intel/issues/250
  [i915#31]: https://gitlab.freedesktop.org/drm/intel/issues/31
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
  [i915#83]: https://gitlab.freedesktop.org/drm/intel/issues/83
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (11 -> 8)
------------------------------

  Missing    (3): pig-skl-6260u pig-glk-j5005 pig-icl-1065g7 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5769 -> IGTPW_4890
  * Piglit: piglit_4509 -> None

  CI-20190529: 20190529
  CI_DRM_8901: 39e63f96cd9438015d6204a3ca33819447e4c066 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_4890: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/index.html
  IGT_5769: 4e5f76be680b65780204668e302026cf638decc9 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4890/index.html

[-- Attachment #1.2: Type: text/html, Size: 25047 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4] tests: Add nouveau-crc tests
  2020-08-18 21:00         ` [igt-dev] " Lyude
@ 2020-09-28 21:36             ` Jeremy Cline
  -1 siblings, 0 replies; 33+ messages in thread
From: Jeremy Cline @ 2020-09-28 21:36 UTC (permalink / raw)
  To: Lyude
  Cc: igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Hi,

On Tue, Aug 18, 2020 at 05:00:51PM -0400, Lyude wrote:
> From: Lyude Paul <lyude@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 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@redhat.com>
> ---
>  .gitlab-ci.yml      |   2 +-
>  lib/drmtest.c       |  10 ++
>  lib/drmtest.h       |   2 +
>  tests/meson.build   |   1 +
>  tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 411 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 684de043..92647991 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -74,6 +74,7 @@ test_progs = [
>  	'kms_vblank',
>  	'kms_vrr',
>  	'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..05c2f4de
> --- /dev/null
> +++ b/tests/nouveau_crc.c
> @@ -0,0 +1,397 @@
> +/*
> + * 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));
> +}
> +
> +static void create_colors(data_t *data,
> +			  struct color_fb *colors,
> +			  size_t len,
> +			  igt_pipe_crc_t *pipe_crc)

Not to bikeshed too much, but this function seems to be more about
generating CRCs given some pre-existing colors. Maybe
create_color_crcs() would be better? And it wouldn't hurt to throw a
little docblock on it, even something as short as:

/*
 * Calculate and set the CRC for each color_fb
 */

> +{
> +	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_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);
> +}
> +
> +/* Hard-coded to PIPE_A for now, we don't really need to test this on more then
> + * one head
> + */

Perhaps expand this doc-block out a bit with the details you have in the
commit:

/* Test CRCs are reported across notifier context flips
 *
 * Nvidia GPUs store CRCs in a limited memory region called the notifier
 * context. When the region fills, new CRCs are not reported. To work
 * around this, two notifier contexts are allocated and the driver flips
 * between the two of them when a threshold is reached. Even with this
 * approach, a single frame is lost during the context flip.
 *
 * This test adjusts the threshold at which the notifier context flips
 * to the other context and asserts the CRCs are correctly reported with
 * the exception of the frame lost during the flip.
 *
 * Hard-coded to PIPE_A for now, we don't really need to test this on
 * more then one head
 */

I was guilty of reading the code while testing without going back to
consult the commit message and I only just now realized the test purpose
was clearly explained. It'd be nice to keep that close to the test
definition rather than in the commit log.

Also, as far as I can tell it's not actually hard-coded to PIPE_A, but
test_ctx_flip_threshold_reset_after_capture() is. Maybe I'm
mis-understanding that?

> +static void test_ctx_flip_detection(data_t *data)
> +{
> +	struct color_fb colors[] = {
> +		HEX_COLOR(0xFF, 0x00, 0x18),
> +		HEX_COLOR(0xFF, 0xA5, 0x2C),
> +		HEX_COLOR(0xFF, 0xFF, 0x41),
> +		HEX_COLOR(0x00, 0x80, 0x18),
> +		HEX_COLOR(0x00, 0x00, 0xF9),
> +		HEX_COLOR(0x86, 0x00, 0x7D),
> +	};
> +	igt_output_t *output = data->output;
> +	igt_plane_t *primary = data->primary;
> +	igt_pipe_crc_t *pipe_crc;
> +	const int n_colors = ARRAY_SIZE(colors);
> +	const int n_crcs = 20;
> +	igt_crc_t *crcs = NULL;
> +	int start = -1, frame, start_color = -1, i;
> +	bool found_skip = false;
> +
> +	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
> +
> +	create_colors(data, colors, n_colors, pipe_crc);
> +
> +	set_crc_flip_threshold(data, n_crcs / 2);
> +	igt_pipe_crc_start(pipe_crc);
> +
> +	for (i = 0; i < n_crcs; i++) {
> +		const int color_idx = i % n_colors;
> +
> +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> +		do_or_die(drmModePageFlip(data->drm_fd,
> +					  output->config.crtc->crtc_id,
> +					  colors[color_idx].fb.fb_id,
> +					  DRM_MODE_PAGE_FLIP_EVENT,
> +					  NULL));
> +		kmstest_wait_for_pageflip(data->drm_fd);

While testing I was experiencing some test failures, at which point I
turned on a bunch of debug logging on the kernel side. This led to this
test reliably failing because this call timed out waiting on the pageflip
event, which is unfortunate. I'm not sure what the larger usage of this
particular function is, but having tests start to fail when verbose
logging is enabled isn't ideal.

Obviously hanging forever is also not ideal, so maybe the timeout of
this function just needs adjustment, or even just have the assertion
include a hint that perhaps debug logging is slowing things down too
much. It's not within the scope of this change so I don't think anything
needs to change in this patch, more just wanted to see what folks think
the best approach is since I spent longer than I care to admit figuring
that out and don't want others to have to suffer the same way.

> +	}
> +
> +	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
> +	igt_pipe_crc_stop(pipe_crc);
> +
> +	/*
> +	 * Find the first color in our pattern with a CRC that differs from the
> +	 * last CRC, so we can use it to find the start of the pattern
> +	 */

It might be worth explicitly noting this is to avoid CRC collisions (I'm
assuming) since I had to ponder for a bit:

/*
 * Guard against CRC collisions in the color framebuffers. Find the
 * first color in our pattern with a CRC that differs from the last CRC,
 * so we can use it to find the start of the pattern
 */

> +	for (i = 0; i < n_colors - 1; i++) {
> +		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors - 1].crc))
> +			continue;
> +
> +		igt_debug("Using frame %d of pattern for finding start\n", i);
> +		start_color = i;
> +		break;
> +	}
> +	igt_assert_lte(0, start_color);
> +
> +	/* Now, figure out where the pattern starts */
> +	for (i = 0; i < n_crcs; i++) {
> +		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
> +			continue;
> +
> +		start = i - start_color;
> +		frame = crcs[i].frame;
> +		igt_debug("Pattern started on frame %d\n", frame);
> +		break;
> +	}
> +	igt_assert_lte(0, start);
> +
> +	/* And finally, assert that according to the CRCs exactly all but one
> +	 * frame was displayed in order. The missing frame comes from
> +	 * (inevitably) losing a single CRC event when nouveau switches notifier
> +	 * contexts
> +	 */
> +	for (i = start; i < n_crcs; i++, frame++) {
> +		igt_crc_t *crc = &crcs[i];
> +		char *crc_str;
> +		int color_idx;
> +
> +		crc_str = igt_crc_to_string(crc);
> +		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
> +		free(crc_str);
> +
> +		if (!found_skip && crc->frame != frame) {
> +			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
> +				  crc->frame - 1);
> +			found_skip = true;
> +			frame++;
> +		}
> +
> +		/* We should never skip more then one frame */
> +		if (found_skip) {
> +			igt_assert_eq(crc->frame, frame);
> +			color_idx = (i - start + 1) % n_colors;
> +		} else {
> +			color_idx = (i - start) % n_colors;
> +		}
> +
> +		igt_assert_crc_equal(crc, &colors[color_idx].crc);

This consistently fails for me. The reason is that there are multiple
frames with the same color/CRC. As far as I can tell, that's perfectly
reasonable when a page flip is slow (possibly due to debug logs 😬), but
I don't know for certain what the interface expectations are.

If that assumption is correct, I guess you'll need to expect either the
same color as the previous frame, or the next color in the array after
the color in the previous frame.

> +	}
> +	igt_assert(found_skip);
> +
> +	free(crcs);
> +	igt_pipe_crc_free(pipe_crc);
> +	destroy_colors(data, colors, ARRAY_SIZE(colors));
> +}
> +
> +/* Test whether or not IGT is able to handle frame skips when requesting the
> + * CRC for the current frame
> + */
> +static void test_ctx_flip_skip_current_frame(data_t *data)
> +{
> +	struct color_fb colors[] = {
> +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> +		{ .r = 0.0, .g = 0.0, .b = 1.0 },
> +	};
> +	igt_output_t *output = data->output;
> +	igt_pipe_crc_t *pipe_crc;
> +	igt_plane_t *primary = data->primary;
> +	const int fd = data->drm_fd;
> +	const int n_colors = ARRAY_SIZE(colors);
> +	const int n_crcs = 30;
> +
> +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> +	create_colors(data, colors, n_colors, pipe_crc);
> +
> +	set_crc_flip_threshold(data, 5);
> +	igt_pipe_crc_start(pipe_crc);
> +
> +	for (int i = 0; i < n_crcs; i++) {
> +		igt_crc_t crc;
> +		const int color_idx = i % n_colors;
> +
> +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> +		do_or_die(drmModePageFlip(fd,
> +					  output->config.crtc->crtc_id,
> +					  colors[color_idx].fb.fb_id,
> +					  DRM_MODE_PAGE_FLIP_EVENT,
> +					  NULL));
> +		kmstest_wait_for_pageflip(fd);
> +
> +		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
> +		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
> +	}
> +
> +	igt_pipe_crc_stop(pipe_crc);
> +	igt_pipe_crc_free(pipe_crc);
> +	destroy_colors(data, colors, n_colors);
> +}
> +

Maybe a short doc-block with what the test should be doing here would be
good:

/*
 * Assert that after a CRC capture is started and stopped, the context
 * notifier flip threshold is reset to its default value.
 */

> +static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
> +{
> +	igt_pipe_crc_t *pipe_crc;
> +	const int fd = data->drm_fd;
> +
> +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> +
> +	set_crc_flip_threshold(data, 5);
> +	igt_pipe_crc_start(pipe_crc);
> +	igt_pipe_crc_stop(pipe_crc);
> +
> +	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"), 5);

As it currently stands, this test could fail if the default is 5, or it
could pass if "flip_threshold" was broken and didn't report the actual
flip_threshold anyway. The default being 5 doesn't look to be something
that you necessarily need to be worried about, but it might be worth
reading the value back after setting the threshold to make sure you do
see 5.

> +	igt_pipe_crc_free(pipe_crc);
> +}
> +

Same note about a docblock 🙂:

/*
 * Assert that, for a given source, two consecutive CRCs are equal if
 * the content hasn't changed.
 */

> +static void test_source(data_t *data, const char *source)
> +{
> +	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, source);
> +	igt_crc_t *crcs;
> +
> +	igt_pipe_crc_start(pipe_crc);
> +	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
> +	igt_pipe_crc_stop(pipe_crc);
> +
> +	/* The CRC shouldn't change if the source content hasn't changed */
> +	igt_assert_crc_equal(&crcs[0], &crcs[1]);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +	free(crcs);
> +}
> +

I'm not as certain about what exactly the "outp-inactive" source (or the
other CRC sources) is so I'm not sure what to put in the doc-block that
I'd recommend putting here.

> +static void test_source_outp_inactive(data_t *data)
> +{
> +	struct color_fb colors[] = {
> +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> +	};
> +	igt_pipe_crc_t *pipe_crc;
> +	const int fd = data->drm_fd;
> +	const int n_colors = ARRAY_SIZE(colors);
> +
> +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
> +	create_colors(data, colors, n_colors, pipe_crc);
> +
> +	/* Changing the color should not change what's outside the active raster */
> +	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +	destroy_colors(data, colors, n_colors);
> +}
> +
> +data_t data = {0, };
> +
> +#define pipe_test(name) igt_subtest_f("pipe-%s-" name, kmstest_pipe_name(pipe))
> +igt_main
> +{
> +	int pipe;
> +
> +	igt_fixture {
> +		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
> +		igt_require_nouveau(data.drm_fd);
> +
> +		kmstest_set_vt_graphics_mode();
> +
> +		igt_require_pipe_crc(data.drm_fd);
> +		igt_display_require(&data.display, data.drm_fd);
> +		igt_display_reset(&data.display);
> +	}
> +
> +	for_each_pipe_static(pipe) {
> +		igt_fixture {
> +			int dir;
> +
> +			data.pipe = pipe;
> +			igt_display_require_output_on_pipe(&data.display, pipe);
> +			data.output = igt_get_single_output_for_pipe(&data.display, pipe);
> +			data.mode = igt_output_get_mode(data.output);
> +
> +			/* None of these tests need to perform modesets,
> +			 * just page flips. So running display setup
> +			 * here is fine
> +			 */
> +			igt_output_set_pipe(data.output, pipe);
> +			data.primary = igt_output_get_plane(data.output, 0);
> +			igt_create_color_fb(data.drm_fd,
> +					    data.mode->hdisplay,
> +					    data.mode->vdisplay,
> +					    DRM_FORMAT_XRGB8888,
> +					    LOCAL_DRM_FORMAT_MOD_NONE,
> +					    0.0, 0.0, 0.0,
> +					    &data.default_fb);
> +			igt_plane_set_fb(data.primary, &data.default_fb);
> +			igt_display_commit(&data.display);
> +
> +			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe, O_DIRECTORY);
> +			igt_require_fd(dir);
> +			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
> +			close(dir);
> +			igt_require_fd(data.nv_crc_dir);
> +		}
> +
> +		/* We don't need to test this on every pipe, but the
> +		 * setup is the same */
> +		if (pipe == PIPE_A) {
> +			igt_describe("Make sure that the CRC notifier context flip threshold "
> +				     "is reset to its default value after a single capture.");
> +			igt_subtest("ctx-flip-threshold-reset-after-capture")
> +				test_ctx_flip_threshold_reset_after_capture(&data);
> +		}
> +
> +		igt_describe("Make sure the association between each CRC and its "
> +			     "respective frame index is not broken when the driver "
> +			     "performs a notifier context flip.");
> +		pipe_test("ctx-flip-detection")
> +			test_ctx_flip_detection(&data);
> +
> +		igt_describe("Make sure that igt_pipe_crc_get_current() works even "
> +			     "when the CRC for the current frame index is lost.");
> +		pipe_test("ctx-flip-skip-current-frame")
> +			test_ctx_flip_skip_current_frame(&data);
> +
> +		igt_describe("Check that basic CRC readback using the outp-complete "
> +			     "source works.");
> +		pipe_test("source-outp-complete")
> +			test_source(&data, "outp-complete");
> +
> +		igt_describe("Check that basic CRC readback using the rg source "
> +			     "works.");
> +		pipe_test("source-rg")
> +			test_source(&data, "rg");
> +
> +		igt_describe("Make sure that the outp-inactive source is actually "
> +			     "capturing the inactive raster.");
> +		pipe_test("source-outp-inactive")
> +			test_source_outp_inactive(&data);
> +
> +		igt_fixture {
> +			igt_output_set_pipe(data.output, PIPE_NONE);
> +			igt_display_commit(&data.display);
> +			igt_remove_fb(data.drm_fd, &data.default_fb);
> +			close(data.nv_crc_dir);
> +		}
> +	}
> +	igt_fixture
> +		igt_display_fini(&data.display);
> +
> +}
> -- 
> 2.26.2
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4] tests: Add nouveau-crc tests
@ 2020-09-28 21:36             ` Jeremy Cline
  0 siblings, 0 replies; 33+ messages in thread
From: Jeremy Cline @ 2020-09-28 21:36 UTC (permalink / raw)
  To: Lyude; +Cc: igt-dev, nouveau

Hi,

On Tue, Aug 18, 2020 at 05:00:51PM -0400, Lyude wrote:
> From: Lyude Paul <lyude@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 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@redhat.com>
> ---
>  .gitlab-ci.yml      |   2 +-
>  lib/drmtest.c       |  10 ++
>  lib/drmtest.h       |   2 +
>  tests/meson.build   |   1 +
>  tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 411 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 684de043..92647991 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -74,6 +74,7 @@ test_progs = [
>  	'kms_vblank',
>  	'kms_vrr',
>  	'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..05c2f4de
> --- /dev/null
> +++ b/tests/nouveau_crc.c
> @@ -0,0 +1,397 @@
> +/*
> + * 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));
> +}
> +
> +static void create_colors(data_t *data,
> +			  struct color_fb *colors,
> +			  size_t len,
> +			  igt_pipe_crc_t *pipe_crc)

Not to bikeshed too much, but this function seems to be more about
generating CRCs given some pre-existing colors. Maybe
create_color_crcs() would be better? And it wouldn't hurt to throw a
little docblock on it, even something as short as:

/*
 * Calculate and set the CRC for each color_fb
 */

> +{
> +	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_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);
> +}
> +
> +/* Hard-coded to PIPE_A for now, we don't really need to test this on more then
> + * one head
> + */

Perhaps expand this doc-block out a bit with the details you have in the
commit:

/* Test CRCs are reported across notifier context flips
 *
 * Nvidia GPUs store CRCs in a limited memory region called the notifier
 * context. When the region fills, new CRCs are not reported. To work
 * around this, two notifier contexts are allocated and the driver flips
 * between the two of them when a threshold is reached. Even with this
 * approach, a single frame is lost during the context flip.
 *
 * This test adjusts the threshold at which the notifier context flips
 * to the other context and asserts the CRCs are correctly reported with
 * the exception of the frame lost during the flip.
 *
 * Hard-coded to PIPE_A for now, we don't really need to test this on
 * more then one head
 */

I was guilty of reading the code while testing without going back to
consult the commit message and I only just now realized the test purpose
was clearly explained. It'd be nice to keep that close to the test
definition rather than in the commit log.

Also, as far as I can tell it's not actually hard-coded to PIPE_A, but
test_ctx_flip_threshold_reset_after_capture() is. Maybe I'm
mis-understanding that?

> +static void test_ctx_flip_detection(data_t *data)
> +{
> +	struct color_fb colors[] = {
> +		HEX_COLOR(0xFF, 0x00, 0x18),
> +		HEX_COLOR(0xFF, 0xA5, 0x2C),
> +		HEX_COLOR(0xFF, 0xFF, 0x41),
> +		HEX_COLOR(0x00, 0x80, 0x18),
> +		HEX_COLOR(0x00, 0x00, 0xF9),
> +		HEX_COLOR(0x86, 0x00, 0x7D),
> +	};
> +	igt_output_t *output = data->output;
> +	igt_plane_t *primary = data->primary;
> +	igt_pipe_crc_t *pipe_crc;
> +	const int n_colors = ARRAY_SIZE(colors);
> +	const int n_crcs = 20;
> +	igt_crc_t *crcs = NULL;
> +	int start = -1, frame, start_color = -1, i;
> +	bool found_skip = false;
> +
> +	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
> +
> +	create_colors(data, colors, n_colors, pipe_crc);
> +
> +	set_crc_flip_threshold(data, n_crcs / 2);
> +	igt_pipe_crc_start(pipe_crc);
> +
> +	for (i = 0; i < n_crcs; i++) {
> +		const int color_idx = i % n_colors;
> +
> +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> +		do_or_die(drmModePageFlip(data->drm_fd,
> +					  output->config.crtc->crtc_id,
> +					  colors[color_idx].fb.fb_id,
> +					  DRM_MODE_PAGE_FLIP_EVENT,
> +					  NULL));
> +		kmstest_wait_for_pageflip(data->drm_fd);

While testing I was experiencing some test failures, at which point I
turned on a bunch of debug logging on the kernel side. This led to this
test reliably failing because this call timed out waiting on the pageflip
event, which is unfortunate. I'm not sure what the larger usage of this
particular function is, but having tests start to fail when verbose
logging is enabled isn't ideal.

Obviously hanging forever is also not ideal, so maybe the timeout of
this function just needs adjustment, or even just have the assertion
include a hint that perhaps debug logging is slowing things down too
much. It's not within the scope of this change so I don't think anything
needs to change in this patch, more just wanted to see what folks think
the best approach is since I spent longer than I care to admit figuring
that out and don't want others to have to suffer the same way.

> +	}
> +
> +	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
> +	igt_pipe_crc_stop(pipe_crc);
> +
> +	/*
> +	 * Find the first color in our pattern with a CRC that differs from the
> +	 * last CRC, so we can use it to find the start of the pattern
> +	 */

It might be worth explicitly noting this is to avoid CRC collisions (I'm
assuming) since I had to ponder for a bit:

/*
 * Guard against CRC collisions in the color framebuffers. Find the
 * first color in our pattern with a CRC that differs from the last CRC,
 * so we can use it to find the start of the pattern
 */

> +	for (i = 0; i < n_colors - 1; i++) {
> +		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors - 1].crc))
> +			continue;
> +
> +		igt_debug("Using frame %d of pattern for finding start\n", i);
> +		start_color = i;
> +		break;
> +	}
> +	igt_assert_lte(0, start_color);
> +
> +	/* Now, figure out where the pattern starts */
> +	for (i = 0; i < n_crcs; i++) {
> +		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
> +			continue;
> +
> +		start = i - start_color;
> +		frame = crcs[i].frame;
> +		igt_debug("Pattern started on frame %d\n", frame);
> +		break;
> +	}
> +	igt_assert_lte(0, start);
> +
> +	/* And finally, assert that according to the CRCs exactly all but one
> +	 * frame was displayed in order. The missing frame comes from
> +	 * (inevitably) losing a single CRC event when nouveau switches notifier
> +	 * contexts
> +	 */
> +	for (i = start; i < n_crcs; i++, frame++) {
> +		igt_crc_t *crc = &crcs[i];
> +		char *crc_str;
> +		int color_idx;
> +
> +		crc_str = igt_crc_to_string(crc);
> +		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
> +		free(crc_str);
> +
> +		if (!found_skip && crc->frame != frame) {
> +			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
> +				  crc->frame - 1);
> +			found_skip = true;
> +			frame++;
> +		}
> +
> +		/* We should never skip more then one frame */
> +		if (found_skip) {
> +			igt_assert_eq(crc->frame, frame);
> +			color_idx = (i - start + 1) % n_colors;
> +		} else {
> +			color_idx = (i - start) % n_colors;
> +		}
> +
> +		igt_assert_crc_equal(crc, &colors[color_idx].crc);

This consistently fails for me. The reason is that there are multiple
frames with the same color/CRC. As far as I can tell, that's perfectly
reasonable when a page flip is slow (possibly due to debug logs 😬), but
I don't know for certain what the interface expectations are.

If that assumption is correct, I guess you'll need to expect either the
same color as the previous frame, or the next color in the array after
the color in the previous frame.

> +	}
> +	igt_assert(found_skip);
> +
> +	free(crcs);
> +	igt_pipe_crc_free(pipe_crc);
> +	destroy_colors(data, colors, ARRAY_SIZE(colors));
> +}
> +
> +/* Test whether or not IGT is able to handle frame skips when requesting the
> + * CRC for the current frame
> + */
> +static void test_ctx_flip_skip_current_frame(data_t *data)
> +{
> +	struct color_fb colors[] = {
> +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> +		{ .r = 0.0, .g = 0.0, .b = 1.0 },
> +	};
> +	igt_output_t *output = data->output;
> +	igt_pipe_crc_t *pipe_crc;
> +	igt_plane_t *primary = data->primary;
> +	const int fd = data->drm_fd;
> +	const int n_colors = ARRAY_SIZE(colors);
> +	const int n_crcs = 30;
> +
> +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> +	create_colors(data, colors, n_colors, pipe_crc);
> +
> +	set_crc_flip_threshold(data, 5);
> +	igt_pipe_crc_start(pipe_crc);
> +
> +	for (int i = 0; i < n_crcs; i++) {
> +		igt_crc_t crc;
> +		const int color_idx = i % n_colors;
> +
> +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> +		do_or_die(drmModePageFlip(fd,
> +					  output->config.crtc->crtc_id,
> +					  colors[color_idx].fb.fb_id,
> +					  DRM_MODE_PAGE_FLIP_EVENT,
> +					  NULL));
> +		kmstest_wait_for_pageflip(fd);
> +
> +		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
> +		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
> +	}
> +
> +	igt_pipe_crc_stop(pipe_crc);
> +	igt_pipe_crc_free(pipe_crc);
> +	destroy_colors(data, colors, n_colors);
> +}
> +

Maybe a short doc-block with what the test should be doing here would be
good:

/*
 * Assert that after a CRC capture is started and stopped, the context
 * notifier flip threshold is reset to its default value.
 */

> +static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
> +{
> +	igt_pipe_crc_t *pipe_crc;
> +	const int fd = data->drm_fd;
> +
> +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> +
> +	set_crc_flip_threshold(data, 5);
> +	igt_pipe_crc_start(pipe_crc);
> +	igt_pipe_crc_stop(pipe_crc);
> +
> +	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"), 5);

As it currently stands, this test could fail if the default is 5, or it
could pass if "flip_threshold" was broken and didn't report the actual
flip_threshold anyway. The default being 5 doesn't look to be something
that you necessarily need to be worried about, but it might be worth
reading the value back after setting the threshold to make sure you do
see 5.

> +	igt_pipe_crc_free(pipe_crc);
> +}
> +

Same note about a docblock 🙂:

/*
 * Assert that, for a given source, two consecutive CRCs are equal if
 * the content hasn't changed.
 */

> +static void test_source(data_t *data, const char *source)
> +{
> +	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, source);
> +	igt_crc_t *crcs;
> +
> +	igt_pipe_crc_start(pipe_crc);
> +	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
> +	igt_pipe_crc_stop(pipe_crc);
> +
> +	/* The CRC shouldn't change if the source content hasn't changed */
> +	igt_assert_crc_equal(&crcs[0], &crcs[1]);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +	free(crcs);
> +}
> +

I'm not as certain about what exactly the "outp-inactive" source (or the
other CRC sources) is so I'm not sure what to put in the doc-block that
I'd recommend putting here.

> +static void test_source_outp_inactive(data_t *data)
> +{
> +	struct color_fb colors[] = {
> +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> +	};
> +	igt_pipe_crc_t *pipe_crc;
> +	const int fd = data->drm_fd;
> +	const int n_colors = ARRAY_SIZE(colors);
> +
> +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
> +	create_colors(data, colors, n_colors, pipe_crc);
> +
> +	/* Changing the color should not change what's outside the active raster */
> +	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +	destroy_colors(data, colors, n_colors);
> +}
> +
> +data_t data = {0, };
> +
> +#define pipe_test(name) igt_subtest_f("pipe-%s-" name, kmstest_pipe_name(pipe))
> +igt_main
> +{
> +	int pipe;
> +
> +	igt_fixture {
> +		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
> +		igt_require_nouveau(data.drm_fd);
> +
> +		kmstest_set_vt_graphics_mode();
> +
> +		igt_require_pipe_crc(data.drm_fd);
> +		igt_display_require(&data.display, data.drm_fd);
> +		igt_display_reset(&data.display);
> +	}
> +
> +	for_each_pipe_static(pipe) {
> +		igt_fixture {
> +			int dir;
> +
> +			data.pipe = pipe;
> +			igt_display_require_output_on_pipe(&data.display, pipe);
> +			data.output = igt_get_single_output_for_pipe(&data.display, pipe);
> +			data.mode = igt_output_get_mode(data.output);
> +
> +			/* None of these tests need to perform modesets,
> +			 * just page flips. So running display setup
> +			 * here is fine
> +			 */
> +			igt_output_set_pipe(data.output, pipe);
> +			data.primary = igt_output_get_plane(data.output, 0);
> +			igt_create_color_fb(data.drm_fd,
> +					    data.mode->hdisplay,
> +					    data.mode->vdisplay,
> +					    DRM_FORMAT_XRGB8888,
> +					    LOCAL_DRM_FORMAT_MOD_NONE,
> +					    0.0, 0.0, 0.0,
> +					    &data.default_fb);
> +			igt_plane_set_fb(data.primary, &data.default_fb);
> +			igt_display_commit(&data.display);
> +
> +			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe, O_DIRECTORY);
> +			igt_require_fd(dir);
> +			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
> +			close(dir);
> +			igt_require_fd(data.nv_crc_dir);
> +		}
> +
> +		/* We don't need to test this on every pipe, but the
> +		 * setup is the same */
> +		if (pipe == PIPE_A) {
> +			igt_describe("Make sure that the CRC notifier context flip threshold "
> +				     "is reset to its default value after a single capture.");
> +			igt_subtest("ctx-flip-threshold-reset-after-capture")
> +				test_ctx_flip_threshold_reset_after_capture(&data);
> +		}
> +
> +		igt_describe("Make sure the association between each CRC and its "
> +			     "respective frame index is not broken when the driver "
> +			     "performs a notifier context flip.");
> +		pipe_test("ctx-flip-detection")
> +			test_ctx_flip_detection(&data);
> +
> +		igt_describe("Make sure that igt_pipe_crc_get_current() works even "
> +			     "when the CRC for the current frame index is lost.");
> +		pipe_test("ctx-flip-skip-current-frame")
> +			test_ctx_flip_skip_current_frame(&data);
> +
> +		igt_describe("Check that basic CRC readback using the outp-complete "
> +			     "source works.");
> +		pipe_test("source-outp-complete")
> +			test_source(&data, "outp-complete");
> +
> +		igt_describe("Check that basic CRC readback using the rg source "
> +			     "works.");
> +		pipe_test("source-rg")
> +			test_source(&data, "rg");
> +
> +		igt_describe("Make sure that the outp-inactive source is actually "
> +			     "capturing the inactive raster.");
> +		pipe_test("source-outp-inactive")
> +			test_source_outp_inactive(&data);
> +
> +		igt_fixture {
> +			igt_output_set_pipe(data.output, PIPE_NONE);
> +			igt_display_commit(&data.display);
> +			igt_remove_fb(data.drm_fd, &data.default_fb);
> +			close(data.nv_crc_dir);
> +		}
> +	}
> +	igt_fixture
> +		igt_display_fini(&data.display);
> +
> +}
> -- 
> 2.26.2
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4] tests: Add nouveau-crc tests
  2020-09-28 21:36             ` Jeremy Cline
@ 2020-09-29 16:13               ` Lyude Paul
  -1 siblings, 0 replies; 33+ messages in thread
From: Lyude Paul @ 2020-09-29 16:13 UTC (permalink / raw)
  To: Jeremy Cline
  Cc: igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Mon, 2020-09-28 at 17:36 -0400, Jeremy Cline wrote:
> Hi,
> 
> On Tue, Aug 18, 2020 at 05:00:51PM -0400, Lyude wrote:
> > From: Lyude Paul <lyude@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 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@redhat.com>
> > ---
> >  .gitlab-ci.yml      |   2 +-
> >  lib/drmtest.c       |  10 ++
> >  lib/drmtest.h       |   2 +
> >  tests/meson.build   |   1 +
> >  tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 411 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 684de043..92647991 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -74,6 +74,7 @@ test_progs = [
> >  	'kms_vblank',
> >  	'kms_vrr',
> >  	'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..05c2f4de
> > --- /dev/null
> > +++ b/tests/nouveau_crc.c
> > @@ -0,0 +1,397 @@
> > +/*
> > + * 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));
> > +}
> > +
> > +static void create_colors(data_t *data,
> > +			  struct color_fb *colors,
> > +			  size_t len,
> > +			  igt_pipe_crc_t *pipe_crc)
> 
> Not to bikeshed too much, but this function seems to be more about
> generating CRCs given some pre-existing colors. Maybe
> create_color_crcs() would be better? And it wouldn't hurt to throw a
> little docblock on it, even something as short as:
> 
> /*
>  * Calculate and set the CRC for each color_fb
>  */
> 
> > +{
> > +	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_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);
> > +}
> > +
> > +/* Hard-coded to PIPE_A for now, we don't really need to test this on
> > more then
> > + * one head
> > + */
> 
> Perhaps expand this doc-block out a bit with the details you have in the
> commit:
> 
> /* Test CRCs are reported across notifier context flips
>  *
>  * Nvidia GPUs store CRCs in a limited memory region called the notifier
>  * context. When the region fills, new CRCs are not reported. To work
>  * around this, two notifier contexts are allocated and the driver flips
>  * between the two of them when a threshold is reached. Even with this
>  * approach, a single frame is lost during the context flip.
>  *
>  * This test adjusts the threshold at which the notifier context flips
>  * to the other context and asserts the CRCs are correctly reported with
>  * the exception of the frame lost during the flip.
>  *
>  * Hard-coded to PIPE_A for now, we don't really need to test this on
>  * more then one head
>  */
> 
> I was guilty of reading the code while testing without going back to
> consult the commit message and I only just now realized the test purpose
> was clearly explained. It'd be nice to keep that close to the test
> definition rather than in the commit log.
> 
> Also, as far as I can tell it's not actually hard-coded to PIPE_A, but
> test_ctx_flip_threshold_reset_after_capture() is. Maybe I'm
> mis-understanding that?

No you aren't-that's definitely a bit of doc I had written before all of the
tests were complete and I was undecided if we needed to test this on all pipes
or not (turned out all pipes is a good idea).

> 
> > +static void test_ctx_flip_detection(data_t *data)
> > +{
> > +	struct color_fb colors[] = {
> > +		HEX_COLOR(0xFF, 0x00, 0x18),
> > +		HEX_COLOR(0xFF, 0xA5, 0x2C),
> > +		HEX_COLOR(0xFF, 0xFF, 0x41),
> > +		HEX_COLOR(0x00, 0x80, 0x18),
> > +		HEX_COLOR(0x00, 0x00, 0xF9),
> > +		HEX_COLOR(0x86, 0x00, 0x7D),
> > +	};
> > +	igt_output_t *output = data->output;
> > +	igt_plane_t *primary = data->primary;
> > +	igt_pipe_crc_t *pipe_crc;
> > +	const int n_colors = ARRAY_SIZE(colors);
> > +	const int n_crcs = 20;
> > +	igt_crc_t *crcs = NULL;
> > +	int start = -1, frame, start_color = -1, i;
> > +	bool found_skip = false;
> > +
> > +	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
> > +
> > +	create_colors(data, colors, n_colors, pipe_crc);
> > +
> > +	set_crc_flip_threshold(data, n_crcs / 2);
> > +	igt_pipe_crc_start(pipe_crc);
> > +
> > +	for (i = 0; i < n_crcs; i++) {
> > +		const int color_idx = i % n_colors;
> > +
> > +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> > +		do_or_die(drmModePageFlip(data->drm_fd,
> > +					  output->config.crtc->crtc_id,
> > +					  colors[color_idx].fb.fb_id,
> > +					  DRM_MODE_PAGE_FLIP_EVENT,
> > +					  NULL));
> > +		kmstest_wait_for_pageflip(data->drm_fd);
> 
> While testing I was experiencing some test failures, at which point I
> turned on a bunch of debug logging on the kernel side. This led to this
> test reliably failing because this call timed out waiting on the pageflip
> event, which is unfortunate. I'm not sure what the larger usage of this
> particular function is, but having tests start to fail when verbose
> logging is enabled isn't ideal.
> 
> Obviously hanging forever is also not ideal, so maybe the timeout of
> this function just needs adjustment, or even just have the assertion
> include a hint that perhaps debug logging is slowing things down too
> much. It's not within the scope of this change so I don't think anything
> needs to change in this patch, more just wanted to see what folks think
> the best approach is since I spent longer than I care to admit figuring
> that out and don't want others to have to suffer the same way.

If you turn on enough debugging info it definitely makes sense that it might
cause us to miss a page flip on accident, although I've never managed to get
debugging output to slow things down that much. We should probably look to see
if there's anything we could do to speed up debugging output like that on
nouveau's side.

JFYI too - we shouldn't ever be missing a pageflip in general and for this
test, especially under normal circumstances since it sounds like you were
seeing intermittent failures before you had debugging code turned on? We can't
accurately figure out if the CRC flip happened otherwise since we rely on
there being exactly one frame with a missing CRC, with each successive frame
matching the steps in the color pattern that would have followed that frame. 

> 
> > +	}
> > +
> > +	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
> > +	igt_pipe_crc_stop(pipe_crc);
> > +
> > +	/*
> > +	 * Find the first color in our pattern with a CRC that differs from
> > the
> > +	 * last CRC, so we can use it to find the start of the pattern
> > +	 */
> 
> It might be worth explicitly noting this is to avoid CRC collisions (I'm
> assuming) since I had to ponder for a bit:
> 
> /*
>  * Guard against CRC collisions in the color framebuffers. Find the
>  * first color in our pattern with a CRC that differs from the last CRC,
>  * so we can use it to find the start of the pattern
>  */
> 
> > +	for (i = 0; i < n_colors - 1; i++) {
> > +		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors -
> > 1].crc))
> > +			continue;
> > +
> > +		igt_debug("Using frame %d of pattern for finding start\n", i);
> > +		start_color = i;
> > +		break;
> > +	}
> > +	igt_assert_lte(0, start_color);
> > +
> > +	/* Now, figure out where the pattern starts */
> > +	for (i = 0; i < n_crcs; i++) {
> > +		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
> > +			continue;
> > +
> > +		start = i - start_color;
> > +		frame = crcs[i].frame;
> > +		igt_debug("Pattern started on frame %d\n", frame);
> > +		break;
> > +	}
> > +	igt_assert_lte(0, start);
> > +
> > +	/* And finally, assert that according to the CRCs exactly all but one
> > +	 * frame was displayed in order. The missing frame comes from
> > +	 * (inevitably) losing a single CRC event when nouveau switches
> > notifier
> > +	 * contexts
> > +	 */
> > +	for (i = start; i < n_crcs; i++, frame++) {
> > +		igt_crc_t *crc = &crcs[i];
> > +		char *crc_str;
> > +		int color_idx;
> > +
> > +		crc_str = igt_crc_to_string(crc);
> > +		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
> > +		free(crc_str);
> > +
> > +		if (!found_skip && crc->frame != frame) {
> > +			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
> > +				  crc->frame - 1);
> > +			found_skip = true;
> > +			frame++;
> > +		}
> > +
> > +		/* We should never skip more then one frame */
> > +		if (found_skip) {
> > +			igt_assert_eq(crc->frame, frame);
> > +			color_idx = (i - start + 1) % n_colors;
> > +		} else {
> > +			color_idx = (i - start) % n_colors;
> > +		}
> > +
> > +		igt_assert_crc_equal(crc, &colors[color_idx].crc);
> 
> This consistently fails for me. The reason is that there are multiple
> frames with the same color/CRC. As far as I can tell, that's perfectly
> reasonable when a page flip is slow (possibly due to debug logs 😬), but
> I don't know for certain what the interface expectations are.

Yeah-something is definitely broken with your setup. Page flips should never
be slow, except -maybe- in the most exceptional of debugging circumstances.

> 
> If that assumption is correct, I guess you'll need to expect either the
> same color as the previous frame, or the next color in the array after
> the color in the previous frame.
> 
> > +	}
> > +	igt_assert(found_skip);
> > +
> > +	free(crcs);
> > +	igt_pipe_crc_free(pipe_crc);
> > +	destroy_colors(data, colors, ARRAY_SIZE(colors));
> > +}
> > +
> > +/* Test whether or not IGT is able to handle frame skips when requesting
> > the
> > + * CRC for the current frame
> > + */
> > +static void test_ctx_flip_skip_current_frame(data_t *data)
> > +{
> > +	struct color_fb colors[] = {
> > +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> > +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> > +		{ .r = 0.0, .g = 0.0, .b = 1.0 },
> > +	};
> > +	igt_output_t *output = data->output;
> > +	igt_pipe_crc_t *pipe_crc;
> > +	igt_plane_t *primary = data->primary;
> > +	const int fd = data->drm_fd;
> > +	const int n_colors = ARRAY_SIZE(colors);
> > +	const int n_crcs = 30;
> > +
> > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> > +	create_colors(data, colors, n_colors, pipe_crc);
> > +
> > +	set_crc_flip_threshold(data, 5);
> > +	igt_pipe_crc_start(pipe_crc);
> > +
> > +	for (int i = 0; i < n_crcs; i++) {
> > +		igt_crc_t crc;
> > +		const int color_idx = i % n_colors;
> > +
> > +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> > +		do_or_die(drmModePageFlip(fd,
> > +					  output->config.crtc->crtc_id,
> > +					  colors[color_idx].fb.fb_id,
> > +					  DRM_MODE_PAGE_FLIP_EVENT,
> > +					  NULL));
> > +		kmstest_wait_for_pageflip(fd);
> > +
> > +		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
> > +		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
> > +	}
> > +
> > +	igt_pipe_crc_stop(pipe_crc);
> > +	igt_pipe_crc_free(pipe_crc);
> > +	destroy_colors(data, colors, n_colors);
> > +}
> > +
> 
> Maybe a short doc-block with what the test should be doing here would be
> good:
> 
> /*
>  * Assert that after a CRC capture is started and stopped, the context
>  * notifier flip threshold is reset to its default value.
>  */
> 
> > +static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
> > +{
> > +	igt_pipe_crc_t *pipe_crc;
> > +	const int fd = data->drm_fd;
> > +
> > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> > +
> > +	set_crc_flip_threshold(data, 5);
> > +	igt_pipe_crc_start(pipe_crc);
> > +	igt_pipe_crc_stop(pipe_crc);
> > +
> > +	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"),
> > 5);
> 
> As it currently stands, this test could fail if the default is 5, or it
> could pass if "flip_threshold" was broken and didn't report the actual
> flip_threshold anyway. The default being 5 doesn't look to be something
> that you necessarily need to be worried about, but it might be worth
> reading the value back after setting the threshold to make sure you do
> see 5.
> 
> > +	igt_pipe_crc_free(pipe_crc);
> > +}
> > +
> 
> Same note about a docblock 🙂:
> 
> /*
>  * Assert that, for a given source, two consecutive CRCs are equal if
>  * the content hasn't changed.
>  */
> 
> > +static void test_source(data_t *data, const char *source)
> > +{
> > +	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe,
> > source);
> > +	igt_crc_t *crcs;
> > +
> > +	igt_pipe_crc_start(pipe_crc);
> > +	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
> > +	igt_pipe_crc_stop(pipe_crc);
> > +
> > +	/* The CRC shouldn't change if the source content hasn't changed */
> > +	igt_assert_crc_equal(&crcs[0], &crcs[1]);
> > +
> > +	igt_pipe_crc_free(pipe_crc);
> > +	free(crcs);
> > +}
> > +
> 
> I'm not as certain about what exactly the "outp-inactive" source (or the
> other CRC sources) is so I'm not sure what to put in the doc-block that
> I'd recommend putting here.
> 
> > +static void test_source_outp_inactive(data_t *data)
> > +{
> > +	struct color_fb colors[] = {
> > +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> > +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> > +	};
> > +	igt_pipe_crc_t *pipe_crc;
> > +	const int fd = data->drm_fd;
> > +	const int n_colors = ARRAY_SIZE(colors);
> > +
> > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
> > +	create_colors(data, colors, n_colors, pipe_crc);
> > +
> > +	/* Changing the color should not change what's outside the active
> > raster */
> > +	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
> > +
> > +	igt_pipe_crc_free(pipe_crc);
> > +	destroy_colors(data, colors, n_colors);
> > +}
> > +
> > +data_t data = {0, };
> > +
> > +#define pipe_test(name) igt_subtest_f("pipe-%s-" name,
> > kmstest_pipe_name(pipe))
> > +igt_main
> > +{
> > +	int pipe;
> > +
> > +	igt_fixture {
> > +		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > +		igt_require_nouveau(data.drm_fd);
> > +
> > +		kmstest_set_vt_graphics_mode();
> > +
> > +		igt_require_pipe_crc(data.drm_fd);
> > +		igt_display_require(&data.display, data.drm_fd);
> > +		igt_display_reset(&data.display);
> > +	}
> > +
> > +	for_each_pipe_static(pipe) {
> > +		igt_fixture {
> > +			int dir;
> > +
> > +			data.pipe = pipe;
> > +			igt_display_require_output_on_pipe(&data.display,
> > pipe);
> > +			data.output =
> > igt_get_single_output_for_pipe(&data.display, pipe);
> > +			data.mode = igt_output_get_mode(data.output);
> > +
> > +			/* None of these tests need to perform modesets,
> > +			 * just page flips. So running display setup
> > +			 * here is fine
> > +			 */
> > +			igt_output_set_pipe(data.output, pipe);
> > +			data.primary = igt_output_get_plane(data.output, 0);
> > +			igt_create_color_fb(data.drm_fd,
> > +					    data.mode->hdisplay,
> > +					    data.mode->vdisplay,
> > +					    DRM_FORMAT_XRGB8888,
> > +					    LOCAL_DRM_FORMAT_MOD_NONE,
> > +					    0.0, 0.0, 0.0,
> > +					    &data.default_fb);
> > +			igt_plane_set_fb(data.primary, &data.default_fb);
> > +			igt_display_commit(&data.display);
> > +
> > +			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe,
> > O_DIRECTORY);
> > +			igt_require_fd(dir);
> > +			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
> > +			close(dir);
> > +			igt_require_fd(data.nv_crc_dir);
> > +		}
> > +
> > +		/* We don't need to test this on every pipe, but the
> > +		 * setup is the same */
> > +		if (pipe == PIPE_A) {
> > +			igt_describe("Make sure that the CRC notifier context
> > flip threshold "
> > +				     "is reset to its default value after a
> > single capture.");
> > +			igt_subtest("ctx-flip-threshold-reset-after-capture")
> > +				test_ctx_flip_threshold_reset_after_capture(&d
> > ata);
> > +		}
> > +
> > +		igt_describe("Make sure the association between each CRC and
> > its "
> > +			     "respective frame index is not broken when the
> > driver "
> > +			     "performs a notifier context flip.");
> > +		pipe_test("ctx-flip-detection")
> > +			test_ctx_flip_detection(&data);
> > +
> > +		igt_describe("Make sure that igt_pipe_crc_get_current() works
> > even "
> > +			     "when the CRC for the current frame index is
> > lost.");
> > +		pipe_test("ctx-flip-skip-current-frame")
> > +			test_ctx_flip_skip_current_frame(&data);
> > +
> > +		igt_describe("Check that basic CRC readback using the outp-
> > complete "
> > +			     "source works.");
> > +		pipe_test("source-outp-complete")
> > +			test_source(&data, "outp-complete");
> > +
> > +		igt_describe("Check that basic CRC readback using the rg
> > source "
> > +			     "works.");
> > +		pipe_test("source-rg")
> > +			test_source(&data, "rg");
> > +
> > +		igt_describe("Make sure that the outp-inactive source is
> > actually "
> > +			     "capturing the inactive raster.");
> > +		pipe_test("source-outp-inactive")
> > +			test_source_outp_inactive(&data);
> > +
> > +		igt_fixture {
> > +			igt_output_set_pipe(data.output, PIPE_NONE);
> > +			igt_display_commit(&data.display);
> > +			igt_remove_fb(data.drm_fd, &data.default_fb);
> > +			close(data.nv_crc_dir);
> > +		}
> > +	}
> > +	igt_fixture
> > +		igt_display_fini(&data.display);
> > +
> > +}
> > -- 
> > 2.26.2
> > 
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev
-- 
Cheers,
	Lyude Paul (she/her)
	Software Engineer at Red Hat

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4] tests: Add nouveau-crc tests
@ 2020-09-29 16:13               ` Lyude Paul
  0 siblings, 0 replies; 33+ messages in thread
From: Lyude Paul @ 2020-09-29 16:13 UTC (permalink / raw)
  To: Jeremy Cline; +Cc: igt-dev, nouveau

On Mon, 2020-09-28 at 17:36 -0400, Jeremy Cline wrote:
> Hi,
> 
> On Tue, Aug 18, 2020 at 05:00:51PM -0400, Lyude wrote:
> > From: Lyude Paul <lyude@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 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@redhat.com>
> > ---
> >  .gitlab-ci.yml      |   2 +-
> >  lib/drmtest.c       |  10 ++
> >  lib/drmtest.h       |   2 +
> >  tests/meson.build   |   1 +
> >  tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 411 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 684de043..92647991 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -74,6 +74,7 @@ test_progs = [
> >  	'kms_vblank',
> >  	'kms_vrr',
> >  	'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..05c2f4de
> > --- /dev/null
> > +++ b/tests/nouveau_crc.c
> > @@ -0,0 +1,397 @@
> > +/*
> > + * 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));
> > +}
> > +
> > +static void create_colors(data_t *data,
> > +			  struct color_fb *colors,
> > +			  size_t len,
> > +			  igt_pipe_crc_t *pipe_crc)
> 
> Not to bikeshed too much, but this function seems to be more about
> generating CRCs given some pre-existing colors. Maybe
> create_color_crcs() would be better? And it wouldn't hurt to throw a
> little docblock on it, even something as short as:
> 
> /*
>  * Calculate and set the CRC for each color_fb
>  */
> 
> > +{
> > +	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_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);
> > +}
> > +
> > +/* Hard-coded to PIPE_A for now, we don't really need to test this on
> > more then
> > + * one head
> > + */
> 
> Perhaps expand this doc-block out a bit with the details you have in the
> commit:
> 
> /* Test CRCs are reported across notifier context flips
>  *
>  * Nvidia GPUs store CRCs in a limited memory region called the notifier
>  * context. When the region fills, new CRCs are not reported. To work
>  * around this, two notifier contexts are allocated and the driver flips
>  * between the two of them when a threshold is reached. Even with this
>  * approach, a single frame is lost during the context flip.
>  *
>  * This test adjusts the threshold at which the notifier context flips
>  * to the other context and asserts the CRCs are correctly reported with
>  * the exception of the frame lost during the flip.
>  *
>  * Hard-coded to PIPE_A for now, we don't really need to test this on
>  * more then one head
>  */
> 
> I was guilty of reading the code while testing without going back to
> consult the commit message and I only just now realized the test purpose
> was clearly explained. It'd be nice to keep that close to the test
> definition rather than in the commit log.
> 
> Also, as far as I can tell it's not actually hard-coded to PIPE_A, but
> test_ctx_flip_threshold_reset_after_capture() is. Maybe I'm
> mis-understanding that?

No you aren't-that's definitely a bit of doc I had written before all of the
tests were complete and I was undecided if we needed to test this on all pipes
or not (turned out all pipes is a good idea).

> 
> > +static void test_ctx_flip_detection(data_t *data)
> > +{
> > +	struct color_fb colors[] = {
> > +		HEX_COLOR(0xFF, 0x00, 0x18),
> > +		HEX_COLOR(0xFF, 0xA5, 0x2C),
> > +		HEX_COLOR(0xFF, 0xFF, 0x41),
> > +		HEX_COLOR(0x00, 0x80, 0x18),
> > +		HEX_COLOR(0x00, 0x00, 0xF9),
> > +		HEX_COLOR(0x86, 0x00, 0x7D),
> > +	};
> > +	igt_output_t *output = data->output;
> > +	igt_plane_t *primary = data->primary;
> > +	igt_pipe_crc_t *pipe_crc;
> > +	const int n_colors = ARRAY_SIZE(colors);
> > +	const int n_crcs = 20;
> > +	igt_crc_t *crcs = NULL;
> > +	int start = -1, frame, start_color = -1, i;
> > +	bool found_skip = false;
> > +
> > +	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
> > +
> > +	create_colors(data, colors, n_colors, pipe_crc);
> > +
> > +	set_crc_flip_threshold(data, n_crcs / 2);
> > +	igt_pipe_crc_start(pipe_crc);
> > +
> > +	for (i = 0; i < n_crcs; i++) {
> > +		const int color_idx = i % n_colors;
> > +
> > +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> > +		do_or_die(drmModePageFlip(data->drm_fd,
> > +					  output->config.crtc->crtc_id,
> > +					  colors[color_idx].fb.fb_id,
> > +					  DRM_MODE_PAGE_FLIP_EVENT,
> > +					  NULL));
> > +		kmstest_wait_for_pageflip(data->drm_fd);
> 
> While testing I was experiencing some test failures, at which point I
> turned on a bunch of debug logging on the kernel side. This led to this
> test reliably failing because this call timed out waiting on the pageflip
> event, which is unfortunate. I'm not sure what the larger usage of this
> particular function is, but having tests start to fail when verbose
> logging is enabled isn't ideal.
> 
> Obviously hanging forever is also not ideal, so maybe the timeout of
> this function just needs adjustment, or even just have the assertion
> include a hint that perhaps debug logging is slowing things down too
> much. It's not within the scope of this change so I don't think anything
> needs to change in this patch, more just wanted to see what folks think
> the best approach is since I spent longer than I care to admit figuring
> that out and don't want others to have to suffer the same way.

If you turn on enough debugging info it definitely makes sense that it might
cause us to miss a page flip on accident, although I've never managed to get
debugging output to slow things down that much. We should probably look to see
if there's anything we could do to speed up debugging output like that on
nouveau's side.

JFYI too - we shouldn't ever be missing a pageflip in general and for this
test, especially under normal circumstances since it sounds like you were
seeing intermittent failures before you had debugging code turned on? We can't
accurately figure out if the CRC flip happened otherwise since we rely on
there being exactly one frame with a missing CRC, with each successive frame
matching the steps in the color pattern that would have followed that frame. 

> 
> > +	}
> > +
> > +	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
> > +	igt_pipe_crc_stop(pipe_crc);
> > +
> > +	/*
> > +	 * Find the first color in our pattern with a CRC that differs from
> > the
> > +	 * last CRC, so we can use it to find the start of the pattern
> > +	 */
> 
> It might be worth explicitly noting this is to avoid CRC collisions (I'm
> assuming) since I had to ponder for a bit:
> 
> /*
>  * Guard against CRC collisions in the color framebuffers. Find the
>  * first color in our pattern with a CRC that differs from the last CRC,
>  * so we can use it to find the start of the pattern
>  */
> 
> > +	for (i = 0; i < n_colors - 1; i++) {
> > +		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors -
> > 1].crc))
> > +			continue;
> > +
> > +		igt_debug("Using frame %d of pattern for finding start\n", i);
> > +		start_color = i;
> > +		break;
> > +	}
> > +	igt_assert_lte(0, start_color);
> > +
> > +	/* Now, figure out where the pattern starts */
> > +	for (i = 0; i < n_crcs; i++) {
> > +		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
> > +			continue;
> > +
> > +		start = i - start_color;
> > +		frame = crcs[i].frame;
> > +		igt_debug("Pattern started on frame %d\n", frame);
> > +		break;
> > +	}
> > +	igt_assert_lte(0, start);
> > +
> > +	/* And finally, assert that according to the CRCs exactly all but one
> > +	 * frame was displayed in order. The missing frame comes from
> > +	 * (inevitably) losing a single CRC event when nouveau switches
> > notifier
> > +	 * contexts
> > +	 */
> > +	for (i = start; i < n_crcs; i++, frame++) {
> > +		igt_crc_t *crc = &crcs[i];
> > +		char *crc_str;
> > +		int color_idx;
> > +
> > +		crc_str = igt_crc_to_string(crc);
> > +		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
> > +		free(crc_str);
> > +
> > +		if (!found_skip && crc->frame != frame) {
> > +			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
> > +				  crc->frame - 1);
> > +			found_skip = true;
> > +			frame++;
> > +		}
> > +
> > +		/* We should never skip more then one frame */
> > +		if (found_skip) {
> > +			igt_assert_eq(crc->frame, frame);
> > +			color_idx = (i - start + 1) % n_colors;
> > +		} else {
> > +			color_idx = (i - start) % n_colors;
> > +		}
> > +
> > +		igt_assert_crc_equal(crc, &colors[color_idx].crc);
> 
> This consistently fails for me. The reason is that there are multiple
> frames with the same color/CRC. As far as I can tell, that's perfectly
> reasonable when a page flip is slow (possibly due to debug logs 😬), but
> I don't know for certain what the interface expectations are.

Yeah-something is definitely broken with your setup. Page flips should never
be slow, except -maybe- in the most exceptional of debugging circumstances.

> 
> If that assumption is correct, I guess you'll need to expect either the
> same color as the previous frame, or the next color in the array after
> the color in the previous frame.
> 
> > +	}
> > +	igt_assert(found_skip);
> > +
> > +	free(crcs);
> > +	igt_pipe_crc_free(pipe_crc);
> > +	destroy_colors(data, colors, ARRAY_SIZE(colors));
> > +}
> > +
> > +/* Test whether or not IGT is able to handle frame skips when requesting
> > the
> > + * CRC for the current frame
> > + */
> > +static void test_ctx_flip_skip_current_frame(data_t *data)
> > +{
> > +	struct color_fb colors[] = {
> > +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> > +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> > +		{ .r = 0.0, .g = 0.0, .b = 1.0 },
> > +	};
> > +	igt_output_t *output = data->output;
> > +	igt_pipe_crc_t *pipe_crc;
> > +	igt_plane_t *primary = data->primary;
> > +	const int fd = data->drm_fd;
> > +	const int n_colors = ARRAY_SIZE(colors);
> > +	const int n_crcs = 30;
> > +
> > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> > +	create_colors(data, colors, n_colors, pipe_crc);
> > +
> > +	set_crc_flip_threshold(data, 5);
> > +	igt_pipe_crc_start(pipe_crc);
> > +
> > +	for (int i = 0; i < n_crcs; i++) {
> > +		igt_crc_t crc;
> > +		const int color_idx = i % n_colors;
> > +
> > +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> > +		do_or_die(drmModePageFlip(fd,
> > +					  output->config.crtc->crtc_id,
> > +					  colors[color_idx].fb.fb_id,
> > +					  DRM_MODE_PAGE_FLIP_EVENT,
> > +					  NULL));
> > +		kmstest_wait_for_pageflip(fd);
> > +
> > +		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
> > +		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
> > +	}
> > +
> > +	igt_pipe_crc_stop(pipe_crc);
> > +	igt_pipe_crc_free(pipe_crc);
> > +	destroy_colors(data, colors, n_colors);
> > +}
> > +
> 
> Maybe a short doc-block with what the test should be doing here would be
> good:
> 
> /*
>  * Assert that after a CRC capture is started and stopped, the context
>  * notifier flip threshold is reset to its default value.
>  */
> 
> > +static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
> > +{
> > +	igt_pipe_crc_t *pipe_crc;
> > +	const int fd = data->drm_fd;
> > +
> > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> > +
> > +	set_crc_flip_threshold(data, 5);
> > +	igt_pipe_crc_start(pipe_crc);
> > +	igt_pipe_crc_stop(pipe_crc);
> > +
> > +	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"),
> > 5);
> 
> As it currently stands, this test could fail if the default is 5, or it
> could pass if "flip_threshold" was broken and didn't report the actual
> flip_threshold anyway. The default being 5 doesn't look to be something
> that you necessarily need to be worried about, but it might be worth
> reading the value back after setting the threshold to make sure you do
> see 5.
> 
> > +	igt_pipe_crc_free(pipe_crc);
> > +}
> > +
> 
> Same note about a docblock 🙂:
> 
> /*
>  * Assert that, for a given source, two consecutive CRCs are equal if
>  * the content hasn't changed.
>  */
> 
> > +static void test_source(data_t *data, const char *source)
> > +{
> > +	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe,
> > source);
> > +	igt_crc_t *crcs;
> > +
> > +	igt_pipe_crc_start(pipe_crc);
> > +	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
> > +	igt_pipe_crc_stop(pipe_crc);
> > +
> > +	/* The CRC shouldn't change if the source content hasn't changed */
> > +	igt_assert_crc_equal(&crcs[0], &crcs[1]);
> > +
> > +	igt_pipe_crc_free(pipe_crc);
> > +	free(crcs);
> > +}
> > +
> 
> I'm not as certain about what exactly the "outp-inactive" source (or the
> other CRC sources) is so I'm not sure what to put in the doc-block that
> I'd recommend putting here.
> 
> > +static void test_source_outp_inactive(data_t *data)
> > +{
> > +	struct color_fb colors[] = {
> > +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> > +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> > +	};
> > +	igt_pipe_crc_t *pipe_crc;
> > +	const int fd = data->drm_fd;
> > +	const int n_colors = ARRAY_SIZE(colors);
> > +
> > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
> > +	create_colors(data, colors, n_colors, pipe_crc);
> > +
> > +	/* Changing the color should not change what's outside the active
> > raster */
> > +	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
> > +
> > +	igt_pipe_crc_free(pipe_crc);
> > +	destroy_colors(data, colors, n_colors);
> > +}
> > +
> > +data_t data = {0, };
> > +
> > +#define pipe_test(name) igt_subtest_f("pipe-%s-" name,
> > kmstest_pipe_name(pipe))
> > +igt_main
> > +{
> > +	int pipe;
> > +
> > +	igt_fixture {
> > +		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > +		igt_require_nouveau(data.drm_fd);
> > +
> > +		kmstest_set_vt_graphics_mode();
> > +
> > +		igt_require_pipe_crc(data.drm_fd);
> > +		igt_display_require(&data.display, data.drm_fd);
> > +		igt_display_reset(&data.display);
> > +	}
> > +
> > +	for_each_pipe_static(pipe) {
> > +		igt_fixture {
> > +			int dir;
> > +
> > +			data.pipe = pipe;
> > +			igt_display_require_output_on_pipe(&data.display,
> > pipe);
> > +			data.output =
> > igt_get_single_output_for_pipe(&data.display, pipe);
> > +			data.mode = igt_output_get_mode(data.output);
> > +
> > +			/* None of these tests need to perform modesets,
> > +			 * just page flips. So running display setup
> > +			 * here is fine
> > +			 */
> > +			igt_output_set_pipe(data.output, pipe);
> > +			data.primary = igt_output_get_plane(data.output, 0);
> > +			igt_create_color_fb(data.drm_fd,
> > +					    data.mode->hdisplay,
> > +					    data.mode->vdisplay,
> > +					    DRM_FORMAT_XRGB8888,
> > +					    LOCAL_DRM_FORMAT_MOD_NONE,
> > +					    0.0, 0.0, 0.0,
> > +					    &data.default_fb);
> > +			igt_plane_set_fb(data.primary, &data.default_fb);
> > +			igt_display_commit(&data.display);
> > +
> > +			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe,
> > O_DIRECTORY);
> > +			igt_require_fd(dir);
> > +			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
> > +			close(dir);
> > +			igt_require_fd(data.nv_crc_dir);
> > +		}
> > +
> > +		/* We don't need to test this on every pipe, but the
> > +		 * setup is the same */
> > +		if (pipe == PIPE_A) {
> > +			igt_describe("Make sure that the CRC notifier context
> > flip threshold "
> > +				     "is reset to its default value after a
> > single capture.");
> > +			igt_subtest("ctx-flip-threshold-reset-after-capture")
> > +				test_ctx_flip_threshold_reset_after_capture(&d
> > ata);
> > +		}
> > +
> > +		igt_describe("Make sure the association between each CRC and
> > its "
> > +			     "respective frame index is not broken when the
> > driver "
> > +			     "performs a notifier context flip.");
> > +		pipe_test("ctx-flip-detection")
> > +			test_ctx_flip_detection(&data);
> > +
> > +		igt_describe("Make sure that igt_pipe_crc_get_current() works
> > even "
> > +			     "when the CRC for the current frame index is
> > lost.");
> > +		pipe_test("ctx-flip-skip-current-frame")
> > +			test_ctx_flip_skip_current_frame(&data);
> > +
> > +		igt_describe("Check that basic CRC readback using the outp-
> > complete "
> > +			     "source works.");
> > +		pipe_test("source-outp-complete")
> > +			test_source(&data, "outp-complete");
> > +
> > +		igt_describe("Check that basic CRC readback using the rg
> > source "
> > +			     "works.");
> > +		pipe_test("source-rg")
> > +			test_source(&data, "rg");
> > +
> > +		igt_describe("Make sure that the outp-inactive source is
> > actually "
> > +			     "capturing the inactive raster.");
> > +		pipe_test("source-outp-inactive")
> > +			test_source_outp_inactive(&data);
> > +
> > +		igt_fixture {
> > +			igt_output_set_pipe(data.output, PIPE_NONE);
> > +			igt_display_commit(&data.display);
> > +			igt_remove_fb(data.drm_fd, &data.default_fb);
> > +			close(data.nv_crc_dir);
> > +		}
> > +	}
> > +	igt_fixture
> > +		igt_display_fini(&data.display);
> > +
> > +}
> > -- 
> > 2.26.2
> > 
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev
-- 
Cheers,
	Lyude Paul (she/her)
	Software Engineer at Red Hat

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4] tests: Add nouveau-crc tests
  2020-09-29 16:13               ` Lyude Paul
@ 2020-09-29 17:42                   ` Jeremy Cline
  -1 siblings, 0 replies; 33+ messages in thread
From: Jeremy Cline @ 2020-09-29 17:42 UTC (permalink / raw)
  To: Lyude Paul
  Cc: igt-dev-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Tue, Sep 29, 2020 at 12:13:23PM -0400, Lyude Paul wrote:
> On Mon, 2020-09-28 at 17:36 -0400, Jeremy Cline wrote:
> > Hi,
> > 
> > On Tue, Aug 18, 2020 at 05:00:51PM -0400, Lyude wrote:
> > > From: Lyude Paul <lyude@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 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@redhat.com>
> > > ---
> > >  .gitlab-ci.yml      |   2 +-
> > >  lib/drmtest.c       |  10 ++
> > >  lib/drmtest.h       |   2 +
> > >  tests/meson.build   |   1 +
> > >  tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
> > >  5 files changed, 411 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 684de043..92647991 100644
> > > --- a/tests/meson.build
> > > +++ b/tests/meson.build
> > > @@ -74,6 +74,7 @@ test_progs = [
> > >  	'kms_vblank',
> > >  	'kms_vrr',
> > >  	'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..05c2f4de
> > > --- /dev/null
> > > +++ b/tests/nouveau_crc.c
> > > @@ -0,0 +1,397 @@
> > > +/*
> > > + * 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));
> > > +}
> > > +
> > > +static void create_colors(data_t *data,
> > > +			  struct color_fb *colors,
> > > +			  size_t len,
> > > +			  igt_pipe_crc_t *pipe_crc)
> > 
> > Not to bikeshed too much, but this function seems to be more about
> > generating CRCs given some pre-existing colors. Maybe
> > create_color_crcs() would be better? And it wouldn't hurt to throw a
> > little docblock on it, even something as short as:
> > 
> > /*
> >  * Calculate and set the CRC for each color_fb
> >  */
> > 
> > > +{
> > > +	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_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);
> > > +}
> > > +
> > > +/* Hard-coded to PIPE_A for now, we don't really need to test this on
> > > more then
> > > + * one head
> > > + */
> > 
> > Perhaps expand this doc-block out a bit with the details you have in the
> > commit:
> > 
> > /* Test CRCs are reported across notifier context flips
> >  *
> >  * Nvidia GPUs store CRCs in a limited memory region called the notifier
> >  * context. When the region fills, new CRCs are not reported. To work
> >  * around this, two notifier contexts are allocated and the driver flips
> >  * between the two of them when a threshold is reached. Even with this
> >  * approach, a single frame is lost during the context flip.
> >  *
> >  * This test adjusts the threshold at which the notifier context flips
> >  * to the other context and asserts the CRCs are correctly reported with
> >  * the exception of the frame lost during the flip.
> >  *
> >  * Hard-coded to PIPE_A for now, we don't really need to test this on
> >  * more then one head
> >  */
> > 
> > I was guilty of reading the code while testing without going back to
> > consult the commit message and I only just now realized the test purpose
> > was clearly explained. It'd be nice to keep that close to the test
> > definition rather than in the commit log.
> > 
> > Also, as far as I can tell it's not actually hard-coded to PIPE_A, but
> > test_ctx_flip_threshold_reset_after_capture() is. Maybe I'm
> > mis-understanding that?
> 
> No you aren't-that's definitely a bit of doc I had written before all of the
> tests were complete and I was undecided if we needed to test this on all pipes
> or not (turned out all pipes is a good idea).
> 
> > 
> > > +static void test_ctx_flip_detection(data_t *data)
> > > +{
> > > +	struct color_fb colors[] = {
> > > +		HEX_COLOR(0xFF, 0x00, 0x18),
> > > +		HEX_COLOR(0xFF, 0xA5, 0x2C),
> > > +		HEX_COLOR(0xFF, 0xFF, 0x41),
> > > +		HEX_COLOR(0x00, 0x80, 0x18),
> > > +		HEX_COLOR(0x00, 0x00, 0xF9),
> > > +		HEX_COLOR(0x86, 0x00, 0x7D),
> > > +	};
> > > +	igt_output_t *output = data->output;
> > > +	igt_plane_t *primary = data->primary;
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	const int n_colors = ARRAY_SIZE(colors);
> > > +	const int n_crcs = 20;
> > > +	igt_crc_t *crcs = NULL;
> > > +	int start = -1, frame, start_color = -1, i;
> > > +	bool found_skip = false;
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
> > > +
> > > +	create_colors(data, colors, n_colors, pipe_crc);
> > > +
> > > +	set_crc_flip_threshold(data, n_crcs / 2);
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +
> > > +	for (i = 0; i < n_crcs; i++) {
> > > +		const int color_idx = i % n_colors;
> > > +
> > > +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> > > +		do_or_die(drmModePageFlip(data->drm_fd,
> > > +					  output->config.crtc->crtc_id,
> > > +					  colors[color_idx].fb.fb_id,
> > > +					  DRM_MODE_PAGE_FLIP_EVENT,
> > > +					  NULL));
> > > +		kmstest_wait_for_pageflip(data->drm_fd);
> > 
> > While testing I was experiencing some test failures, at which point I
> > turned on a bunch of debug logging on the kernel side. This led to this
> > test reliably failing because this call timed out waiting on the pageflip
> > event, which is unfortunate. I'm not sure what the larger usage of this
> > particular function is, but having tests start to fail when verbose
> > logging is enabled isn't ideal.
> > 
> > Obviously hanging forever is also not ideal, so maybe the timeout of
> > this function just needs adjustment, or even just have the assertion
> > include a hint that perhaps debug logging is slowing things down too
> > much. It's not within the scope of this change so I don't think anything
> > needs to change in this patch, more just wanted to see what folks think
> > the best approach is since I spent longer than I care to admit figuring
> > that out and don't want others to have to suffer the same way.
> 
> If you turn on enough debugging info it definitely makes sense that it might
> cause us to miss a page flip on accident, although I've never managed to get
> debugging output to slow things down that much. We should probably look to see
> if there's anything we could do to speed up debugging output like that on
> nouveau's side.
> 

Well, I did flip on a bunch of debug options so maybe if I turn all
those off it'll pass. Perhaps all IGT tests are sensitive to timing and
have particular requirements when it comes to configuration and so on,
but I think ideally tests should not start to fail in low-performance
environments unless they're specifically about testing performance.
However, I know we don't live in an ideal world.

> JFYI too - we shouldn't ever be missing a pageflip in general and for this
> test, especially under normal circumstances since it sounds like you were
> seeing intermittent failures before you had debugging code turned on? We can't
> accurately figure out if the CRC flip happened otherwise since we rely on
> there being exactly one frame with a missing CRC, with each successive frame
> matching the steps in the color pattern that would have followed that frame. 
> 

Hmm. What about the frame numbers? I didn't find any documentation on
what to expect for those, but based on what I saw while debugging they
increment and it was clear where the flip happened based on the missing
frame number in the CRCs.

> > 
> > > +	}
> > > +
> > > +	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +
> > > +	/*
> > > +	 * Find the first color in our pattern with a CRC that differs from
> > > the
> > > +	 * last CRC, so we can use it to find the start of the pattern
> > > +	 */
> > 
> > It might be worth explicitly noting this is to avoid CRC collisions (I'm
> > assuming) since I had to ponder for a bit:
> > 
> > /*
> >  * Guard against CRC collisions in the color framebuffers. Find the
> >  * first color in our pattern with a CRC that differs from the last CRC,
> >  * so we can use it to find the start of the pattern
> >  */
> > 
> > > +	for (i = 0; i < n_colors - 1; i++) {
> > > +		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors -
> > > 1].crc))
> > > +			continue;
> > > +
> > > +		igt_debug("Using frame %d of pattern for finding start\n", i);
> > > +		start_color = i;
> > > +		break;
> > > +	}
> > > +	igt_assert_lte(0, start_color);
> > > +
> > > +	/* Now, figure out where the pattern starts */
> > > +	for (i = 0; i < n_crcs; i++) {
> > > +		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
> > > +			continue;
> > > +
> > > +		start = i - start_color;
> > > +		frame = crcs[i].frame;
> > > +		igt_debug("Pattern started on frame %d\n", frame);
> > > +		break;
> > > +	}
> > > +	igt_assert_lte(0, start);
> > > +
> > > +	/* And finally, assert that according to the CRCs exactly all but one
> > > +	 * frame was displayed in order. The missing frame comes from
> > > +	 * (inevitably) losing a single CRC event when nouveau switches
> > > notifier
> > > +	 * contexts
> > > +	 */
> > > +	for (i = start; i < n_crcs; i++, frame++) {
> > > +		igt_crc_t *crc = &crcs[i];
> > > +		char *crc_str;
> > > +		int color_idx;
> > > +
> > > +		crc_str = igt_crc_to_string(crc);
> > > +		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
> > > +		free(crc_str);
> > > +
> > > +		if (!found_skip && crc->frame != frame) {
> > > +			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
> > > +				  crc->frame - 1);
> > > +			found_skip = true;
> > > +			frame++;
> > > +		}
> > > +
> > > +		/* We should never skip more then one frame */
> > > +		if (found_skip) {
> > > +			igt_assert_eq(crc->frame, frame);
> > > +			color_idx = (i - start + 1) % n_colors;
> > > +		} else {
> > > +			color_idx = (i - start) % n_colors;
> > > +		}
> > > +
> > > +		igt_assert_crc_equal(crc, &colors[color_idx].crc);
> > 
> > This consistently fails for me. The reason is that there are multiple
> > frames with the same color/CRC. As far as I can tell, that's perfectly
> > reasonable when a page flip is slow (possibly due to debug logs 😬), but
> > I don't know for certain what the interface expectations are.
> 
> Yeah-something is definitely broken with your setup. Page flips should never
> be slow, except -maybe- in the most exceptional of debugging circumstances.
> 
> > 
> > If that assumption is correct, I guess you'll need to expect either the
> > same color as the previous frame, or the next color in the array after
> > the color in the previous frame.
> > 
> > > +	}
> > > +	igt_assert(found_skip);
> > > +
> > > +	free(crcs);
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	destroy_colors(data, colors, ARRAY_SIZE(colors));
> > > +}
> > > +
> > > +/* Test whether or not IGT is able to handle frame skips when requesting
> > > the
> > > + * CRC for the current frame
> > > + */
> > > +static void test_ctx_flip_skip_current_frame(data_t *data)
> > > +{
> > > +	struct color_fb colors[] = {
> > > +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> > > +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> > > +		{ .r = 0.0, .g = 0.0, .b = 1.0 },
> > > +	};
> > > +	igt_output_t *output = data->output;
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	igt_plane_t *primary = data->primary;
> > > +	const int fd = data->drm_fd;
> > > +	const int n_colors = ARRAY_SIZE(colors);
> > > +	const int n_crcs = 30;
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> > > +	create_colors(data, colors, n_colors, pipe_crc);
> > > +
> > > +	set_crc_flip_threshold(data, 5);
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +
> > > +	for (int i = 0; i < n_crcs; i++) {
> > > +		igt_crc_t crc;
> > > +		const int color_idx = i % n_colors;
> > > +
> > > +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> > > +		do_or_die(drmModePageFlip(fd,
> > > +					  output->config.crtc->crtc_id,
> > > +					  colors[color_idx].fb.fb_id,
> > > +					  DRM_MODE_PAGE_FLIP_EVENT,
> > > +					  NULL));
> > > +		kmstest_wait_for_pageflip(fd);
> > > +
> > > +		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
> > > +		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
> > > +	}
> > > +
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	destroy_colors(data, colors, n_colors);
> > > +}
> > > +
> > 
> > Maybe a short doc-block with what the test should be doing here would be
> > good:
> > 
> > /*
> >  * Assert that after a CRC capture is started and stopped, the context
> >  * notifier flip threshold is reset to its default value.
> >  */
> > 
> > > +static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
> > > +{
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	const int fd = data->drm_fd;
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> > > +
> > > +	set_crc_flip_threshold(data, 5);
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +
> > > +	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"),
> > > 5);
> > 
> > As it currently stands, this test could fail if the default is 5, or it
> > could pass if "flip_threshold" was broken and didn't report the actual
> > flip_threshold anyway. The default being 5 doesn't look to be something
> > that you necessarily need to be worried about, but it might be worth
> > reading the value back after setting the threshold to make sure you do
> > see 5.
> > 
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +}
> > > +
> > 
> > Same note about a docblock 🙂:
> > 
> > /*
> >  * Assert that, for a given source, two consecutive CRCs are equal if
> >  * the content hasn't changed.
> >  */
> > 
> > > +static void test_source(data_t *data, const char *source)
> > > +{
> > > +	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe,
> > > source);
> > > +	igt_crc_t *crcs;
> > > +
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +
> > > +	/* The CRC shouldn't change if the source content hasn't changed */
> > > +	igt_assert_crc_equal(&crcs[0], &crcs[1]);
> > > +
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	free(crcs);
> > > +}
> > > +
> > 
> > I'm not as certain about what exactly the "outp-inactive" source (or the
> > other CRC sources) is so I'm not sure what to put in the doc-block that
> > I'd recommend putting here.
> > 
> > > +static void test_source_outp_inactive(data_t *data)
> > > +{
> > > +	struct color_fb colors[] = {
> > > +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> > > +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> > > +	};
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	const int fd = data->drm_fd;
> > > +	const int n_colors = ARRAY_SIZE(colors);
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
> > > +	create_colors(data, colors, n_colors, pipe_crc);
> > > +
> > > +	/* Changing the color should not change what's outside the active
> > > raster */
> > > +	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
> > > +
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	destroy_colors(data, colors, n_colors);
> > > +}
> > > +
> > > +data_t data = {0, };
> > > +
> > > +#define pipe_test(name) igt_subtest_f("pipe-%s-" name,
> > > kmstest_pipe_name(pipe))
> > > +igt_main
> > > +{
> > > +	int pipe;
> > > +
> > > +	igt_fixture {
> > > +		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > +		igt_require_nouveau(data.drm_fd);
> > > +
> > > +		kmstest_set_vt_graphics_mode();
> > > +
> > > +		igt_require_pipe_crc(data.drm_fd);
> > > +		igt_display_require(&data.display, data.drm_fd);
> > > +		igt_display_reset(&data.display);
> > > +	}
> > > +
> > > +	for_each_pipe_static(pipe) {
> > > +		igt_fixture {
> > > +			int dir;
> > > +
> > > +			data.pipe = pipe;
> > > +			igt_display_require_output_on_pipe(&data.display,
> > > pipe);
> > > +			data.output =
> > > igt_get_single_output_for_pipe(&data.display, pipe);
> > > +			data.mode = igt_output_get_mode(data.output);
> > > +
> > > +			/* None of these tests need to perform modesets,
> > > +			 * just page flips. So running display setup
> > > +			 * here is fine
> > > +			 */
> > > +			igt_output_set_pipe(data.output, pipe);
> > > +			data.primary = igt_output_get_plane(data.output, 0);
> > > +			igt_create_color_fb(data.drm_fd,
> > > +					    data.mode->hdisplay,
> > > +					    data.mode->vdisplay,
> > > +					    DRM_FORMAT_XRGB8888,
> > > +					    LOCAL_DRM_FORMAT_MOD_NONE,
> > > +					    0.0, 0.0, 0.0,
> > > +					    &data.default_fb);
> > > +			igt_plane_set_fb(data.primary, &data.default_fb);
> > > +			igt_display_commit(&data.display);
> > > +
> > > +			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe,
> > > O_DIRECTORY);
> > > +			igt_require_fd(dir);
> > > +			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
> > > +			close(dir);
> > > +			igt_require_fd(data.nv_crc_dir);
> > > +		}
> > > +
> > > +		/* We don't need to test this on every pipe, but the
> > > +		 * setup is the same */
> > > +		if (pipe == PIPE_A) {
> > > +			igt_describe("Make sure that the CRC notifier context
> > > flip threshold "
> > > +				     "is reset to its default value after a
> > > single capture.");
> > > +			igt_subtest("ctx-flip-threshold-reset-after-capture")
> > > +				test_ctx_flip_threshold_reset_after_capture(&d
> > > ata);
> > > +		}
> > > +
> > > +		igt_describe("Make sure the association between each CRC and
> > > its "
> > > +			     "respective frame index is not broken when the
> > > driver "
> > > +			     "performs a notifier context flip.");
> > > +		pipe_test("ctx-flip-detection")
> > > +			test_ctx_flip_detection(&data);
> > > +
> > > +		igt_describe("Make sure that igt_pipe_crc_get_current() works
> > > even "
> > > +			     "when the CRC for the current frame index is
> > > lost.");
> > > +		pipe_test("ctx-flip-skip-current-frame")
> > > +			test_ctx_flip_skip_current_frame(&data);
> > > +
> > > +		igt_describe("Check that basic CRC readback using the outp-
> > > complete "
> > > +			     "source works.");
> > > +		pipe_test("source-outp-complete")
> > > +			test_source(&data, "outp-complete");
> > > +
> > > +		igt_describe("Check that basic CRC readback using the rg
> > > source "
> > > +			     "works.");
> > > +		pipe_test("source-rg")
> > > +			test_source(&data, "rg");
> > > +
> > > +		igt_describe("Make sure that the outp-inactive source is
> > > actually "
> > > +			     "capturing the inactive raster.");
> > > +		pipe_test("source-outp-inactive")
> > > +			test_source_outp_inactive(&data);
> > > +
> > > +		igt_fixture {
> > > +			igt_output_set_pipe(data.output, PIPE_NONE);
> > > +			igt_display_commit(&data.display);
> > > +			igt_remove_fb(data.drm_fd, &data.default_fb);
> > > +			close(data.nv_crc_dir);
> > > +		}
> > > +	}
> > > +	igt_fixture
> > > +		igt_display_fini(&data.display);
> > > +
> > > +}
> > > -- 
> > > 2.26.2
> > > 
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> -- 
> Cheers,
> 	Lyude Paul (she/her)
> 	Software Engineer at Red Hat
> 

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4] tests: Add nouveau-crc tests
@ 2020-09-29 17:42                   ` Jeremy Cline
  0 siblings, 0 replies; 33+ messages in thread
From: Jeremy Cline @ 2020-09-29 17:42 UTC (permalink / raw)
  To: Lyude Paul; +Cc: igt-dev, nouveau

On Tue, Sep 29, 2020 at 12:13:23PM -0400, Lyude Paul wrote:
> On Mon, 2020-09-28 at 17:36 -0400, Jeremy Cline wrote:
> > Hi,
> > 
> > On Tue, Aug 18, 2020 at 05:00:51PM -0400, Lyude wrote:
> > > From: Lyude Paul <lyude@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 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@redhat.com>
> > > ---
> > >  .gitlab-ci.yml      |   2 +-
> > >  lib/drmtest.c       |  10 ++
> > >  lib/drmtest.h       |   2 +
> > >  tests/meson.build   |   1 +
> > >  tests/nouveau_crc.c | 397 ++++++++++++++++++++++++++++++++++++++++++++
> > >  5 files changed, 411 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 684de043..92647991 100644
> > > --- a/tests/meson.build
> > > +++ b/tests/meson.build
> > > @@ -74,6 +74,7 @@ test_progs = [
> > >  	'kms_vblank',
> > >  	'kms_vrr',
> > >  	'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..05c2f4de
> > > --- /dev/null
> > > +++ b/tests/nouveau_crc.c
> > > @@ -0,0 +1,397 @@
> > > +/*
> > > + * 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));
> > > +}
> > > +
> > > +static void create_colors(data_t *data,
> > > +			  struct color_fb *colors,
> > > +			  size_t len,
> > > +			  igt_pipe_crc_t *pipe_crc)
> > 
> > Not to bikeshed too much, but this function seems to be more about
> > generating CRCs given some pre-existing colors. Maybe
> > create_color_crcs() would be better? And it wouldn't hurt to throw a
> > little docblock on it, even something as short as:
> > 
> > /*
> >  * Calculate and set the CRC for each color_fb
> >  */
> > 
> > > +{
> > > +	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_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);
> > > +}
> > > +
> > > +/* Hard-coded to PIPE_A for now, we don't really need to test this on
> > > more then
> > > + * one head
> > > + */
> > 
> > Perhaps expand this doc-block out a bit with the details you have in the
> > commit:
> > 
> > /* Test CRCs are reported across notifier context flips
> >  *
> >  * Nvidia GPUs store CRCs in a limited memory region called the notifier
> >  * context. When the region fills, new CRCs are not reported. To work
> >  * around this, two notifier contexts are allocated and the driver flips
> >  * between the two of them when a threshold is reached. Even with this
> >  * approach, a single frame is lost during the context flip.
> >  *
> >  * This test adjusts the threshold at which the notifier context flips
> >  * to the other context and asserts the CRCs are correctly reported with
> >  * the exception of the frame lost during the flip.
> >  *
> >  * Hard-coded to PIPE_A for now, we don't really need to test this on
> >  * more then one head
> >  */
> > 
> > I was guilty of reading the code while testing without going back to
> > consult the commit message and I only just now realized the test purpose
> > was clearly explained. It'd be nice to keep that close to the test
> > definition rather than in the commit log.
> > 
> > Also, as far as I can tell it's not actually hard-coded to PIPE_A, but
> > test_ctx_flip_threshold_reset_after_capture() is. Maybe I'm
> > mis-understanding that?
> 
> No you aren't-that's definitely a bit of doc I had written before all of the
> tests were complete and I was undecided if we needed to test this on all pipes
> or not (turned out all pipes is a good idea).
> 
> > 
> > > +static void test_ctx_flip_detection(data_t *data)
> > > +{
> > > +	struct color_fb colors[] = {
> > > +		HEX_COLOR(0xFF, 0x00, 0x18),
> > > +		HEX_COLOR(0xFF, 0xA5, 0x2C),
> > > +		HEX_COLOR(0xFF, 0xFF, 0x41),
> > > +		HEX_COLOR(0x00, 0x80, 0x18),
> > > +		HEX_COLOR(0x00, 0x00, 0xF9),
> > > +		HEX_COLOR(0x86, 0x00, 0x7D),
> > > +	};
> > > +	igt_output_t *output = data->output;
> > > +	igt_plane_t *primary = data->primary;
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	const int n_colors = ARRAY_SIZE(colors);
> > > +	const int n_crcs = 20;
> > > +	igt_crc_t *crcs = NULL;
> > > +	int start = -1, frame, start_color = -1, i;
> > > +	bool found_skip = false;
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe, "auto");
> > > +
> > > +	create_colors(data, colors, n_colors, pipe_crc);
> > > +
> > > +	set_crc_flip_threshold(data, n_crcs / 2);
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +
> > > +	for (i = 0; i < n_crcs; i++) {
> > > +		const int color_idx = i % n_colors;
> > > +
> > > +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> > > +		do_or_die(drmModePageFlip(data->drm_fd,
> > > +					  output->config.crtc->crtc_id,
> > > +					  colors[color_idx].fb.fb_id,
> > > +					  DRM_MODE_PAGE_FLIP_EVENT,
> > > +					  NULL));
> > > +		kmstest_wait_for_pageflip(data->drm_fd);
> > 
> > While testing I was experiencing some test failures, at which point I
> > turned on a bunch of debug logging on the kernel side. This led to this
> > test reliably failing because this call timed out waiting on the pageflip
> > event, which is unfortunate. I'm not sure what the larger usage of this
> > particular function is, but having tests start to fail when verbose
> > logging is enabled isn't ideal.
> > 
> > Obviously hanging forever is also not ideal, so maybe the timeout of
> > this function just needs adjustment, or even just have the assertion
> > include a hint that perhaps debug logging is slowing things down too
> > much. It's not within the scope of this change so I don't think anything
> > needs to change in this patch, more just wanted to see what folks think
> > the best approach is since I spent longer than I care to admit figuring
> > that out and don't want others to have to suffer the same way.
> 
> If you turn on enough debugging info it definitely makes sense that it might
> cause us to miss a page flip on accident, although I've never managed to get
> debugging output to slow things down that much. We should probably look to see
> if there's anything we could do to speed up debugging output like that on
> nouveau's side.
> 

Well, I did flip on a bunch of debug options so maybe if I turn all
those off it'll pass. Perhaps all IGT tests are sensitive to timing and
have particular requirements when it comes to configuration and so on,
but I think ideally tests should not start to fail in low-performance
environments unless they're specifically about testing performance.
However, I know we don't live in an ideal world.

> JFYI too - we shouldn't ever be missing a pageflip in general and for this
> test, especially under normal circumstances since it sounds like you were
> seeing intermittent failures before you had debugging code turned on? We can't
> accurately figure out if the CRC flip happened otherwise since we rely on
> there being exactly one frame with a missing CRC, with each successive frame
> matching the steps in the color pattern that would have followed that frame. 
> 

Hmm. What about the frame numbers? I didn't find any documentation on
what to expect for those, but based on what I saw while debugging they
increment and it was clear where the flip happened based on the missing
frame number in the CRCs.

> > 
> > > +	}
> > > +
> > > +	igt_pipe_crc_get_crcs(pipe_crc, n_crcs, &crcs);
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +
> > > +	/*
> > > +	 * Find the first color in our pattern with a CRC that differs from
> > > the
> > > +	 * last CRC, so we can use it to find the start of the pattern
> > > +	 */
> > 
> > It might be worth explicitly noting this is to avoid CRC collisions (I'm
> > assuming) since I had to ponder for a bit:
> > 
> > /*
> >  * Guard against CRC collisions in the color framebuffers. Find the
> >  * first color in our pattern with a CRC that differs from the last CRC,
> >  * so we can use it to find the start of the pattern
> >  */
> > 
> > > +	for (i = 0; i < n_colors - 1; i++) {
> > > +		if (igt_check_crc_equal(&colors[i].crc, &colors[n_colors -
> > > 1].crc))
> > > +			continue;
> > > +
> > > +		igt_debug("Using frame %d of pattern for finding start\n", i);
> > > +		start_color = i;
> > > +		break;
> > > +	}
> > > +	igt_assert_lte(0, start_color);
> > > +
> > > +	/* Now, figure out where the pattern starts */
> > > +	for (i = 0; i < n_crcs; i++) {
> > > +		if (!igt_check_crc_equal(&colors[start_color].crc, &crcs[i]))
> > > +			continue;
> > > +
> > > +		start = i - start_color;
> > > +		frame = crcs[i].frame;
> > > +		igt_debug("Pattern started on frame %d\n", frame);
> > > +		break;
> > > +	}
> > > +	igt_assert_lte(0, start);
> > > +
> > > +	/* And finally, assert that according to the CRCs exactly all but one
> > > +	 * frame was displayed in order. The missing frame comes from
> > > +	 * (inevitably) losing a single CRC event when nouveau switches
> > > notifier
> > > +	 * contexts
> > > +	 */
> > > +	for (i = start; i < n_crcs; i++, frame++) {
> > > +		igt_crc_t *crc = &crcs[i];
> > > +		char *crc_str;
> > > +		int color_idx;
> > > +
> > > +		crc_str = igt_crc_to_string(crc);
> > > +		igt_debug("CRC %d: vbl=%d val=%s\n", i, crc->frame, crc_str);
> > > +		free(crc_str);
> > > +
> > > +		if (!found_skip && crc->frame != frame) {
> > > +			igt_debug("^^^ Found expected skipped CRC %d ^^^\n",
> > > +				  crc->frame - 1);
> > > +			found_skip = true;
> > > +			frame++;
> > > +		}
> > > +
> > > +		/* We should never skip more then one frame */
> > > +		if (found_skip) {
> > > +			igt_assert_eq(crc->frame, frame);
> > > +			color_idx = (i - start + 1) % n_colors;
> > > +		} else {
> > > +			color_idx = (i - start) % n_colors;
> > > +		}
> > > +
> > > +		igt_assert_crc_equal(crc, &colors[color_idx].crc);
> > 
> > This consistently fails for me. The reason is that there are multiple
> > frames with the same color/CRC. As far as I can tell, that's perfectly
> > reasonable when a page flip is slow (possibly due to debug logs 😬), but
> > I don't know for certain what the interface expectations are.
> 
> Yeah-something is definitely broken with your setup. Page flips should never
> be slow, except -maybe- in the most exceptional of debugging circumstances.
> 
> > 
> > If that assumption is correct, I guess you'll need to expect either the
> > same color as the previous frame, or the next color in the array after
> > the color in the previous frame.
> > 
> > > +	}
> > > +	igt_assert(found_skip);
> > > +
> > > +	free(crcs);
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	destroy_colors(data, colors, ARRAY_SIZE(colors));
> > > +}
> > > +
> > > +/* Test whether or not IGT is able to handle frame skips when requesting
> > > the
> > > + * CRC for the current frame
> > > + */
> > > +static void test_ctx_flip_skip_current_frame(data_t *data)
> > > +{
> > > +	struct color_fb colors[] = {
> > > +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> > > +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> > > +		{ .r = 0.0, .g = 0.0, .b = 1.0 },
> > > +	};
> > > +	igt_output_t *output = data->output;
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	igt_plane_t *primary = data->primary;
> > > +	const int fd = data->drm_fd;
> > > +	const int n_colors = ARRAY_SIZE(colors);
> > > +	const int n_crcs = 30;
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> > > +	create_colors(data, colors, n_colors, pipe_crc);
> > > +
> > > +	set_crc_flip_threshold(data, 5);
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +
> > > +	for (int i = 0; i < n_crcs; i++) {
> > > +		igt_crc_t crc;
> > > +		const int color_idx = i % n_colors;
> > > +
> > > +		igt_plane_set_fb(primary, &colors[color_idx].fb);
> > > +		do_or_die(drmModePageFlip(fd,
> > > +					  output->config.crtc->crtc_id,
> > > +					  colors[color_idx].fb.fb_id,
> > > +					  DRM_MODE_PAGE_FLIP_EVENT,
> > > +					  NULL));
> > > +		kmstest_wait_for_pageflip(fd);
> > > +
> > > +		igt_pipe_crc_get_current(fd, pipe_crc, &crc);
> > > +		igt_assert_crc_equal(&colors[color_idx].crc, &crc);
> > > +	}
> > > +
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	destroy_colors(data, colors, n_colors);
> > > +}
> > > +
> > 
> > Maybe a short doc-block with what the test should be doing here would be
> > good:
> > 
> > /*
> >  * Assert that after a CRC capture is started and stopped, the context
> >  * notifier flip threshold is reset to its default value.
> >  */
> > 
> > > +static void test_ctx_flip_threshold_reset_after_capture(data_t *data)
> > > +{
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	const int fd = data->drm_fd;
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "auto");
> > > +
> > > +	set_crc_flip_threshold(data, 5);
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +
> > > +	igt_assert_neq(igt_sysfs_get_u32(data->nv_crc_dir, "flip_threshold"),
> > > 5);
> > 
> > As it currently stands, this test could fail if the default is 5, or it
> > could pass if "flip_threshold" was broken and didn't report the actual
> > flip_threshold anyway. The default being 5 doesn't look to be something
> > that you necessarily need to be worried about, but it might be worth
> > reading the value back after setting the threshold to make sure you do
> > see 5.
> > 
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +}
> > > +
> > 
> > Same note about a docblock 🙂:
> > 
> > /*
> >  * Assert that, for a given source, two consecutive CRCs are equal if
> >  * the content hasn't changed.
> >  */
> > 
> > > +static void test_source(data_t *data, const char *source)
> > > +{
> > > +	igt_pipe_crc_t *pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe,
> > > source);
> > > +	igt_crc_t *crcs;
> > > +
> > > +	igt_pipe_crc_start(pipe_crc);
> > > +	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
> > > +	igt_pipe_crc_stop(pipe_crc);
> > > +
> > > +	/* The CRC shouldn't change if the source content hasn't changed */
> > > +	igt_assert_crc_equal(&crcs[0], &crcs[1]);
> > > +
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	free(crcs);
> > > +}
> > > +
> > 
> > I'm not as certain about what exactly the "outp-inactive" source (or the
> > other CRC sources) is so I'm not sure what to put in the doc-block that
> > I'd recommend putting here.
> > 
> > > +static void test_source_outp_inactive(data_t *data)
> > > +{
> > > +	struct color_fb colors[] = {
> > > +		{ .r = 1.0, .g = 0.0, .b = 0.0 },
> > > +		{ .r = 0.0, .g = 1.0, .b = 0.0 },
> > > +	};
> > > +	igt_pipe_crc_t *pipe_crc;
> > > +	const int fd = data->drm_fd;
> > > +	const int n_colors = ARRAY_SIZE(colors);
> > > +
> > > +	pipe_crc = igt_pipe_crc_new(fd, data->pipe, "outp-inactive");
> > > +	create_colors(data, colors, n_colors, pipe_crc);
> > > +
> > > +	/* Changing the color should not change what's outside the active
> > > raster */
> > > +	igt_assert_crc_equal(&colors[0].crc, &colors[1].crc);
> > > +
> > > +	igt_pipe_crc_free(pipe_crc);
> > > +	destroy_colors(data, colors, n_colors);
> > > +}
> > > +
> > > +data_t data = {0, };
> > > +
> > > +#define pipe_test(name) igt_subtest_f("pipe-%s-" name,
> > > kmstest_pipe_name(pipe))
> > > +igt_main
> > > +{
> > > +	int pipe;
> > > +
> > > +	igt_fixture {
> > > +		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > +		igt_require_nouveau(data.drm_fd);
> > > +
> > > +		kmstest_set_vt_graphics_mode();
> > > +
> > > +		igt_require_pipe_crc(data.drm_fd);
> > > +		igt_display_require(&data.display, data.drm_fd);
> > > +		igt_display_reset(&data.display);
> > > +	}
> > > +
> > > +	for_each_pipe_static(pipe) {
> > > +		igt_fixture {
> > > +			int dir;
> > > +
> > > +			data.pipe = pipe;
> > > +			igt_display_require_output_on_pipe(&data.display,
> > > pipe);
> > > +			data.output =
> > > igt_get_single_output_for_pipe(&data.display, pipe);
> > > +			data.mode = igt_output_get_mode(data.output);
> > > +
> > > +			/* None of these tests need to perform modesets,
> > > +			 * just page flips. So running display setup
> > > +			 * here is fine
> > > +			 */
> > > +			igt_output_set_pipe(data.output, pipe);
> > > +			data.primary = igt_output_get_plane(data.output, 0);
> > > +			igt_create_color_fb(data.drm_fd,
> > > +					    data.mode->hdisplay,
> > > +					    data.mode->vdisplay,
> > > +					    DRM_FORMAT_XRGB8888,
> > > +					    LOCAL_DRM_FORMAT_MOD_NONE,
> > > +					    0.0, 0.0, 0.0,
> > > +					    &data.default_fb);
> > > +			igt_plane_set_fb(data.primary, &data.default_fb);
> > > +			igt_display_commit(&data.display);
> > > +
> > > +			dir = igt_debugfs_pipe_dir(data.drm_fd, pipe,
> > > O_DIRECTORY);
> > > +			igt_require_fd(dir);
> > > +			data.nv_crc_dir = openat(dir, "nv_crc", O_DIRECTORY);
> > > +			close(dir);
> > > +			igt_require_fd(data.nv_crc_dir);
> > > +		}
> > > +
> > > +		/* We don't need to test this on every pipe, but the
> > > +		 * setup is the same */
> > > +		if (pipe == PIPE_A) {
> > > +			igt_describe("Make sure that the CRC notifier context
> > > flip threshold "
> > > +				     "is reset to its default value after a
> > > single capture.");
> > > +			igt_subtest("ctx-flip-threshold-reset-after-capture")
> > > +				test_ctx_flip_threshold_reset_after_capture(&d
> > > ata);
> > > +		}
> > > +
> > > +		igt_describe("Make sure the association between each CRC and
> > > its "
> > > +			     "respective frame index is not broken when the
> > > driver "
> > > +			     "performs a notifier context flip.");
> > > +		pipe_test("ctx-flip-detection")
> > > +			test_ctx_flip_detection(&data);
> > > +
> > > +		igt_describe("Make sure that igt_pipe_crc_get_current() works
> > > even "
> > > +			     "when the CRC for the current frame index is
> > > lost.");
> > > +		pipe_test("ctx-flip-skip-current-frame")
> > > +			test_ctx_flip_skip_current_frame(&data);
> > > +
> > > +		igt_describe("Check that basic CRC readback using the outp-
> > > complete "
> > > +			     "source works.");
> > > +		pipe_test("source-outp-complete")
> > > +			test_source(&data, "outp-complete");
> > > +
> > > +		igt_describe("Check that basic CRC readback using the rg
> > > source "
> > > +			     "works.");
> > > +		pipe_test("source-rg")
> > > +			test_source(&data, "rg");
> > > +
> > > +		igt_describe("Make sure that the outp-inactive source is
> > > actually "
> > > +			     "capturing the inactive raster.");
> > > +		pipe_test("source-outp-inactive")
> > > +			test_source_outp_inactive(&data);
> > > +
> > > +		igt_fixture {
> > > +			igt_output_set_pipe(data.output, PIPE_NONE);
> > > +			igt_display_commit(&data.display);
> > > +			igt_remove_fb(data.drm_fd, &data.default_fb);
> > > +			close(data.nv_crc_dir);
> > > +		}
> > > +	}
> > > +	igt_fixture
> > > +		igt_display_fini(&data.display);
> > > +
> > > +}
> > > -- 
> > > 2.26.2
> > > 
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> -- 
> Cheers,
> 	Lyude Paul (she/her)
> 	Software Engineer at Red Hat
> 

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2020-09-29 17:42 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-17 21:10 [PATCH i-g-t v3 0/5] Add nouveau-crc tests Lyude
2020-04-17 21:10 ` [igt-dev] " Lyude
     [not found] ` <20200417211025.109574-1-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-04-17 21:10   ` [PATCH i-g-t v3 1/5] lib/igt_core: Fix igt_assert_fd() documentation Lyude
2020-04-17 21:10     ` [igt-dev] " Lyude
     [not found]     ` <20200417211025.109574-2-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-04-20  9:29       ` Petri Latvala
2020-04-20  9:29         ` Petri Latvala
2020-04-17 21:10   ` [PATCH i-g-t v3 2/5] lib/igt_core: Add igt_require_fd() Lyude
2020-04-17 21:10     ` [igt-dev] " Lyude
     [not found]     ` <20200417211025.109574-3-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-04-20  9:29       ` Petri Latvala
2020-04-20  9:29         ` Petri Latvala
2020-04-17 21:10   ` [PATCH i-g-t v3 3/5] lib/igt_debugfs: Add igt_debugfs_pipe_dir() Lyude
2020-04-17 21:10     ` [igt-dev] " Lyude
     [not found]     ` <20200417211025.109574-4-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-08-18 21:01       ` [i-g-t, v3, " Jeremy Cline
2020-08-18 21:01         ` [igt-dev] " Jeremy Cline
2020-04-17 21:10   ` [PATCH i-g-t v3 4/5] lib/igt_kms: Hook up connector dithering prop Lyude
2020-04-17 21:10     ` [igt-dev] " Lyude
     [not found]     ` <20200417211025.109574-5-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-08-18 21:18       ` [i-g-t, v3, " Jeremy Cline
2020-08-18 21:18         ` [igt-dev] " Jeremy Cline
2020-04-17 21:10   ` [PATCH i-g-t v3 5/5] tests: Add nouveau-crc tests Lyude
2020-04-17 21:10     ` [igt-dev] " Lyude
     [not found]     ` <20200417211025.109574-6-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-08-18 21:00       ` [PATCH i-g-t v4] " Lyude
2020-08-18 21:00         ` [igt-dev] " Lyude
     [not found]         ` <20200818210051.28705-1-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-09-28 21:36           ` Jeremy Cline
2020-09-28 21:36             ` Jeremy Cline
2020-09-29 16:13             ` Lyude Paul
2020-09-29 16:13               ` Lyude Paul
     [not found]               ` <b5673893f45f4bb72a90ca55d45100391a49c8e8.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-09-29 17:42                 ` Jeremy Cline
2020-09-29 17:42                   ` Jeremy Cline
2020-04-17 23:16 ` [igt-dev] ✗ GitLab.Pipeline: warning for Add nouveau-crc tests (rev3) Patchwork
2020-04-17 23:29 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
2020-04-19 20:33 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2020-08-18 21:57 ` [igt-dev] ✓ Fi.CI.BAT: success for Add nouveau-crc tests (rev4) Patchwork
2020-08-19  4:40 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.