* [PATCH i-g-t 0/3] IGT support for nuclear pageflip
@ 2015-01-20 4:05 Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 1/3] lib/kms: Let display commits wait for keypress while debugging Matt Roper
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Matt Roper @ 2015-01-20 4:05 UTC (permalink / raw)
To: intel-gfx
These patches add support for nuclear pageflip to the IGT testsuite to help
exercise the kernel patches just posted.
Note that nuclear pageflip (and eventually full atomic modeset) support
requires a very new libdrm that hasn't yet gone upstream; you can find a copy
in Rob Clark's repo here:
https://github.com/robclark/libdrm.git atomic
All of the nuclear/atomic code is contained inside #ifdef blocks managed by
autoconf, so everything should continue to work properly if you build/run
against an older libdrm that does not have atomic support.
The actual kms_nuclear test added here is a quick copy/paste of parts of the
universal_plane test; it's enough to exercise the nuclear interface and sanity
test that things are hooked up, but it will definitely need to be signficantly
extended to try out all of the corner cases before I'd really consider it
"done."
Matt Roper (3):
lib/kms: Let display commits wait for keypress while debugging
lib/kms: Add nuclear pageflip commit style
tests: Introduce kms_nuclear
configure.ac | 3 +
lib/igt_kms.c | 170 ++++++++++++++++++++++++--
lib/igt_kms.h | 19 ++-
tests/Makefile.sources | 1 +
tests/kms_nuclear.c | 318 +++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 501 insertions(+), 10 deletions(-)
create mode 100644 tests/kms_nuclear.c
--
1.8.5.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH i-g-t 1/3] lib/kms: Let display commits wait for keypress while debugging
2015-01-20 4:05 [PATCH i-g-t 0/3] IGT support for nuclear pageflip Matt Roper
@ 2015-01-20 4:05 ` Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 2/3] lib/kms: Add nuclear pageflip commit style Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 3/3] tests: Introduce kms_nuclear Matt Roper
2 siblings, 0 replies; 7+ messages in thread
From: Matt Roper @ 2015-01-20 4:05 UTC (permalink / raw)
To: intel-gfx
Add a call to igt_debug_wait_for_keypress() immediately before we commit
new hardware state to help simplify display debugging.
To use this, just set the environment variable:
IGT_DEBUG_INTERACTIVE=commit
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
lib/igt_kms.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index d0c3690..bb72c68 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -1551,6 +1551,7 @@ static int do_display_commit(igt_display_t *display,
LOG_INDENT(display, "commit");
+ igt_debug_wait_for_keypress("commit");
igt_display_refresh(display);
for (i = 0; i < display->n_outputs; i++) {
--
1.8.5.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH i-g-t 2/3] lib/kms: Add nuclear pageflip commit style
2015-01-20 4:05 [PATCH i-g-t 0/3] IGT support for nuclear pageflip Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 1/3] lib/kms: Let display commits wait for keypress while debugging Matt Roper
@ 2015-01-20 4:05 ` Matt Roper
2015-03-17 11:53 ` Ander Conselvan De Oliveira
2015-01-20 4:05 ` [PATCH i-g-t 3/3] tests: Introduce kms_nuclear Matt Roper
2 siblings, 1 reply; 7+ messages in thread
From: Matt Roper @ 2015-01-20 4:05 UTC (permalink / raw)
To: intel-gfx
This commit style only covers the "nuclear pageflip" subset of the
atomic API (i.e., single CRTC, plane updates only). In the future when
our kernel driver has full atomic modeset support, we'll add another
commit style 'atomic' which will re-use the same plane commit calls
added here, but will generate and commit property sets in the display's
commit handler rather than the output's commit handler.
Since nuclear pageflip (and full atomic eventually) depend on very new
(currently unreleased) libdrm, use autoconf to check for support so that
we can still run with just legacy + universal styles when built with
older libdrm's.
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
configure.ac | 3 ++
lib/igt_kms.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
lib/igt_kms.h | 19 ++++++-
3 files changed, 181 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac
index 16d6a2e..1e3c2f1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,6 +87,9 @@ PKG_CHECK_MODULES(PCIACCESS, [pciaccess >= 0.10])
PKG_CHECK_MODULES(OVERLAY_XVLIB, [xv x11 xext dri2proto >= 2.6], enable_overlay_xvlib=yes, enable_overlay_xvlib=no)
PKG_CHECK_MODULES(OVERLAY_XLIB, [cairo-xlib dri2proto >= 2.6], enable_overlay_xlib=yes, enable_overlay_xlib=no)
+# Check for atomic modeset support in libdrm
+AC_CHECK_LIB(drm, drmModePropertySetCommit, AC_DEFINE(HAVE_ATOMIC, [], [Atomic modeset supported]))
+
AM_CONDITIONAL(BUILD_OVERLAY_XVLIB, [test "x$enable_overlay_xvlib" = xyes])
AM_CONDITIONAL(BUILD_OVERLAY_XLIB, [test "x$enable_overlay_xlib" = xyes])
AM_CONDITIONAL(BUILD_OVERLAY, [test "x$enable_overlay_xlib" = xyes -o "x$enable_overlay_xvlib"])
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index bb72c68..26e4913 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -50,13 +50,15 @@
#include "igt_debugfs.h"
/*
- * There hasn't been a release of libdrm containing these #define's yet, so
- * copy them here to allow compilation to succeed in the mean time.
+ * Universal plane bits didn't show up until libdrm 2.4.55 and atomic hasn't
+ * landed in a release yet, so copy the relevant #define's here to allow
+ * compilation to succeeed on older libdrm's.
*
* We can drop these #define's and just make i-g-t depend on the proper libdrm
* version in the future.
*/
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
+#define DRM_CLIENT_CAP_ATOMIC 3
#define DRM_PLANE_TYPE_OVERLAY 0
#define DRM_PLANE_TYPE_PRIMARY 1
#define DRM_PLANE_TYPE_CURSOR 2
@@ -944,6 +946,42 @@ static int get_drm_plane_type(int drm_fd, uint32_t plane_id)
return DRM_PLANE_TYPE_OVERLAY;
}
+/*
+ * Lookup all of the properties we use for a plane.
+ */
+static void lookup_plane_properties(int drm_fd,
+ igt_plane_t *plane)
+{
+ uint64_t prop_value;
+
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "rotation",
+ &plane->rotation_property, &prop_value, NULL);
+ plane->rotation = (igt_rotation_t)prop_value;
+
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "FB_ID",
+ &plane->fb_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_ID",
+ &plane->crtc_property, NULL, NULL);
+
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_X",
+ &plane->dstx_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_Y",
+ &plane->dsty_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_W",
+ &plane->dstw_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_H",
+ &plane->dsth_property, NULL, NULL);
+
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "SRC_X",
+ &plane->srcx_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "SRC_Y",
+ &plane->srcy_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "SRC_W",
+ &plane->srcw_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "SRC_H",
+ &plane->srch_property, NULL, NULL);
+}
+
void igt_display_init(igt_display_t *display, int drm_fd)
{
drmModeRes *resources;
@@ -966,6 +1004,7 @@ void igt_display_init(igt_display_t *display, int drm_fd)
display->n_pipes = resources->count_crtcs;
drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
plane_resources = drmModeGetPlaneResources(display->drm_fd);
igt_assert(plane_resources);
@@ -981,7 +1020,6 @@ void igt_display_init(igt_display_t *display, int drm_fd)
/* add the planes that can be used with that pipe */
for (j = 0; j < plane_resources->count_planes; j++) {
drmModePlane *drm_plane;
- uint64_t prop_value;
drm_plane = drmModeGetPlane(display->drm_fd,
plane_resources->planes[j]);
@@ -1023,12 +1061,21 @@ void igt_display_init(igt_display_t *display, int drm_fd)
plane->pipe = pipe;
plane->drm_plane = drm_plane;
- get_plane_property(display->drm_fd, drm_plane->plane_id,
- "rotation",
- &plane->rotation_property,
- &prop_value,
- NULL);
- plane->rotation = (igt_rotation_t)prop_value;
+ lookup_plane_properties(display->drm_fd, plane);
+#ifdef HAVE_ATOMIC
+ display->has_atomic_props =
+ (plane->fb_property &&
+ plane->crtc_property &&
+ plane->rotation_property &&
+ plane->dstx_property &&
+ plane->dsty_property &&
+ plane->dstw_property &&
+ plane->dsth_property &&
+ plane->srcx_property &&
+ plane->srcy_property &&
+ plane->srcw_property &&
+ plane->srch_property);
+#endif
}
if (display->has_universal_planes) {
@@ -1336,6 +1383,79 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
return 0;
}
+#ifdef HAVE_ATOMIC
+/*
+ * Apply plane changes for an atomic operation. Note that we don't actually
+ * perform the commit here; we just push the proper values into the atomic
+ * property set and let either igt_output_commit (nuclear) or
+ * igt_display_commit (atomic) issue the actual commit.
+ */
+static int igt_drm_plane_commit_atomic(igt_plane_t *plane,
+ igt_output_t *output,
+ drmModePropertySetPtr set,
+ bool fail_on_error)
+{
+ uint32_t fb_id, crtc_id, plane_id;
+
+ igt_assert(set);
+ igt_assert(plane->drm_plane);
+
+ /* it's an error to try an unsupported feature */
+ igt_assert(igt_plane_supports_rotation(plane) ||
+ !plane->rotation_changed);
+
+ fb_id = igt_plane_get_fb_id(plane);
+ crtc_id = fb_id ? output->config.crtc->crtc_id : 0;
+ plane_id = plane->drm_plane->plane_id;
+
+ if (plane->fb_changed) {
+ drmModePropertySetAdd(set, plane_id, plane->fb_property,
+ fb_id);
+ drmModePropertySetAdd(set, plane_id,
+ plane->crtc_property, crtc_id);
+ }
+
+ if (plane->fb &&
+ (plane->fb_changed || plane->position_changed || plane->panning_changed)) {
+ /* Source coordinates */
+ drmModePropertySetAdd(set, plane_id,
+ plane->srcx_property,
+ IGT_FIXED(plane->pan_x,0));
+ drmModePropertySetAdd(set, plane_id,
+ plane->srcy_property,
+ IGT_FIXED(plane->pan_y,0));
+ drmModePropertySetAdd(set, plane_id,
+ plane->srcw_property,
+ IGT_FIXED(plane->fb->width - plane->pan_x,0));
+ drmModePropertySetAdd(set, plane_id,
+ plane->srch_property,
+ IGT_FIXED(plane->fb->height - plane->pan_y,0));
+
+ /* Destination coordinates */
+ drmModePropertySetAdd(set, plane_id, plane->dstx_property,
+ plane->crtc_x);
+ drmModePropertySetAdd(set, plane_id, plane->dsty_property,
+ plane->crtc_y);
+ drmModePropertySetAdd(set, plane_id, plane->dstw_property,
+ plane->crtc_w);
+ drmModePropertySetAdd(set, plane_id, plane->dsth_property,
+ plane->crtc_h);
+ }
+
+ if (plane->rotation_changed)
+ drmModePropertySetAdd(set, plane_id, plane->rotation_property,
+ plane->rotation);
+
+
+ plane->fb_changed = false;
+ plane->position_changed = false;
+ plane->panning_changed = false;
+ plane->rotation = false;
+
+ return 0;
+}
+#endif
+
/*
* Commit position and fb changes to a cursor via legacy ioctl's. If commit
* fails, we'll either fail immediately (for tests that expect the commit to
@@ -1486,6 +1606,11 @@ static int igt_plane_commit(igt_plane_t *plane,
} else if (plane->is_primary && s == COMMIT_LEGACY) {
return igt_primary_plane_commit_legacy(plane, output,
fail_on_error);
+#ifdef HAVE_ATOMIC
+ } else if (s == COMMIT_NUCLEAR) {
+ return igt_drm_plane_commit_atomic(plane, output, output->set,
+ fail_on_error);
+#endif
} else {
return igt_drm_plane_commit(plane, output, fail_on_error);
}
@@ -1513,6 +1638,13 @@ static int igt_output_commit(igt_output_t *output,
pipe = igt_output_get_driving_pipe(output);
+#ifdef HAVE_ATOMIC
+ if (s == COMMIT_NUCLEAR) {
+ output->set = drmModePropertySetAlloc();
+ igt_assert(output->set);
+ }
+#endif
+
for (i = 0; i < pipe->n_planes; i++) {
igt_plane_t *plane = &pipe->planes[i];
@@ -1523,6 +1655,17 @@ static int igt_output_commit(igt_output_t *output,
CHECK_RETURN(ret, fail_on_error);
}
+#ifdef HAVE_ATOMIC
+ /* Nuclear pageflip commit */
+ if (s == COMMIT_NUCLEAR) {
+ ret = drmModePropertySetCommit(display->drm_fd, 0, NULL,
+ output->set);
+ drmModePropertySetFree(output->set);
+ output->set = NULL;
+ CHECK_RETURN(ret, fail_on_error);
+ }
+#endif
+
/*
* If the crtc is enabled, wait until the next vblank before returning
* if we made changes to any of the planes.
@@ -1551,6 +1694,14 @@ static int do_display_commit(igt_display_t *display,
LOG_INDENT(display, "commit");
+#ifndef HAVE_ATOMIC
+ /*
+ * If our libdrm doesn't support atomic; skip any tests that explicitly
+ * ask for nuclear pageflip or atomic modeset.
+ */
+ igt_skip_on(s == COMMIT_NUCLEAR);
+#endif
+
igt_debug_wait_for_keypress("commit");
igt_display_refresh(display);
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index a1483a4..2fab30e 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -154,7 +154,8 @@ void kmstest_unset_all_crtcs(int drm_fd, drmModeResPtr resources);
enum igt_commit_style {
COMMIT_LEGACY = 0,
COMMIT_UNIVERSAL,
- /* We'll add atomic here eventually. */
+ COMMIT_NUCLEAR, /* atomic plane operations on single crtc only */
+ /* We'll add full atomic here eventually. */
};
typedef struct igt_display igt_display_t;
@@ -189,6 +190,16 @@ typedef struct {
struct igt_fb *fb;
uint32_t rotation_property;
+ uint32_t fb_property;
+ uint32_t crtc_property;
+ uint32_t dstx_property;
+ uint32_t dsty_property;
+ uint32_t dstw_property;
+ uint32_t dsth_property;
+ uint32_t srcx_property;
+ uint32_t srcy_property;
+ uint32_t srcw_property;
+ uint32_t srch_property;
/* position within pipe_src_w x pipe_src_h */
int crtc_x, crtc_y;
@@ -216,6 +227,11 @@ typedef struct {
char *name;
bool valid;
unsigned long pending_crtc_idx_mask;
+
+#ifdef HAVE_ATOMIC
+ /* Property set for nuclear pageflip */
+ drmModePropertySetPtr set;
+#endif
} igt_output_t;
struct igt_display {
@@ -227,6 +243,7 @@ struct igt_display {
igt_output_t *outputs;
igt_pipe_t pipes[I915_MAX_PIPES];
bool has_universal_planes;
+ bool has_atomic_props;
};
void igt_display_init(igt_display_t *display, int drm_fd);
--
1.8.5.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH i-g-t 3/3] tests: Introduce kms_nuclear
2015-01-20 4:05 [PATCH i-g-t 0/3] IGT support for nuclear pageflip Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 1/3] lib/kms: Let display commits wait for keypress while debugging Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 2/3] lib/kms: Add nuclear pageflip commit style Matt Roper
@ 2015-01-20 4:05 ` Matt Roper
2015-01-20 18:17 ` Thomas Wood
2 siblings, 1 reply; 7+ messages in thread
From: Matt Roper @ 2015-01-20 4:05 UTC (permalink / raw)
To: intel-gfx
A very simple testcase to exercise nuclear pageflip. We'll definitely
want to expand upon this in the future, but this is a good starting
point to sanity check nuclear pageflip support.
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
tests/Makefile.sources | 1 +
tests/kms_nuclear.c | 318 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 319 insertions(+)
create mode 100644 tests/kms_nuclear.c
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 74deec3..9ab0ff4 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -70,6 +70,7 @@ TESTS_progs_M = \
kms_flip_event_leak \
kms_flip_tiling \
kms_mmio_vs_cs_flip \
+ kms_nuclear \
kms_pipe_crc_basic \
kms_plane \
kms_psr_sink_crc \
diff --git a/tests/kms_nuclear.c b/tests/kms_nuclear.c
new file mode 100644
index 0000000..31bfbfe
--- /dev/null
+++ b/tests/kms_nuclear.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright © 2015 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 <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "drmtest.h"
+#include "igt_debugfs.h"
+#include "igt_kms.h"
+
+typedef struct {
+ int drm_fd;
+ igt_display_t display;
+} data_t;
+
+typedef struct {
+ data_t *data;
+ igt_pipe_crc_t *pipe_crc;
+ igt_crc_t crc_1, crc_2, crc_3, crc_4, crc_5, crc_6, crc_7, crc_8,
+ crc_9, crc_10;
+ struct igt_fb red_fb, blue_fb, black_fb, yellow_fb;
+ drmModeModeInfo *mode;
+} functional_test_t;
+
+typedef struct {
+ data_t *data;
+ drmModeResPtr moderes;
+ struct igt_fb blue_fb, oversized_fb, undersized_fb;
+} sanity_test_t;
+
+typedef struct {
+ data_t *data;
+ struct igt_fb red_fb, blue_fb;
+} pageflip_test_t;
+
+static void
+functional_test_init(functional_test_t *test, igt_output_t *output, enum pipe pipe)
+{
+ data_t *data = test->data;
+ drmModeModeInfo *mode;
+
+ test->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+
+ igt_output_set_pipe(output, pipe);
+
+ mode = igt_output_get_mode(output);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 0.0,
+ &test->black_fb);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &test->blue_fb);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 1.0, 1.0, 0.0,
+ &test->yellow_fb);
+ igt_create_color_fb(data->drm_fd, 100, 100,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 1.0, 0.0, 0.0,
+ &test->red_fb);
+
+ test->mode = mode;
+}
+
+static void
+functional_test_fini(functional_test_t *test, igt_output_t *output)
+{
+ igt_pipe_crc_free(test->pipe_crc);
+
+ igt_remove_fb(test->data->drm_fd, &test->black_fb);
+ igt_remove_fb(test->data->drm_fd, &test->blue_fb);
+ igt_remove_fb(test->data->drm_fd, &test->red_fb);
+ igt_remove_fb(test->data->drm_fd, &test->yellow_fb);
+
+ igt_output_set_pipe(output, PIPE_ANY);
+ igt_display_commit2(&test->data->display, COMMIT_LEGACY);
+}
+
+/*
+ * Nuclear pageflip functional testing.
+ * - Black primary plane via traditional interfaces, red sprite, grab CRC:1.
+ * - Blue primary plane via traditional interfaces, red sprite, grab CRC:2.
+ * - Yellow primary via traditional interfaces
+ * - Blue primary plane, red sprite via universal planes, grab CRC:3 and compare
+ * with CRC:2 (should be the same)
+ * - Disable primary plane, grab CRC:4 (should be same as CRC:1)
+ * - Reenable primary, grab CRC:5 (should be same as CRC:2 and CRC:3)
+ * - Yellow primary, no sprite
+ * - Disable CRTC
+ * - Program red sprite (while CRTC off)
+ * - Program blue primary (while CRTC off)
+ * - Enable CRTC, grab CRC:6 (should be same as CRC:2)
+ */
+static void
+functional_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
+{
+ functional_test_t test = { .data = data };
+ igt_display_t *display = &data->display;
+ igt_plane_t *primary, *sprite;
+
+ igt_skip_on(pipe >= display->n_pipes);
+
+ igt_info("Testing connector %s using pipe %s\n", igt_output_name(output),
+ kmstest_pipe_name(pipe));
+
+ functional_test_init(&test, output, pipe);
+
+ primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+ sprite = igt_output_get_plane(output, IGT_PLANE_2);
+ if (!sprite) {
+ functional_test_fini(&test, output);
+ igt_skip("No sprite plane available\n");
+ }
+
+ igt_plane_set_position(sprite, 100, 100);
+
+ /* Step 1: Legacy API's, black primary, red sprite (CRC 1) */
+ igt_plane_set_fb(primary, &test.black_fb);
+ igt_plane_set_fb(sprite, &test.red_fb);
+ igt_display_commit2(display, COMMIT_LEGACY);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_1);
+
+ /* Step 2: Legacy API', blue primary, red sprite (CRC 2) */
+ igt_plane_set_fb(primary, &test.blue_fb);
+ igt_plane_set_fb(sprite, &test.red_fb);
+ igt_display_commit2(display, COMMIT_LEGACY);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_2);
+
+ /* Step 3: Legacy API's, yellow primary (CRC 3) */
+ igt_plane_set_fb(primary, &test.yellow_fb);
+ igt_display_commit2(display, COMMIT_LEGACY);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_3);
+
+ /* Step 4: Nuclear pageflip, blue primary, red sprite (CRC 4) */
+ igt_plane_set_fb(primary, &test.blue_fb);
+ igt_plane_set_fb(sprite, &test.red_fb);
+ igt_display_commit2(display, COMMIT_NUCLEAR);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_4);
+
+ /* Step 5: Nuclear pageflip, disable primary plane (CRC 5) */
+ igt_plane_set_fb(primary, NULL);
+ igt_display_commit2(display, COMMIT_NUCLEAR);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_5);
+
+ /* Step 6: Nuclear pageflip, re-enable primary with blue (CRC 6) */
+ igt_plane_set_fb(primary, &test.blue_fb);
+ igt_display_commit2(display, COMMIT_NUCLEAR);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_6);
+
+ /* Step 7: Disable CRTC */
+ igt_plane_set_fb(primary, NULL);
+ igt_display_commit2(display, COMMIT_LEGACY);
+
+ /* Blue bg + red sprite should be same under both types of API's */
+ igt_assert(igt_crc_equal(&test.crc_2, &test.crc_4));
+
+ /* Disabling primary plane should be same as black primary */
+ igt_assert(igt_crc_equal(&test.crc_1, &test.crc_5));
+
+ /* Re-enabling primary should return to blue properly */
+ igt_assert(igt_crc_equal(&test.crc_2, &test.crc_6));
+
+ igt_plane_set_fb(primary, NULL);
+ igt_plane_set_fb(sprite, NULL);
+
+ functional_test_fini(&test, output);
+}
+
+static void
+sanity_test_init(sanity_test_t *test, igt_output_t *output, enum pipe pipe)
+{
+ data_t *data = test->data;
+ drmModeModeInfo *mode;
+
+ igt_output_set_pipe(output, pipe);
+
+ mode = igt_output_get_mode(output);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &test->blue_fb);
+ igt_create_color_fb(data->drm_fd,
+ mode->hdisplay + 100, mode->vdisplay + 100,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &test->oversized_fb);
+ igt_create_color_fb(data->drm_fd,
+ mode->hdisplay - 100, mode->vdisplay - 100,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &test->undersized_fb);
+
+ test->moderes = drmModeGetResources(data->drm_fd);
+}
+
+static void
+sanity_test_fini(sanity_test_t *test, igt_output_t *output)
+{
+ drmModeFreeResources(test->moderes);
+
+ igt_remove_fb(test->data->drm_fd, &test->oversized_fb);
+ igt_remove_fb(test->data->drm_fd, &test->undersized_fb);
+ igt_remove_fb(test->data->drm_fd, &test->blue_fb);
+
+ igt_output_set_pipe(output, PIPE_ANY);
+ igt_display_commit2(&test->data->display, COMMIT_LEGACY);
+}
+
+static void
+sanity_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
+{
+ sanity_test_t test = { .data = data };
+ igt_plane_t *primary;
+ int ret = 0;
+
+ igt_output_set_pipe(output, pipe);
+
+ sanity_test_init(&test, output, pipe);
+
+ primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+
+ /* Use legacy API to set a mode with a blue FB */
+ igt_plane_set_fb(primary, &test.blue_fb);
+ igt_display_commit2(&data->display, COMMIT_LEGACY);
+
+ /*
+ * Try to use nuclear pageflip API to set primary plane that
+ * doesn't cover CRTC (should fail).
+ */
+ igt_plane_set_fb(primary, &test.undersized_fb);
+ ret = igt_display_try_commit2(&data->display, COMMIT_NUCLEAR);
+ igt_assert(ret == -EINVAL);
+
+ /* Same as above, but different plane positioning. */
+ igt_plane_set_position(primary, 100, 100);
+ ret = igt_display_try_commit2(&data->display, COMMIT_NUCLEAR);
+ igt_assert(ret == -EINVAL);
+
+ igt_plane_set_position(primary, 0, 0);
+ igt_plane_set_fb(primary, NULL);
+ sanity_test_fini(&test, output);
+}
+
+static void
+run_tests_for_pipe(data_t *data, enum pipe pipe)
+{
+ igt_output_t *output;
+
+ igt_subtest_f("nuclear-pageflip-pipe-%s-functional",
+ kmstest_pipe_name(pipe))
+ for_each_connected_output(&data->display, output)
+ functional_test_pipe(data, pipe, output);
+
+ igt_subtest_f("nuclear-pageflip-pipe-%s-sanity",
+ kmstest_pipe_name(pipe))
+ for_each_connected_output(&data->display, output)
+ sanity_test_pipe(data, pipe, output);
+}
+
+static data_t data;
+
+igt_main
+{
+ int num_pipes;
+
+ igt_skip_on_simulation();
+
+ igt_fixture {
+ data.drm_fd = drm_open_any_master();
+
+ kmstest_set_vt_graphics_mode();
+
+ igt_require_pipe_crc();
+ igt_display_init(&data.display, data.drm_fd);
+
+ igt_require(data.display.has_universal_planes);
+ igt_require(data.display.has_atomic_props);
+ }
+
+ num_pipes = igt_display_get_n_pipes(&data.display);
+ for (int pipe = 0; pipe < num_pipes; pipe++)
+ run_tests_for_pipe(&data, pipe);
+
+ igt_fixture {
+ igt_display_fini(&data.display);
+ }
+}
--
1.8.5.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH i-g-t 3/3] tests: Introduce kms_nuclear
2015-01-20 4:05 ` [PATCH i-g-t 3/3] tests: Introduce kms_nuclear Matt Roper
@ 2015-01-20 18:17 ` Thomas Wood
2015-01-26 17:14 ` [PATCH i-g-t 3/3] tests: Introduce kms_nuclear (v2) Matt Roper
0 siblings, 1 reply; 7+ messages in thread
From: Thomas Wood @ 2015-01-20 18:17 UTC (permalink / raw)
To: Matt Roper; +Cc: Intel Graphics Development
On 20 January 2015 at 04:05, Matt Roper <matthew.d.roper@intel.com> wrote:
> A very simple testcase to exercise nuclear pageflip. We'll definitely
> want to expand upon this in the future, but this is a good starting
> point to sanity check nuclear pageflip support.
Just a few comments from an i-g-t perspective: could you add a short
description of the test using IGT_TEST_DESCRIPTION and also add the
binary to .gitignore?
>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
> tests/Makefile.sources | 1 +
> tests/kms_nuclear.c | 318 +++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 319 insertions(+)
> create mode 100644 tests/kms_nuclear.c
>
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 74deec3..9ab0ff4 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -70,6 +70,7 @@ TESTS_progs_M = \
> kms_flip_event_leak \
> kms_flip_tiling \
> kms_mmio_vs_cs_flip \
> + kms_nuclear \
> kms_pipe_crc_basic \
> kms_plane \
> kms_psr_sink_crc \
> diff --git a/tests/kms_nuclear.c b/tests/kms_nuclear.c
> new file mode 100644
> index 0000000..31bfbfe
> --- /dev/null
> +++ b/tests/kms_nuclear.c
> @@ -0,0 +1,318 @@
> +/*
> + * Copyright © 2015 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 <errno.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +#include "drmtest.h"
> +#include "igt_debugfs.h"
> +#include "igt_kms.h"
> +
> +typedef struct {
> + int drm_fd;
> + igt_display_t display;
> +} data_t;
> +
> +typedef struct {
> + data_t *data;
> + igt_pipe_crc_t *pipe_crc;
> + igt_crc_t crc_1, crc_2, crc_3, crc_4, crc_5, crc_6, crc_7, crc_8,
> + crc_9, crc_10;
> + struct igt_fb red_fb, blue_fb, black_fb, yellow_fb;
> + drmModeModeInfo *mode;
> +} functional_test_t;
> +
> +typedef struct {
> + data_t *data;
> + drmModeResPtr moderes;
> + struct igt_fb blue_fb, oversized_fb, undersized_fb;
> +} sanity_test_t;
> +
> +typedef struct {
> + data_t *data;
> + struct igt_fb red_fb, blue_fb;
> +} pageflip_test_t;
> +
> +static void
> +functional_test_init(functional_test_t *test, igt_output_t *output, enum pipe pipe)
> +{
> + data_t *data = test->data;
> + drmModeModeInfo *mode;
> +
> + test->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
> +
> + igt_output_set_pipe(output, pipe);
> +
> + mode = igt_output_get_mode(output);
> + igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
> + DRM_FORMAT_XRGB8888,
> + false, /* tiled */
> + 0.0, 0.0, 0.0,
> + &test->black_fb);
> + igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
> + DRM_FORMAT_XRGB8888,
> + false, /* tiled */
> + 0.0, 0.0, 1.0,
> + &test->blue_fb);
> + igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
> + DRM_FORMAT_XRGB8888,
> + false, /* tiled */
> + 1.0, 1.0, 0.0,
> + &test->yellow_fb);
> + igt_create_color_fb(data->drm_fd, 100, 100,
> + DRM_FORMAT_XRGB8888,
> + false, /* tiled */
> + 1.0, 0.0, 0.0,
> + &test->red_fb);
> +
> + test->mode = mode;
> +}
> +
> +static void
> +functional_test_fini(functional_test_t *test, igt_output_t *output)
> +{
> + igt_pipe_crc_free(test->pipe_crc);
> +
> + igt_remove_fb(test->data->drm_fd, &test->black_fb);
> + igt_remove_fb(test->data->drm_fd, &test->blue_fb);
> + igt_remove_fb(test->data->drm_fd, &test->red_fb);
> + igt_remove_fb(test->data->drm_fd, &test->yellow_fb);
> +
> + igt_output_set_pipe(output, PIPE_ANY);
> + igt_display_commit2(&test->data->display, COMMIT_LEGACY);
> +}
> +
> +/*
> + * Nuclear pageflip functional testing.
> + * - Black primary plane via traditional interfaces, red sprite, grab CRC:1.
> + * - Blue primary plane via traditional interfaces, red sprite, grab CRC:2.
> + * - Yellow primary via traditional interfaces
> + * - Blue primary plane, red sprite via universal planes, grab CRC:3 and compare
> + * with CRC:2 (should be the same)
> + * - Disable primary plane, grab CRC:4 (should be same as CRC:1)
> + * - Reenable primary, grab CRC:5 (should be same as CRC:2 and CRC:3)
> + * - Yellow primary, no sprite
> + * - Disable CRTC
> + * - Program red sprite (while CRTC off)
> + * - Program blue primary (while CRTC off)
> + * - Enable CRTC, grab CRC:6 (should be same as CRC:2)
> + */
> +static void
> +functional_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
> +{
> + functional_test_t test = { .data = data };
> + igt_display_t *display = &data->display;
> + igt_plane_t *primary, *sprite;
> +
> + igt_skip_on(pipe >= display->n_pipes);
> +
> + igt_info("Testing connector %s using pipe %s\n", igt_output_name(output),
> + kmstest_pipe_name(pipe));
> +
> + functional_test_init(&test, output, pipe);
> +
> + primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
> + sprite = igt_output_get_plane(output, IGT_PLANE_2);
> + if (!sprite) {
> + functional_test_fini(&test, output);
> + igt_skip("No sprite plane available\n");
> + }
> +
> + igt_plane_set_position(sprite, 100, 100);
> +
> + /* Step 1: Legacy API's, black primary, red sprite (CRC 1) */
> + igt_plane_set_fb(primary, &test.black_fb);
> + igt_plane_set_fb(sprite, &test.red_fb);
> + igt_display_commit2(display, COMMIT_LEGACY);
> + igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_1);
> +
> + /* Step 2: Legacy API', blue primary, red sprite (CRC 2) */
> + igt_plane_set_fb(primary, &test.blue_fb);
> + igt_plane_set_fb(sprite, &test.red_fb);
> + igt_display_commit2(display, COMMIT_LEGACY);
> + igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_2);
> +
> + /* Step 3: Legacy API's, yellow primary (CRC 3) */
> + igt_plane_set_fb(primary, &test.yellow_fb);
> + igt_display_commit2(display, COMMIT_LEGACY);
> + igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_3);
> +
> + /* Step 4: Nuclear pageflip, blue primary, red sprite (CRC 4) */
> + igt_plane_set_fb(primary, &test.blue_fb);
> + igt_plane_set_fb(sprite, &test.red_fb);
> + igt_display_commit2(display, COMMIT_NUCLEAR);
> + igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_4);
> +
> + /* Step 5: Nuclear pageflip, disable primary plane (CRC 5) */
> + igt_plane_set_fb(primary, NULL);
> + igt_display_commit2(display, COMMIT_NUCLEAR);
> + igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_5);
> +
> + /* Step 6: Nuclear pageflip, re-enable primary with blue (CRC 6) */
> + igt_plane_set_fb(primary, &test.blue_fb);
> + igt_display_commit2(display, COMMIT_NUCLEAR);
> + igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_6);
> +
> + /* Step 7: Disable CRTC */
> + igt_plane_set_fb(primary, NULL);
> + igt_display_commit2(display, COMMIT_LEGACY);
> +
> + /* Blue bg + red sprite should be same under both types of API's */
> + igt_assert(igt_crc_equal(&test.crc_2, &test.crc_4));
> +
> + /* Disabling primary plane should be same as black primary */
> + igt_assert(igt_crc_equal(&test.crc_1, &test.crc_5));
> +
> + /* Re-enabling primary should return to blue properly */
> + igt_assert(igt_crc_equal(&test.crc_2, &test.crc_6));
> +
> + igt_plane_set_fb(primary, NULL);
> + igt_plane_set_fb(sprite, NULL);
> +
> + functional_test_fini(&test, output);
> +}
> +
> +static void
> +sanity_test_init(sanity_test_t *test, igt_output_t *output, enum pipe pipe)
> +{
> + data_t *data = test->data;
> + drmModeModeInfo *mode;
> +
> + igt_output_set_pipe(output, pipe);
> +
> + mode = igt_output_get_mode(output);
> + igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
> + DRM_FORMAT_XRGB8888,
> + false, /* tiled */
> + 0.0, 0.0, 1.0,
> + &test->blue_fb);
> + igt_create_color_fb(data->drm_fd,
> + mode->hdisplay + 100, mode->vdisplay + 100,
> + DRM_FORMAT_XRGB8888,
> + false, /* tiled */
> + 0.0, 0.0, 1.0,
> + &test->oversized_fb);
> + igt_create_color_fb(data->drm_fd,
> + mode->hdisplay - 100, mode->vdisplay - 100,
> + DRM_FORMAT_XRGB8888,
> + false, /* tiled */
> + 0.0, 0.0, 1.0,
> + &test->undersized_fb);
> +
> + test->moderes = drmModeGetResources(data->drm_fd);
> +}
> +
> +static void
> +sanity_test_fini(sanity_test_t *test, igt_output_t *output)
> +{
> + drmModeFreeResources(test->moderes);
> +
> + igt_remove_fb(test->data->drm_fd, &test->oversized_fb);
> + igt_remove_fb(test->data->drm_fd, &test->undersized_fb);
> + igt_remove_fb(test->data->drm_fd, &test->blue_fb);
> +
> + igt_output_set_pipe(output, PIPE_ANY);
> + igt_display_commit2(&test->data->display, COMMIT_LEGACY);
> +}
> +
> +static void
> +sanity_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
> +{
> + sanity_test_t test = { .data = data };
> + igt_plane_t *primary;
> + int ret = 0;
> +
> + igt_output_set_pipe(output, pipe);
> +
> + sanity_test_init(&test, output, pipe);
> +
> + primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
> +
> + /* Use legacy API to set a mode with a blue FB */
> + igt_plane_set_fb(primary, &test.blue_fb);
> + igt_display_commit2(&data->display, COMMIT_LEGACY);
> +
> + /*
> + * Try to use nuclear pageflip API to set primary plane that
> + * doesn't cover CRTC (should fail).
> + */
> + igt_plane_set_fb(primary, &test.undersized_fb);
> + ret = igt_display_try_commit2(&data->display, COMMIT_NUCLEAR);
> + igt_assert(ret == -EINVAL);
> +
> + /* Same as above, but different plane positioning. */
> + igt_plane_set_position(primary, 100, 100);
> + ret = igt_display_try_commit2(&data->display, COMMIT_NUCLEAR);
> + igt_assert(ret == -EINVAL);
> +
> + igt_plane_set_position(primary, 0, 0);
> + igt_plane_set_fb(primary, NULL);
> + sanity_test_fini(&test, output);
> +}
> +
> +static void
> +run_tests_for_pipe(data_t *data, enum pipe pipe)
> +{
> + igt_output_t *output;
> +
> + igt_subtest_f("nuclear-pageflip-pipe-%s-functional",
> + kmstest_pipe_name(pipe))
> + for_each_connected_output(&data->display, output)
> + functional_test_pipe(data, pipe, output);
> +
> + igt_subtest_f("nuclear-pageflip-pipe-%s-sanity",
> + kmstest_pipe_name(pipe))
> + for_each_connected_output(&data->display, output)
> + sanity_test_pipe(data, pipe, output);
> +}
> +
> +static data_t data;
> +
> +igt_main
> +{
> + int num_pipes;
> +
> + igt_skip_on_simulation();
> +
> + igt_fixture {
> + data.drm_fd = drm_open_any_master();
> +
> + kmstest_set_vt_graphics_mode();
> +
> + igt_require_pipe_crc();
> + igt_display_init(&data.display, data.drm_fd);
> +
> + igt_require(data.display.has_universal_planes);
> + igt_require(data.display.has_atomic_props);
> + }
> +
> + num_pipes = igt_display_get_n_pipes(&data.display);
> + for (int pipe = 0; pipe < num_pipes; pipe++)
> + run_tests_for_pipe(&data, pipe);
Using data.display here means that --list-subtests doesn't list any
subtests. The igt_fixture blocks (and the subtests themselves) are not
run when enumerating subtests, which means data.display is not
initialised.
> +
> + igt_fixture {
> + igt_display_fini(&data.display);
> + }
> +}
> --
> 1.8.5.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH i-g-t 3/3] tests: Introduce kms_nuclear (v2)
2015-01-20 18:17 ` Thomas Wood
@ 2015-01-26 17:14 ` Matt Roper
0 siblings, 0 replies; 7+ messages in thread
From: Matt Roper @ 2015-01-26 17:14 UTC (permalink / raw)
To: intel-gfx
A very simple testcase to exercise nuclear pageflip. We'll definitely
want to expand upon this in the future, but this is a good starting
point to sanity check nuclear pageflip support.
v2:
- Add IGT_TEST_DESCRIPTION() (Thomas Wood)
- Don't use fixture-generated pipe number for main loop since this will
prevent proper test enumeration. Just assume three pipes for the
main loop and skip inside the tests if we have fewer. (Thomas Wood)
- Add to .gitignore (Thomas Wood)
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
tests/.gitignore | 1 +
tests/Makefile.sources | 1 +
tests/kms_nuclear.c | 320 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 322 insertions(+)
create mode 100644 tests/kms_nuclear.c
diff --git a/tests/.gitignore b/tests/.gitignore
index 88a6405..15fcf0e 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -128,6 +128,7 @@ kms_flip_event_leak
kms_flip_tiling
kms_force_connector
kms_mmio_vs_cs_flip
+kms_nuclear
kms_pipe_crc_basic
kms_plane
kms_psr_sink_crc
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 74deec3..9ab0ff4 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -70,6 +70,7 @@ TESTS_progs_M = \
kms_flip_event_leak \
kms_flip_tiling \
kms_mmio_vs_cs_flip \
+ kms_nuclear \
kms_pipe_crc_basic \
kms_plane \
kms_psr_sink_crc \
diff --git a/tests/kms_nuclear.c b/tests/kms_nuclear.c
new file mode 100644
index 0000000..e3f7182
--- /dev/null
+++ b/tests/kms_nuclear.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright © 2015 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 <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "drmtest.h"
+#include "igt_debugfs.h"
+#include "igt_kms.h"
+
+IGT_TEST_DESCRIPTION("Simple test of nuclear pageflip functionality");
+
+typedef struct {
+ int drm_fd;
+ igt_display_t display;
+} data_t;
+
+typedef struct {
+ data_t *data;
+ igt_pipe_crc_t *pipe_crc;
+ igt_crc_t crc_1, crc_2, crc_3, crc_4, crc_5, crc_6, crc_7, crc_8,
+ crc_9, crc_10;
+ struct igt_fb red_fb, blue_fb, black_fb, yellow_fb;
+ drmModeModeInfo *mode;
+} functional_test_t;
+
+typedef struct {
+ data_t *data;
+ drmModeResPtr moderes;
+ struct igt_fb blue_fb, oversized_fb, undersized_fb;
+} sanity_test_t;
+
+typedef struct {
+ data_t *data;
+ struct igt_fb red_fb, blue_fb;
+} pageflip_test_t;
+
+static void
+functional_test_init(functional_test_t *test, igt_output_t *output, enum pipe pipe)
+{
+ data_t *data = test->data;
+ drmModeModeInfo *mode;
+
+ test->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+
+ igt_output_set_pipe(output, pipe);
+
+ mode = igt_output_get_mode(output);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 0.0,
+ &test->black_fb);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &test->blue_fb);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 1.0, 1.0, 0.0,
+ &test->yellow_fb);
+ igt_create_color_fb(data->drm_fd, 100, 100,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 1.0, 0.0, 0.0,
+ &test->red_fb);
+
+ test->mode = mode;
+}
+
+static void
+functional_test_fini(functional_test_t *test, igt_output_t *output)
+{
+ igt_pipe_crc_free(test->pipe_crc);
+
+ igt_remove_fb(test->data->drm_fd, &test->black_fb);
+ igt_remove_fb(test->data->drm_fd, &test->blue_fb);
+ igt_remove_fb(test->data->drm_fd, &test->red_fb);
+ igt_remove_fb(test->data->drm_fd, &test->yellow_fb);
+
+ igt_output_set_pipe(output, PIPE_ANY);
+ igt_display_commit2(&test->data->display, COMMIT_LEGACY);
+}
+
+/*
+ * Nuclear pageflip functional testing.
+ * - Black primary plane via traditional interfaces, red sprite, grab CRC:1.
+ * - Blue primary plane via traditional interfaces, red sprite, grab CRC:2.
+ * - Yellow primary via traditional interfaces
+ * - Blue primary plane, red sprite via universal planes, grab CRC:3 and compare
+ * with CRC:2 (should be the same)
+ * - Disable primary plane, grab CRC:4 (should be same as CRC:1)
+ * - Reenable primary, grab CRC:5 (should be same as CRC:2 and CRC:3)
+ * - Yellow primary, no sprite
+ * - Disable CRTC
+ * - Program red sprite (while CRTC off)
+ * - Program blue primary (while CRTC off)
+ * - Enable CRTC, grab CRC:6 (should be same as CRC:2)
+ */
+static void
+functional_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
+{
+ functional_test_t test = { .data = data };
+ igt_display_t *display = &data->display;
+ igt_plane_t *primary, *sprite;
+
+ igt_skip_on(pipe >= display->n_pipes);
+
+ igt_info("Testing connector %s using pipe %s\n", igt_output_name(output),
+ kmstest_pipe_name(pipe));
+
+ functional_test_init(&test, output, pipe);
+
+ primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+ sprite = igt_output_get_plane(output, IGT_PLANE_2);
+ if (!sprite) {
+ functional_test_fini(&test, output);
+ igt_skip("No sprite plane available\n");
+ }
+
+ igt_plane_set_position(sprite, 100, 100);
+
+ /* Step 1: Legacy API's, black primary, red sprite (CRC 1) */
+ igt_plane_set_fb(primary, &test.black_fb);
+ igt_plane_set_fb(sprite, &test.red_fb);
+ igt_display_commit2(display, COMMIT_LEGACY);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_1);
+
+ /* Step 2: Legacy API', blue primary, red sprite (CRC 2) */
+ igt_plane_set_fb(primary, &test.blue_fb);
+ igt_plane_set_fb(sprite, &test.red_fb);
+ igt_display_commit2(display, COMMIT_LEGACY);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_2);
+
+ /* Step 3: Legacy API's, yellow primary (CRC 3) */
+ igt_plane_set_fb(primary, &test.yellow_fb);
+ igt_display_commit2(display, COMMIT_LEGACY);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_3);
+
+ /* Step 4: Nuclear pageflip, blue primary, red sprite (CRC 4) */
+ igt_plane_set_fb(primary, &test.blue_fb);
+ igt_plane_set_fb(sprite, &test.red_fb);
+ igt_display_commit2(display, COMMIT_NUCLEAR);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_4);
+
+ /* Step 5: Nuclear pageflip, disable primary plane (CRC 5) */
+ igt_plane_set_fb(primary, NULL);
+ igt_display_commit2(display, COMMIT_NUCLEAR);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_5);
+
+ /* Step 6: Nuclear pageflip, re-enable primary with blue (CRC 6) */
+ igt_plane_set_fb(primary, &test.blue_fb);
+ igt_display_commit2(display, COMMIT_NUCLEAR);
+ igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_6);
+
+ /* Step 7: Disable CRTC */
+ igt_plane_set_fb(primary, NULL);
+ igt_display_commit2(display, COMMIT_LEGACY);
+
+ /* Blue bg + red sprite should be same under both types of API's */
+ igt_assert(igt_crc_equal(&test.crc_2, &test.crc_4));
+
+ /* Disabling primary plane should be same as black primary */
+ igt_assert(igt_crc_equal(&test.crc_1, &test.crc_5));
+
+ /* Re-enabling primary should return to blue properly */
+ igt_assert(igt_crc_equal(&test.crc_2, &test.crc_6));
+
+ igt_plane_set_fb(primary, NULL);
+ igt_plane_set_fb(sprite, NULL);
+
+ functional_test_fini(&test, output);
+}
+
+static void
+sanity_test_init(sanity_test_t *test, igt_output_t *output, enum pipe pipe)
+{
+ data_t *data = test->data;
+ drmModeModeInfo *mode;
+
+ igt_output_set_pipe(output, pipe);
+
+ mode = igt_output_get_mode(output);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &test->blue_fb);
+ igt_create_color_fb(data->drm_fd,
+ mode->hdisplay + 100, mode->vdisplay + 100,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &test->oversized_fb);
+ igt_create_color_fb(data->drm_fd,
+ mode->hdisplay - 100, mode->vdisplay - 100,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &test->undersized_fb);
+
+ test->moderes = drmModeGetResources(data->drm_fd);
+}
+
+static void
+sanity_test_fini(sanity_test_t *test, igt_output_t *output)
+{
+ drmModeFreeResources(test->moderes);
+
+ igt_remove_fb(test->data->drm_fd, &test->oversized_fb);
+ igt_remove_fb(test->data->drm_fd, &test->undersized_fb);
+ igt_remove_fb(test->data->drm_fd, &test->blue_fb);
+
+ igt_output_set_pipe(output, PIPE_ANY);
+ igt_display_commit2(&test->data->display, COMMIT_LEGACY);
+}
+
+static void
+sanity_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
+{
+ sanity_test_t test = { .data = data };
+ igt_plane_t *primary;
+ int ret = 0;
+
+ igt_skip_on(pipe >= data->display.n_pipes);
+
+ igt_output_set_pipe(output, pipe);
+
+ sanity_test_init(&test, output, pipe);
+
+ primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+
+ /* Use legacy API to set a mode with a blue FB */
+ igt_plane_set_fb(primary, &test.blue_fb);
+ igt_display_commit2(&data->display, COMMIT_LEGACY);
+
+ /*
+ * Try to use nuclear pageflip API to set primary plane that
+ * doesn't cover CRTC (should fail).
+ */
+ igt_plane_set_fb(primary, &test.undersized_fb);
+ ret = igt_display_try_commit2(&data->display, COMMIT_NUCLEAR);
+ igt_assert(ret == -EINVAL);
+
+ /* Same as above, but different plane positioning. */
+ igt_plane_set_position(primary, 100, 100);
+ ret = igt_display_try_commit2(&data->display, COMMIT_NUCLEAR);
+ igt_assert(ret == -EINVAL);
+
+ igt_plane_set_position(primary, 0, 0);
+ igt_plane_set_fb(primary, NULL);
+ sanity_test_fini(&test, output);
+}
+
+static void
+run_tests_for_pipe(data_t *data, enum pipe pipe)
+{
+ igt_output_t *output;
+
+ igt_subtest_f("nuclear-pageflip-pipe-%s-functional",
+ kmstest_pipe_name(pipe))
+ for_each_connected_output(&data->display, output)
+ functional_test_pipe(data, pipe, output);
+
+ igt_subtest_f("nuclear-pageflip-pipe-%s-sanity",
+ kmstest_pipe_name(pipe))
+ for_each_connected_output(&data->display, output)
+ sanity_test_pipe(data, pipe, output);
+}
+
+static data_t data;
+
+igt_main
+{
+
+ igt_skip_on_simulation();
+
+ igt_fixture {
+ data.drm_fd = drm_open_any_master();
+
+ kmstest_set_vt_graphics_mode();
+
+ igt_require_pipe_crc();
+ igt_display_init(&data.display, data.drm_fd);
+
+ igt_require(data.display.has_universal_planes);
+ igt_require(data.display.has_atomic_props);
+ }
+
+ for (int pipe = 0; pipe < 3; pipe++)
+ run_tests_for_pipe(&data, pipe);
+
+ igt_fixture {
+ igt_display_fini(&data.display);
+ }
+}
--
1.8.5.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH i-g-t 2/3] lib/kms: Add nuclear pageflip commit style
2015-01-20 4:05 ` [PATCH i-g-t 2/3] lib/kms: Add nuclear pageflip commit style Matt Roper
@ 2015-03-17 11:53 ` Ander Conselvan De Oliveira
0 siblings, 0 replies; 7+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-17 11:53 UTC (permalink / raw)
To: Matt Roper; +Cc: intel-gfx
On Mon, 2015-01-19 at 20:05 -0800, Matt Roper wrote:
> This commit style only covers the "nuclear pageflip" subset of the
> atomic API (i.e., single CRTC, plane updates only). In the future when
> our kernel driver has full atomic modeset support, we'll add another
> commit style 'atomic' which will re-use the same plane commit calls
> added here, but will generate and commit property sets in the display's
> commit handler rather than the output's commit handler.
>
> Since nuclear pageflip (and full atomic eventually) depend on very new
> (currently unreleased) libdrm, use autoconf to check for support so that
> we can still run with just legacy + universal styles when built with
> older libdrm's.
>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
> configure.ac | 3 ++
> lib/igt_kms.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
> lib/igt_kms.h | 19 ++++++-
> 3 files changed, 181 insertions(+), 10 deletions(-)
[...]
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index a1483a4..2fab30e 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
[...]
> @@ -216,6 +227,11 @@ typedef struct {
> char *name;
> bool valid;
> unsigned long pending_crtc_idx_mask;
> +
> +#ifdef HAVE_ATOMIC
> + /* Property set for nuclear pageflip */
> + drmModePropertySetPtr set;
> +#endif
> } igt_output_t;
Need to include config.h in the header file, otherwise code that depends
on the size of igt_output_t on the tests might do the wrong thing.
Ander
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-03-17 11:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-20 4:05 [PATCH i-g-t 0/3] IGT support for nuclear pageflip Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 1/3] lib/kms: Let display commits wait for keypress while debugging Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 2/3] lib/kms: Add nuclear pageflip commit style Matt Roper
2015-03-17 11:53 ` Ander Conselvan De Oliveira
2015-01-20 4:05 ` [PATCH i-g-t 3/3] tests: Introduce kms_nuclear Matt Roper
2015-01-20 18:17 ` Thomas Wood
2015-01-26 17:14 ` [PATCH i-g-t 3/3] tests: Introduce kms_nuclear (v2) Matt Roper
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox