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 <[email protected]>
---
 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

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to