[Intel-gfx] [PATCH i-g-t] tests: Introduce kms_wm_stress

Matt Roper matthew.d.roper at intel.com
Tue Jun 21 02:05:04 UTC 2016


Stress test watermark programming by programming lots of random
pipe/plane configurations.  The test itself should always return
success, but the presence of underrun messages in dmesg will indicate
watermark programming failures.

There's a lot of room for future improvement here --- we should exercise
random plane scaling, random pipe scaling, random modesets, etc.  But
this should at least provide a starting point upon which additional
testcases can be written.

Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
---
 tests/Makefile.sources |   1 +
 tests/kms_wm_stress.c  | 185 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 186 insertions(+)
 create mode 100644 tests/kms_wm_stress.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 8d8ede6..db2d5af 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -106,6 +106,7 @@ TESTS_progs_M = \
 	kms_setmode \
 	kms_universal_plane \
 	kms_vblank \
+	kms_wm_stress \
 	kms_crtc_background_color \
 	kms_plane_scaling \
 	kms_panel_fitting \
diff --git a/tests/kms_wm_stress.c b/tests/kms_wm_stress.c
new file mode 100644
index 0000000..2fc4b13
--- /dev/null
+++ b/tests/kms_wm_stress.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "igt.h"
+#include <stdlib.h>
+
+IGT_TEST_DESCRIPTION(
+    "Runs through several random display plane configurations to search for "
+    "corner cases where watermarks are programmed incorrectly.  This test "
+    "is always expected to return SUCCESS at the moment.  The presence of "
+    "underrun errors in the dmesg will indicate a watermark programming "
+    "failure.");
+
+/* Adjust this to tweak how many iterations each subtest performs. */
+#define NUMITER 100
+
+/* Test flags */
+#define NONE               0
+#define PLANES_OFFSCREEN   1
+
+struct {
+	int fd;
+
+	igt_display_t display;
+	struct igt_fb fb[2][IGT_MAX_PLANES * I915_MAX_PIPES];
+
+	int fbset;
+	unsigned fbmask[2];
+} data;
+
+static void
+randomize_plane(igt_plane_t *plane,
+		drmModeModeInfo *mode,
+		bool allow_offscreen)
+{
+	int x, y;
+	unsigned w, h;
+	double r, g, b;
+	unsigned index = plane->pipe->pipe * IGT_MAX_PLANES + plane->index;
+	struct igt_fb *fb = &data.fb[data.fbset][index];
+
+	igt_debug("Randomizing plane %d.%d\n", plane->pipe->pipe, plane->index);
+
+retry:
+	x = rand() % (mode->hdisplay * 2) - mode->hdisplay;
+	y = rand() % (mode->vdisplay * 2) - mode->vdisplay;
+	if (plane->is_cursor) {
+		w = 64;
+		h = 64;
+	} else {
+		w = rand() % (mode->hdisplay * 3/2) + 1;
+		h = rand() % (mode->vdisplay * 3/2) + 1;
+	}
+
+	if (!allow_offscreen &&
+	    (x+w > mode->hdisplay || y+h > mode->vdisplay || x < 0 || y < 0))
+		goto retry;
+
+	r = (rand() & 0xFF) / 255.0;
+	g = (rand() & 0xFF) / 255.0;
+	b = (rand() & 0xFF) / 255.0;
+	igt_create_color_fb(data.fd, w, h, DRM_FORMAT_ARGB8888,
+			    LOCAL_DRM_FORMAT_MOD_NONE, r, g, b, fb);
+	data.fbmask[data.fbset] |= 1 << index;
+
+	igt_plane_set_position(plane, x, y);
+	igt_plane_set_size(plane, w, h);
+	igt_plane_set_fb(plane, fb);
+}
+
+static void
+disable_plane(igt_plane_t *plane)
+{
+	igt_debug("Disabling plane %d\n", plane->index);
+	igt_plane_set_fb(plane, NULL);
+}
+
+static void
+randomize_planes(igt_output_t *output, unsigned flags)
+{
+	drmModeModeInfo *mode;
+	igt_plane_t *plane;
+	enum pipe pipe;
+	unsigned use_planes;
+	bool allow_offscreen = flags & PLANES_OFFSCREEN;
+
+	pipe = output->config.pipe;
+
+	mode = igt_output_get_mode(output);
+
+	use_planes = rand();
+	for_each_plane_on_pipe(&data.display, pipe, plane) {
+		if (use_planes & (1 << plane->index))
+			randomize_plane(plane, mode, allow_offscreen);
+		else
+			disable_plane(plane);
+	}
+}
+
+static void
+cleanup_fbs(int fbset)
+{
+	int i;
+
+	for (i = 0; i < I915_MAX_PIPES * IGT_MAX_PLANES; i++)
+		if (data.fbmask[fbset] & (1 << i))
+			igt_remove_fb(data.fd, &data.fb[fbset][i]);
+	data.fbmask[fbset] = 0;
+}
+
+static void
+run_test(unsigned flags)
+{
+	igt_output_t *output;
+	int ret, i;
+	unsigned fails = 0;
+
+	for (i = 0; i < NUMITER; i++) {
+		data.fbset = i % 2;
+		for_each_connected_output(&data.display, output)
+			randomize_planes(output, flags);
+
+		ret = igt_display_try_commit2(&data.display, COMMIT_ATOMIC);
+		if (ret)
+			fails++;
+
+		if (i > 0)
+			cleanup_fbs(data.fbset ^ 1);
+	}
+
+	/*
+	 * It's certainly possible to hit some configurations here that our
+	 * platform can't support (i.e., that exceed system watermark
+	 * limitations).  But let's make sure we didn't fail an unrealistically
+	 * high number of commits...that would imply we have some other bug
+	 * causing the failures.
+	 */
+	igt_assert(fails < NUMITER / 2);
+}
+
+igt_main
+{
+	igt_fixture {
+		data.fd = drm_open_driver(DRIVER_INTEL);
+		igt_skip_on(drmSetClientCap(data.fd, DRM_CLIENT_CAP_ATOMIC, 1));
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_init(&data.display, data.fd);
+
+		igt_skip_on(drmSetClientCap(data.fd, DRM_CLIENT_CAP_ATOMIC, 1));
+	}
+
+	/* Random planes on a single pipe, all planes inside CRTC bounds */
+	igt_subtest_f("bounded-planes")
+		run_test(NONE);
+
+	igt_subtest_f("unbounded-planes")
+		run_test(PLANES_OFFSCREEN);
+
+	igt_fixture
+		igt_display_fini(&data.display);
+}
+
-- 
2.1.4



More information about the Intel-gfx mailing list